You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@reef.apache.org by af...@apache.org on 2016/01/31 10:00:10 UTC

reef git commit: [REEF-1169] Implement REST requests using .NET HttpClient in O.A.R.Client

Repository: reef
Updated Branches:
  refs/heads/master 407041dcd -> 76adb40cf


[REEF-1169] Implement REST requests using .NET HttpClient in O.A.R.Client

This addressed the issue by
 * Implementing IRestRequest, IRestResponse and IRestClient based on .NET
 * httpclient

JIRA:
  [REEF-1169](https://issues.apache.org/jira/browse/REEF-1169)

Pull Request:
  Closes #805


Project: http://git-wip-us.apache.org/repos/asf/reef/repo
Commit: http://git-wip-us.apache.org/repos/asf/reef/commit/76adb40c
Tree: http://git-wip-us.apache.org/repos/asf/reef/tree/76adb40c
Diff: http://git-wip-us.apache.org/repos/asf/reef/diff/76adb40c

Branch: refs/heads/master
Commit: 76adb40cf422e0d46021516ec3a9318ddf13dc3a
Parents: 407041d
Author: Anupam <an...@gmail.com>
Authored: Thu Jan 7 16:27:23 2016 -0800
Committer: Andrew Chung <af...@apache.org>
Committed: Sun Jan 31 00:58:45 2016 -0800

----------------------------------------------------------------------
 lang/cs/.nuget/packages.config                  |   2 +-
 .../Org.Apache.REEF.Client.Tests.csproj         |  12 +-
 .../RestClientTests.cs                          | 188 +++++++++++++++++++
 .../YarnClientTests.cs                          |  35 ++--
 .../packages.config                             |   3 +-
 .../Org.Apache.REEF.Client.csproj               |  25 ++-
 .../YARN/RESTClient/HttpClient.cs               |  59 ++++++
 .../YARN/RESTClient/HttpClientRetryHandler.cs   |  68 +++++++
 .../YARN/RESTClient/IDeserializer.cs            |  33 ++++
 .../YARN/RESTClient/IHttpClient.cs              |  37 ++++
 .../YARN/RESTClient/IRequestFactory.cs          |  43 +++++
 .../YARN/RESTClient/IRestClient.cs              |  43 +++++
 .../YARN/RESTClient/IRestClientFactory.cs       |  52 -----
 .../YARN/RESTClient/IRestRequestExecutor.cs     |  20 +-
 .../YARN/RESTClient/ISerializer.cs              |  33 ++++
 .../YARN/RESTClient/Method.cs                   |  26 +++
 .../YARN/RESTClient/RequestFactory.cs           |  76 ++++++++
 .../YARN/RESTClient/RestClient.cs               | 141 ++++++++++++++
 .../YARN/RESTClient/RestJsonDeserializer.cs     |  31 +--
 .../YARN/RESTClient/RestJsonSerializer.cs       |  28 ++-
 .../YARN/RESTClient/RestRequest.cs              |  49 +++++
 .../YARN/RESTClient/RestRequestExecutor.cs      |  92 ++++++---
 .../YARN/RESTClient/RestResponse.cs             |  50 +++++
 .../YARN/RESTClient/YarnClient.cs               |  57 +++---
 .../YARN/RESTClient/YarnRestAPIException.cs     |   3 +
 lang/cs/Org.Apache.REEF.Client/packages.config  |   4 +-
 .../AsyncUtils/VoidResult.cs                    |  31 +++
 .../Org.Apache.Reef.Utilities.csproj            |   1 +
 lang/cs/Org.Apache.REEF.sln                     | Bin 34256 -> 34618 bytes
 29 files changed, 1057 insertions(+), 185 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/.nuget/packages.config
----------------------------------------------------------------------
diff --git a/lang/cs/.nuget/packages.config b/lang/cs/.nuget/packages.config
index a4f6043..ca0774b 100644
--- a/lang/cs/.nuget/packages.config
+++ b/lang/cs/.nuget/packages.config
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <!--
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client.Tests/Org.Apache.REEF.Client.Tests.csproj
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client.Tests/Org.Apache.REEF.Client.Tests.csproj b/lang/cs/Org.Apache.REEF.Client.Tests/Org.Apache.REEF.Client.Tests.csproj
index 7260f07..724fe05 100644
--- a/lang/cs/Org.Apache.REEF.Client.Tests/Org.Apache.REEF.Client.Tests.csproj
+++ b/lang/cs/Org.Apache.REEF.Client.Tests/Org.Apache.REEF.Client.Tests.csproj
@@ -41,11 +41,8 @@ under the License.
       <HintPath>$(PackagesDir)\NSubstitute.1.8.2.0\lib\net45\NSubstitute.dll</HintPath>
       <Private>True</Private>
     </Reference>
-    <Reference Include="RestSharp, Version=100.0.0.0, Culture=neutral, PublicKeyToken=598062e77f915f75, processorArchitecture=MSIL">
-      <HintPath>$(PackagesDir)\RestSharpSigned.105.2.3\lib\net45\RestSharp.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
     <Reference Include="System" />
+    <Reference Include="System.Net.Http" />
     <Reference Include="System.ServiceProcess" />
     <Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
       <HintPath>$(PackagesDir)\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll</HintPath>
@@ -68,6 +65,7 @@ under the License.
     <Compile Include="JobResourceUploaderTests.cs" />
     <Compile Include="LegacyJobResourceUploaderTests.cs" />
     <Compile Include="MultipleRMUrlProviderTests.cs" />
+    <Compile Include="RestClientTests.cs" />
     <Compile Include="WindowsHadoopEmulatorYarnClientTests.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="YarnClientTests.cs" />
@@ -87,6 +85,10 @@ under the License.
       <Project>{97DBB573-3994-417A-9F69-FFA25F00D2A6}</Project>
       <Name>Org.Apache.REEF.Tang</Name>
     </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\Org.Apache.REEF.Utilities\Org.Apache.REEF.Utilities.csproj">
+      <Project>{79E7F89A-1DFB-45E1-8D43-D71A954AEB98}</Project>
+      <Name>Org.Apache.REEF.Utilities</Name>
+    </ProjectReference>
   </ItemGroup>
   <ItemGroup>
     <None Include="packages.config" />
@@ -109,4 +111,4 @@ under the License.
   <Target Name="AfterBuild">
   </Target>
   -->
-</Project>
+</Project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client.Tests/RestClientTests.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client.Tests/RestClientTests.cs b/lang/cs/Org.Apache.REEF.Client.Tests/RestClientTests.cs
new file mode 100644
index 0000000..a970cf9
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Client.Tests/RestClientTests.cs
@@ -0,0 +1,188 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+
+using System;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using NSubstitute;
+using Org.Apache.REEF.Client.YARN.RestClient;
+using Org.Apache.REEF.Tang.Implementations.Tang;
+using Org.Apache.REEF.Tang.Util;
+
+namespace Org.Apache.REEF.Client.Tests
+{
+    [TestClass]
+    public class RestClientTests
+    {
+        private const string AnyResource = "anyResource";
+        private const string AnyRootElement = "anyRootElement";
+        private const int AnyIntField = 42;
+        private const string AnyStringField = "AnyStringFieldValue";
+        private const string MediaType = @"application/json";
+
+        private static readonly string ExpectedReturnJson =
+            "{anyRootElement:{\"AnyStringField\":\"" + AnyStringField + "\",\"AnyIntField\":" + AnyIntField + "}}";
+
+        private static readonly string AnyPostContent =
+            "{\"AnyStringField\":\"" + AnyStringField + "\"}";
+
+        private static readonly Uri AnyRequestUri = new Uri("http://any/request/uri");
+        private static readonly Encoding Encoding = Encoding.UTF8;
+
+        [TestMethod]
+        public async Task RestClientGetRequestReturnsResponse()
+        {
+            var tc = new TestContext();
+
+            var client = tc.GetRestClient();
+
+            var anyRequest = new RestRequest
+            {
+                Method = Method.GET,
+                Resource = AnyResource,
+                RootElement = AnyRootElement
+            };
+
+            var successfulResponseMessage = CreateSuccessfulResponseMessage();
+            tc.HttpClient.GetAsync(AnyRequestUri + anyRequest.Resource, CancellationToken.None)
+                .Returns(Task.FromResult(successfulResponseMessage));
+
+            var response =
+                await client.ExecuteRequestAsync<AnyResponse>(anyRequest, AnyRequestUri, CancellationToken.None);
+
+            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
+            Assert.AreEqual(AnyStringField, response.Data.AnyStringField);
+            Assert.AreEqual(AnyIntField, response.Data.AnyIntField);
+            Assert.IsNull(response.Exception);
+            var unused = tc.HttpClient.Received(1).GetAsync(AnyRequestUri + anyRequest.Resource, CancellationToken.None);
+        }
+
+        [TestMethod]
+        public async Task RestClientPostRequestReturnsResponse()
+        {
+            var tc = new TestContext();
+
+            var client = tc.GetRestClient();
+
+            var anyRequest = new RestRequest
+            {
+                Method = Method.POST,
+                Resource = AnyResource,
+                RootElement = AnyRootElement,
+                Content = new StringContent(AnyPostContent, Encoding, MediaType)
+            };
+
+            var successfulResponseMessage = CreateSuccessfulResponseMessage();
+            tc.HttpClient.PostAsync(AnyRequestUri + anyRequest.Resource,
+                Arg.Is<StringContent>(
+                    stringContent =>
+                        stringContent.Headers.ContentType.MediaType == MediaType &&
+                        stringContent.ReadAsStringAsync().Result == AnyPostContent),
+                CancellationToken.None)
+                .Returns(Task.FromResult(successfulResponseMessage));
+
+            var response =
+                await client.ExecuteRequestAsync<AnyResponse>(anyRequest, AnyRequestUri, CancellationToken.None);
+
+            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
+            Assert.AreEqual(AnyStringField, response.Data.AnyStringField);
+            Assert.AreEqual(AnyIntField, response.Data.AnyIntField);
+            Assert.IsNull(response.Exception);
+            var unused = tc.HttpClient.Received(1).PostAsync(AnyRequestUri + anyRequest.Resource,
+                Arg.Is<StringContent>(
+                    stringContent =>
+                        stringContent.Headers.ContentType.MediaType == MediaType &&
+                        stringContent.ReadAsStringAsync().Result == AnyPostContent),
+                CancellationToken.None);
+        }
+
+        [TestMethod]
+        public async Task RestClientRequestReturnsFailureResponse()
+        {
+            var tc = new TestContext();
+
+            var client = tc.GetRestClient();
+
+            var anyRequest = new RestRequest
+            {
+                Method = Method.GET,
+                Resource = AnyResource,
+                RootElement = AnyRootElement
+            };
+
+            var successfulResponseMessage = CreateFailedResponseMessage();
+            tc.HttpClient.GetAsync(AnyRequestUri + anyRequest.Resource, CancellationToken.None)
+                .Returns(Task.FromResult(successfulResponseMessage));
+
+            var response =
+                await client.ExecuteRequestAsync<AnyResponse>(anyRequest, AnyRequestUri, CancellationToken.None);
+
+            Assert.AreEqual(HttpStatusCode.InternalServerError, response.StatusCode);
+            Assert.IsNull(response.Data);
+            Assert.IsNotNull(response.Exception);
+            Assert.IsInstanceOfType(response.Exception, typeof(HttpRequestException));
+            var unused = tc.HttpClient.Received(1).GetAsync(AnyRequestUri + anyRequest.Resource, CancellationToken.None);
+        }
+
+        private HttpResponseMessage CreateSuccessfulResponseMessage()
+        {
+            return new HttpResponseMessage(HttpStatusCode.OK)
+            {
+                Content = new StringContent(ExpectedReturnJson, Encoding, MediaType)
+            };
+        }
+
+        private HttpResponseMessage CreateFailedResponseMessage()
+        {
+            return new HttpResponseMessage(HttpStatusCode.InternalServerError)
+            {
+                Content = new StringContent("AnyFailedContent", Encoding, MediaType)
+            };
+        }
+
+        private class TestContext
+        {
+            public readonly IHttpClient HttpClient = Substitute.For<IHttpClient>();
+
+            public readonly IDeserializer Deserializer = Substitute.For<IDeserializer>();
+
+            public IRestClient GetRestClient()
+            {
+                var injector = TangFactory.GetTang().NewInjector();
+                injector.BindVolatileInstance(GenericType<IHttpClient>.Class, HttpClient);
+                ////injector.BindVolatileInstance(GenericType<IDeserializer>.Class, Deserializer);
+                return injector.GetInstance<IRestClient>();
+            }
+        }
+
+        private class AnyResponse
+        {
+            public string AnyStringField { get; set; }
+
+            public int AnyIntField { get; set; }
+        }
+
+        private class AnyRequest
+        {
+            public string AnyStringField { get; set; }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client.Tests/YarnClientTests.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client.Tests/YarnClientTests.cs b/lang/cs/Org.Apache.REEF.Client.Tests/YarnClientTests.cs
index fe07cc0..3858b12 100644
--- a/lang/cs/Org.Apache.REEF.Client.Tests/YarnClientTests.cs
+++ b/lang/cs/Org.Apache.REEF.Client.Tests/YarnClientTests.cs
@@ -27,7 +27,7 @@ using Org.Apache.REEF.Client.YARN.RestClient;
 using Org.Apache.REEF.Client.YARN.RestClient.DataModel;
 using Org.Apache.REEF.Tang.Implementations.Tang;
 using Org.Apache.REEF.Tang.Util;
-using RestSharp;
+using Org.Apache.REEF.Utilities.AsyncUtils;
 using Xunit;
 
 namespace Org.Apache.REEF.Client.Tests
@@ -50,7 +50,7 @@ namespace Org.Apache.REEF.Client.Tests
                 HadoopVersionBuiltOn = "AnyVersionBuildOn",
             };
             restReqExecutor.ExecuteAsync<ClusterInfo>(
-                Arg.Is<IRestRequest>(
+                Arg.Is<RestRequest>(
                     req =>
                         req.Resource == "ws/v1/cluster/info" && req.RootElement == "clusterInfo" &&
                         req.Method == Method.GET),
@@ -82,7 +82,7 @@ namespace Org.Apache.REEF.Client.Tests
                 AppsCompleted = 301
             };
             restReqExecutor.ExecuteAsync<ClusterMetrics>(
-                Arg.Is<IRestRequest>(
+                Arg.Is<RestRequest>(
                     req =>
                         req.Resource == "ws/v1/cluster/metrics" && req.RootElement == "clusterMetrics" &&
                         req.Method == Method.GET),
@@ -116,7 +116,7 @@ namespace Org.Apache.REEF.Client.Tests
                 RunningContainers = 0
             };
             restReqExecutor.ExecuteAsync<Application>(
-                Arg.Is<IRestRequest>(
+                Arg.Is<RestRequest>(
                     req =>
                         req.Resource == "ws/v1/cluster/apps/" + applicationId
                         && req.RootElement == "app"
@@ -152,7 +152,7 @@ namespace Org.Apache.REEF.Client.Tests
                 RunningContainers = 0
             };
             restReqExecutor.ExecuteAsync<Application>(
-                Arg.Is<IRestRequest>(
+                Arg.Is<RestRequest>(
                     req =>
                         req.Resource == "ws/v1/cluster/apps/" + applicationId
                         && req.RootElement == "app"
@@ -181,7 +181,7 @@ namespace Org.Apache.REEF.Client.Tests
                 ApplicationId = applicationId
             };
             restReqExecutor.ExecuteAsync<NewApplication>(
-                Arg.Is<IRestRequest>(
+                Arg.Is<RestRequest>(
                     req =>
                         req.Resource == "ws/v1/cluster/apps/new-application"
                         && req.Method == Method.POST),
@@ -298,30 +298,23 @@ namespace Org.Apache.REEF.Client.Tests
                 RunningContainers = 0
             };
 
-            var response = Substitute.For<IRestResponse>();
-            response.Headers.Returns(new List<Parameter>
+            var response = new RestResponse<VoidResult>
             {
-                new Parameter
-                {
-                    Name = "Location",
-                    Value = "http://somelocation"
-                }
-            });
-            response.StatusCode.Returns(HttpStatusCode.Accepted);
+                StatusCode = HttpStatusCode.Accepted
+            };
 
             restReqExecutor.ExecuteAsync(
-                Arg.Is<IRestRequest>(
+                Arg.Is<RestRequest>(
                     req =>
                         req.Resource == "ws/v1/cluster/apps"
                         && req.Method == Method.POST
-                        && req.JsonSerializer is RestJsonSerializer
-                        && req.Parameters.First().Name == "application/json"
+                        && req.Content.Headers.ContentType.MediaType == "application/json"
                         && IsExpectedJson(req, expectedJson)),
                 anyUri.First(),
                 CancellationToken.None).Returns(Task.FromResult(response));
 
             restReqExecutor.ExecuteAsync<Application>(
-                Arg.Is<IRestRequest>(
+                Arg.Is<RestRequest>(
                     req =>
                         req.Resource == "ws/v1/cluster/apps/" + applicationId
                         && req.RootElement == "app"
@@ -336,9 +329,9 @@ namespace Org.Apache.REEF.Client.Tests
             var unused = urlProvider.Received(2).GetUrlAsync();
         }
 
-        private static bool IsExpectedJson(IRestRequest req, string expectedJson)
+        private static bool IsExpectedJson(RestRequest req, string expectedJson)
         {
-            return (string)req.Parameters.First().Value == expectedJson;
+            return req.Content.ReadAsStringAsync().Result == expectedJson;
         }
 
         private class TestContext

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client.Tests/packages.config
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client.Tests/packages.config b/lang/cs/Org.Apache.REEF.Client.Tests/packages.config
index 779566d..4a71ef7 100644
--- a/lang/cs/Org.Apache.REEF.Client.Tests/packages.config
+++ b/lang/cs/Org.Apache.REEF.Client.Tests/packages.config
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <!--
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
@@ -19,7 +19,6 @@ under the License.
 -->
 <packages>
   <package id="NSubstitute" version="1.8.2.0" targetFramework="net45" />
-  <package id="RestSharpSigned" version="105.2.3" targetFramework="net45" />
   <package id="StyleCop.MSBuild" version="4.7.49.1" targetFramework="net45" developmentDependency="true" />
   <package id="xunit" version="2.1.0" targetFramework="net45" />
   <package id="xunit.abstractions" version="2.0.0" targetFramework="net45" />

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/Org.Apache.REEF.Client.csproj
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/Org.Apache.REEF.Client.csproj b/lang/cs/Org.Apache.REEF.Client/Org.Apache.REEF.Client.csproj
index df01b65..91a2114 100644
--- a/lang/cs/Org.Apache.REEF.Client/Org.Apache.REEF.Client.csproj
+++ b/lang/cs/Org.Apache.REEF.Client/Org.Apache.REEF.Client.csproj
@@ -38,12 +38,13 @@ under the License.
   </PropertyGroup>
   <ItemGroup>
     <Reference Include="Microsoft.CSharp" />
+    <Reference Include="Microsoft.Practices.TransientFaultHandling.Core, Version=5.1.1209.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>$(PackagesDir)\TransientFaultHandling.Core.5.1.1209.1\lib\NET4\Microsoft.Practices.TransientFaultHandling.Core.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
     <Reference Include="Newtonsoft.Json">
       <HintPath>$(PackagesDir)\Newtonsoft.Json.$(NewtonsoftJsonVersion)\lib\net45\Newtonsoft.Json.dll</HintPath>
     </Reference>
-    <Reference Include="RestSharp, Version=100.0.0.0, Culture=neutral, PublicKeyToken=598062e77f915f75, processorArchitecture=MSIL">
-      <HintPath>$(PackagesDir)\RestSharpSigned.105.2.3\lib\net45\RestSharp.dll</HintPath>
-    </Reference>
     <Reference Include="Microsoft.Hadoop.Avro">
       <HintPath>$(PackagesDir)\Microsoft.Hadoop.Avro.$(AvroVersion)\lib\net45\Microsoft.Hadoop.Avro.dll</HintPath>
     </Reference>
@@ -52,6 +53,7 @@ under the License.
     <Reference Include="System.IO.Compression" />
     <Reference Include="System.IO.Compression.FileSystem" />
     <Reference Include="System.Net.Http" />
+    <Reference Include="System.Net.Http.WebRequest" />
     <Reference Include="System.Xml" />
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Runtime.Serialization" />
@@ -95,6 +97,20 @@ under the License.
     <Compile Include="YARN\IJobSubmissionDirectoryProvider.cs" />
     <Compile Include="YARN\Parameters\DriverMaxMemoryAllicationPoolSizeMB.cs" />
     <Compile Include="YARN\Parameters\DriverMaxPermSizeMB.cs" />
+    <Compile Include="YARN\RestClient\HttpClient.cs" />
+    <Compile Include="YARN\RestClient\IDeserializer.cs" />
+    <Compile Include="YARN\RestClient\IHttpClient.cs" />
+    <Compile Include="YARN\RestClient\IRequestFactory.cs" />
+    <Compile Include="YARN\RestClient\IRestClient.cs" />
+    <Compile Include="YARN\RestClient\ISerializer.cs" />
+    <Compile Include="YARN\RestClient\Method.cs" />
+    <Compile Include="YARN\RestClient\RequestFactory.cs" />
+    <Compile Include="YARN\RestClient\RestClient.cs" />
+    <Compile Include="YARN\RestClient\RestJsonDeserializer.cs" />
+    <Compile Include="YARN\RestClient\RestJsonSerializer.cs" />
+    <Compile Include="YARN\RestClient\RestRequest.cs" />
+    <Compile Include="YARN\RestClient\RestResponse.cs" />
+    <Compile Include="YARN\RestClient\HttpClientRetryHandler.cs" />
     <Compile Include="YARN\WindowsYarnJobCommandProvider.cs" />
     <Compile Include="YARN\JobResource.cs" />
     <Compile Include="YARN\JobSubmissionDirectoryProvider.cs" />
@@ -121,11 +137,8 @@ under the License.
     <Compile Include="YARN\RestClient\IUrlProvider.cs" />
     <Compile Include="YARN\RestClient\FileSystemJobResourceUploader.cs" />
     <Compile Include="YARN\RestClient\MultipleRMUrlProvider.cs" />
-    <Compile Include="YARN\RestClient\RestJsonDeserializer.cs" />
-    <Compile Include="YARN\RestClient\RestJsonSerializer.cs" />
     <Compile Include="YARN\YarnJobSubmissionResult.cs" />
     <Compile Include="YARN\YARNREEFClient.cs" />
-    <Compile Include="YARN\RestClient\IRestClientFactory.cs" />
     <Compile Include="YARN\RestClient\RestRequestExecutor.cs" />
     <Compile Include="YARN\RestClient\IYarnRMClient.cs" />
     <Compile Include="YARN\RestClient\DataModel\Application.cs" />

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/HttpClient.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/HttpClient.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/HttpClient.cs
new file mode 100644
index 0000000..6d636d2
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/HttpClient.cs
@@ -0,0 +1,59 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+using Org.Apache.REEF.Tang.Annotations;
+
+namespace Org.Apache.REEF.Client.YARN.RestClient
+{
+    /// <summary>
+    /// Pass through HTTP client which calls into <see cref="System.Net.Http.HttpClient"/>
+    /// </summary>
+    internal class HttpClient : IHttpClient
+    {
+        private readonly System.Net.Http.HttpClient _httpClient;
+
+        [Inject]
+        private HttpClient()
+        {
+            _httpClient = new System.Net.Http.HttpClient(
+                new HttpClientRetryHandler(new WebRequestHandler()),
+                disposeHandler: false);
+        }
+
+        public async Task<HttpResponseMessage> GetAsync(string requestResource, CancellationToken cancellationToken)
+        {
+            return await _httpClient.GetAsync(requestResource, cancellationToken);
+        }
+
+        public async Task<HttpResponseMessage> PostAsync(string requestResource,
+            StringContent content,
+            CancellationToken cancellationToken)
+        {
+            return await _httpClient.PostAsync(requestResource, content, cancellationToken);
+        }
+
+        public async Task<HttpResponseMessage> PutAsync(string requestResource,
+            StringContent content,
+            CancellationToken cancellationToken)
+        {
+            return await _httpClient.PutAsync(requestResource, content, cancellationToken);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/HttpClientRetryHandler.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/HttpClientRetryHandler.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/HttpClientRetryHandler.cs
new file mode 100644
index 0000000..ccc9052
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/HttpClientRetryHandler.cs
@@ -0,0 +1,68 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+
+using System;
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Practices.TransientFaultHandling;
+
+namespace Org.Apache.REEF.Client.YARN.RestClient
+{
+    /// <summary>
+    /// DelegatingHandler for retrying requests with HTTP client
+    /// </summary>
+    internal class HttpClientRetryHandler : DelegatingHandler
+    {
+        private const int RetryCount = 3;
+        private static readonly TimeSpan MinBackoffTimeSpan = TimeSpan.FromMilliseconds(100);
+        private static readonly TimeSpan MaxBackoffTimeSpan = TimeSpan.FromSeconds(5);
+        private static readonly TimeSpan DeltaBackoffTimeSpan = TimeSpan.FromMilliseconds(500);
+
+        private readonly RetryPolicy<AllErrorsTransientStrategy> _retryPolicy;
+
+        public HttpClientRetryHandler(HttpMessageHandler innerHandler)
+            : base(innerHandler)
+        {
+            this._retryPolicy = new RetryPolicy<AllErrorsTransientStrategy>(
+                new ExponentialBackoff(
+                    "YarnRESTRetryHandler",
+                    RetryCount,
+                    MinBackoffTimeSpan,
+                    MaxBackoffTimeSpan,
+                    DeltaBackoffTimeSpan,
+                    firstFastRetry: true));
+        }
+
+        protected override async Task<HttpResponseMessage> SendAsync(
+            HttpRequestMessage request,
+            CancellationToken cancellationToken)
+        {
+            return await this._retryPolicy.ExecuteAsync(
+                async () => await base.SendAsync(request, cancellationToken),
+                cancellationToken);
+        }
+    }
+
+    internal class AllErrorsTransientStrategy : ITransientErrorDetectionStrategy
+    {
+        public bool IsTransient(Exception ex)
+        {
+            return true;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IDeserializer.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IDeserializer.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IDeserializer.cs
new file mode 100644
index 0000000..869a157
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IDeserializer.cs
@@ -0,0 +1,33 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+
+using Org.Apache.REEF.Tang.Annotations;
+
+namespace Org.Apache.REEF.Client.YARN.RestClient
+{
+    /// <summary>
+    /// Deserialize from string representation to corresponding data model object
+    /// </summary>
+    [DefaultImplementation(typeof(RestJsonDeserializer))]
+    internal interface IDeserializer
+    {
+        /// <summary>
+        /// Deserialize content string to <typeparam name="T"></typeparam>
+        /// </summary>
+        T Deserialize<T>(string contentString, string rootElement);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IHttpClient.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IHttpClient.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IHttpClient.cs
new file mode 100644
index 0000000..366dd29
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IHttpClient.cs
@@ -0,0 +1,37 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+using Org.Apache.REEF.Tang.Annotations;
+
+namespace Org.Apache.REEF.Client.YARN.RestClient
+{
+    /// <summary>
+    /// Wrapper interface on <see cref="System.Net.Http.HttpClient"/> for ease of unit-testing
+    /// </summary>
+    [DefaultImplementation(typeof(HttpClient))]
+    internal interface IHttpClient
+    {
+        Task<HttpResponseMessage> GetAsync(string requestResource, CancellationToken cancellationToken);
+
+        Task<HttpResponseMessage> PostAsync(string requestResource, StringContent content, CancellationToken cancellationToken);
+
+        Task<HttpResponseMessage> PutAsync(string requestResource, StringContent content, CancellationToken cancellationToken);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRequestFactory.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRequestFactory.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRequestFactory.cs
new file mode 100644
index 0000000..ecef9f5
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRequestFactory.cs
@@ -0,0 +1,43 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+
+using Org.Apache.REEF.Tang.Annotations;
+
+namespace Org.Apache.REEF.Client.YARN.RestClient
+{
+    /// <summary>
+    /// Factory for generating REST requests
+    /// </summary>
+    [DefaultImplementation(typeof(RequestFactory))]
+    internal interface IRequestFactory
+    {
+        /// <summary>
+        /// Generate REST request
+        /// </summary>
+        RestRequest CreateRestRequest(string resourcePath, Method method);
+
+        /// <summary>
+        /// Generate REST request
+        /// </summary>
+        RestRequest CreateRestRequest(string resourcePath, Method method, string rootElement);
+
+        /// <summary>
+        /// Generate REST request
+        /// </summary>
+        RestRequest CreateRestRequest(string resourcePath, Method method, string rootElement, object body);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRestClient.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRestClient.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRestClient.cs
new file mode 100644
index 0000000..4ac1654
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRestClient.cs
@@ -0,0 +1,43 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Org.Apache.REEF.Tang.Annotations;
+using Org.Apache.REEF.Utilities.AsyncUtils;
+
+namespace Org.Apache.REEF.Client.YARN.RestClient
+{
+    /// <summary>
+    /// Interface for the client that executes the RestRequests and handles
+    /// errors and retries
+    /// </summary>
+    [DefaultImplementation(typeof(RestClient))]
+    internal interface IRestClient
+    {
+        /// <summary>
+        /// Execute request where the response is expected to be type T
+        /// </summary>
+        Task<RestResponse<T>> ExecuteRequestAsync<T>(RestRequest request, Uri requestBaseUri, CancellationToken cancellationToken);
+
+        /// <summary>
+        /// Execute request where no response object is expected
+        /// </summary>
+        Task<RestResponse<VoidResult>> ExecuteRequestAsync(RestRequest request, Uri requestBaseUri, CancellationToken cancellationToken);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRestClientFactory.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRestClientFactory.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRestClientFactory.cs
deleted file mode 100644
index 77e813d..0000000
--- a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRestClientFactory.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-using System;
-using Org.Apache.REEF.Client.YARN.RestClient;
-using Org.Apache.REEF.Tang.Annotations;
-using RestSharp;
-
-namespace Org.Apache.REEF.Client.Yarn.RestClient
-{
-    [DefaultImplementation(typeof(RestClientFactory))]
-    internal interface IRestClientFactory
-    {
-        IRestClient CreateRestClient(Uri baseUri);
-    }
-
-    internal class RestClientFactory : IRestClientFactory
-    {
-        [Inject]
-        private RestClientFactory()
-        {
-        }
-
-        public IRestClient CreateRestClient(Uri baseUri)
-        {
-            // TODO: We are creating a new client per request
-            // as one client can contact only one baseUri.
-            // This is not very bad but it might still be worth
-            // it to cache clients per baseUri in the future.
-            var restClient = new RestSharp.RestClient(baseUri)
-            {
-                FollowRedirects = true
-            };
-            restClient.AddHandler("application/json", new RestJsonDeserializer());
-            return restClient;
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRestRequestExecutor.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRestRequestExecutor.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRestRequestExecutor.cs
index 7bb492a..ca4e2bc 100644
--- a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRestRequestExecutor.cs
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRestRequestExecutor.cs
@@ -18,21 +18,31 @@
 using System;
 using System.Threading;
 using System.Threading.Tasks;
+using Org.Apache.REEF.Client.YARN.RestClient;
 using Org.Apache.REEF.Tang.Annotations;
-using RestSharp;
+using Org.Apache.REEF.Utilities.AsyncUtils;
 
 namespace Org.Apache.REEF.Client.Yarn.RestClient
 {
+    /// <summary>
+    /// Executes a REST request
+    /// </summary>
     [DefaultImplementation(typeof(RestRequestExecutor))]
     internal interface IRestRequestExecutor
     {
+        /// <summary>
+        /// Executes a REST request where a response is expected
+        /// </summary>
         Task<T> ExecuteAsync<T>(
-            IRestRequest request,
+            RestRequest request,
             Uri uri,
-            CancellationToken cancellationToken) where T : new();
+            CancellationToken cancellationToken);
 
-        Task<IRestResponse> ExecuteAsync(
-            IRestRequest request,
+        /// <summary>
+        /// Executes a REST request where a response is NOT expected
+        /// </summary>
+        Task<RestResponse<VoidResult>> ExecuteAsync(
+            RestRequest request,
             Uri uri,
             CancellationToken cancellationToken);
     }

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/ISerializer.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/ISerializer.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/ISerializer.cs
new file mode 100644
index 0000000..abea5c6
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/ISerializer.cs
@@ -0,0 +1,33 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+
+using Org.Apache.REEF.Tang.Annotations;
+
+namespace Org.Apache.REEF.Client.YARN.RestClient
+{
+    /// <summary>
+    /// Serializes a data model object to string
+    /// </summary>
+    [DefaultImplementation(typeof(RestJsonSerializer))]
+    internal interface ISerializer
+    {
+        /// <summary>
+        /// Serializes <param name="obj"></param> to <see cref="string"/>
+        /// </summary>
+        string Serialize(object obj);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/Method.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/Method.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/Method.cs
new file mode 100644
index 0000000..2b78e71
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/Method.cs
@@ -0,0 +1,26 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+namespace Org.Apache.REEF.Client.YARN.RestClient
+{
+    internal enum Method
+    {
+        INVALID,
+        GET,
+        POST,
+        PUT
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RequestFactory.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RequestFactory.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RequestFactory.cs
new file mode 100644
index 0000000..b499c55
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RequestFactory.cs
@@ -0,0 +1,76 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+
+using System.Net.Http;
+using System.Text;
+using Org.Apache.REEF.Tang.Annotations;
+
+namespace Org.Apache.REEF.Client.YARN.RestClient
+{
+    /// <summary>
+    /// Factory to generate REST requests
+    /// </summary>
+    internal class RequestFactory : IRequestFactory
+    {
+        private readonly ISerializer _serializer;
+        private readonly string _baseResourceString;
+
+        [Inject]
+        private RequestFactory(ISerializer serializer)
+        {
+            _serializer = serializer;
+            _baseResourceString = @"ws/v1/";
+        }
+
+        /// <summary>
+        /// Generate REST request
+        /// </summary>
+        public RestRequest CreateRestRequest(string resourcePath, Method method)
+        {
+            return CreateRestRequest(resourcePath, method, null);
+        }
+
+        /// <summary>
+        /// Generate REST request
+        /// </summary>
+        public RestRequest CreateRestRequest(string resourcePath, Method method, string rootElement)
+        {
+            return CreateRestRequest(resourcePath, method, rootElement, null);
+        }
+
+        /// <summary>
+        /// Generate REST request
+        /// </summary>
+        public RestRequest CreateRestRequest(string resourcePath, Method method, string rootElement, object body)
+        {
+            var request = new RestRequest
+            {
+                Resource = _baseResourceString + resourcePath,
+                RootElement = rootElement,
+                Method = method,
+            };
+
+            if (body != null)
+            {
+                string content = _serializer.Serialize(body);
+                request.Content = new StringContent(content, Encoding.UTF8, @"application/json");
+            }
+
+            return request;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestClient.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestClient.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestClient.cs
new file mode 100644
index 0000000..d034c73
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestClient.cs
@@ -0,0 +1,141 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+
+using System;
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+using Org.Apache.REEF.Tang.Annotations;
+using Org.Apache.REEF.Utilities.AsyncUtils;
+
+namespace Org.Apache.REEF.Client.YARN.RestClient
+{
+    /// <summary>
+    /// Implementation of RestClient which uses HTTPClient to 
+    /// make REST requests and handles errors
+    /// </summary>
+    internal class RestClient : IRestClient
+    {
+        private readonly IDeserializer _deserializer;
+        private readonly IHttpClient _httpClient;
+
+        [Inject]
+        private RestClient(IDeserializer deserializer, IHttpClient httpClient)
+        {
+            _httpClient = httpClient;
+            _deserializer = deserializer;
+        }
+
+        /// <summary>
+        /// Execute request where no response object is expected
+        /// </summary>
+        public async Task<RestResponse<VoidResult>> ExecuteRequestAsync(
+            RestRequest request,
+            Uri requestBaseUri,
+            CancellationToken cancellationToken)
+        {
+            var httpResponseMessage = await GetHttpResponseAsync(request, requestBaseUri, cancellationToken);
+            Exception exception = null;
+            if (!httpResponseMessage.IsSuccessStatusCode)
+            {
+                exception =
+                    new HttpRequestException(string.Format("HTTP call failed with status [{0}] and content [{1}]",
+                        httpResponseMessage.StatusCode,
+                        await GetContentStringFromHttpResponseMessage(httpResponseMessage)));
+            }
+
+            return new RestResponse<VoidResult>
+            {
+                Data = new VoidResult(),
+                Exception = exception,
+                StatusCode = httpResponseMessage.StatusCode
+            };
+        }
+
+        /// <summary>
+        /// Execute request where the response is expected to be type T
+        /// </summary>
+        public async Task<RestResponse<T>> ExecuteRequestAsync<T>(
+            RestRequest request,
+            Uri requestBaseUri,
+            CancellationToken cancellationToken)
+        {
+            var httpResponseMessage = await GetHttpResponseAsync(request, requestBaseUri, cancellationToken);
+            string contentString = await GetContentStringFromHttpResponseMessage(httpResponseMessage);
+            Exception exception = null;
+            T returnObj = default(T);
+
+            if (!httpResponseMessage.IsSuccessStatusCode)
+            {
+                exception =
+                    new HttpRequestException(string.Format("HTTP call failed with status [{0}] and content [{1}]",
+                        httpResponseMessage.StatusCode,
+                        contentString));
+            }
+            else
+            {
+                returnObj = _deserializer.Deserialize<T>(contentString,
+                    request.RootElement);
+            }
+            return new RestResponse<T>
+            {
+                Content = contentString,
+                Data = returnObj,
+                StatusCode = httpResponseMessage.StatusCode,
+                Exception = exception
+            };
+        }
+
+        private async Task<HttpResponseMessage> GetHttpResponseAsync(
+            RestRequest request,
+            Uri requestBaseUri,
+            CancellationToken cancellationToken)
+        {
+            HttpResponseMessage httpResponseMessage;
+            var requestResource = requestBaseUri + request.Resource;
+            switch (request.Method)
+            {
+                case Method.GET:
+                    httpResponseMessage = await _httpClient.GetAsync(
+                        requestResource,
+                        cancellationToken);
+                    break;
+                case Method.PUT:
+                    httpResponseMessage = await _httpClient.PutAsync(
+                        requestResource,
+                        request.Content,
+                        cancellationToken);
+                    break;
+                case Method.POST:
+                    httpResponseMessage = await _httpClient.PostAsync(
+                        requestResource,
+                        request.Content,
+                        cancellationToken);
+                    break;
+                default:
+                    throw new InvalidOperationException(string.Format("Unknown method type {0}", request.Method));
+            }
+
+            return httpResponseMessage;
+        }
+
+        private static async Task<string> GetContentStringFromHttpResponseMessage(HttpResponseMessage response)
+        {
+            return response.Content == null ? string.Empty : await response.Content.ReadAsStringAsync();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestJsonDeserializer.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestJsonDeserializer.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestJsonDeserializer.cs
index aa6fd7b..c58f3b4 100644
--- a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestJsonDeserializer.cs
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestJsonDeserializer.cs
@@ -18,18 +18,21 @@
 using Newtonsoft.Json;
 using Newtonsoft.Json.Converters;
 using Newtonsoft.Json.Linq;
-using RestSharp;
-using RestSharp.Deserializers;
+using Org.Apache.REEF.Tang.Annotations;
 
 namespace Org.Apache.REEF.Client.YARN.RestClient
 {
+    /// <summary>
+    /// Simple implementation of JSON deserializer by using Newtonsoft JSON lib
+    /// </summary>
     internal sealed class RestJsonDeserializer : IDeserializer
     {
-        public string RootElement { get; set; }
-        public string Namespace { get; set; }
-        public string DateFormat { get; set; }
+        [Inject]
+        private RestJsonDeserializer()
+        {
+        }
 
-        public T Deserialize<T>(IRestResponse response)
+        public T Deserialize<T>(string contentString, string rootElement)
         {
             /* If root element is not empty, then we want to 
              * skip the top level token and parse only one level deeper
@@ -49,17 +52,17 @@ namespace Org.Apache.REEF.Client.YARN.RestClient
              * }
              * 
              * This logic helps us avoid such classes.
-            */ 
-            if (!string.IsNullOrEmpty(RootElement))
+            */
+            if (string.IsNullOrEmpty(rootElement))
             {
-                var jobject = JObject.Parse(response.Content);
-                var jtoken = jobject[RootElement];
-                var jsonSerializer = new JsonSerializer();
-                jsonSerializer.Converters.Add(new StringEnumConverter());
-                return jtoken.ToObject<T>(jsonSerializer);
+                return JsonConvert.DeserializeObject<T>(contentString, new StringEnumConverter());
             }
 
-            return JsonConvert.DeserializeObject<T>(response.Content, new StringEnumConverter());
+            var jobject = JObject.Parse(contentString);
+            var jtoken = jobject[rootElement];
+            var jsonSerializer = new JsonSerializer();
+            jsonSerializer.Converters.Add(new StringEnumConverter());
+            return jtoken.ToObject<T>(jsonSerializer);
         }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestJsonSerializer.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestJsonSerializer.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestJsonSerializer.cs
index abd88b9..14eb5b8 100644
--- a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestJsonSerializer.cs
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestJsonSerializer.cs
@@ -17,34 +17,30 @@
 
 using Newtonsoft.Json;
 using Newtonsoft.Json.Converters;
-using RestSharp.Serializers;
+using Newtonsoft.Json.Serialization;
+using Org.Apache.REEF.Tang.Annotations;
 
 namespace Org.Apache.REEF.Client.YARN.RestClient
 {
     /// <summary>
-    /// RestSharp by default uses SimpleJsonSerializer which 
-    /// does not understand property renaming. Here we create a
-    /// simple ISerializer implementation that uses Newtonsoft.Json
-    /// for performing serialization
+    /// Simple implementation of JSON serializer by using Newtonsoft JSON lib
     /// </summary>
     internal sealed class RestJsonSerializer : ISerializer
     {
-        public RestJsonSerializer()
+        private readonly JsonSerializerSettings _jsonSerializerSettings = new JsonSerializerSettings
         {
-            ContentType = "application/json";
-        }
-
-        public string RootElement { get; set; }
-
-        public string Namespace { get; set; }
+            ContractResolver = new CamelCasePropertyNamesContractResolver(),
+            Converters = new JsonConverter[] { new StringEnumConverter() }
+        };
 
-        public string DateFormat { get; set; }
-
-        public string ContentType { get; set; }
+        [Inject]
+        private RestJsonSerializer()
+        {
+        }
 
         public string Serialize(object obj)
         {
-            return JsonConvert.SerializeObject(obj, new StringEnumConverter());
+            return JsonConvert.SerializeObject(obj, _jsonSerializerSettings);
         }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestRequest.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestRequest.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestRequest.cs
new file mode 100644
index 0000000..a70191c
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestRequest.cs
@@ -0,0 +1,49 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+
+using System.Net.Http;
+using System.Text;
+
+namespace Org.Apache.REEF.Client.YARN.RestClient
+{
+    /// <summary>
+    /// Encapsulated data related to a REST request
+    /// </summary>
+    internal class RestRequest
+    {
+        /// <summary>
+        /// Path to the resource being accessed
+        /// This path is relative to the base path.
+        /// </summary>
+        public string Resource { get; set; }
+
+        /// <summary>
+        /// Root element (if any) in the response JSON
+        /// </summary>
+        public string RootElement { get; set; }
+
+        /// <summary>
+        /// HTTP method to be invoked for the request
+        /// </summary>
+        public Method Method { get; set; }
+
+        /// <summary>
+        /// The serialized string content for the request
+        /// </summary>
+        public StringContent Content { get; internal set; }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestRequestExecutor.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestRequestExecutor.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestRequestExecutor.cs
index 75187a5..538c705 100644
--- a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestRequestExecutor.cs
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestRequestExecutor.cs
@@ -5,9 +5,9 @@
 // to you 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
@@ -20,73 +20,103 @@ using System.Net;
 using System.Threading;
 using System.Threading.Tasks;
 using Newtonsoft.Json;
+using Org.Apache.REEF.Client.YARN.RestClient;
 using Org.Apache.REEF.Client.YARN.RestClient.DataModel;
 using Org.Apache.REEF.Tang.Annotations;
+using Org.Apache.REEF.Utilities.AsyncUtils;
 using Org.Apache.REEF.Utilities.Logging;
-using RestSharp;
 
 namespace Org.Apache.REEF.Client.Yarn.RestClient
 {
+    /// <summary>
+    /// Executes a REST request
+    /// </summary>
     internal class RestRequestExecutor : IRestRequestExecutor
     {
         private static readonly Logger Log = Logger.GetLogger(typeof(RestRequestExecutor));
-        private readonly IRestClientFactory _clientFactory;
+        private readonly IRestClient _client;
 
         [Inject]
         private RestRequestExecutor(
-            IRestClientFactory clientFactory)
+            IRestClient client)
         {
-            _clientFactory = clientFactory;
+            _client = client;
         }
 
         public async Task<T> ExecuteAsync<T>(
-            IRestRequest request,
+            RestRequest request,
             Uri requestUri,
-            CancellationToken cancellationToken) where T : new()
+            CancellationToken cancellationToken)
         {
-            var client = _clientFactory.CreateRestClient(requestUri);
-
-            var response =
-                await
-                    client.ExecuteTaskAsync<T>(request, cancellationToken);
-
-            if (response.ErrorException != null)
+            RestResponse<T> response;
+            try
             {
-                throw new YarnRestAPIException("Executing REST API failed", response.ErrorException);
+                response = await _client.ExecuteRequestAsync<T>(request, requestUri, cancellationToken);
+            }
+            catch (Exception exception)
+            {
+                throw new YarnRestAPIException("Unhandled exception in executing REST request.", exception);
             }
 
+            HandleResponse(response.Exception, response.StatusCode, response.Content);
+
+            return response.Data;
+        }
+
+        public async Task<RestResponse<VoidResult>> ExecuteAsync(RestRequest request,
+            Uri requestUri,
+            CancellationToken cancellationToken)
+        {
+            RestResponse<VoidResult> response;
             try
             {
-                // HTTP status code greater than 300 is unexpected here.
-                // See if the server sent a error response and throw suitable
-                // exception to user.
-                if (response.StatusCode >= HttpStatusCode.Ambiguous)
-                {
-                    Log.Log(Level.Error, "RESTRequest failed. StatusCode: {0}; Response: {1}", response.StatusCode, response.Content);
-                    var errorResponse = JsonConvert.DeserializeObject<Error>(response.Content);
-                    throw new YarnRestAPIException { Error = errorResponse };
-                }
+                response = await _client.ExecuteRequestAsync(request, requestUri, cancellationToken);
             }
             catch (Exception exception)
             {
-                throw new YarnRestAPIException("Unhandled exception in deserializing error response.", exception);
+                throw new YarnRestAPIException("Unhandled exception in executing REST request.", exception);
             }
 
-            return response.Data;
+            HandleResponse(response.Exception, response.StatusCode, response.Content);
+            return response;
         }
 
-        public async Task<IRestResponse> ExecuteAsync(IRestRequest request, Uri uri, CancellationToken cancellationToken)
+        private static void HandleResponse(Exception responseException, HttpStatusCode httpStatusCode, string content)
         {
-            var client = _clientFactory.CreateRestClient(uri);
+            if (responseException != null)
+            {
+                throw new YarnRestAPIException("Executing REST API failed", responseException)
+                {
+                    StatusCode = httpStatusCode
+                };
+            }
 
+            // HTTP status code greater than 300 is unexpected here.
+            // See if the server sent a error response and throw suitable
+            // exception to user.
+            if (httpStatusCode < HttpStatusCode.Ambiguous)
+            {
+                return;
+            }
+
+            Log.Log(Level.Error,
+                "RESTRequest failed. StatusCode: {0}; Response: {1}",
+                httpStatusCode,
+                content);
+            Error errorResponse;
             try
             {
-                return await client.ExecuteTaskAsync(request, cancellationToken);
+                errorResponse = JsonConvert.DeserializeObject<Error>(content);
             }
             catch (Exception exception)
             {
-                throw new YarnRestAPIException("Unhandled exception in executing REST request.", exception);
+                throw new YarnRestAPIException("Unhandled exception in deserializing error response.", exception)
+                {
+                    StatusCode = httpStatusCode
+                };
             }
+
+            throw new YarnRestAPIException { Error = errorResponse, StatusCode = httpStatusCode };
         }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestResponse.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestResponse.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestResponse.cs
new file mode 100644
index 0000000..87872c6
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/RestResponse.cs
@@ -0,0 +1,50 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+
+using System;
+using System.Net;
+
+namespace Org.Apache.REEF.Client.YARN.RestClient
+{
+    /// <summary>
+    /// Represents the response of a REST request
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    internal class RestResponse<T>
+    {
+        /// <summary>
+        /// Deserialized response for REST request
+        /// </summary>
+        public T Data { get; set; }
+
+        /// <summary>
+        /// StatusCode of the REST response
+        /// </summary>
+        public HttpStatusCode StatusCode { get; set; }
+
+        /// <summary>
+        /// Exception details if a communication/protocol 
+        /// error happened while processing the request
+        /// </summary>
+        public Exception Exception { get; set; }
+
+        /// <summary>
+        /// String content (serialized) of the response
+        /// </summary>
+        public string Content { get; set; }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/YarnClient.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/YarnClient.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/YarnClient.cs
index 62f0c14..ec47d8b 100644
--- a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/YarnClient.cs
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/YarnClient.cs
@@ -26,7 +26,6 @@ using Org.Apache.REEF.Client.YARN.RestClient.DataModel;
 using Org.Apache.REEF.Tang.Annotations;
 using Org.Apache.REEF.Utilities.AsyncUtils;
 using Org.Apache.REEF.Utilities.Logging;
-using RestSharp;
 
 namespace Org.Apache.REEF.Client.Yarn.RestClient
 {
@@ -39,15 +38,18 @@ namespace Org.Apache.REEF.Client.Yarn.RestClient
     internal sealed partial class YarnClient : IYarnRMClient
     {
         private static readonly Logger Logger = Logger.GetLogger(typeof(YarnClient));
-        private readonly string _baseResourceString;
         private readonly IUrlProvider _yarnRmUrlProviderUri;
         private readonly IRestRequestExecutor _restRequestExecutor;
+        private readonly IRequestFactory _requestFactory;
 
         [Inject]
-        internal YarnClient(IUrlProvider yarnRmUrlProviderUri, IRestRequestExecutor restRequestExecutor)
+        private YarnClient(
+            IUrlProvider yarnRmUrlProviderUri,
+            IRestRequestExecutor restRequestExecutor,
+            IRequestFactory requestFactory)
         {
+            _requestFactory = requestFactory;
             _yarnRmUrlProviderUri = yarnRmUrlProviderUri;
-            _baseResourceString = @"ws/v1/";
             _restRequestExecutor = restRequestExecutor;
         }
 
@@ -55,7 +57,10 @@ namespace Org.Apache.REEF.Client.Yarn.RestClient
         {
             await new RemoveSynchronizationContextAwaiter();
 
-            IRestRequest request = CreateRestRequest(ClusterInfo.Resource, Method.GET, ClusterInfo.RootElement);
+            var request = _requestFactory.CreateRestRequest(
+                ClusterInfo.Resource,
+                Method.GET,
+                ClusterInfo.RootElement);
 
             return
                 await GenerateUrlAndExecuteRequestAsync<ClusterInfo>(request, cancellationToken);
@@ -65,7 +70,9 @@ namespace Org.Apache.REEF.Client.Yarn.RestClient
         {
             await new RemoveSynchronizationContextAwaiter();
 
-            var request = CreateRestRequest(ClusterMetrics.Resource, Method.GET, ClusterMetrics.RootElement);
+            var request = _requestFactory.CreateRestRequest(ClusterMetrics.Resource,
+                Method.GET,
+                ClusterMetrics.RootElement);
 
             return
                 await
@@ -76,7 +83,9 @@ namespace Org.Apache.REEF.Client.Yarn.RestClient
         {
             await new RemoveSynchronizationContextAwaiter();
 
-            var request = CreateRestRequest(Application.Resource + appId, Method.GET, Application.RootElement);
+            var request = _requestFactory.CreateRestRequest(Application.Resource + appId,
+                Method.GET,
+                Application.RootElement);
 
             return
                 await GenerateUrlAndExecuteRequestAsync<Application>(request, cancellationToken);
@@ -86,7 +95,7 @@ namespace Org.Apache.REEF.Client.Yarn.RestClient
         {
             await new RemoveSynchronizationContextAwaiter();
 
-            var request = CreateRestRequest(NewApplication.Resource, Method.POST);
+            var request = _requestFactory.CreateRestRequest(NewApplication.Resource, Method.POST);
 
             return
                 await
@@ -99,38 +108,26 @@ namespace Org.Apache.REEF.Client.Yarn.RestClient
         {
             await new RemoveSynchronizationContextAwaiter();
 
-            var request = CreateRestRequest(SubmitApplication.Resource, Method.POST);
+            var request = _requestFactory.CreateRestRequest(
+                SubmitApplication.Resource,
+                Method.POST,
+                rootElement: null,
+                body: submitApplication);
 
-            request.AddBody(submitApplication);
             var submitResponse = await GenerateUrlAndExecuteRequestAsync(request, cancellationToken);
 
             if (submitResponse.StatusCode != HttpStatusCode.Accepted)
             {
                 throw new YarnRestAPIException(
                     string.Format("Application submission failed with HTTP STATUS {0}",
-                    submitResponse.StatusCode));
+                        submitResponse.StatusCode));
             }
 
             return await GetApplicationAsync(submitApplication.ApplicationId, cancellationToken);
         }
 
-        private RestRequest CreateRestRequest(string resourcePath, Method method, string rootElement = null)
-        {
-            var request = new RestRequest
-            {
-                Resource = _baseResourceString + resourcePath,
-                RootElement = rootElement,
-                Method = method,
-                RequestFormat = DataFormat.Json,
-                JsonSerializer = new RestJsonSerializer()
-            };
-
-            return request;
-        }
-
-        private async Task<T> GenerateUrlAndExecuteRequestAsync<T>(IRestRequest request,
+        private async Task<T> GenerateUrlAndExecuteRequestAsync<T>(RestRequest request,
             CancellationToken cancellationToken)
-            where T : new()
         {
             IEnumerable<Uri> yarnRmUris = await _yarnRmUrlProviderUri.GetUrlAsync();
             var exceptions = new List<Exception>();
@@ -145,7 +142,7 @@ namespace Org.Apache.REEF.Client.Yarn.RestClient
                 catch (Exception e)
                 {
                     exceptions.Add(e);
-                    Logger.Log(Level.Verbose, 
+                    Logger.Log(Level.Verbose,
                         string.Format(CultureInfo.CurrentCulture, "Possibly transient error in rest call {0}", e.Message));
                 }
             }
@@ -153,7 +150,7 @@ namespace Org.Apache.REEF.Client.Yarn.RestClient
             throw new AggregateException("Failed Rest Request", exceptions);
         }
 
-        private async Task<IRestResponse> GenerateUrlAndExecuteRequestAsync(IRestRequest request,
+        private async Task<RestResponse<VoidResult>> GenerateUrlAndExecuteRequestAsync(RestRequest request,
             CancellationToken cancellationToken)
         {
             IEnumerable<Uri> yarnRmUris = await _yarnRmUrlProviderUri.GetUrlAsync();
@@ -169,7 +166,7 @@ namespace Org.Apache.REEF.Client.Yarn.RestClient
                 catch (Exception e)
                 {
                     exceptions.Add(e);
-                    Logger.Log(Level.Verbose, 
+                    Logger.Log(Level.Verbose,
                         string.Format(CultureInfo.CurrentCulture, "Possibly transient error in rest call {0}", e.Message));
                 }
             }

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/YarnRestAPIException.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/YarnRestAPIException.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/YarnRestAPIException.cs
index 7ee9889..b25a30c 100644
--- a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/YarnRestAPIException.cs
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/YarnRestAPIException.cs
@@ -16,6 +16,7 @@
 // under the License.
 
 using System;
+using System.Net;
 using Org.Apache.REEF.Client.YARN.RestClient.DataModel;
 
 namespace Org.Apache.REEF.Client.Yarn.RestClient
@@ -38,5 +39,7 @@ namespace Org.Apache.REEF.Client.Yarn.RestClient
         }
 
         public Error Error { get; internal set; }
+
+        public HttpStatusCode StatusCode { get; internal set; }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Client/packages.config
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Client/packages.config b/lang/cs/Org.Apache.REEF.Client/packages.config
index 827a433..63005d5 100644
--- a/lang/cs/Org.Apache.REEF.Client/packages.config
+++ b/lang/cs/Org.Apache.REEF.Client/packages.config
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <!--
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
@@ -19,6 +19,6 @@ under the License.
 -->
 <packages>
   <package id="Newtonsoft.Json" version="6.0.8" targetFramework="net45" />
-  <package id="RestSharpSigned" version="105.2.3" targetFramework="net45" />
   <package id="StyleCop.MSBuild" version="4.7.49.1" targetFramework="net45" developmentDependency="true" />
+  <package id="TransientFaultHandling.Core" version="5.1.1209.1" targetFramework="net45" />
 </packages>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Utilities/AsyncUtils/VoidResult.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Utilities/AsyncUtils/VoidResult.cs b/lang/cs/Org.Apache.REEF.Utilities/AsyncUtils/VoidResult.cs
new file mode 100644
index 0000000..a9404a4
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Utilities/AsyncUtils/VoidResult.cs
@@ -0,0 +1,31 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+
+using System.Threading.Tasks;
+
+namespace Org.Apache.REEF.Utilities.AsyncUtils
+{
+    /// <summary>
+    /// A type used to indicate that no meaningful value is returned.
+    /// We often use this type with <see cref="Task{TResult}"/> to indicate that an asynchronous
+    /// operation returns no meaningful value. This eliminates the need to simultaneously
+    /// support <see cref="Task"/> APIs and <see cref="Task{TResult}"/> APIs
+    /// </summary>
+    public struct VoidResult
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.Utilities/Org.Apache.Reef.Utilities.csproj
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Utilities/Org.Apache.Reef.Utilities.csproj b/lang/cs/Org.Apache.REEF.Utilities/Org.Apache.Reef.Utilities.csproj
index 5065af6..4576cd6 100644
--- a/lang/cs/Org.Apache.REEF.Utilities/Org.Apache.Reef.Utilities.csproj
+++ b/lang/cs/Org.Apache.REEF.Utilities/Org.Apache.Reef.Utilities.csproj
@@ -38,6 +38,7 @@ under the License.
   </ItemGroup>
   <ItemGroup>
     <Compile Include="AsyncUtils\RemoveSynchronizationContextAwaiter.cs" />
+    <Compile Include="AsyncUtils\VoidResult.cs" />
     <Compile Include="Attributes\ClientSideAttribute.cs" />
     <Compile Include="Attributes\DriverSideAttribute.cs" />
     <Compile Include="Attributes\EvaluatorSideAttribute.cs" />

http://git-wip-us.apache.org/repos/asf/reef/blob/76adb40c/lang/cs/Org.Apache.REEF.sln
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.sln b/lang/cs/Org.Apache.REEF.sln
index 3b13a5e..41932c1 100644
Binary files a/lang/cs/Org.Apache.REEF.sln and b/lang/cs/Org.Apache.REEF.sln differ