[REEF-1838] add API to Kill Yarn Job Application from .Net client

  * Add API in IYarnREEFClient
  * Implement in YarnClient and YarnREEFClient
  * The  code is from #1352 and implemented on top of the latest interface change

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

Pull Request:
  This closes #1363
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 2c3df86..791af4f 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
@@ -119,6 +119,7 @@
     <Compile Include="YARN\Parameters\DriverStderrFilePath.cs" />
     <Compile Include="YARN\Parameters\DriverStdoutFilePath.cs" />
     <Compile Include="YARN\Parameters\FileSystemUrl.cs" />
+    <Compile Include="YARN\RestClient\DataModel\KillApplication.cs" />
     <Compile Include="YARN\RestClient\HttpClient.cs" />
     <Compile Include="YARN\RestClient\IDeserializer.cs" />
     <Compile Include="YARN\RestClient\IHttpClient.cs" />
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/IYarnREEFClient.cs b/lang/cs/Org.Apache.REEF.Client/YARN/IYarnREEFClient.cs
index e208277..37860c4 100644
--- a/lang/cs/Org.Apache.REEF.Client/YARN/IYarnREEFClient.cs
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/IYarnREEFClient.cs
@@ -18,6 +18,7 @@
 using System.Collections.Generic;
 using System.Threading.Tasks;
 using Org.Apache.REEF.Client.API;
+using Org.Apache.REEF.Client.YARN.RestClient.DataModel;
 using Org.Apache.REEF.Utilities.Attributes;
 
 namespace Org.Apache.REEF.Client.YARN
@@ -33,5 +34,13 @@
         /// <returns></returns>
         [Unstable("0.17", "Working in progress for rest API id returned")]
         Task<IReadOnlyDictionary<string, IApplicationReport>> GetApplicationReports();
+
+        /// <summary>
+        /// Kills the application with specified application id.
+        /// </summary>
+        /// <param name="appId">Application id to kill.</param>
+        /// <returns>Returns true if the application is killed otherwise return false.</returns>
+        [Unstable("0.17", "Working in progress for rest API status returned")]
+        Task<bool> KillApplication(string appId);
     }
 }
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/DataModel/KillApplication.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/DataModel/KillApplication.cs
new file mode 100644
index 0000000..96207ce
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/DataModel/KillApplication.cs
@@ -0,0 +1,35 @@
+// 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 Newtonsoft.Json;
+
+namespace Org.Apache.REEF.Client.YARN.RestClient.DataModel
+{
+    /// <summary>
+    /// Class generated based on schema provided in
+    /// <a href="http://hadoop.apache.org/docs/r2.6.0/hadoop-yarn/hadoop-yarn-site/WebServicesIntro.html">
+    /// Hadoop RM REST API</a> documentation.
+    /// </summary>
+    internal sealed class KillApplication
+    {
+        internal static readonly string Resource = @"cluster/apps/";
+        internal static readonly string StateTag = @"/state";
+
+        [JsonProperty("state")]
+        public State State { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IYarnRMClient.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IYarnRMClient.cs
index ee63b60..e53ceac 100644
--- a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IYarnRMClient.cs
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IYarnRMClient.cs
@@ -62,5 +62,20 @@
         Task<Application> SubmitApplicationAsync(
             SubmitApplication submitApplicationRequest,
             CancellationToken cancellationToken);
+
+        /// <summary>
+        /// Kills the application asynchronous.
+        /// </summary>
+        /// <param name="appId">The application identifier.</param>
+        /// <returns>Returns true if the application is killed otherwise return false.</returns>
+        Task<bool> KillApplicationAsync(string appId);
+
+        /// <summary>
+        /// Kills the application asynchronous.
+        /// </summary>
+        /// <param name="appId">The application identifier.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Returns true if the application is killed otherwise returns false.</returns>
+        Task<bool> KillApplicationAsync(string appId, CancellationToken cancellationToken);
     }
 }
\ No newline at end of file
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 6a29c49..47d975a 100644
--- a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/YarnClient.cs
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/YarnClient.cs
@@ -17,6 +17,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.ComponentModel;
 using System.Globalization;
 using System.Net;
 using System.Threading;
@@ -145,6 +146,48 @@
             return await GetApplicationAsync(submitApplication.ApplicationId, cancellationToken);
         }
 
+        /// <summary>
+        /// Kills the application asynchronous.
+        /// </summary>
+        /// <param name="appId">The application identifier.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Returns true if the application is killed otherwise returns false.</returns>
+        /// <exception cref="YarnRestAPIException"></exception>
+        public async Task<bool> KillApplicationAsync(string appId, CancellationToken cancellationToken)
+        {
+            try
+            {
+                var killApplication = new KillApplication()
+                {
+                    State = State.KILLED
+                };
+
+                var restParm = KillApplication.Resource + appId + KillApplication.StateTag;
+                await new RemoveSynchronizationContextAwaiter();
+                var request = _requestFactory.CreateRestRequest(
+                    restParm,
+                    Method.PUT,
+                    rootElement: null,
+                    body: killApplication);
+
+                var response = await GenerateUrlAndExecuteRequestAsync(request, cancellationToken);
+                Logger.Log(Level.Info, "StatusCode from response {0}", response.StatusCode);
+
+                if (response.StatusCode != HttpStatusCode.Accepted)
+                {
+                    throw new YarnRestAPIException(
+                        string.Format("Kill Application failed with HTTP STATUS {0}",
+                            response.StatusCode));
+                }
+                return true;
+            }
+            catch (AggregateException e)
+            {
+                Logger.Log(Level.Error, "YarnClient:KillApplicationAsync got exception for application id {0}, {1}", appId, e);
+                return false;
+            }
+        }
+
         private async Task<T> GenerateUrlAndExecuteRequestAsync<T>(RestRequest request,
             CancellationToken cancellationToken)
         {
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/YarnClientNoCancellationToken.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/YarnClientNoCancellationToken.cs
index 2d490f8..7492bed 100644
--- a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/YarnClientNoCancellationToken.cs
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/YarnClientNoCancellationToken.cs
@@ -78,5 +78,16 @@
             await new RemoveSynchronizationContextAwaiter();
             return await SubmitApplicationAsync(submitApplicationRequest, CancellationToken.None);
         }
+
+        /// <summary>
+        /// Kills the application asynchronous.
+        /// </summary>
+        /// <param name="appId">The application identifier.</param>
+        /// <returns>Returns true if the application is killed otherwise returns false.</returns>
+        public async Task<bool> KillApplicationAsync(string appId)
+        {
+            await new RemoveSynchronizationContextAwaiter();
+            return KillApplicationAsync(appId, CancellationToken.None).Result;
+        }
     }
 }
\ No newline at end of file
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/YARNREEFClient.cs b/lang/cs/Org.Apache.REEF.Client/YARN/YARNREEFClient.cs
index c00be21..4559c73 100644
--- a/lang/cs/Org.Apache.REEF.Client/YARN/YARNREEFClient.cs
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/YARNREEFClient.cs
@@ -144,6 +144,16 @@
             return new ReadOnlyDictionary<string, IApplicationReport>(appReports);
         }
 
+        /// <summary>
+        /// Kills the application with specified application id.
+        /// </summary>
+        /// <param name="appId">Application id to kill.</param>
+        /// <returns>Returns true if the application is killed otherwise returns false.</returns>
+        public async Task<bool> KillApplication(string appId)
+        {
+            return await _yarnClient.KillApplicationAsync(appId);
+        }
+
         private void Launch(JobRequest jobRequest, string driverFolderPath)
         {
             _driverFolderPreparationHelper.PrepareDriverFolder(jobRequest.AppParameters, driverFolderPath);
diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/YarnREEFDotNetClient.cs b/lang/cs/Org.Apache.REEF.Client/YARN/YarnREEFDotNetClient.cs
index fcae2e4..babb613 100644
--- a/lang/cs/Org.Apache.REEF.Client/YARN/YarnREEFDotNetClient.cs
+++ b/lang/cs/Org.Apache.REEF.Client/YARN/YarnREEFDotNetClient.cs
@@ -157,6 +157,16 @@
             throw new NotImplementedException();
         }
 
+        /// <summary>
+        /// Kills the application with specified application id.
+        /// </summary>
+        /// <param name="appId"></param>
+        /// <returns>Returns true if the application is killed otherwise returns false.</returns>
+        public async Task<bool> KillApplication(string appId)
+        {
+            return await _yarnRMClient.KillApplicationAsync(appId);
+        }
+
         private SubmitApplication CreateApplicationSubmissionRequest(
            JobParameters jobParameters,
            string appId,
diff --git a/lang/cs/Org.Apache.REEF.Examples.HelloREEF/HelloREEFYarn.cs b/lang/cs/Org.Apache.REEF.Examples.HelloREEF/HelloREEFYarn.cs
index 6044569..b7564f6 100644
--- a/lang/cs/Org.Apache.REEF.Examples.HelloREEF/HelloREEFYarn.cs
+++ b/lang/cs/Org.Apache.REEF.Examples.HelloREEF/HelloREEFYarn.cs
@@ -95,14 +95,17 @@
                 .Build();
 
             var result = _reefClient.SubmitAndGetJobStatus(helloJobRequest);
-
             LogApplicationReport();
+
+            //// This is an example to Kill Job Application
+            //// KillApplication(result.AppId);
+
             var state = PullFinalJobStatus(result);
-            Logger.Log(Level.Info, "Application state : {0}.", state);
+            Logger.Log(Level.Info, "Application final state : {0}.", state);
         }
 
         /// <summary>
-        /// Get application report and log.
+        /// Sample code to get application report and log.
         /// </summary>
         private void LogApplicationReport()
         {
@@ -115,7 +118,25 @@
         }
 
         /// <summary>
-        /// This is to pull job final status until the Job is done
+        /// Sample code to kill Job Application.
+        /// </summary>
+        /// <param name="appId">Application id to kill</param>
+        private void KillApplication(string appId)
+        {
+            if (_reefClient.KillApplication(appId).Result)
+            {
+                Logger.Log(Level.Info, "Application {0} is killed successfully.", appId);
+            }
+            else
+            {
+                Logger.Log(Level.Info, 
+                    "Failed to kill application {0}, possible reasons are application id is invalid or application has completed.", 
+                    appId);
+            }
+        }
+
+        /// <summary>
+        /// Sample code to pull job final status until the Job is done
         /// </summary>
         /// <param name="jobSubmitionResult"></param>
         /// <returns></returns>