This is documentation for Apprenda 7 and 8.
Documentation for newer version is available at https://new.docs.apprenda.com.

Custom Bootstrapper Creation Tutorial

This tutorial will walk through the process of creating a simple sample Custom Bootstrapper that can be used to modify the title of the Apprenda Platform error page.

Prerequisites

In order to complete this tutorial, you will need a running instance of the Apprenda Platform; the Apprenda SDK matching the version of the Apprenda Platform you are running must be installed on the machine you are using.

Creating an Apprenda Custom Bootstrapper

Apprenda Custom Bootstrapper Structure

At a minimum, a Custom Bootstrapper is a ZIP archive that contains the following: 

  • a DLL created by the developer containing a Boostrapper implementation

A Bootstrapper implementation is simply a class that inherits from the BootstrapperBase class that is defined in Apprenda.API.Extension.dll, which is included in the Apprenda SDK and should be referenced appropriately.  

Creating the Bootstrapper

First, let's examine the BootstrapperBase class and its supporting objects:

BootstrapperBase

 public abstract class BootstrapperBase
    {
        /// <summary>
        /// The method called to cause bootstrapping of an instance to occur.
        /// </summary>
        /// <param name="bootstrappingRequest">A <see cref="BootstrappingRequest"/> with the relevant parameters available for use when bootstrapping the instance.</param>
        /// <returns>
        /// A <see cref="BootstrappingResult"/> with the results of the bootstrapping process. If null, bootstrapping will be assumed to have failed and a generic
        /// error message will be displayed to the component's developer.
        /// </returns>
        public abstract BootstrappingResult Bootstrap(BootstrappingRequest bootstrappingRequest);
    }

BootstrapperResult

    /// <summary>
    /// Represents the results of bootstrapping a component.
    /// </summary>
    [Serializable]
    public class BootstrappingResult : MarshalByRefObject
    {
        /// <summary>
        /// The command line arguments that should be used when starting the instance.
        /// </summary>
        public string CommandLineArguments { get; set; }

        /// <summary>
        /// Indicates that bootstrapping succeeded or failed.
        /// </summary>
        public bool Succeeded { get; set; }

        /// <summary>
        /// Errors that should be displayed to the developer of the component due to failed bootstrapping.
        /// </summary>
        public IEnumerable<string> Errors { get; set; }
    }

​BootstrapperRequest

    /// <summary>
    /// Represents a request to bootstrap an instance of a component.
    /// </summary>
    [Serializable]
    public class BootstrappingRequest : MarshalByRefObject
    {
        /// <summary>
        /// Creates a new bootstrapping request.
        /// </summary>
        /// <param name="componentPath">The path where the component's files can be found and modified.</param>
        /// <param name="componentType">The type of component that is being bootstrapped.</param>
        /// <param name="componentId">The unique id of the component that is being bootstrapped.</param>
        /// <param name="instanceId">The unique id of the instance that is being bootstrapped.</param>
        /// <param name="componentName">The name of the component that is being bootstrapped.</param>
        /// <param name="applicationAlias">The alias for the application to which the component being bootstrapped belongs.</param>
        /// <param name="versionAlias">The alias for the version to which the component being bootstrapped belongs.</param>
        /// <param name="properties">The custom properties defined for the component and its parent application.</param>
        public BootstrappingRequest(string componentPath, ComponentType componentType, Guid componentId, Guid instanceId, string componentName, string applicationAlias, string versionAlias, IEnumerable<CustomProperty> properties)
        /// <summary>
        /// The unique Apprenda alias assigned to the development team responsible for the component.
        /// </summary>
        public virtual string DevelopmentTeamAlias { get { return GetPropertyValue("DevelopmentTeamAlias", CustomPropertySourceType.Application); } }

        /// <summary>
        /// Indicates if Apprenda authentication is enabled for the component's application.
        /// </summary>
        public virtual bool IsAuthenticationEnabled { get { return bool.Parse(GetPropertyValue("Authentication", CustomPropertySourceType.Application)); } }

        /// <summary>
        /// Indicates if Apprenda authorization is enabled for the component's application.
        /// </summary>
        public virtual bool IsAuthorizationEnabled { get { return bool.Parse(GetPropertyValue("Authorization", CustomPropertySourceType.Application)); } }

        /// <summary>
        /// Indicates if Apprenda multi-tenancy is enabled for the component's application.
        /// </summary>
        public virtual bool IsMultitenancyEnabled { get { return bool.Parse(GetPropertyValue("Multi-tenancy", CustomPropertySourceType.Application)); } }

        /// <summary>
        /// Indicates if Apprenda billing is enabled for the component's application.
        /// </summary>
        public virtual bool IsBillingEnabled { get { return bool.Parse(GetPropertyValue("Billing", CustomPropertySourceType.Application)); } }

        /// <summary>
        /// The current lifecycle stage for the component's application.
        /// </summary>
        public virtual Stage Stage { get { return (Stage)Enum.Parse(typeof(Stage), GetPropertyValue("DeploymentStage", CustomPropertySourceType.Component), true); } }
	}

Please note that a full list of properties that can be leveraged for the BootstrappingRequest class can be found in our API Docs, as can a list of valid enumerations for Stage and ComponentType.

To create a new Custom Bootstrapper, open Visual Studio and create a new C# class library project.  Add a reference to Apprenda.API.Extension, and then create a new class and inherit from Apprenda.API.Extension.Bootstrapping.BootstrapperBase.  

The example below creates a Custom Bootstrapper that will replace the term "Apprenda" with "Your Company" (see line 30) in the Errors page hosted as part of the Platform's Common UI Resources application (identified by the application alias "resources"; see line 9):

ErrorPageBootstrapper.cs

namespace ErrorPageBootstrapper
{
    public class ErrorPageBootstrapper : BootstrapperBase
    {
        public override BootstrappingResult Bootstrap(BootstrappingRequest bootstrappingRequest)
        {
            try
            {
                if (bootstrappingRequest.ApplicationAlias.Equals("resources"))
                {
                    var modifyErrorPageResult = ModifyErrorPage(bootstrappingRequest);

                    return !modifyErrorPageResult.Succeeded ? modifyErrorPageResult : BootstrappingResult.Success();
                }

                return BootstrappingResult.Success();
            }
            catch (Exception e)
            {
                return BootstrappingResult.Failure(new[] { e.Message });
            }
        }

        private static BootstrappingResult ModifyErrorPage(BootstrappingRequest bootstrappingRequest)
        {
            var sitePath = Path.Combine(bootstrappingRequest.ComponentPath, @"root\Pages\Errors\Default.htm");

            try
            {
                File.WriteAllText(sitePath, Regex.Replace(File.ReadAllText(sitePath), "Apprenda", "Your Company"));
            }
            catch (Exception e)
            {
                return BootstrappingResult.Failure(new string[] { e.Message });
            }

            return BootstrappingResult.Success();
        }
    }
}

Packaging a Custom Bootstrapper and Creating a Bootstrap Policy

Once your Custom Bootstrapper is written and built, it needs to be packaged.  Packaging is quite simple; you just need to put  the assembly that contains your Custom Bootstrapper, the Apprenda.API.Extension assembly, and any other files your specific implementation requires into a ZIP file.  It is now ready to be uploaded to the Apprenda Platform as part of an Application Bootstrap Policy created in the SOC.

When built, packaged, and uploaded to the Platform under an appropriate Bootstrap Policy, the above sample Custom Bootstrapper will take effect on any future deployments of the Common UI Resources .NET UI component. The effects can be viewed in the page title at https://{your root url here}/resources/Pages/Errors/Default.htm.