Поиск на сайте: Расширенный поиск


Новые программы oszone.net Читать ленту новостей RSS
CheckBootSpeed - это диагностический пакет на основе скриптов PowerShell, создающий отчет о скорости загрузки Windows 7 ...
Вы когда-нибудь хотели создать установочный диск Windows, который бы автоматически установил систему, не задавая вопросо...
Если после установки Windows XP у вас перестала загружаться Windows Vista или Windows 7, вам необходимо восстановить заг...
Программа подготовки документов и ведения учетных и отчетных данных по командировкам. Используются формы, утвержденные п...
Red Button – это мощная утилита для оптимизации и очистки всех актуальных клиентских версий операционной системы Windows...
OSzone.net Microsoft Разработка приложений Облако/Azure Передача контента из SharePoint в Windows Azure Storage RSS

Передача контента из SharePoint в Windows Azure Storage

Текущий рейтинг: 0 (проголосовало 0)
 Посетителей: 833 | Просмотров: 1092 (сегодня 0)  Шрифт: - +

На этот раз у меня появился соавтор, так как коллега Шэд Филлипс (Shad Phillips) помогал мне в недавнем проекте, где я работал с заказчиком по проверке концепции, в которой SharePoint 2010 использовался в качестве платформы приложений. Попутно, один из сотрудников заказчика спросил меня, не мог бы я придумать приемлемый способ принимать одобренный контент от SharePoint и публиковать его, делая его доступным людям вне корпоративной сети.

Текущая инфраструктура у заказчика не поддерживала внешний контент (скачиваемые документы и видеоролики). Много работая с Windows Azure, я сразу же подумал, что было бы совсем не сложно реализовать передачу контента в Windows Azure Storage как часть рабочего процесса, а затем — в зависимости от потребностей — делать его общедоступным или предоставлять договорной доступ к нему.

С учетом этого я поговорил со своим коллегой, Шэдом, который ранее решал подобную задачу, где он реализовал метод-пример для архивации документов, передавая их из библиотеки SharePoint в Windows Azure Storage. Хотя цели того решения отличались от моих, механика одна и та же. Поэтому сегодня Шэд и я пошагово рассмотрим реализацию-пример, которая обеспечивает продвижение контента из SharePoint в Windows Azure Storage, и расскажем немного об управлении доступом к файлам на договорной основе.

Сценарий и подготовка

Мы разработали собственную функцию, которая позволяет пользователю избирательно перемещать документы из SharePoint в Windows Azure Storage. По какой-то необъяснимой причине пользователям обычно не нравится, когда их документы перемещаются, а новых ссылок на них не дают, поэтому мы оставляли в библиотеке документов ссылку на местоположение документа в облаке, которая вела себя так, будто документ вовсе и не был перемещен в облако.

Необходимое ПО:

  • Visual Studio 2010;
  • Microsoft SharePoint 2010:
  • Windows Azure SDK;
  • Windows Azure Development Storage Service.

Конфигурация сайта SharePoint 2010 и библиотеки документов

В этом сценарии мы создали сайт SharePoint с применением шаблона Team Site. В библиотеке Shared Documents мы сформировали столбец, который позволяет помечать элемент как архивируемый и отправляемый в Windows Azure. Это делается через команду Library Settings на ленте. В Library Settings мы создали столбец со свойствами, показанными на рис. 1.

*

Рис. 1 Настройки столбца в шаблоне Team Site

В Advanced Settings мы также выбрали Yes для параметра Allow the management of content types.

Мы использовали это как часть Content Type, который мы назвали «Link to a Document». Затем мы создали экземпляры этого Content Type, позволяющие ссылаться на архивный документ (рис. 2).

*

Рис. 2 Наш новый тип контента «Link to a Document»

Добавив столбец и тип контента в библиотеку документов, мы загрузили пример документа Word с названием Services SOW.docx.

Файл web.config для SharePoint 2010

Чтобы подключиться к облаку, нужно получить настройки, необходимые для соединения с Windows Azure. В данном случае мы использовали хранилище для разработки и добавили ключи в элемент <appSettings> в web.config, как показано на рис. 3.

*

Рис. 3 Добавление ключей в web.config

Проект SharePoint

К счастью, SharePoint 2010 полностью взаимодействует с Visual Studio 2010, и с его помощью очень удобно создавать, отлаживать и публиковать новые функции (feature). Мы создали SharePoint Feature (о функциях SharePoint см. по ссылке msdn.microsoft.com/library/bb861828(office.12)), которая добавляет собственное действие в раскрывающиеся меню действий для элементов в библиотеке документов. Пользователь будет выбирать это действие для архивации.

Мы начали с создания решения MSSAzureArchive, используя шаблон Empty SharePoint Project (рис. 4).

*

Рис. 4 Выбор проекта в Visual Studio 2010

Далее мы указали сайт и уровень защиты для отладки. Мы предпочли вариант «Deploy as a farm solution», так как коду понадобится делать внешние вызовы, а решение в изолированной программной среде («песочнице») этого не позволило бы. В проект нужно добавить ссылки на Microsoft.Windows.Azure.StorageClient и System.Web. Затем мы добавили в проект элемент Empty Element, используя шаблон EmptyElement, и присвоили ему имя AzureStorageElement. Элемент <CustomAction/> был добавлен для включения нового действия в контекстное меню элемента в библиотеке документов (рис. 5).

*

Рис. 5 Добавление AzureStorageElement через Add New Item

После этого в проект была автоматически добавлена новая функция с именем Feature1, которую мы переименовали в MSSAzureArchive. Мы заменили содержимое файла Elements.xml для AzureStorageElement следующим:

<?xml version="1.0" encoding="utf-8"?>
 <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   <CustomAction
     Id="UserInterfaceCustomActions.ECBItemToolbar"
     RegistrationType="List"
     RegistrationId="101"
     Location="EditControlBlock"
     Sequence="106"
     Title="Azure Storage">
     <UrlAction Url="~sitecollection/
       _layouts/MSSAzureArchive/
       AzureStorage.aspx?ItemUrl={ItemUrl}" />
   </CustomAction>
 </Elements>

Для неопытных разработчиков в SharePoint на рис. 6 дано краткое описание некоторых свойств <CustomAction/> (подробнее об элементе <CustomAction/> и его свойствах см. по ссылке msdn.microsoft.com/library/ms460194).

Рис. 6 Свойства элемента <CustomAction/>

СвойствоОписание
IdУникальный идентификатор
LocationУказывает, где в SharePoint UI должен появиться элемент. В данном случае нужно местоположение — меню элемента (EditControlBlock), а не лента, например
SequenceУказывает приоритет действий

Обратите внимание на свойство Url элемента UrlAction; это навигационное действие, вызывающее обработку команды на архивацию документа. На основе этой конфигурации SharePoint знает, где ему нужно разместить функцию в UI и что делать, когда кто-то ее выберет. SharePoint переадресует пользователя на созданную нами страницу, которая обработает архивацию выбранного документа. Эта страница позволит пользователю указывать или создавать целевой контейнер-хранилище для данного элемента, поэтому нам нужно было добавить в проект элемент Application Page. Вновь используя шаблоны SharePoint 2010, мы выбрали шаблон Application Page и назвали его AzureStorage.aspx (рис. 7).

*

Рис. 7 Добавление новой страницы в SharePoint 2010

Так как в этом примере мы не собирались поражать кого-либо дизайном своего UI, мы добавили лишь те элементы управления, без которых нельзя выполнить работу. В элемент <asp:Content> разметки страницы был включен код, показанный на рис. 8.

Рис. 8 Добавление минимально необходимых элементов управления

Document to Archive:
<asp:Label ID="fileName" runat="server" ></asp:Label>   <br/>
Choose Azure Container:
<asp:DropDownList ID="azureContainers" runat="server"
  Visible="true"></asp:DropDownList>
<asp:TextBox id="newContainerName" runat="server" Visible="false"></asp:TextBox>
<asp:Button ID="saveContainer" runat="server" Text="Save Container"
  OnClick="SaveContainer_Click" Visible="false"></asp:Button>
<br />
<asp:Button ID="createContainer" runat="server" Text="Create New Container"
  OnClick="CreateContainer_Click" />
<br/>
<asp:Button ID="archiveFile" runat="server" Text="Archive File"
  OnClick="Archive_Click" />
<br/>
<asp:Label ID="errMessage" runat="server" Text=""></asp:Label>

Далее мы отредактировали отделенный код и подключили UI-элементы к коду, обеспечивающему взаимодействие с Windows Azure Storage. Инициализация клиента облачного хранилища осуществляется при событии загрузки для страницы; при этом мы получаем доступные контейнеры, используя предыдущие настройки web.config ( рис. 9).

Рис. 9 Инициализация клиента облачного хранилища

protected void Page_Load(object sender, EventArgs e)
{

  this.InitializeCloudStorage();
  if (!IsPostBack)
  {
    this.GetContainers();
  }
}

private void GetContainers()
{
  IEnumerable<CloudBlobContainer> blobContainers =
    cloudBlobClient.ListContainers();

  this.azureContainers.DataSource = blobContainers;
  azureContainers.DataTextField = "Name";
  this.azureContainers.DataBind();
  if (azureContainers.Items.Count < 1)
  {
    ListItem defaultContainer = new ListItem(defaultContainerName);
    defaultContainer.Selected = true;
    azureContainers.Items.Add(defaultContainer);
  }
}

Нас интересовала в основном функциональность архивации — на ней мы и сосредоточимся здесь. Остальной код можно скачать по ссылке code.msdn.microsoft.com/mag201012Cloudy. Мы добавили обработчик щелчков для кнопки archiveFile и подключили функцию Archive_Click. На основе элемента UrlAction мы можем получать путь к нужному элементу. Функция обработки щелчка выбирает этот элемент из SharePoint с применением его объектной модели, проверяет, не был ли он уже заархивирован, и, если нет, загружает его в выбранный контейнер ( рис. 10).

Рис. 10 Код для функции обработки щелчка элемента из SharePoint

protected void Archive_Click(object o, EventArgs e)
{
  try
  {
    webSite = SPContext.Current.Web;
    filePath = webSite.Url.ToString() +
    Request.QueryString["ItemUrl"].ToString();
    fileToArchive = webSite.GetFile(filePath);
    string sArchived = fileToArchive.Item["IsArchived"].ToString();

    bool isArchived = Convert.ToBoolean(sArchived);

    if (isArchived)
    {
      errMessage.Text = "This document has already been archived!";
    }
    else
    {
      string newGuid = Guid.NewGuid().ToString();
      string uniqueBlobName = string.Format(newGuid + "_" +
        fileToArchive.Name.ToString());

      blobContainer = cloudBlobClient.GetContainerReference(
        this.azureContainers.SelectedValue);
      blobContainer.CreateIfNotExist();
      cloudBlob = blobContainer.GetBlockBlobReference(uniqueBlobName);
      cloudBlob.UploadByteArray(fileToArchive.OpenBinary());

После загрузки элемента в хранилище вместо исходного документа создается новый архивный элемент типа «Link to a Document», а исходный документ удаляется. Если вместо архивации требуется публикация, то исходный элемент не удаляется, а помечается как опубликованный со ссылкой на опубликованную версию. Исходный элемент используется для получения целевой библиотеки документов и пути к оригинальному документу. Новый элемент помечается как заархивированный добавлением свойства IsArchived и присваиванием ему значения true. Но, прежде чем создавать новый элемент и присваивать ему значения, мы сначала выполняем кое-какую работу, необходимую для получения некоторых из этих значений:

SPDocumentLibrary docLib =
  fileToArchive.DocumentLibrary;

Hashtable docProperties = new Hashtable();
docProperties["IsArchived"] = true;
string docLibRelPath =
  docLib.RootFolder.ServerRelativeUrl;
string docLibPath = string.Empty;
webSiteCollection = SPContext.Current.Site;
docLibPath =
  webSiteCollection.MakeFullUrl(docLibRelPath);

string azureURL = cloudBlob.Uri.ToString();

Функция BuildLinkToItem создает экземпляр типа контента «Link to a Document», используя путь у элементу в Windows Azure Storage. Этот экземпляр будет добавлен в библиотеку как ссылка; с ее помощью в SharePoint UI можно будет получить соответствующий элемент из Windows Azure Storage:

string azureStub = this.BuildLinkToItem(azureURL).ToString();

  SPFile newFile = webSite.Files.Add(documentPath,
    UTF8Encoding.UTF8.GetBytes(azureStub), docProperties, true);

  SPListItem item = newFile.Item;
  item["Content Type"] = "Link to a Document";
  SPFieldUrlValue itemUrl = new SPFieldUrlValue();
  itemUrl.Description = fileToArchive.Name;
  itemUrl.Url = azureURL;
  item["URL"] = itemUrl;
  item["IsArchived"] = true;
  item.Update();
  fileToArchive.Delete();

Написав код для сохранения документа, его перемещения и замены ссылкой на Windows Azure Storage, можно было заняться компиляцией и развертыванием решения. Дважды щелкните файл Package.package, чтобы открыть дизайнер упаковки, и выберите вкладку Advanced в нижней части экрана. Именно здесь мы добавляли сборки пакета, необходимые для включения Microsoft.WindowsAzure.StorageClient.dll. Чтобы не усложнять пример, мы задали в Deployment Target значение GlobalAssemblyCache. Чтобы запустить хранилищ для разработок (Development Storage), мы перешли в Server Explorer, щелкнули узел Windows Azure Storage, а затем раскрыли узел «(Development)».

Теперь нажимаем клавишу F5 для компиляции, развертываем и инициируем сеанс браузера для запуска отладки нашей функции. После этого переходим обратно в библиотеку Shared Documents и открываем раскрывающееся меню, подключенное к ранее загруженному документу. Выбираем новый элемент, Azure Storage, и это приводит к переходу на собственную страницу приложения, где можно выбрать нужный контейнер (рис. 11).

*

Рис. 11 Выбор элемента Windows Azure Storage

На этой странице мы могли бы создать новый контейнер, но вместо этого использовали существующий контейнер документов и щелкнули кнопку Archive File для запуска соответствующего кода (рис. 12).

*

Рис. 12 Выбор контейнера

Отправив файл в Windows Azure Storage, возвращаемся в библиотеку Shared Documents. Вместо документа Services SOW.docx в ней появляется элемент «Link to a Document» (рис. 13).

*

Рис. 13 Ссылка на документ в библиотеке документов SharePoint

Посмотрев на свойства этого элемента, вы увидели бы поля, относящиеся к типу контента, и, в частности, URL, по которому документ теперь размещается в Windows Azure Storage (рис. 14).

*

Рис. 14 Свойства ссылки

Мы могли открывать документ напрямую из Windows Azure Storage, щелкая Link to a Document. Мы могли использовать свойство URL для прямого доступа к нему или через некий другой код либо UI. Например, если бы нам нужно было по-прежнему индексировать такие элементы с помощью SharePoint Index Service, то можно было бы создать собственный IFilter, которому известно, как обрабатывать тип контента «Link to a Document» для корректной индексации его содержимого.

После реализации архивирования контента из библиотеки документов SharePoint в контейнер Windows Azure Storage неаутентифицированные пользователи получали доступ только к общедоступным архивным документам.

Управление доступом при публикации

Как упоминалось, я обратился к Шэду по поводу его кода архивации документов из-за того, что он использовал Windows Azure Storage в качестве места размещения общедоступного контента, который прошел проверку и одобрен к публикации. В моем случае управление доступом не требовалось, так как документы были доступны всем. Однако через пару минут кто-нибудь обязательно спросит: «А как быть, если нам нужно публиковать какие-то материалы и открывать к ним доступ лишь определенному кругу лиц, например поставщикам, заказчикам или сотрудникам?». Зачастую задача наподобие этой решается в компаниях включением соответствующих людей в некий корпоративный домен или объединением их в федерацию для идентификации по имени и паролю. Здесь это было лишним — заказчик на самом деле не хотел устанавливать дополнительный прикладной уровень или внутренний интерфейс для управления доступом; разработка такого интерфейса уменьшила бы ему ценность решения из-за увеличения расходов на реализацию.

Одно из решений — использовать SharedAccessPolicy применительно к большим двоичным объектам (blobs). Для контейнера и таких объектов в контейнере можно установить PublicAccess в Off и написать немного кода. Ниже показано, как можно задать PublicAccess равным Off, но разрешить SharedAccess:

BlobContainerPermissions permissions = new BlobContainerPermissions();
  permissions.PublicAccess = BlobContainerPublicAccessType.Off;

  SharedAccessPolicy accesspolicy = new SharedAccessPolicy();
  accesspolicy.Permissions = SharedAccessPermissions.Read;
  permissions.SharedAccessPolicies.Add("Read", accesspolicy);

  BlobContainer.SetPermissions(permissions);

Если мы запросим ресурс напрямую в контейнере хранилища, то получим ошибку с кодом 404 (Page Not Found). При загрузке больших двоичных объектов мы делаем для них похожую работу, но создаем SharedAccessPolicy, который разрешает чтение, задает срок действия этого разрешения и запрашивает SharedAccessSignature:

SharedAccessPolicy policy = new SharedAccessPolicy();
policy.Permissions = SharedAccessPermissions.Read;
policy.SharedAccessExpiryTime = DateTime.Now.AddDays(5);
string SharedAccessSignature = destBlob.GetSharedAccessSignature(policy));

Вызов GetSharedAccessSignature возвращает примерно такую строку:

?se=2010-08-26T18%3A22%3A07Z&sr=b&sp=r&sig=WdUHKvQYnbOcMwUdFavn4QS0lvhAnqBAnVnC6x0zPj8%3D

Если я присоединяю эту строку запроса к концу URI двоичного объекта, то должен впоследствии принимать ее обратно при условии, что срок действия не истек. Подробнее о подписи и политиках совместного доступа см. по ссылке msdn.microsoft.com/library/ee395415.

Чтобы решить эту задачу, я генерировал бы подписи и предоставлял бы подписанные URI с длительным сроком действия, что упростило бы их создание в момент загрузки, а затем хранил бы список ссылок на опубликованные документы. Для разработки более безопасного варианта и при необходимости обеспечивать доступ единственному пользователю на короткое время понадобилось бы создание соответствующей части UI. Через этот UI пользователь мог бы запрашивать доступ к одному или более ресурсам и получать подписанные URI, разрешающие доступ на короткое время.

Универсальное решение — и для облака, и для локального размещения

Шэд и я использовали здесь одну универсальную реализацию для решения двух разных задач. Такое решение особенно удобно, так как нам требовалась предоставляемая облаком конкретная часть функциональности (масштабируемость, надежность и расширяемое хранилище), чтобы избежать лишних усилий с нашей стороны и свести затраты к минимуму. Основная идея в том, что концепции, стоящие за нашим решением, не требуют его размещения исключительно в облаке или локально на предприятии. Эти варианты можно легко смешивать. Со временем станет все легче и легче смешивать корпоративные сети и облачные. Полагаю, что в будущем между ними не будет особой разницы. Итак, если вы ищете решения для своего ПО или бизнес-систем, то, наверное, сделаете здесь паузу и задумаетесь: «Что в облачных вычислениях может мне помочь?».

Автор: Джозеф Фулц и Шед Филлипс  •  Иcточник: MSDN Magazine  •  Опубликована: 21.07.2011
Нашли ошибку в тексте? Сообщите о ней автору: выделите мышкой и нажмите CTRL + ENTER


Оценить статью:
Вверх
Комментарии посетителей
Комментарии отключены. С вопросами по статьям обращайтесь в форум.