Skip to content

Latest commit

 

History

History
184 lines (137 loc) · 9.14 KB

portalfx-cdn.md

File metadata and controls

184 lines (137 loc) · 9.14 KB

Using the CDN

Extension authors may choose to use a CDN to serve static images, scripts, and stylesheets. The Azure Portal SDK does not require the use of a CDN, or the use of a particular CDN. However, extensions served from Azure can take advantage of the built-in CDN capabilities in the SDK.

Creating the CDN account

Follow this guide to set up your CDN account:

http://www.windowsazure.com/en-us/documentation/articles/cdn-how-to-use/

Configuring your CDN service

After creating your CDN, there are a few options that need to be set.

  • Make sure HTTP and HTTPS are enabled by clicking the "Enable HTTPS" command.
  • Make sure query string status is enabled by clicking the "Enable Query String" command.

Configuring your extension

To take advantage of the CDN capabilities in the Portal SDK, there are a few pieces that must be configured.

Configuring the Prefix

After setting up your CDN, you will receive a url which can be used to access your content. It will be in the form:

//<MyCDNNamespace>.vo.msecnd.net/

This is the prefix for your CDN service. Your production service should be configured to use this prefix. In your local web.config, can set this with the following appSetting:

<add key="Microsoft.Portal.Extensions.SamplesExtension.ApplicationConfiguration.CdnPrefix" 
     value="//<MyCDNNamespace>.vo.msecnd.net/" />

Notice that neither http nor https are used in the url. This is important. It allows your page to request content based on the current protocol of the request. Oftentimes, this setting will be blank in web.config, and instead configured in a cscfg for a cloud service.

Reading the prefix from configuration

To read any FX configuration, you must have a class which inherits from ApplicationContext. This class needs to include a CdnPrefix property:

\SamplesExtension\Configuration\CustomApplicationContext.cs
[Export(typeof(ApplicationContext))]
internal class CustomApplicationContext : ApplicationContext
{
    private ApplicationConfiguration configuration;

    [ImportingConstructor]
    public CustomApplicationContext(ApplicationConfiguration configuration)
    {
        this.configuration = configuration;
    }

    public override bool IsDevelopmentMode
    {
        get
        {
            return this.configuration.IsDevelopmentMode;
        }
    }

    public override string CdnPrefix
    {
        get
        {
            return this.configuration.CdnPrefix;
        }
    }
}

This class will assign properties which are available in your web.config or *.cscfg. To read the values from those files, create a C# class which inherits from ConfigurationSettings and exports ApplicationConfiguration:

\SamplesExtension\Configuration\ApplicationConfiguration.cs
[Export(typeof(ApplicationConfiguration))]
public class ApplicationConfiguration : ConfigurationSettings
{
    /// <summary>
    /// Gets a value indicating whether development mode is enabled.
	/// Development mode turns minification off
    /// </summary>
    /// <remarks>
	/// Development mode turns minification off. 
	/// It also disables any caching that be happening.
	/// </remarks>
    [ConfigurationSetting]
    public bool IsDevelopmentMode
    {
        get;
        private set;
    }

    /// <summary>
    /// Gets a value indicating a custom location where browser should 
	/// find cache-able content (rather than from the application itself).
    /// </summary>
    [ConfigurationSetting]
    public string CdnPrefix
    {
        get;
        private set;
    }
}

IIS / ASP.NET Configuration

Files are pushed to the CDN using the following process:

To enable this workflow, the CDN must be able to make an HTTP request to your extension. This would normally not be an issue, but some CDNs will make an HTTP 1.0 request. HTTP 1.0 technically does not support gzip/deflated content, so IIS does not enable compression by default. To turn this on, the noCompressionForHttp10 setting in <httpCompression> must be set to false:

http://www.iis.net/configreference/system.webserver/httpcompression

The url used for the request is in the following form:

http://myextension.cloudapp.net/CDN/Content/jquery.js

The /CDN/ portion of this url is inserted after the host address, and before the rest of the route for requested content. The request handling code in the SDK automatically handles incoming requests of the form /CDN/Content/... and /Content/...

Invalidating content on the CDN

When you release to ensure that users are served the latest static content, as opposed to stale content, you need to configure versioning.

Configuring versioning of your Extensioon

Updating extensions

The portal shell relies on environment version for making runtime decisions, e.g.:

  • invalidating cached manifests
  • invalidating static content served indirectly via CDN or from directly from your extension

By default this value is populated based on the version attributes present in the extension assembly. First the runtime tries to find the AssemblyInformationalVersionAttribute attribute and get the value from there. If this attribute isn't defined in the assembly, the runtime searches for the AssemblyFileVersion attribute and gets the value from this attribute. You can check the version of your extensions by typing in window.fx.environment.version in the browser console from the extension frame.

You should ensure that while building your extension assembly, the version number is correctly stamped and updated on every build. The assembly version is added to your assembly by specifying the assembly level attribute as shown below.

[assembly: System.Reflection.AssemblyFileVersion("5.0.0.56")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("5.0.0.56 (COMPUTER.150701-1627)")]

You can also override this behavior by deriving from the ApplicationContext class and MEF-exporting the derived class as [Export(typeof(ApplicationContext))] and overriding the getter for the Version property on the class. If you do this, please ensure that the overridden getter returns a constant value for a specific build.

see AssemblyVersionAttribute see AssemblyInformationalVersionAttribute see (Azure internal teams only) OneBranch versioning

Once configured content will be served directly from your extension, or via CDN if configured, using a URL segment such as /Content/ e.g /Content/5.0.0.56/Scripts, Content/5.0.0.56/Images.

Implications of changing the version

You should not introduce breaking changes in your server code (e.g. incompatibility between client and server code). Instead leave a compatibile version of the old code around on the server for a few days, monitor its usage to ensure that customers/browsers are no longer accessing it (i.e all users have switched to the newer version of your code - likely by refreshing the portal), and then delete the code. This can easily be accomplished by making new controllers/methods instead of making breaking changes to existing ones. If you do end up in a situation where you make a breaking change, users will likely see a broken experience until they reload the portal. You will need to contact the portal team in order to find a way to get past this issue.

FAQ

  • I am not seeing paths w/ versioning during debug.
    • Ensure IsDevelomentMode in your *.config is set to false