Part 1 – Building a Custom Connection Manager

Following on from my introductory post, here I will be explaining how to develop a Custom Connection Manager for RabbitMQ. This connection manager will then be used in future posts by a custom Source and Destination component.

What is a Connection Manager for?

From the MSDN documentation:

“Integration Services uses connection managers to encapsulate the information needed to connect to an external data source. […] If the connection managers and external data sources supported by Integration Services do not entirely meet your requirements, you can create a custom connection manager.”

By the sounds of it, creating a Connection Manager should be pretty straightforward:

  1. To create a custom connection manager, you have to create a class that inherits from the ConnectionManagerBase base class,
  2. Apply the DtsConnectionAttributeattribute to your new class,
  3. Override the important methods and properties of the base class, including the ConnectionString property and the AcquireConnection method.

Prerequisites

All of these examples will be designed against the SDK for SQL Server 2012. You will need to ensure you installed the Client SDK during the installation of SQL Server.

Setting up the solution

I created a new solution and added a new class library projects to it called SSISRabbitMQ.RabbitMQConnectionManager.

To this project I then added the RabbitMQ client library via NuGet:

Adding RabbitMQ client via NuGet

The next step is to add a reference to the Microsoft.SqlServer.ManagedDTS.dll, from the documentation:

“The Microsoft.SqlServer.Dts.Runtime namespace contains the classes and interfaces to create packages, custom tasks, and other package control flow elements.”

This assembly can be found in C:\Program Files (x86)\Microsoft SQL Server\110\SDK\Assemblies

ssis-rabbit-sdk

There are a few other assemblies in this directory that will be used in later stages.

For SSDT BI to pick up the custom connection manager it needs to be stored in the GAC, as well as a few other folders in the SQL Server directory.

The next step is to create a post build action that will automate this each time the project is built. Open the project properties by double clicking on Properties or by going to the Project menu and selecting “SSISRabbitMQ.RabbitMQConnectionManager Properties…”

Click Build Events and the paste the following into the Post Build event text area:

"C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\gacutil.exe" -u $(TargetName)
"C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\gacutil.exe" -iF $(TargetFileName)
copy $(TargetFileName) "C:\Program Files (x86)\Microsoft SQL Server\110\DTS\Connections\$(TargetFileName)" /y

copy "$(TargetDir)RabbitMQ.Client.dll" "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies" /y
copy "$(TargetDir)RabbitMQ.Client.dll" "C:\Program Files\Microsoft SQL Server\110\DTS\Binn" /y

The last step to setting up the project is to sign the assembly, the reason for this is because the assembly that will be built is going into the GAC. All assemblies that go into the GAC need to be signed with a strong name. See here for more details.

With the properties still open click on “Signing” .

Tick the checkbox “Sign the assembly”, select <New…”> from the “Choose  a strong name key file” drop down, and I created one called ssisrabbitmq.snk

ssis-rabbit-signing

The solution so far looks like this:

ssis-rabbit-solution

Creating the Connection Manager

Now that the solution is setup with all dependencies it is time to start on the actual connection manager class.

Start by adding a new class file “RabbitMQConnectionManager.cs”, to this class apply the DtsConnection attribute. There are three properties which will need to be set:

  • ConnectionType
  • DisplayName
  • Description

These are the properties which will appear in SQL Server Data Tools BI when a user goes to add a new connection.

The next step is to extend the ConnectionManagerBase class.

This is the code so far:

[DtsConnection(ConnectionType = "RABBITMQ",DisplayName = "RabbitMQ",
               Description = "Connection Manager for RabbitMQ")]
public class RabbitMQConnectionManager : ConnectionManagerBase
{
}

The next step is to add a number of properties which will be used for the actual connection to the RabbitMQ broker:

public string HostName { get; set; }
public string VirtualHost { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public int Port { get; set; }

For the sake of speedy development, in the constructor I’m setting the default properties for the connection.

public RabbitMQConnectionManager()
{
  HostName = "localhost";
  VirtualHost = "/";
  UserName = "guest";
  Password = "guest";
  Port = 5672;
}

Validating the Connection Manager

By overriding the Validate method, SSDT BI is able to make sure that the user has configured the connection correctly. If the method returns DTSExecResult.Failure then the package won’t begin execution.

public override Microsoft.SqlServer.Dts.Runtime.DTSExecResult Validate(Microsoft.SqlServer.Dts.Runtime.IDTSInfoEvents infoEvents)
{
  if (string.IsNullOrWhitespace(HostName))
  {
    return DTSExecResult.Failure;
  }
  else if (string.IsNullOrWhitespace(VirtualHost))
  {
    return DTSExecResult.Failure;
  }
  else if (string.IsNullOrWhitespace(UserName))
  {
    return DTSExecResult.Failure;
  }
  else if (string.IsNullOrWhitespace(Password))
  {
    return DTSExecResult.Failure;
  }
  else if (Port <= 0)
  {
    return DTSExecResult.Failure;
  }

  return DTSExecResult.Success;
}

Setting up the connection to RabbitMQ

The next two methods to override are AcquireConnection and ReleaseConnection.

These methods are called at various times during Design Time and Run Time.


public override object AcquireConnection(object txn)
{
  ConnectionFactory connFactory = new ConnectionFactory()
  {
    UserName = UserName,
    HostName = HostName,
    Password = Password,
    Port = Port,
    VirtualHost = VirtualHost
  };

  var connection = connFactory.CreateConnection();

  return connection;
}

In the AcquireConnection method we are basically just setting up the connection to RabbitMQ. (As I am aiming to be as simple as possible I’m leaving out a lot of exception handling, so beware!)

If you aren’t familiar with the RabbitMQ API for C# then it is definitely worthwhile to have a read through the user guide which can be found on the RabbitMQ website here.

The next method is ReleaseConnection:


public override void ReleaseConnection(object connection)
{
  if (connection != null)
  {
    ((IConnection)connection).Close();
  }
}

Here we are closing the connection.

The solution so far

A custom connection manager which users can use to add connections to RabbitMQ into their packages. This is obviously useless until the Source and Destination components have been added.

After building the solution and creating a new Integration Services project in SSDT BI I can now add the connection manager into a new package:

ssis-rabbitmq-adding-connection

The properties are also visible:

ssis-rabbitmq-connection-properties

That is it for now on the custom connection manager.

Stay tuned, in the next post I will be showing how to create a custom source which uses the RabbitMQConnectionManager custom user interface for the RabbitMQConnectionManager.

UPDATE:

Something that I forgot to mention, because of the post build action calling the gacutil.exe you will need to run Visual Studio as Administrator.

Advertisements

30 thoughts on “Part 1 – Building a Custom Connection Manager

  1. Mattia says:

    Hi i have a problem, if i put the component in the SSIS.
    The error message is:

    Error at Data Flow Task [RabbitMQ Source [1]]: System.IO.FileNotFoundException: Could not load file or assembly ‘RabbitMQ.Client, Version=3.1.1.0, Culture=neutral, PublicKeyToken=89e7d7c5feba84ce’ or one of its dependencies. The system cannot find the file specified.
    File name: ‘RabbitMQ.Client, Version=3.1.1.0, Culture=neutral, PublicKeyToken=89e7d7c5feba84ce’
    at SSISRabbitMQ.RabbitMQSource.RabbitMQSource.AcquireConnections(Object transaction)
    at Microsoft.SqlServer.Dts.Pipeline.ManagedComponentHost.HostAcquireConnections(IDTSManagedComponentWrapper100 wrapper, Object transaction)

    Error at Data Flow Task [SSIS.Pipeline]: RabbitMQ Source failed validation and returned error code 0x80070002.

    Error at Data Flow Task [SSIS.Pipeline]: One or more component failed validation.

    Error at Data Flow Task: There were errors during task validation.

    (Microsoft.DataTransformationServices.VsIntegration)

    can you help me?

    • KenR says:

      I believe that you’ll actually have to put the RabbitMQ.Client into the GAC you can do this from the “Developer Command prompt for Visual Studio” then use gacutil like this:
      gacutil.exe” -iF RabbitMQ.Client.dll

      • Mattia says:

        ok perfect, ty, i test it and all works.
        i have an another question, it’s possible to add this component in VS2008?

  2. Jeff says:

    Hi Ken, this series has been great for me I am writing custom WebsphereMQ components, did you ever complete the pipeline destination component? I am trying to write this and having a few issues, thanks

  3. Jeff says:

    Hey Ken, remember you said you’d try and help you may regret that!
    I keep getting Object reference not set to an instance object when I try the put in the ProcessInput procedure, I think this comes for the acquireconnection but this seems to run okay when I debug it in pre-validation.
    Code pasted below I’m a sql developer not a c# developer which is pretty obvious from this code 🙂 any advice would be appreciated

    using System;
    using System.Collections;
    using System.Text;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.SqlServer.Dts.Design;
    using Microsoft.SqlServer.Dts.Runtime;
    using Microsoft.SqlServer.Dts.Runtime.Wrapper;
    using Microsoft.SqlServer.Dts.Pipeline;
    using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
    using IBM.WMQ;
    using WEBSPHEREMQ;

    namespace WEBSPHEREMQ
    {
    [DtsPipelineComponent(IconResource = “MQIntegrationPipelineDestination.myTask.ico”,
    DisplayName = “WebsphereMQ Destination”,
    ComponentType = ComponentType.DestinationAdapter,
    Description = “Connection source for WebsphereMQ”)]
    public class MQSource : PipelineComponent
    {
    private WEBSPHEREMQ.MQConnectionManager websphereMqConnectionManager;
    private MQQueueManager mQManager;
    public MQQueue MQueue;
    private string queueName;
    private const string ColumnName = “Message”;
    private ArrayList columnInfos = new ArrayList();
    private const string MessageInputName = “Message”;

    #region ColumnInfo
    private struct ColumnInfo
    {
    public int BufferColumnIndex;
    public string ColumnName;
    }
    #endregion

    public override void ProvideComponentProperties()
    {

    // Reset the component.
    base.RemoveAllInputsOutputsAndCustomProperties();
    ComponentMetaData.RuntimeConnectionCollection.RemoveAll();

    IDTSInput100 input = ComponentMetaData.InputCollection.New();
    input.Name = MessageInputName;

    IDTSCustomProperty100 queueName = ComponentMetaData.CustomPropertyCollection.New();
    queueName.Name = “QueueName”;
    queueName.Description = “The name of WebsphereMQ queue to read messages from”;

    IDTSRuntimeConnection100 connection = ComponentMetaData.RuntimeConnectionCollection.New();
    connection.Name = “WEBSPHEREMQ”;
    connection.ConnectionManagerID = “WEBSPHEREMQ”;

    CreateColumns();
    }
    private void CreateColumns()
    {
    IDTSInput100 input = ComponentMetaData.InputCollection[0];

    input.InputColumnCollection.RemoveAll();
    IDTSInputColumn100 column1 = input.InputColumnCollection.New();
    column1.Name = ColumnName;
    }

    public override DTSValidationStatus Validate()
    {
    bool cancel;
    string qName = ComponentMetaData.CustomPropertyCollection[“QueueName”].Value;

    if (string.IsNullOrWhiteSpace(qName))
    {
    //Validate that the QueueName property is set
    ComponentMetaData.FireError(0, ComponentMetaData.Name, “The QueueName property must be set”, “”, 0, out cancel);
    return DTSValidationStatus.VS_ISBROKEN;
    }

    return base.Validate();
    }
    public override void AcquireConnections(object transaction)
    {
    if (ComponentMetaData.RuntimeConnectionCollection[0].ConnectionManager != null)
    {

    ConnectionManager connectionManager = Microsoft.SqlServer.Dts.Runtime.DtsConvert.GetWrapper(ComponentMetaData.RuntimeConnectionCollection[0].ConnectionManager);
    websphereMqConnectionManager = connectionManager.InnerObject as WEBSPHEREMQ.MQConnectionManager;

    if (websphereMqConnectionManager != null)
    {
    //object mQTemp = websphereMqConnectionManager.AcquireConnection(transaction) as object;
    mQManager = (MQQueueManager)websphereMqConnectionManager.AcquireConnection(transaction);
    queueName = ComponentMetaData.CustomPropertyCollection[“QueueName”].Value;

    if (mQManager.IsConnected)
    {
    ComponentMetaData.FireInformation(0, “AcquireConnections()”, “Connected.”, null, 0, true);
    ComponentMetaData.FireInformation(0, “AcquireConnections()”, “Connecting to queue”, null, 0, true);
    MQueue = mQManager.AccessQueue(queueName, MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING);

    }

    }
    }
    }

    public override void ReleaseConnections()
    {
    //if (websphereMqConnectionManager != null)
    //{
    // websphereMqConnectionManager.ReleaseConnection(mQManager);
    //}
    if (MQueue != null)
    MQueue.Close();

    base.ReleaseConnections();

    }

    public override void ProcessInput(int inputID, PipelineBuffer buffer)
    {
    ComponentMetaData.FireInformation(0, “ProcessInput”, “Beginning Process Input”, null, 0, true);

    if (!buffer.EndOfRowset)
    {
    while (buffer.NextRow())
    {

    for (int i = 0; i < columnInfos.Count; i++)
    {

    ColumnInfo ci = (ColumnInfo)columnInfos[i];
    object o = buffer[ci.BufferColumnIndex];
    if (o == null)
    {
    ComponentMetaData.FireInformation(0, "ProcessInput()", "o is Null", null, 0, true);
    }
    else
    {
    ComponentMetaData.FireInformation(0, "ProcessInput()", Convert.ToString(ci.ColumnName), null, 0, true);
    if (ci.ColumnName == ColumnName)
    {
    string MQPut = buffer[ci.BufferColumnIndex].ToString();
    ComponentMetaData.FireInformation(0, "ProcessInput()", Convert.ToString(ci.BufferColumnIndex), null, 0, true);

    MQMessage queueMessage = new IBM.WMQ.MQMessage();
    queueMessage.WriteString("JeffTest");
    queueMessage.Format = MQC.MQFMT_STRING;
    MQPutMessageOptions queuePutMessageOptions = new IBM.WMQ.MQPutMessageOptions();
    try
    {
    MQueue.Put(queueMessage, queuePutMessageOptions);
    }
    catch (MQException MQexp)
    {
    ComponentMetaData.FireInformation(0, "ProcessInput()", "Exception: " + MQexp.Message, null, 0, true);
    }
    catch (Exception exp)
    {
    ComponentMetaData.FireInformation(0, "ProcessInput()", "Exception: " + exp.Message, null, 0, true);
    }
    }
    }

    }

    //ComponentMetaData.FireInformation(0, "ProcessInput()", "Beginning loop of columnns", null, 0, true);
    //var message = new IBM.WMQ.MQMessage();
    //string MQPut = buffer[0].ToString();

    //message.Persistence = 0;

    //message.Format = MQC.MQFMT_STRING;
    //message.MessageType = MQC.MQMT_REQUEST;
    //message.MessageId = GenerateMQMsgId();
    //message.CorrelationId = message.MessageId;
    //message.WriteString(MQPut);
    //ComponentMetaData.FireInformation(0, "ProcessInput()", MQPut, null, 0, true);
    }
    }
    }
    private Byte[] GenerateMQMsgId()
    {
    string _mqMsgID = System.Convert.ToString(System.Guid.NewGuid());
    _mqMsgID = _mqMsgID.Replace("-", "");
    _mqMsgID = _mqMsgID.PadRight(48, '0');

    int byteLength = _mqMsgID.Length / 2;
    byte[] bytes = new byte[byteLength];
    string hex;
    int j = 0;
    for (int i = 0; i 0)
    {
    _profinput.ExternalMetadataColumnCollection.RemoveAll();
    }
    if (_profinput.InputColumnCollection.Count > 0)
    {
    _profinput.InputColumnCollection.RemoveAll();
    }
    CreateMetaDataColumns(_profinput);
    }

    private void CreateMetaDataColumns(IDTSInput100 input)
    {
    IDTSExternalMetadataColumnCollection100 extCols = input.ExternalMetadataColumnCollection;

    //IDTSInputColumn100 inCol = messageInput.InputColumnCollection.New();
    //inCol.Name = ColumnName;

    foreach (IDTSInputColumn100 inCol in input.InputColumnCollection)
    {
    if (inCol.Name == ColumnName)
    {
    IDTSExternalMetadataColumn100 extCol = extCols.New();
    extCol.Name = inCol.Name;
    extCol.ID = inCol.ID;
    extCol.DataType = inCol.DataType;
    extCol.Length = inCol.Length;
    extCol.Precision = inCol.Precision;
    extCol.Scale = inCol.Scale;
    extCol.CodePage = inCol.CodePage;
    }

    }
    }

    }
    }

    • KenR says:

      Hi Jeff, unfortunately the bug is not immediately obvious from the code you’ve posted and to debug it I would need to be able to run and compile it. However, I can share with you a helpful debugging tip which should help you figure out what is causing the Object reference exception.

      Add this line of code:
      Debugger.Launch();
      Into the ProcessInput method, you will also need to add
      using System.Diagnostics;
      to your existing using statements.

      After you’ve added that line of code, compile the extension then open a new instance of SSDT (so you should have visual studio open with you code still up and SSDT open with your test package). The next time you run your test package with the destination component, when SSIS hits the ProcessInput method you’ll get an OS level window popup asking you if you want to debug the application with a list of Visual Studio instances to select from, click on the one that contains your solution then OK. It should then drop you into your code and you can step through it to figure out what the cause of the Object reference exception is.

      Let me know if that helps or if you need me to clarify anything. I’m planning to write up a post on how to debug SSIS components but not sure exactly when I’ll get around to it.

  4. Aaron says:

    I’ve been trying to create a custom connection manager for a few days now and keep having a problem. I’ve even tried your example, line for line, and I still can’t get it to work.

    I’m using Visual studio 2013 and the latest SSDT BI. I can create a connection manger, from ConnectionManagerBase, and it compiles fine. I can deploy it to the GAC without problems. But, no matter what I do, it does not show up as a connection option in an “Integration Services Project”. What am I doing wrong?

  5. Aaron says:

    I have successfully created a custom connection manager, and data source, based on this series of articles. Thank you very much for writing these. I am, however, running into one big issue. I cannot get these components work once the package has been deployed to our server.

    I can create a package on my computer, using Visual Studio 2013, and it will run perfectly. When the package/project is deployed to our server (Server 2012R2 with Sql Serve 2014), it will not run. I keep getting an “AccessViolationException” when the connection manager is instanced. When stepping through the code, using the debugger, I can see the constructor being called (it’s an empty constructor), but when it reaches the end of the constructor, the AccessViolationException is thrown. It contains no information other than the basic exception info (nothing that helps find the problem).

    The following stack trace can be in the windows event viewer.

    Application: ISServerExec.exe Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: System.AccessViolationException Stack: at Microsoft.SqlServer.Dts.Runtime.Wrapper.IDTSPackagePersist100.LoadPackageFromXML(System.Object, Boolean, Microsoft.SqlServer.Dts.Runtime.Wrapper.IDTSEvents100) at Microsoft.SqlServer.Dts.Runtime.Wrapper.IDTSPackagePersist100.LoadPackageFromXML(System.Object, Boolean, Microsoft.SqlServer.Dts.Runtime.Wrapper.IDTSEvents100) at Microsoft.SqlServer.Dts.Runtime.Package.LoadFromXML(System.String, Microsoft.SqlServer.Dts.Runtime.IDTSEvents) at Microsoft.SqlServer.Dts.Runtime.Project.LoadPackage(Microsoft.SqlServer.Dts.Runtime.IProjectStorage, Microsoft.SqlServer.Dts.Runtime.Package, System.String, Microsoft.SqlServer.Dts.Runtime.IDTSEvents) at Microsoft.SqlServer.Dts.Runtime.PackageItem.Load(Microsoft.SqlServer.Dts.Runtime.IDTSEvents) at Microsoft.SqlServer.Dts.Runtime.PackageItem.LoadPackage(Microsoft.SqlServer.Dts.Runtime.IDTSEvents) at Microsoft.SqlServer.IntegrationServices.Server.ISServerExec.ISServerExecutionEvents.LoadPackage(Microsoft.SqlServer.Dts.Runtime.PackageItem) at Microsoft.SqlServer.IntegrationServices.Server.ISServerExec.ProjectOperator.StartPackage() at Microsoft.SqlServer.IntegrationServices.Server.ISServerExec.ProjectOperator.PerformOperation() at Microsoft.SqlServer.IntegrationServices.Server.ISServerExec.ExecuteMain.Main(System.String[])

    • KenR says:

      Well…That’s an interesting one! A very quick google around suggests that AccessViolationException could be caused by mixing 32bit and 64bit libraries. Are you using any external libraries in your custom connection manager? Perhaps you could try compiling your custom connection manager explicitly for x64 or x86 rather than “Any Cpu”.

      • Aaron says:

        That’s what I suspected too, and I have tried that. I tried all combinations again just to make sure I didn’t miss anything with no luck. When I compile to x64, I get the same messages. When I compile for x86 it still fails with the same errors but I don’t seem to get any messages written to the windows event viewer like I do with the MSIL or x64 versions.

        My project/solution includes Oracles latest “Managed” ODP.net library (https://www.nuget.org/packages/odp.net.managed/) which shows up in the GAC as MSIL.

        When compiling for “Any CPU” or “x64” I do get a compiler warning saying:

        “Warning 8 There was a mismatch between the processor architecture of the project being built “MSIL” and the processor architecture of the reference “Microsoft.SQLServer.DTSRuntimeWrap, Version=12.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=x86”, “x86″”

        When I compile for x86 I do not get this warning. From what little debugging I can do, the exception seems to be coming from the DTSRuntimWrap.

        Both development machine, and the server, are 64 bit machines. I do have x86 and AMD64 versions of the Microsoft.SqlServer.DTSRuntimeWrap.dll in the GAC on both my dev machine and the server. However, when adding the reference to the project, I can’t seem to find, or target the amd64 version of the dll.

      • KenR says:

        Aaron sorry for the delayed response. Two thoughts :
        1. What is happening in the constructor? Try commenting out everything in the constructor and see if the problem occurs.
        2. Who is the package running as? If you have a test instance you can reproduce this on maybe try running a sql server as your user account, or create a proxy credential and run as a sql agent job.

  6. Aaron says:

    Don’t worry about the delay. I’m happy you’re responding at all. This issue is really bugging me and I’m running out of things to try (I’m normally pretty good at figuring out these kind issues).

    The constructor is empty. The only reason it’s even defined is to help with debugging. When stepping through the code in the debugger, it exits the constructor but never steps into any other methods/properties. The exception seems to be getting thrown in the base, “ConnectionManagerBase”, code.

    All of our SSIS jobs run as a proxy account through the sql agent. I’ve also tried running it as “me”, without using the sql agent, and seem to have the same issue. I have also given proxy account full admin access to the server without any success.

    I’m pretty sure this has to be either a 64bit vs 32bit issue or a permissions issue, but I can’t figure out where.

    • KenR says:

      I’m also pretty sure about the 64bit/32bit stuff being the problem. Are you able to debug it using visual studio while it is running on the server?

      • Aaron says:

        Yes but I get VERY limited info. I added “System.Diagnostics.Debugger.Launch();”, to my empty constructor, which will trigger the debugger to launch. The only thing I can see is that it executes the constructor, then throws the exception. This is all the info I can get from the Visual Studio debugger.

        System.AccessViolationException was unhandled
        Message: An unhandled exception of type ‘System.AccessViolationException’ occurred in Microsoft.SqlServer.ManagedDTS.dll
        Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

        I was able to find, what appears to be a partial stack trace (which is posted in one my comments above), in the windows event log. Even that doesn’t really provide any useful information.

  7. sanat says:

    Hi,

    I have successfully built the RabbitMQ connection manager and RabbitMQ source and it is working fine.
    May i know when well be RabbitMQ Destination component will be ready, i am waiting for that to implement in my ssis package.
    I am new to .Net ,so dont know how to write custom ssis component

  8. Andrei says:

    Hi Ken.

    I just want to ask you for help. Maybe you know why I am getting this error.
    When I’ve been trying to add your custom connection manager to my Integration Services project by choosing “Connection Manager for RabbitMQ” in “Add SSIS connection manager window” in Visual Studio I’ve got an error:

    The new connection manager could not be created. (Microsoft Visual Studio)

    ===================================

    Object reference not set to an instance of an object. (Microsoft.DataTransformationServices.Design)

    ——————————
    Program Location:

    at Microsoft.DataTransformationServices.Design.DtsSCMConnectionService.CreateConnection(String connectionType, ConnectionManagerUIArgs connectionUIArg)

    Do you happen to know why could that be?

    • KenR says:

      Sorry for the late reply, I’ve recently become a father 🙂 I presume you’ve built the component yourself using visual studio? You could try my post on debugging SSIS components.

      • dave says:

        Yeah – i can get the connection manager to show by right clicking on connections pane and selecting new connection, but there is nothing on the toolbox for RabbitMQ source. I can confirm that the rabbitmq client dll is available in GAC too.

        FYI i am using SQL SSMS 2014, and Visual Studio 2015 so I changed the build event to do the following:

        Connection Manager

        “C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\gacutil.exe” -u $(TargetName)
        “C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\gacutil.exe” -iF $(TargetFileName)
        copy $(TargetFileName) “C:\Program Files (x86)\Microsoft SQL Server\130\DTS\Connections\SSISRabbitMQ.RabbitMQConnectionManager.dll” /y

        copy “$(TargetDir)RabbitMQ.Client.dll” “C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies” /y
        copy “$(TargetDir)RabbitMQ.Client.dll” “C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\PublicAssemblies” /y
        copy “$(TargetDir)RabbitMQ.Client.dll” “C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\PublicAssemblies” /y
        copy “$(TargetDir)RabbitMQ.Client.dll” “C:\Program Files (x86)\Microsoft SQL Server\130\DTS\Binn” /y

        RabbitMq

        “C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\gacutil.exe” -u $(TargetName)
        “C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\gacutil.exe” -iF $(TargetFileName)
        copy $(TargetFileName) “C:\Program Files (x86)\Microsoft SQL Server\130\DTS\PipelineComponents\SSISRabbitMQ.RabbitMQSource.dll” /y

        copy “$(TargetDir)RabbitMQ.Client.dll” “C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies” /y
        copy “$(TargetDir)RabbitMQ.Client.dll” “C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\PublicAssemblies” /y
        copy “$(TargetDir)RabbitMQ.Client.dll” “C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\PublicAssemblies” /y
        copy “$(TargetDir)RabbitMQ.Client.dll” “C:\Program Files (x86)\Microsoft SQL Server\130\DTS\Binn” /y

  9. soyungordoblog says:

    Hello Ken
    I am trying to follow your tutorial with a fork of the github project. However, I am having some issues when building the custom connection manager. I had to change the post build commands to the following:

    “C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\gacutil.exe” -u $(TargetName)
    “C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\gacutil.exe” -i $(TargetFileName)
    copy $(TargetFileName) “C:\Program Files\Microsoft SQL Server\120\DTS\Connections\$(TargetFileName)” /y
    copy “$(TargetDir)RabbitMQ.Client.dll” “C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\PublicAssemblies” /y
    copy “$(TargetDir)RabbitMQ.Client.dll” “C:\Program Files\Microsoft SQL Server\120\DTS\Binn” /y
    “C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\gacutil.exe” /if $(TargetName).dll

    After that however I do not see the RABBITMQ connection manager on the SSDT
    I have verified and the assembly is in the GAC correctly, what can it be?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s