0

I referred the site https://github.com/toddkitta/azure-content/blob/master/articles/data-lake-analytics/data-lake-analytics-get-started-net-sdk.md for submitting a U-SQL job but the above GitHub sample showing error in the console application in the Authentication AcquireToken method.enter image description here

Please Suggest me a sample for submitting a U-SQL job using.Net SDK

enter image description here

Edited: PlatformParameters is showing error in my Visual Studio. I think, forgot include that class. enter image description here

Arron
  • 1,134
  • 2
  • 13
  • 32
  • What error are you getting? What have you tried yourself to get it to work. Please give us some more info (and show us the effort you did to get it to work). – rickvdbosch Jul 11 '17 at 06:56
  • I have used the authContext.AcquireToken(resource, appClientId, appRedirectUri, PromptBehavior.Auto); – Arron Jul 11 '17 at 07:01
  • in the authContext class there is no AcquireToken method – Arron Jul 11 '17 at 07:02
  • instead it have AcquireTokenAsync,AcquireTokenByAuthorizationCodeAsync,AcquireTokenSilentAsync methods – Arron Jul 11 '17 at 07:03
  • so i am unable to submit the job using the C# console application – Arron Jul 11 '17 at 07:03
  • I don't understand. You could just as easily use AcquireTokenAsync. Call like ```AcquireTokenAsync(parameters).Result```. This will await the async method and return the result. – rickvdbosch Jul 11 '17 at 07:07
  • The sample from msdn not having the AcquireTokenAsync method – Arron Jul 11 '17 at 07:09
  • AcquireTokenAsync is expecting parameters other than the actual parameters in AcquireToken method – Arron Jul 11 '17 at 07:12

2 Answers2

3

As Rick van den Bosch mentioned that we need to use AcquireTokenAsync method, I also following the document to do a demo. And change some code in my side, then it works correctly on my side. The following is my detail steps.

preparation

1.Registry an native AD application and Add Windows Azure Service Management API permission, more details please refer to Azure official tutorials. After that we can get tenantId, appId, Redirect URI from the Azure Portal.

enter image description here

enter image description here

2.Create Data Lake Analytics and Data Lake Store account. I assgin permission to to folder or file in the data lake store, more detail please refer to another SO thread.

3.Prepare a script file in the local folder,I get the script from your mentioned document.

C:\Tom\SampleUSQLScript.txt

4.Upload the SearchLog.tsv to the Azure storage account and set it as public

Steps:

1.Create a console project and reference to corresponding SDK,details please refer to the packages.config section.

2.Add how to get TokenCredentials function

   public static TokenCredentials AuthenticateUser(string tenantId, string resource, string appClientId, Uri appRedirectUri, string userId = "")
        {
            var authContext = new AuthenticationContext("https://login.microsoftonline.com/" + tenantId);

            var tokenAuthResult = authContext.AcquireTokenAsync(resource, appClientId, appRedirectUri, new PlatformParameters(PromptBehavior.Auto),
                 UserIdentifier.AnyUser).Result;

            return new TokenCredentials(tokenAuthResult.AccessToken);
        }

Test the TokenCredentials functon

enter image description here

3.Add SetupClients function

 public static void SetupClients(TokenCredentials tokenCreds, string subscriptionId)
    {
        _adlaClient = new DataLakeAnalyticsAccountManagementClient(tokenCreds) {SubscriptionId = subscriptionId};

        _adlaJobClient = new DataLakeAnalyticsJobManagementClient(tokenCreds);

        _adlaCatalogClient = new DataLakeAnalyticsCatalogManagementClient(tokenCreds);

        _adlsClient = new DataLakeStoreAccountManagementClient(tokenCreds) {SubscriptionId = subscriptionId};

        _adlsFileSystemClient = new DataLakeStoreFileSystemManagementClient(tokenCreds);
    }

4.Add SubmitJobByPath function

 public static string SubmitJobByPath(string scriptPath, string jobName)
        {
            var script = File.ReadAllText(scriptPath);
            var jobId = Guid.NewGuid();
            var properties = new USqlJobProperties(script);
            var parameters = new JobInformation(jobName, JobType.USql, properties, priority: 1000, degreeOfParallelism: 1);
            var jobInfo = _adlaJobClient.Job.Create(_adlaAccountName,jobId, parameters);
            return jobId.ToString();
        }

5.Add other related functions

 public static void UploadFile(string srcFilePath, string destFilePath, bool force = true)
        {
            var parameters = new UploadParameters(srcFilePath, destFilePath, _adlsAccountName, isOverwrite: force);
            var frontend = new DataLakeStoreFrontEndAdapter(_adlsAccountName, _adlsFileSystemClient);
            var uploader = new DataLakeStoreUploader(parameters, frontend);
            uploader.Execute();
        }

        // Download file
  public static void DownloadFile(string srcPath, string destPath)
        {
            var stream = _adlsFileSystemClient.FileSystem.Open(srcPath, _adlsAccountName);
            var fileStream = new FileStream(destPath, FileMode.Create);

            stream.CopyTo(fileStream);
            fileStream.Close();
            stream.Close();
        }


 public static JobResult WaitForJob(string jobId)
        {
            var jobInfo = _adlaJobClient.Job.Get(_adlaAccountName,Guid.Parse(jobId));
            while (jobInfo.State != JobState.Ended)
            {
                jobInfo = _adlaJobClient.Job.Get(_adlaAccountName, Guid.Parse(jobId)); 
            }
            return jobInfo.Result.Value;
        }

public static void WaitForNewline(string reason, string nextAction = "")
        {
            if (!String.IsNullOrWhiteSpace(nextAction))
            {
                Console.WriteLine(reason + "\r\nPress ENTER to continue...");
                Console.ReadLine();
                Console.WriteLine(nextAction);
            }
            else
            {
                Console.WriteLine(reason + "\r\nPress ENTER to continue...");
                Console.ReadLine();
            }

6.Add the test submitting job code.

 private static void Main(string[] args)
    {
        _adlsAccountName = "data lake store account"; // TODO: Replace this value with the name for a created Store account.
        _adlaAccountName = "data lake analytics"; // TODO: Replace this value with the name for a created Analytics account.
        string localFolderPath = @"C:\tom\"; // TODO: Make sure this exists and contains the U-SQL script.

        // Authenticate the user
        // For more information about applications and instructions on how to get a client ID, see: 
        // https://azure.microsoft.com/en-us/documentation/articles/resource-group-create-service-principal-portal/
        var tokenCreds = AuthenticateUser("common", "https://management.core.windows.net/",
            "application id", new Uri("http://localhost")); // TODO: Replace applicaion id and redirect url values.

        SetupClients(tokenCreds, "subscription id"); // TODO: Replace subscription value.

        // Run sample scenarios

        // Transfer the source file from a public Azure Blob container to Data Lake Store.
        CloudBlockBlob blob = new CloudBlockBlob(new Uri("https://tomnew.blob.core.windows.net/adls-sample-data/SearchLog.tsv"));
        blob.DownloadToFile(localFolderPath + "SearchLog.tsv", FileMode.Create); // from WASB
        UploadFile(localFolderPath + "SearchLog.tsv", "/mytempdir/SearchLog.tsv"); // to ADLS
        WaitForNewline("Source data file prepared.", "Submitting a job.");

        // Submit the job
        string jobId = SubmitJobByPath(localFolderPath + "SampleUSQLScript.txt", "My First ADLA Job");
        WaitForNewline("Job submitted.", "Waiting for job completion.");

        // Wait for job completion
        WaitForJob(jobId);
        WaitForNewline("Job completed.", "Downloading job output.");


    }

7.Debug from the local and check the result from azure portal.

enter image description here

enter image description here

packages.config

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.Azure.KeyVault.Core" version="1.0.0" targetFramework="net46" />
  <package id="Microsoft.Azure.Management.DataLake.Analytics" version="3.0.0" targetFramework="net46" />
  <package id="Microsoft.Azure.Management.DataLake.Store" version="1.0.4" targetFramework="net46" />
  <package id="Microsoft.Azure.Management.DataLake.StoreUploader" version="1.0.1-preview" targetFramework="net46" />
  <package id="Microsoft.Data.Edm" version="5.8.2" targetFramework="net46" />
  <package id="Microsoft.Data.OData" version="5.8.2" targetFramework="net46" />
  <package id="Microsoft.Data.Services.Client" version="5.8.2" targetFramework="net46" />
  <package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.14.1" targetFramework="net46" />
  <package id="Microsoft.Rest.ClientRuntime" version="2.3.8" targetFramework="net46" />
  <package id="Microsoft.Rest.ClientRuntime.Azure" version="3.3.7" targetFramework="net46" />
  <package id="Newtonsoft.Json" version="6.0.8" targetFramework="net46" />
  <package id="System.ComponentModel.EventBasedAsync" version="4.0.11" targetFramework="net46" />
  <package id="System.Dynamic.Runtime" version="4.0.0" targetFramework="net46" />
  <package id="System.Linq.Queryable" version="4.0.0" targetFramework="net46" />
  <package id="System.Net.Requests" version="4.0.11" targetFramework="net46" />
  <package id="System.Spatial" version="5.8.2" targetFramework="net46" />
  <package id="WindowsAzure.Storage" version="8.1.4" targetFramework="net46" />
</packages>

Update:

If we want to use silently login, we could use following code to get tokenCreds var tokenCreds = AuthenticateSlientUser("https://management.core.windows.net/", tenantId, applicationId, secretKey)

public static TokenCredentials AuthenticateSlientUser(string resource,string tenantId, string appClientId, string secretKey)
        {
            var authContext = new AuthenticationContext("https://login.microsoftonline.com/" + tenantId);

            var tokenAuthResult = authContext.AcquireTokenAsync(resource, new ClientCredential(appClientId, secretKey)).Result;

            return new TokenCredentials(tokenAuthResult.AccessToken);
        }
Tom Sun - MSFT
  • 24,161
  • 3
  • 30
  • 47
  • Thanks for your Detailed Answer. – Arron Jul 12 '17 at 07:34
  • Iam having a doubt in the AuthenticateUser Method – Arron Jul 12 '17 at 07:34
  • var tokenAuthResult = authContext.AcquireTokenAsync(resource, appClientId, appRedirectUri, new PlatformParameters(PromptBehavior.Auto), UserIdentifier.AnyUser).Result; – Arron Jul 12 '17 at 07:35
  • PlatformParameters is showing error in my visual studio – Arron Jul 12 '17 at 07:35
  • Please have a try to use my code. It works correctly on my side. `var tokenAuthResult = authContext.AcquireTokenAsync(resource, appClientId, appRedirectUri, new PlatformParameters(PromptBehavior.Auto), UserIdentifier.AnyUser).Result;` – Tom Sun - MSFT Jul 12 '17 at 07:39
  • packages.config section is not given in your example – Arron Jul 12 '17 at 07:43
  • I will update it into the answer, sorry for missing that. – Tom Sun - MSFT Jul 12 '17 at 07:43
  • please look into it – Arron Jul 12 '17 at 07:53
  • `PlatformParameters` is in the namespace `Microsoft.IdentityModel.Clients.ActiveDirectory`. – Tom Sun - MSFT Jul 12 '17 at 07:56
  • PlatformParameters is not found in the Microsoft.IdentityModel.Clients.ActiveDirectory. – Arron Jul 12 '17 at 07:59
  • If you are not using the latest Microsoft.IdentityModel.Clients.ActiveDirectory SDK. Please have a try to use the latest [Microsoft.IdentityModel.Clients.ActiveDirectory](https://www.nuget.org/packages/Microsoft.IdentityModel.Clients.ActiveDirectory) SDK, more detail info about platformparameters, please refer to the [document](https://learn.microsoft.com/en-us/dotnet/api/microsoft.identitymodel.clients.activedirectory.platformparameters?view=azure-dotnet) – Tom Sun - MSFT Jul 12 '17 at 08:06
  • Already Iam using the latest Microsoft.IdentityModel.Clients.ActiveDirectory SDK (3.14.1) – Arron Jul 12 '17 at 08:09
  • I have added the Microsoft.IdentityModel.Clients.ActiveDirectory.platformparameters dll from the project folder. – Arron Jul 12 '17 at 08:52
  • But one small issue, i want to signin to azure silently. It should not ask for credentials in the popup – Arron Jul 12 '17 at 08:53
  • If we want to use silently login, we could use following code to get tokenCreds `var tokenCreds = AuthenticateSlientUser("https://management.core.windows.net/", tenantId, applicationId, secretKey)`, I also update the code to my answer. – Tom Sun - MSFT Jul 12 '17 at 09:54
  • Thanks for your Answer – Arron Jul 12 '17 at 10:08
  • In the SubmitJobByPath method, it is throwing the error "The user does not have the permission to perform this operation". – Arron Jul 12 '17 at 10:09
  • Not worked:I had created a webapp/webapi Application in the AAD. – Arron Jul 12 '17 at 10:28
  • Working: Created a new Native Application – Arron Jul 12 '17 at 10:28
  • Hi Tom sun, I want to use custom extractors for the SampleUSQLScript. – Arron Jul 13 '17 at 09:57
  • along with the above steps. – Arron Jul 13 '17 at 10:05
0

The sample from msdn not having the AcquireTokenAsync method - Arron

Sometimes documentation lags behind. They probably updated the package but haven't updated the documentation yet. Use the Async method, you'll be fine.

You could just as easily use AcquireTokenAsync method. Call it like stated below. This will await the async method and return the result, even in synchronous methods.

var token = authContext.AcquireTokenAsync(parameters).Result;

For the parameters to be used, have a look at the documentation: Authentication​Context.​Acquire​Token​Async Method

You can find multiple examples of working code online. Here's one example.

rickvdbosch
  • 14,105
  • 2
  • 40
  • 53