Repository: reef Updated Branches: refs/heads/master 48d47fe0f -> ec7bc969f
[REEF-1175] Add support for network credential to O.A.R.Client.YarnClient This addressed the issue by: * Adding NetworkCredential support to HttpClient which delegates to .NEt * HTTPClient * Add interface IYarnRestClientCredential which allows user to specify * mechanism to access their credential source JIRA: [REEF-1175](https://issues.apache.org/jira/browse/REEF-1175) Pull Request: Closes #812 Project: http://git-wip-us.apache.org/repos/asf/reef/repo Commit: http://git-wip-us.apache.org/repos/asf/reef/commit/ec7bc969 Tree: http://git-wip-us.apache.org/repos/asf/reef/tree/ec7bc969 Diff: http://git-wip-us.apache.org/repos/asf/reef/diff/ec7bc969 Branch: refs/heads/master Commit: ec7bc969f3b3483f1a81a2b17762d4ae4dc6a3c4 Parents: 48d47fe Author: Anupam <[email protected]> Authored: Tue Jan 5 10:03:07 2016 -0800 Committer: Andrew Chung <[email protected]> Committed: Wed Feb 3 17:45:31 2016 -0800 ---------------------------------------------------------------------- .../HDInsightYarnClientTests.cs | 168 +++++++++++++++++++ .../Org.Apache.REEF.Client.Tests.csproj | 1 + .../Org.Apache.REEF.Client.csproj | 2 + .../YARN/RESTClient/HttpClient.cs | 4 +- .../YARN/RESTClient/IRestRequestExecutor.cs | 4 +- .../RESTClient/IYarnRestClientCredential.cs | 35 ++++ .../RESTClient/NullYarnRestClientCredential.cs | 38 +++++ .../YARN/YARNClientConfiguration.cs | 3 + 8 files changed, 251 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/reef/blob/ec7bc969/lang/cs/Org.Apache.REEF.Client.Tests/HDInsightYarnClientTests.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Client.Tests/HDInsightYarnClientTests.cs b/lang/cs/Org.Apache.REEF.Client.Tests/HDInsightYarnClientTests.cs new file mode 100644 index 0000000..2f61756 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Client.Tests/HDInsightYarnClientTests.cs @@ -0,0 +1,168 @@ +// 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.Collections.Generic; +using System.Linq; +using System.Net; +using System.Threading.Tasks; +using Org.Apache.REEF.Client.Yarn.RestClient; +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 Xunit; + +namespace Org.Apache.REEF.Client.Tests +{ + public class HDInsightYarnClientTests + { + [Trait("Category", "Functional")] + [Fact(Skip = @"Requires HDInsight Cred")] + public async Task TestGetClusterInfo() + { + var injector = TangFactory.GetTang().NewInjector(); + var cred = new HDInsightTestCredential(); + var urlProvider = new HDInsightRMUrlProvider(); + injector.BindVolatileInstance(GenericType<IYarnRestClientCredential>.Class, cred); + injector.BindVolatileInstance(GenericType<IUrlProvider>.Class, urlProvider); + var client = injector.GetInstance<IYarnRMClient>(); + + var clusterInfo = await client.GetClusterInfoAsync(); + + Assert.NotNull(clusterInfo); + Assert.Equal(ClusterState.STARTED, clusterInfo.State); + Assert.True(clusterInfo.StartedOn > 0); + } + + [Trait("Category", "Functional")] + [Fact(Skip = @"Requires HDInsight Cred")] + public async Task TestGetClusterMetrics() + { + var injector = TangFactory.GetTang().NewInjector(); + var cred = new HDInsightTestCredential(); + var urlProvider = new HDInsightRMUrlProvider(); + injector.BindVolatileInstance(GenericType<IYarnRestClientCredential>.Class, cred); + injector.BindVolatileInstance(GenericType<IUrlProvider>.Class, urlProvider); + var client = injector.GetInstance<IYarnRMClient>(); + + var clusterMetrics = await client.GetClusterMetricsAsync(); + + Assert.NotNull(clusterMetrics); + Assert.True(clusterMetrics.TotalMB > 0); + Assert.True(clusterMetrics.ActiveNodes > 0); + } + + [Trait("Category", "Functional")] + [Fact(Skip = @"Requires HDInsight Cred")] + public async Task TestApplicationSubmissionAndQuery() + { + var injector = TangFactory.GetTang().NewInjector(); + var cred = new HDInsightTestCredential(); + var urlProvider = new HDInsightRMUrlProvider(); + injector.BindVolatileInstance(GenericType<IYarnRestClientCredential>.Class, cred); + injector.BindVolatileInstance(GenericType<IUrlProvider>.Class, urlProvider); + var client = injector.GetInstance<IYarnRMClient>(); + + var newApplication = await client.CreateNewApplicationAsync(); + + Assert.NotNull(newApplication); + Assert.False(string.IsNullOrEmpty(newApplication.ApplicationId)); + Assert.True(newApplication.MaximumResourceCapability.MemoryMB > 0); + Assert.True(newApplication.MaximumResourceCapability.VCores > 0); + + string applicationName = "REEFTEST_APPLICATION_" + Guid.NewGuid(); + Console.WriteLine(applicationName); + + const string anyApplicationType = "REEFTest"; + var submitApplicationRequest = new SubmitApplication + { + ApplicationId = newApplication.ApplicationId, + AmResource = new Resouce + { + MemoryMB = 500, + VCores = 1 + }, + ApplicationType = anyApplicationType, + ApplicationName = applicationName, + KeepContainersAcrossApplicationAttempts = false, + MaxAppAttempts = 1, + Priority = 1, + UnmanagedAM = false, + AmContainerSpec = new AmContainerSpec + { + Commands = new Commands + { + Command = @"DONTCARE" + }, + LocalResources = new LocalResources + { + Entries = new List<YARN.RestClient.DataModel.KeyValuePair<string, LocalResourcesValue>> + { + new YARN.RestClient.DataModel.KeyValuePair<string, LocalResourcesValue> + { + Key = "APPLICATIONWILLFAILBUTWEDONTCAREHERE", + Value = new LocalResourcesValue + { + Resource = "Foo", + Type = ResourceType.FILE, + Visibility = Visibility.APPLICATION + } + } + } + } + } + }; + + var application = await client.SubmitApplicationAsync(submitApplicationRequest); + + Assert.NotNull(application); + Assert.Equal(newApplication.ApplicationId, application.Id); + Assert.Equal(applicationName, application.Name); + Assert.Equal(anyApplicationType, application.ApplicationType); + + var getApplicationResult = client.GetApplicationAsync(newApplication.ApplicationId).GetAwaiter().GetResult(); + + Assert.NotNull(getApplicationResult); + Assert.Equal(newApplication.ApplicationId, getApplicationResult.Id); + Assert.Equal(applicationName, getApplicationResult.Name); + Assert.Equal(anyApplicationType, getApplicationResult.ApplicationType); + } + } + + public class HDInsightTestCredential : IYarnRestClientCredential + { + private const string UserName = @"foo"; + private const string Password = @"bar"; // TODO: Do not checkin!!! + private readonly ICredentials _credentials = new NetworkCredential(UserName, Password); + + public ICredentials Credentials + { + get { return _credentials; } + } + } + + public class HDInsightRMUrlProvider : IUrlProvider + { + private const string HDInsightUrl = "https://baz.azurehdinsight.net/"; + + public Task<IEnumerable<Uri>> GetUrlAsync() + { + return Task.FromResult(Enumerable.Repeat(new Uri(HDInsightUrl), 1)); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/reef/blob/ec7bc969/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 724fe05..6d72cdc 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 @@ -62,6 +62,7 @@ under the License. </Reference> </ItemGroup> <ItemGroup> + <Compile Include="HDInsightYarnClientTests.cs" /> <Compile Include="JobResourceUploaderTests.cs" /> <Compile Include="LegacyJobResourceUploaderTests.cs" /> <Compile Include="MultipleRMUrlProviderTests.cs" /> http://git-wip-us.apache.org/repos/asf/reef/blob/ec7bc969/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 91a2114..be6e3e2 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 @@ -103,7 +103,9 @@ under the License. <Compile Include="YARN\RestClient\IRequestFactory.cs" /> <Compile Include="YARN\RestClient\IRestClient.cs" /> <Compile Include="YARN\RestClient\ISerializer.cs" /> + <Compile Include="YARN\RestClient\IYarnRestClientCredential.cs" /> <Compile Include="YARN\RestClient\Method.cs" /> + <Compile Include="YARN\RestClient\NullYarnRestClientCredential.cs" /> <Compile Include="YARN\RestClient\RequestFactory.cs" /> <Compile Include="YARN\RestClient\RestClient.cs" /> <Compile Include="YARN\RestClient\RestJsonDeserializer.cs" /> http://git-wip-us.apache.org/repos/asf/reef/blob/ec7bc969/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 index 6d636d2..311b57b 100644 --- a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/HttpClient.cs +++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/HttpClient.cs @@ -30,10 +30,10 @@ namespace Org.Apache.REEF.Client.YARN.RestClient private readonly System.Net.Http.HttpClient _httpClient; [Inject] - private HttpClient() + private HttpClient(IYarnRestClientCredential yarnRestClientCredential) { _httpClient = new System.Net.Http.HttpClient( - new HttpClientRetryHandler(new WebRequestHandler()), + new HttpClientRetryHandler(new WebRequestHandler { Credentials = yarnRestClientCredential.Credentials }), disposeHandler: false); } http://git-wip-us.apache.org/repos/asf/reef/blob/ec7bc969/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 ca4e2bc..0091a57 100644 --- a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRestRequestExecutor.cs +++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IRestRequestExecutor.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 http://git-wip-us.apache.org/repos/asf/reef/blob/ec7bc969/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IYarnRestClientCredential.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IYarnRestClientCredential.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IYarnRestClientCredential.cs new file mode 100644 index 0000000..567188d --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/IYarnRestClientCredential.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 System.Net; +using Org.Apache.REEF.Tang.Annotations; + +namespace Org.Apache.REEF.Client.YARN.RestClient +{ + /// <summary> + /// Provides the credentials to be used by the REST client to + /// connect to YARN RM. + /// </summary> + [DefaultImplementation(typeof(NullYarnRestClientCredential))] + public interface IYarnRestClientCredential + { + /// <summary> + /// .NET credentials to be used by REST client + /// </summary> + ICredentials Credentials { get; } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/reef/blob/ec7bc969/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/NullYarnRestClientCredential.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/NullYarnRestClientCredential.cs b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/NullYarnRestClientCredential.cs new file mode 100644 index 0000000..eecd3c6 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Client/YARN/RESTClient/NullYarnRestClientCredential.cs @@ -0,0 +1,38 @@ +// 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; +using Org.Apache.REEF.Tang.Annotations; + +namespace Org.Apache.REEF.Client.YARN.RestClient +{ + internal class NullYarnRestClientCredential : IYarnRestClientCredential + { + [Inject] + private NullYarnRestClientCredential() + { + } + + public ICredentials Credentials + { + get + { + return null; + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/reef/blob/ec7bc969/lang/cs/Org.Apache.REEF.Client/YARN/YARNClientConfiguration.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Client/YARN/YARNClientConfiguration.cs b/lang/cs/Org.Apache.REEF.Client/YARN/YARNClientConfiguration.cs index 0920cb7..04753fc 100644 --- a/lang/cs/Org.Apache.REEF.Client/YARN/YARNClientConfiguration.cs +++ b/lang/cs/Org.Apache.REEF.Client/YARN/YARNClientConfiguration.cs @@ -18,6 +18,7 @@ using Org.Apache.REEF.Client.API; using Org.Apache.REEF.Client.YARN; using Org.Apache.REEF.Client.YARN.Parameters; +using Org.Apache.REEF.Client.YARN.RestClient; using Org.Apache.REEF.Tang.Formats; using Org.Apache.REEF.Tang.Util; using Org.Apache.REEF.Utilities.Attributes; @@ -32,6 +33,7 @@ namespace Org.Apache.REEF.Client.Yarn public static readonly OptionalParameter<string> JobSubmissionFolderPrefix = new OptionalParameter<string>(); public static readonly OptionalParameter<string> SecurityTokenKind = new OptionalParameter<string>(); public static readonly OptionalParameter<string> SecurityTokenService = new OptionalParameter<string>(); + public static readonly OptionalImpl<IYarnRestClientCredential> YarnRestClientCredential = new OptionalImpl<IYarnRestClientCredential>(); public static ConfigurationModule ConfigurationModule = new YARNClientConfiguration() .BindImplementation(GenericType<IREEFClient>.Class, GenericType<YarnREEFClient>.Class) @@ -44,6 +46,7 @@ namespace Org.Apache.REEF.Client.Yarn " and ConfigurationModuleYARNRest would be merged.")] public static ConfigurationModule ConfigurationModuleYARNRest = new YARNClientConfiguration() .BindImplementation(GenericType<IREEFClient>.Class, GenericType<YarnREEFDotNetClient>.Class) + .BindImplementation(GenericType<IYarnRestClientCredential>.Class, YarnRestClientCredential) .BindNamedParameter(GenericType<JobSubmissionDirectoryPrefixParameter>.Class, JobSubmissionFolderPrefix) .BindNamedParameter(GenericType<SecurityTokenKindParameter>.Class, SecurityTokenKind) .BindNamedParameter(GenericType<SecurityTokenServiceParameter>.Class, SecurityTokenService)
