2
votes

I want to use ApplicationTokenProvider.LoginSilentAsync(tenantId, clientCredential).Result which is referencing to Microsoft.Rest.Azure.Authentication Namespace. This Microsoft.Rest.Azure.Authentication Namespace is inside Microsoft.Rest.ClientRuntime.Azure.Authentication namespace (dll).

I want to use this inside the SSIS script task that why I have to load that namespace at runtime from local file storage using System.Reflection.Assembly.LoadFile("path").

Because of Microsoft.Rest.Azure.Authentication doesn't have dll file this How It gives me an error at run-time.

Please tell how can load this namespace at runtime.

using Microsoft.IdentityModel.Clients.ActiveDirectory;

using Microsoft.Azure.Management.DataLake.Store; using Microsoft.Rest.Azure.Authentication; using System.Net.Http;

public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
    static ScriptMain()
    {
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
    }
    static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
       if (args.Name.Contains("Newtonsoft.Json"))
        {
            return System.Reflection.Assembly.LoadFile(@"D:\Azure_DLL\Newtonsoft.Json.dll");
        }

        if (args.Name.Contains("Microsoft.Azure.DataLake.Store"))
        {
            return System.Reflection.Assembly.LoadFile(@"D:\Azure_DLL\Microsoft.Azure.DataLake.Store.dll");
        }

        if (args.Name.Contains("Microsoft.Rest.ClientRuntime.Azure.Authentication"))
        {
            return System.Reflection.Assembly.LoadFile(@"D:\Azure_DLL\Microsoft.Rest.ClientRuntime.Azure.Authentication.dll");
        }

        if (args.Name.Contains("Microsoft.Rest.ClientRuntime"))
        {
            return System.Reflection.Assembly.LoadFile(@"D:\Azure_DLL\Microsoft.Rest.ClientRuntime.dll");
        }

        if (args.Name.Contains("System.Net.Http"))
        {
            return System.Reflection.Assembly.LoadFile(@"D:\Azure_DLL\System.Net.Http.dll");
        }

        return null;
    }
   public void Main()
    {
        // TODO: Add your code here
        // 1. Set Synchronization Context

        DataLakeStoreFileSystemManagementClient adlsFileSystemClient;

        // Portal > Azure AD > App Registrations > App > Application ID (aka Client ID)
        string clientId = "0e91";

        // Portal > Azure AD > App Registrations > App > Settings > Keys (aka Client Secret)
        string clientSecret = "6sHH8s7eT18=";

        // Portal > Azure AD > Properties > Directory ID (aka Tenant ID)
        string tenantId = "17788a7";

        // Name of the Azure Data Lake Store
        string adlsAccountName = "sjmadls08";


        string connectionString = "Data Source=SAGARM-PC;Initial Catalog=Destinantion;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;";

        var bytes = datared("Emp", connectionString);
        MemoryStream stream = new MemoryStream(bytes);

        // 1. Set Synchronization Context
        SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());

        // 2. Create credentials to authenticate requests as an Active Directory application
        var clientCredential = new ClientCredential(clientId, clientSecret);
        var creds = ApplicationTokenProvider.LoginSilentAsync(tenantId, clientCredential).Result;

        //// 2. Initialise Data Lake Store File System Client
        //adlsFileSystemClient = new DataLakeStoreFileSystemManagementClient(creds);

        //// 3. Upload a file to the Data Lake Store
        //var destinationfilepath = "/shared/Emp_data_CurrentDate.txt";
        //   adlsFileSystemClient.FileSystem.Create(adlsAccountName, destinationfilepath, overwrite: true);
        //  adlsFileSystemClient.FileSystem.Append(adlsAccountName, destinationfilepath, stream);

        Dts.TaskResult = (int)ScriptResults.Success;
    }}

Error - at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams) at Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTATaskScriptingEngine.ExecuteScript()

Also, I have tried this but -

var DLL = Assembly.LoadFrom(@"D:\Azure_DLL\Microsoft.Rest.ClientRuntime.Azure.Authentication.dll");

 Type t = DLL.GetType("Microsoft.Rest.Azure.Authentication.ApplicationTokenProvider");

var methodInfo = t.GetMethod("LoginSilentAsync", new Type[] { typeof(string), typeof(ClientCredential) });

        var domain = "1dfgf88a7";
        var clientId = "0e499fdfgdf2b7131ee91";
        var clientSecret = "6vagtMMPAaZdfgdfs7eT18=";
        var clientCredential = new ClientCredential(clientId, clientSecret);


        // Gives status wwaiting for activation. 
        var a = methodInfo.Invoke(null, new object[] { domain, clientCredential });

        //Gives me the error No parameter less constructor
        object instance = Activator.CreateInstance(t);

`

1
Does this help? Azure data lake store file read using ssis script component. It shows how to use the CurrentDomain_AssemblyResolve event to load DLLs - Ian
@Ian I have referred the same. But I getting the exception for above mentioned. - Sagar Malandkar
Please post whatever code you've tried, and details of the error you get - Ian
@Ian Added my code and exception. - Sagar Malandkar
Thanks for the extra info @Sagar, but for the error you've only posted the stack trace. Please could you add the error message too? - Ian

1 Answers

0
votes

I was having a similar issue but after hours of crawling through various solutions I managed to find a slightly different implementation here.

So I added the following code:

private static ServiceClientCredentials AuthenticateAzure
    (string domainName, string clientID, string clientSecret)
    {
        SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());

        var clientCredential = new ClientCredential(clientID, clientSecret);
        return ApplicationTokenProvider.LoginSilentAsync(domainName, clientCredential).Result;
    }

And referenced that within the Main() using the following:

var creds = AuthenticateAzure(tenantId, clientId, clientSecret);

Which returned the actual error: System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.IdentityModel.Clients.ActiveDirectory, Version=2.28.3.860

The version I installed originally using NuGet was 5.2.1.0.

I know its a bit hacky but I downloaded Version=2.28.3.860, and replaced the newer version which solved the issue.

In addition, it seemed there was also an issue with the Newtonsoft.Json assembly which needed to be version 6.

And for debugging at runtime, it seems those dll's need copying to the "C:\Users\\AppData\Local\Microsoft\Microsoft SQL Server\140\SSIS\130\x64"

Of course this might differ depending on your version.