Tuesday, April 27, 2010

A SharePoint Feature To Configurate Content Deployment Timout Setting

The default timeout setting in SharePoint 2007 content deployment is 10 minutes. For content deployment on a big site, this may not be long enough, and you may get a timeout exception during the content deployment. The bad news is that you can't change the content deployment timeout setting with stsadm.exe, and you must run custom code to talk with SharePoint API to update this setting. Stefan Gossner provides a console application for such task. But console application is so flexible to reality. Not many admins like the idea of running a console application to update a setting for SharePoint in production environment.

It would be good if we can make the configuration change by browser, idealy a page linked to content deployment section in central administration web site. In this practice I will wrap all that as a SharePoint Feature.

First we need to define the feature.xml:
<?xml version="1.0" encoding="utf-8"?>
<Feature Id="02ca3716-5938-4788-ad67-17e6039f93da"
Title="Content Deployment Timeout Configuration"
Description="Timeout setting for content deployment"
Version="1.0.0.0"
Hidden="FALSE"
Scope="Farm"
DefaultResourceFile="core"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
<ElementManifest Location="elements.xml"/>
</ElementManifests>
</Feature>
In order to add a link in Content Deployment section in SharePoint central admin, the Feature needs to include a custom action. The elements.xml is as following:
<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<CustomAction
Id="Content.Deployment"
GroupId="ContentDeployment"
Location="Microsoft.SharePoint.Administration.Operations"
Sequence="510"
Title="Content deployment timeout setting">
<UrlAction Url="/_admin/CDTimeoutSetting.aspx" />
</CustomAction>
</Elements>
The UrlAction is pointing to the /_admin/CDTimeoutSetting.aspx page which includes a simple UI for timeout update:
<%@ Page Language="C#" MasterPageFile="~/_admin/admin.master" %>

<%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral,PublicKeyToken=71e9bce111e9429c" %>
<%@ Assembly Name="Microsoft.SharePoint.ApplicationPages.Administration, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Assembly Name="Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>
<%@ Assembly Name="System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" %>

<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Import Namespace="System.Web.UI" %>
<%@ Import Namespace="Microsoft.SharePoint.Publishing.Administration" %>

<asp:Content ID="Content2" runat="server" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea">
Manage Content Deployment Remote Timeout Setting
</asp:Content>
<asp:Content ID="Content4" runat="server" ContentPlaceHolderID="PlaceHolderMain">
<div style="margin: 15" runat="server" id="divMain">
<div>
<p>
<asp:Label ID="lblInfo" runat="server"></asp:Label>
<asp:Label ID="lblCurrentTimeout" runat="server" Font-Bold="true"></asp:Label>
</p>
<br />
<p>
<asp:Label ID="Label2" runat="server">Set timeout in minutes</asp:Label>
<asp:TextBox ID="txtTimeout" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" Text="* Required" ErrorMessage="Required" ControlToValidate="txtTimeout" Display="Dynamic" ValidationGroup="update"></asp:RequiredFieldValidator>
<asp:RangeValidator ID="RangeValidator1" runat="server" ErrorMessage="Invalid (1-240)" ControlToValidate="txtTimeout" Display="Dynamic" Type="Integer" MinimumValue="1" MaximumValue="7200" ValidationGroup="update"></asp:RangeValidator>
<asp:Button ID="btnUpdate" runat="server" Text="Update" ValidationGroup="update" OnClick="btnUpdate_Click" />
</p>
</div>
</div>
</asp:Content>
<script runat="server">
ContentDeploymentConfiguration config = null;

void btnUpdate_Click(object sender, EventArgs e)
{
if (config == null)
{
config = ContentDeploymentConfiguration.GetInstance();
}
Microsoft.SharePoint.Administration.SPWebApplication wa = SPContext.Current.Site.WebApplication;
wa.FormDigestSettings.Enabled = false;
SPContext.Current.Web.AllowUnsafeUpdates = true;
config.RemoteTimeout = Convert.ToInt32(txtTimeout.Text) * 60;
config.Update();
SPContext.Current.Web.AllowUnsafeUpdates = false;
}

void Page_PreRender(object sender, System.EventArgs e)
{
if (SPContext.Current == null || SPContext.Current.Site == null || SPContext.Current.Web == null)
{
lblInfo.Text = "Invalid SPContext. Please sign in and try again.";
return;
}
if (config == null)
{
config = ContentDeploymentConfiguration.GetInstance();
}
lblCurrentTimeout.Text = string.Format("Current timeout setting is: {0} minutes", Convert.ToString(config.RemoteTimeout / 60));
}
</script>
The manifext.xml for packaking the Feature to a wsp solution package:
<?xml version="1.0"?>
<Solution SolutionId="04a13d4d-21e2-4e72-a65c-163b16e8bbc8" xmlns="http://schemas.microsoft.com/sharepoint/">
<FeatureManifests>
<FeatureManifest Location="ContentDeploymentTimeoutSetter\feature.xml" />
</FeatureManifests>
<TemplateFiles>
<TemplateFile Location="ADMIN\CDTimeoutSetting.aspx" />
</TemplateFiles>
</Solution>
The screen-shot of the central admin configuration page:


The screen-shot of timeout setting page: