0

When using NServiceBus in a C# project, a file called instance-mapping.xml is used to specify which machine each queue is hosted on. Like this:

<?xml version="1.0" encoding="utf-8" ?>
<endpoints>
    <endpoint name="QueueName1">
        <instance machine="localhost"/>
    </endpoint>

    <endpoint name="QueueName2">
        <instance machine="localhost"/>
    </endpoint>
</endpoints>

In Octopus, how can I do variable substitution on a file like this? So that "machine"-attribute inside QueueName1 is changed to "server1" and the one inside QueueName2 is changed to "server2". Like this:

<?xml version="1.0" encoding="utf-8" ?>
<endpoints>
    <endpoint name="QueueName1">
        <instance machine="server1"/>
    </endpoint>

    <endpoint name="QueueName2">
        <instance machine="server2"/>
    </endpoint>
</endpoints>

Octopus has built-in features for doing simple key/value substitutions on eg. appsettings and connectionstrings. But the above file is a little more complex as the enclosing element identifies the key.

Carsten Gehling
  • 1,218
  • 1
  • 13
  • 31

1 Answers1

1

I might be oversimplifying your question, but to end up with the desired instance-mapping.xml I would use a configuration transform. An example instance-mappings.transform.xml file would be:

<?xml version="1.0" encoding="utf-8" ?>
<endpoints xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <endpoint name="QueueName1" xdt:Locator="Match(name)">
        <instance machine="server1" xdt:Transform="SetAttributes" />
    </endpoint>

    <endpoint name="QueueName2" xdt:Locator="Match(name)">
        <instance machine="server2" xdt:Transform="SetAttributes" />
    </endpoint>
</endpoints>

And then in Octopus add a configuration transform instance-mapping.transform.xml => instance-mapping.xml.

If you want the machine values to be configured as Octopus variables, you could add a variable substitution. Specify the variables: machine[QueueName1] with value machine1 and machine[QueueName2] with value machine2 and modify the transform file:

<?xml version="1.0" encoding="utf-8" ?>
<endpoints xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <endpoint name="QueueName1" xdt:Locator="Match(name)">
        <instance machine="#{machine[QueueName1]}" xdt:Transform="SetAttributes" />
    </endpoint>

    <endpoint name="QueueName2" xdt:Locator="Match(name)">
        <instance machine="#{machine[QueueName2]}" xdt:Transform="SetAttributes" />
    </endpoint>
</endpoints>

If there is friction adding local endpoints while your developing that don't make sense in other environments, you can use Octopus as the source of truth for your endpoints. To achieve that, add variables for each endpoint to your Octopus project:

Example endpoint variable configuration

You can then set your endpoints in the transform file based on the values in Octopus:

<?xml version="1.0" encoding="utf-8" ?>
<endpoints xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform" xdt:Transform="Replace">
#{each e in endpoint}
    <endpoint name="#{e.Name}">
        <instance machine="#{e.Machine}"/>
    </endpoint>
#{/each}
</endpoints>

Given the example variables and transform file, using variable substitution and config transformations in Octopus you will end up with your desired instance-mapping.xml:

<?xml version="1.0" encoding="utf-8"?>
<endpoints>
    <endpoint name="QueueName1">
        <instance machine="Machine1"/>
    </endpoint>
    <endpoint name="QueueName2">
        <instance machine="Machine2"/>
    </endpoint>
</endpoints>

I hope this helps.

Shane Gill
  • 71
  • 1