Getting Started

Composable code promotion is run through a C# console application that manages resource syncing between instances of Composable. The main requirement is a machine with Composable and Visual Studio installed which can access both the source and target instances of Composable but which is not itself hosting either of those instances. Composable credentials for each instance are also required.

Create a Console App

To begin setting up code promotion for a Composable project, open Visual Studio and create a new project, choosing "Console App (.NET Framework)" as the project template. This should give you a simple console app which will become the base for code promotion.

Reference the Composable API

Next add a reference to CompAnaltyics.IServices.dll. To add a reference in Visual Studio, right click on the References header in the Solution Explorer and select "Add Reference...". Then click the "Browse..." and navigate to the desired dll. CompAnalytics.IServices.dll can usually be found in C:\Program Files\CompAnalytics\WebApp\bin. If Composable is installed in another location look for \WebApp\bin underneath the top level Composable directory.

Check App.config

If your App.config file doesn't have a <webHttpBinding> section already, add one like this (inside <configuration> but outside any other sections):

  <system.serviceModel>
      <bindings>
        <webHttpBinding>
          <binding maxReceivedMessageSize="2147483647" receiveTimeout="00:30:00" sendTimeout="00:30:00">
            <readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647"/>
          </binding>
        </webHttpBinding>
      </bindings>
  </system.serviceModel>

Once these have been added, add the lines

using System.Net;
using CompAnalytics.IServices.Deploy;

to the top of Program.cs. Now you're ready to begin writing the code that specifies what resources to deploy and how.

Folder Syncer

Here's a simplified version of the code you need to sync resources, which you would place in Program.Main:

var syncSettings = new SyncSettings();
var syncer = new FolderSyncer(syncSettings);
syncer.Sync();

The method FolderSyncer.Sync will perform all of the syncing operations, retrieving resources from the source instance, applying appropriate transformations, and saving them to the target instance. Progress messages will print in the console while this runs.

In this oversimplified form the deployment will fail, however, because some settings in SyncSettings are required.

Required Settings

A working settings object will look something like this, where some settings reference variables defined earlier in the code and discussed in more detail below.

var syncSettings = new SyncSettings 
{
    SourceConnectionSettings = devConnectionSettings,
    TargetConnectionSettings = prodConnectionSettings,
    Folders = new List<FolderMapping>
    {
        new FolderMapping("/SourceFolder", "/TargetFolder")
    },
    ExtensionAssemblies = new List<string>
    {
        "CompAnalytics.Execution.Modules"
    }
}

Other options also exist that can be configured via SyncSettings but without these 4 properly configured the console app will fail.

Connection Settings

The first required settings are for connecting to the source and destination Composable instances. These connections will look something like this:

var devConnectionSettings = new ConnectionSettings
{
    Uri = new Uri("https://<composable-instance-url>/CompAnalytics/"),
    AuthMode = AuthMode.Form,
    FormCredential = new NetworkCredential("<user-name>", "<password>")
};

The Uri should be the root of the Composable instance. Create a ConnectionSettings instance for each Composable instance you need to connect to. If the code promotion is all within one server and just separated by folders then only one ConnectionSettings object is required.

ConnectionSettings offers three authentication modes: - AuthMode.Form: Forms authentication, with a username and password specific to Composable. FormCredential is required. - AuthMode.Windows: Windows authentication, if you log in to Composable with your Windows account. WindowsCredential is optional; if it is not included the Windows account running the console app will be used (via CredentialCache.DefaultNetworkCredentials). - AuthMode.Hybrid: Windows and forms authentication, in which a windows account is used to access the server but actions in Composable use a separate forms account. FormCredential and WindowsCredential are required.

Note that when passing a WindowsCredential it may be necessary to also specify the domain in the NetworkCredential constructor as new NetworkCredential("<user-name>", "<password>", "<domain>").

Folders

These define what resources will be synced and to where. SyncSettings takes a list of FolderMapping objects, which each defines a folder to include in the sync. In this simple example:

Folders = new List<FolderMapping>
{
    new FolderMapping("/SourceFolder", "/TargetFolder")
},

all the QueryViews and DataFlows in the folder /SourceFolder on the source instance will be saved to the folder /TargetFolder on the destination instance.

If you want the folder structure to be the same on the target as it is on the source, use the shortcut method SyncSettings.Create to generate the list by passing all the folder paths:

Folders = SyncSettings.Create(
    "/Folder1",
    "/Nested/Folder2"
)

Extension Assemblies

SyncSettings.ExtensionAssemblies is a list of namespaces containing the modules used in any DataFlows that will be synced. For example, if you use a SQL Query module, you would add "CompAnalytics.Execution.Modules" to your ExtensionAssemblies list.

All of these assemblies will be loaded during the sync to facilitate the deserialization of DataFlow contracts. Thus you must also add a reference in your project to every dll included in ExtensionAssemblies. These dlls can usually be found alongside CompAnalytics.IServices.dll in \WebApp\bin or in \WebApp\bin\plugins, but if the Composable instances you're syncing have custom extensions that introduce new modules you may need to acquire those dlls separately to reference them.

Run the Console App

Once you have all these pieces together, your Program.cs file should look something like this:

using System.Net;
using CompAnalytics.IServices.Deploy;

namespace DemoDeployment
{
    class Program
    {
        static void Main(string[] args)
        {
            var devConnectionSettings = new ConnectionSettings
            {
                Uri = new Uri("https://<composable-dev-instance-url>/CompAnalytics/"),
                AuthMode = AuthMode.Form,
                FormCredential = new NetworkCredential("<user-name>", "<password>")
            };
            var prodConnectionSettings = new ConnectionSettings
            {
                Uri = new Uri("https://<composable-prod-instance-url>/CompAnalytics/"),
                AuthMode = AuthMode.Form,
                FormCredential = new NetworkCredential("<user-name>", "<password>")
            };
            var syncSettings = new SyncSettings 
            {
                SourceConnectionSettings = devConnectionSettings,
                TargetConnectionSettings = prodConnectionSettings,
                Folders = new List<FolderMapping>
                {
                    new FolderMapping("/SourceFolder", "/TargetFolder")
                },
                ExtensionAssemblies = new List<string>
                {
                    "CompAnalytics.Execution.Modules"
                }
            };

            var syncer = new FolderSyncer(syncSettings);
            syncer.Sync();
            Console.WriteLine("Deployment complete");
            Console.ReadLine();
        }
    }
}

The final two lines are just to provide confirmation that everything has finished and provide an opportunity to review all the progress messages that printed before closing the window (if run in a context where the window persists only with the application, as is the case when running in Visual Studio).

Additionally you should have references in your project to CompAnalytics.IServices and CompAnalytics.Execution.Modules. Once those conditions are met, you can build and run the app and it should sync all QueryViews and DataFlows from /SourceFolder on the dev instance to /TargetFolder on the prod instance.