Microsoft SharePoint 2010 получает заслуженные похвалы как продуманная платформа разработки. Она дополнена новыми сервисами, API, поддержкой программной работы с данными, а также поддержкой UI через инфраструктуру диалогов и Silverlight.Все это открывает массу возможностей для разработчиков для создания приложений на этой развивающейся платформе.
Однако с ростом интереса к вычислениям в облаке мне все чаще задают вопросы о том, как интегрировать собственные приложения SharePoint с технологиями на основе облака. Многие из упомянутых ранее средств можно так или иначе интегрировать с Windows Azure. Более того, вы можете интегрировать SharePoint с облаком с помощью других технологий, таких как OData, REST, API социальных сетей Web 2.0 для приложений наподобие Twitter или Facebook, и, конечно, на основе архитектуры, ориентированной на сервисы (SOA), с использованием SOAP- или WCF-сервисов (Windows Communication Foundation).
Теперь, когда вы знаете, что в SharePoint заложены широкие возможности интеграции с облаком, я проанализирую в этой статье некоторые конкретные точки интеграции между SharePoint и Windows Azure. Попутно мы детально рассмотрим создание вашего первого интеграционного решения.
Базовые сведения о платформе
Платформа Windows Azure состоит из трех частей. Во-первых, сама Windows Azure поддерживает средства работы с данными и управления. Во-вторых, SQL Azure обеспечивает работу с базами данных в облаке с поддержкой транзакций и высокой доступности. В-третьих, Windows Azure AppFabric предоставляет шину сервисов для вариантов применения с более «продвинутыми», прямыми вызовами сервисов.
Используя Windows Azure, вы можете поддерживать целый ряд видов интеграции. Например, вы можете создать и развернуть WCF-сервис в облаке, а затем интегрировать этот сервис в SharePoint. Или использовать данные из Windows Azure, моделируя эти данные в SharePoint. Более того, с помощью Windows Azure AppFabric Service Bus становятся возможными более сложные варианты применения сервиса, где SharePoint Online соединяется с SharePoint на предприятии.
При любой интеграции вы должны понимать имеющиеся возможности. Отправной точкой послужит табл. 1, в которой перечисляются разные способы интеграции SharePoint с Windows Azure. Эта таблица специфична для SharePoint 2010, а некоторые варианты требуют больше усилий в кодировании, чем другие.
Табл. 1. Наиболее популярные точки интеграции
Интеграция с Azure | Осуществляется через |
Клиентская модель объектов SharePoint | Взаимодействие с данными Windows Azure в списке |
Business Connectivity Services (BCS) | Данные модели из Windows Azure или формирование внешнего списка в SQL Azure |
Silverlight | Создание UI для сервисов или данных Windows Azure |
Решения, выполняемые в изолированной среде/SharePoint Online | Приложение Silverlight, использующее Windows Azure и развертываемое на наборе сайтов (site collection) |
Собственный клиент Office | Прямое использование данных из Windows Azure или BCS-списка, предоставляющего данные |
Стандартные/визуальные веб-фрагменты | Использование сервисов и данные из Windows Azure |
Open XML | Управление данными Windows Azure в документе |
REST | Применение REST для взаимодействия с данными Windows Azure, чтобы обеспечить интеграцию с SharePoint |
Office Server Services | Комбинированием с Open XML для автоматической генерации документов (например, в формате PDF) на сервере |
Рабочий процесс/приемники событий | Состояние или события, которые связываются с сервисами, рабочими процессами или данными Windows Azure |
LINQ | Использование для запроса объектов данных Windows Azure |
Поиск | Федеративный поиск, охватывающий данные Windows Azure |
Какой бы вид интеграции вы ни выбрали, важно отметить, что в этой статье рассматривается такая интеграция с Windows Azure, при которой SharePoint является потребителем и не размещается в какой-либо хост-среде. Иначе говоря, SharePoint — не сервис в Windows Azure, а приложение, использующее данные или сервисы Windows Azure. Windows Azure предоставляет приложения или ресурсы, которые будут использоваться частями SharePoint, например веб-фрагментом или приложением Silverlight. В этой статье я дам пример того, как интегрировать приложение Silverlight внутри SharePoint, взаимодействующее с собственным WCF-сервисом, развернутым в Windows Azure.
Если вы начинаете с нуля, вам нужно будет подготовить свою среду разработки. Как минимум, в ней должны быть:
- Visual Studio 2010;
- Windows Azure SDK и инструментарий;
- SharePoint Server 2010;
- Office 2010 Professional Plus;
- SQL Server 2008 R2;
- исполняющая среда Silverlight, SDK и инструментарий.
Для работы с Windows Azure вам понадобится создать учетную запись разработчика, чтобы вы смогли потом создать портал разработки для управления своими облачными приложениями, данными и сервисами. Все необходимые инструменты Windows Azure для создания этих приложений и сервисов вы найдете по ссылке microsoft.com/windowsazure/getstarted. Заметьте, что вы можете установить перечисленные ранее средства на существующий компьютер, используемый для разработок, или скачать по ссылке tinyurl.com/33bgpy6 заранее сконфигурированную виртуальную машину, в которой есть все, кроме инструментов Windows Azure. (Вы также можете дополнительно установить Silverlight Web Part — расширения для Visual Studio, доступное по ссылке code.msdn.microsoft.com/vsixforsp.)
Подготовив среду разработки, вы можете приступить к созданию своего первого интеграционного решения. В этой статье мы проработаем три этапа.
- Создадим и развернем собственный WCF-сервис в Windows Azure.
- Создадим веб-фрагмент (Web Part) на основе Silverlight, способный использовать ваш сервис Windows Azure.
- Развернем и используем этот веб-фрагмент на вашем сайте SharePoint.
Давайте детально рассмотрим каждый из этих этапов.
Создание WCF-сервиса
Допустим, вы хотите развернуть сервис для всей вашей коммерческой организации, но вам нужно разместить этот сервис в облаке. Сервис будет получать информацию о предложениях конкурентов и поддерживать два метода: для получения информации по конкретному конкуренту и возврата списка всех конкурентов. Вы создадите оба метода, но реализуете только возврат информации обо всех конкурентах. Вы сможете расширить этот код после того, как прочтете данную статью, и самостоятельно запрашивать информацию по отдельным конкурентам.
Чтобы создать WCF-сервис, откройте Visual Studio 2010 и создайте новый проект. В мастере New Project выберите шаблон Cloud. Присвойте проекту какое-нибудь имя (я назвал его Competitors) и щелкните OK. Выберите проект WCF Service Web Role и щелкните OK.
Visual Studio создаст новое решение с набором ресурсов, в которые входят файлы конфигурации ролей Windows Azure, а также код и контракт вашего WCF-сервиса. В этом примере используется объект в памяти, поэтому щелкните правой кнопкой мыши проект WCF, выберите Add, а затем Class. Назовите этот класс, скажем, Competitor, и добавьте в файл этого класса следующий код:
namespace WCFServiceWebRole1 {
public class Competitor {
public string svcCompeteID { get; set; }
public string svcCompeteName { get; set; }
public string svcCompeteFY09 { get; set; }
public string svcCompeteFY10 { get; set; }
}
}
Этот код включает четыре свойства (идентификатор конкурента, имя и продажи за финансовые 2009 и 2010 годы).
Поскольку в качестве презентационного уровня вы будете также использовать Silverlight, вам понадобится добавить к проекту файл политики клиентского доступа для поддержки вызовов из Silverlight сервиса Windows Azure через домены. Для этого щелкните правой кнопкой мыши проект WCF, выберите Add, а затем New Item. В диалоге New Item выберите категорию Data и укажите XML. Присвойте новому файлу имя clientaccesspolicy.xml и щелкните Add.Замените XML-код в новом файле вот этим:
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="SOAPAction">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
Далее создайте контракт WCF-сервиса. В этом примере мы не будем ничего усложнять и просто включим два контракта операций. Первая операция позволит получать информацию об одном конкуренте (метод getACompetitor), а вторая — обо всех (метод getAllCompetitors). Заметьте, что вам придется передавать идентификатор (custID), если вы хотите получить запись по определенному конкуренту. На рис. 2 даны определения этих контрактов.
Рис. 2. Контракт сервиса
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WCFServiceWebRole1 {
[ServiceContract]
public interface IService1 {
[OperationContract]
string[] getACompetitor(string custID);
[OperationContract]
List<Competitor> getAllCompetitors();
}
}
Закончив с определениями контрактов, можно добавить код, реализующий их. Код сервиса, соответствующий этому контракту сервиса, показан на рис. 3. Данный код включает методы для получения одной записи конкурента (getACompetitor), для извлечения информации обо всех конкурентах (getAllCompetitors) и генерации информации о конкурентах (generateCompeteData). Этот код довольно прост; он использует структуры данных в памяти вроде наборов-списков и массивов наряду с LINQ для создания и возврата данных вызвавшему приложению. Здесь вызвавшим приложением является программа Silverlight, которая будет развернута в SharePoint.
Рис. 3. Код сервиса
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WCFServiceWebRole1 {
public class Service1 : IService1 {
List<Competitor> myCompetitors = new List<Competitor>();
public string[] getACompetitor(string custID) {
generateCompeteData();
string[] returnCompete = new string[4];
var returnListOfData = (
from compete in myCompetitors
where compete.svcCompeteID == custID
select compete).ToArray();
foreach (var competeRecord in returnListOfData) {
returnCompete[0] = competeRecord.svcCompeteID;
returnCompete[1] = competeRecord.svcCompeteName;
returnCompete[2] = competeRecord.svcCompeteFY09;
returnCompete[3] = competeRecord.svcCompeteFY10;
};
return returnCompete;
}
public List<Competitor> getAllCompetitors() {
generateCompeteData();
List<Competitor> returnlistOfCompetitors =
new List<Competitor>();
var returnListOfData = (
from customer in myCompetitors
select customer).ToArray();
foreach (var compete in returnListOfData) {
Competitor tempCompeteRecord = new Competitor();
tempCompeteRecord.svcCompeteID = compete.svcCompeteID;
tempCompeteRecord.svcCompeteName = compete.svcCompeteName;
tempCompeteRecord.svcCompeteFY09 = compete.svcCompeteFY09;
tempCompeteRecord.svcCompeteFY10 = compete.svcCompeteFY10;
returnlistOfCompetitors.Add(tempCompeteRecord);
};
return returnlistOfCompetitors;
}
private void generateCompeteData() {
Competitor compete1 = new Competitor();
compete1.svcCompeteID = "BR-CAN-8909";
compete1.svcCompeteName = "Bauer - Canada";
compete1.svcCompeteFY09 = "$45,093,028.00";
compete1.svcCompeteFY10 = "$50,493,820.00";
myCompetitors.Add(compete1);
Competitor compete2 = new Competitor();
compete2.svcCompeteID = "NK-USA-8665";
compete2.svcCompeteName = "Nike - USA";
compete2.svcCompeteFY09 = "$50,492,331.00";
compete2.svcCompeteFY10 = "$52,019,828.00";
myCompetitors.Add(compete2);
Competitor compete3 = new Competitor();
compete3.svcCompeteID = "GF-EU-9912";
compete3.svcCompeteName = "Graf - Europe";
compete3.svcCompeteFY09 = "$24,403,920.00";
compete3.svcCompeteFY10 = "$24,001,926.00";
myCompetitors.Add(compete3);
Competitor compete4 = new Competitor();
compete4.svcCompeteID = "CCM-USA-8843";
compete4.svcCompeteName = "CCM Hockey";
compete4.svcCompeteFY09 = "$12,209,105.00";
compete4.svcCompeteFY10 = "$10,092,813.00";
myCompetitors.Add(compete4);
}
}
}
К этому моменту вы уже создали WCF-сервис и почти готовы приступить к той части интеграции, которая относится к SharePoint. Но сначала нужно развернуть сервис в Windows Azure.
А для этого вы должны подготовить учетную запись разработчика в Windows Azure. Если вы сделали это, просто щелкните правой кнопкой мыши проект Windows Azure и выберите Publish.
Публикация вашего сервиса приводит к появлению диалогового окна, где вы может ввести свои удостоверения. Как видно на рис. 4, у вас есть выбор: создать только пакет сервиса (Visual Studio создает два основных файла, которые нужно добавить в локальную папку на портале разработчика в Windows Azure) или автоматически развернуть сервис на основе предварительно сконфигурированной информации. В этом примере щелкните Create Service Package Only, а затем OK.
Рис. 4. Варианты публикации сервиса
Будут созданы два файла:Competitors и ServiceConfiguration. Competitors — это файл пакета сервиса (в основном архив ресурса), а ServiceConfiguration — конфигурационный XML-файл.
Теперь вы можете перейти на портал разработчика в Windows Azure и добавить эти файлы к своему сервису. Для этого перейдите к сервису и щелкните Deploy (или, если вы уже развернули сервис, а теперь хотите обновить его, щелкните Upgrade, как показано на рис. 5). Затем можно перейти к этим двум файлам и щелкнуть OK. Подождите несколько минут, пока загрузятся файлы вашего сервиса.
Рис. 5. Развертывание сервисов в Windows Azure вручную
Увидев сообщение Ready, щелкните ссылку, которая показывается на той же веб-странице, для проверки конечной точки сервиса. Заметьте, что скорее всего вам придется добавить имя сервиса в конец URL сервиса:
http://serviceendpoint.azure.com/Service1.svc.
С этого момента вы можете мысленно отложить Windows Azure в сторону и заняться SharePoint.
Создание веб-фрагмента на основе Silverlight
Создать веб-фрагмент Silverlight для SharePoint можно несколькими способами. Один из них — просто создать приложение Silverlight в Visual Studio, развернуть его XAP-файл в SharePoint (например, загрузив его в библиотеку документов) и использовать встроенный веб-фрагмент Silverlight в SharePoint 2010 для загрузки своего приложения Silverlight. Это самый простой способ развертывания приложения Silverlight в SharePoint, и он требует меньше кодирования.
Второй, чуть более интересный способ — использовать шаблон проекта Silverlight и SharePoint Web Part (code.msdn.microsoft.com/vsixforsp). Это приводит к автоматическому обертыванию приложения Silverlight в веб-фрагмент, что означает следующее:вы просто создаете приложение Silverlight и развертываете его SharePoint как веб-фрагмент. При этом вы получаете немного больший контроль над своим кодом плюс развертываете в SharePoint реальный веб-фрагмент.
Чтобы задействовать этот шаблон, перейдите на сайт Codeplex, щелкните ссылку Silverlight and SharePoint VSIX, скачайте архив и извлеките из него файлы. После этого просто установите файл .vsix, дважды щелкнув его, а потом перезапустив Visual Studio 2010.
После установки шаблона Silverlight Web Part вернитесь в свое решение Visual Studio, выберите File | Add | New Project и укажите Add to Solution в поле Solution. Перейдите в папку SharePoint 2010 и выберите шаблон проекта Silverlight Web Part. Присвойте имя своему веб-фрагменту (я назвал его CompetitorSPWebPart) и щелкните OK.
В этот момент появится запрос URL для сайта SharePoint. Введите URL своего сайта, а затем выберите Deploy as Farm Solution. Далее будет предложено указать ряд параметров, в том числе имя проекта Silverlight, версию, место развертывания XAP-файла, название веб-фрагмента и его описание (рис. 5). Закончив с этой частью мастера, щелкните Finish. (Заметьте, что с этим шаблоном проектов можно использовать Silverlight 3 или 4, и Microsoft в настоящее время занимается обновлением этого шаблона для его повторной публикации на Codeplex.)
Рис. 6. Конфигурирование веб-фрагмента Silverlight
Теперь у вас есть веб-фрагмент SharePoint, обертывающий приложение Silverlight, и вы можете использовать приложение Silverlight для создания UI и функциональности веб-фрагмента.
Для начала в проекте Silverlight добавьте ссылку на сервис Windows Azure, щелкнув правой кнопкой мыши References и выбрав Add Service Reference. Присвойте имя пространству имен своего сервиса (в данном случае — GetCompeteAzureService) и щелкните OK. Здесь все делается так же, как и при использовании ссылки на любой другой сервис в приложении с тем исключением, что в данном случае конечная точка указывает на сервис Windows Azure.
В этот момент вы можете писать код применительно к сервису Windows Azure. Как было упомянуто, вы будете использовать метод getAllCompetitors в приложении SharePoint.
Вам понадобится UI для приложения. Я создал простой UI, который визуализирует данные, возвращаемые в результате вызова сервиса Windows Azure. Основной элемент управления — ListBox с несколькими изображения, добавленными для придания «изюминки». Детали см. в исходном коде, который можно скачать для этой статьи.
Далее добавляем собственный класс Competitor в приложение Silverlight. В Competitor есть четыре свойства, которые соответствуют данным по конкурентам, определенным в коде сервиса на рис. 3:
namespace CompetitorDisplayApp {
public class Competitor {
public string competeID { get; set; }
public string competeName { get; set; }
public string competeFY09 { get; set; }
public string competeFY10 { get; set; }
}
}
В отделенный XAML-код теперь можно добавить код, реализующий метод getAllCustomers. На рис. 7 видно, что я использую набор-список (list collection) с именем myCompetitors для хранения данных, возвращаемых из вызова сервиса Windows Azure. Здесь нет ничего заумного; код использует объект Competitor, помогающий заполнить мой набор-список myCompetitors, который потом связывается с ListBox (competeList).
Рис. 7. Собственный объект Competitor
using CompetitorDisplayApp.GetCompeteAzureService;
namespace CompetitorDisplayApp {
public partial class MainPage : UserControl {
public string SiteUrl { get; set; }
List<Competitor> myCompetitors = new List<Competitor>();
public MainPage() {
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e) {
LoadAzureData();
}
private void LoadAzureData() {
GetCompeteAzureService.Service1Client azureSvcProxy =
new Service1Client();
azureSvcProxy.getAllCompetitorsAsync();
azureSvcProxy.getAllCompetitorsCompleted +=
new EventHandler<getAllCompetitorsCompletedEventArgs>(
azureSvcProxy_getAllCompetitorsCompleted);
}
void azureSvcProxy_getAllCompetitorsCompleted(
object sender, getAllCompetitorsCompletedEventArgs e) {
var competeData = e.Result;
foreach (var item in competeData) {
Competitor tempRecord = new Competitor();
tempRecord.competeID = item.svcCompeteID;
tempRecord.competeName = item.svcCompeteName;
tempRecord.competeFY09 = item.svcCompeteFY09;
tempRecord.competeFY10 = item.svcCompeteFY10;
myCompetitors.Add(tempRecord);
}
competeList.ItemsSource = myCompetitors;
}
}
}
На этом кодирование вручную закончено. Однако стоит взглянуть на код, создаваемый шаблоном Silverlight Web Part по умолчанию, чтобы понять, почему он может оказаться полезнее, чем исходный веб-фрагмент Silverlight, поставляемый с SharePoint.
На рис. 8 показан исходный код веб-фрагмента, генерируемый, когда Visual Studio создает проект Silverlight Web Part. Вы можете увидеть код оболочки, где создается объект SilverlightPluginGenerator настраиваются свойства для вашего веб-фрагмента. Это свойства, управляемые в период разработки (например, избавляющие вас от необходимости открывать веб-фрагмент и редактировать высоту и ширину через панель Tools в SharePoint). Более того, вы может избежать копирования и вставки при условии, что этот веб-фрагмент развертывается в галерею веб-фрагментов — со всей инфраструктурой, требуемой для визуализации приложения Silverlight.
Рис. 8. Код веб-фрагмента по умолчанию
[ToolboxItemAttribute(false)]
public class SilverlightWebPart : WebPart {
private SilverlightPluginGenerator _silverlightPluginGenerator = null;
public SilverlightWebPart() {
this._silverlightPluginGenerator =
new SilverlightPluginGenerator {
Source = new Uri(
"/XAPS/Silverlight/CompetitorDisplayApp/CompetitorDisplayApp.xap",
UriKind.Relative),
Width = new Unit(400, UnitType.Pixel),
Height = new Unit(300, UnitType.Pixel),
BackGround = Color.White,
Version = SilverlightVersion.v3,
AutoUpgrade = true,
OnError = "onSilverlightError",
};
}
protected override void CreateChildControls() {
base.CreateChildControls();
this.Controls.Add(new LiteralControl(
@"<script type=""text/javascript"">" +
Resources.onSilverlightErrorHandler +
"</script>"));
this._silverlightPluginGenerator.InitParams.Add(new InitParam(
"SiteUrl", SPContext.Current.Site.Url));
this.Controls.Add(new LiteralControl(
this._silverlightPluginGenerator.ToString()));
}
protected override void RenderContents(HtmlTextWriter writer) {
base.RenderContents(writer);
}
}
Наконец, свойства веб-фрагмента были заданы, когда вы использовали мастер начальной настройки. Например, если вы откроете файл .webpart, то увидите имя и описание веб-фрагмента (которые здесь можно изменить, если вам это нужно):
<?xml version="1.0" encoding="utf-8"?>
<webParts>
<webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
<metadata>
<type name="CompetitorSPWebPart.SilverlightWebPart.SilverlightWebPart, $SharePoint.Project.AssemblyFullName$" />
<importErrorMessage>$Resources:core,ImportErrorMessage;</importErrorMessage>
</metadata>
<data>
<properties>
<property name="Title" type="string">Compete Information</property>
<property name="Description"
type="string">This Web Part provides compete information.</property>
</properties>
</data>
</webPart>
</webParts>
Закончив веб-фрагмент Silverlight, вы готовы к его развертыванию в SharePoint.
Развертывание веб-фрагмента
Для развертывания щелкните проект веб-фрагмента правой кнопкой мыши (в моем примере — CompetitorSPWebPart) и выберите Deploy. После развертывания веб-фрагмента приложение Silverlight развертывается в библиотеку документов XAPS, и в веб-фрагменте автоматически генерируется ссылка на этот XAP-файл. (Если вы выбрали использование приложения Silverlight вместо шаблона Silverlight Web Part, то просто загрузите XAP-файл в библиотеку документов XAPS, а затем воспользуйтесь встроенным в SharePoint веб-фрагментом Silverlight.)
Теперь откройте свой сайт SharePoint и перейдите к новой странице веб-фрагмента (или создайте ее). (Заметьте, что вы можете создать новую страницу веб-фрагмента, выбрав Site Actions | View All Site Content | Create | Web Part Page.) Выберите Site Actions | Edit Page | Add a Web Part. Перейдите в категорию Custom, укажите веб-фрагмент (который в данном примере называется Compete Information) и щелкните Add.После этого нажмите Stop Editing. У вас должно получиться нечто похожее на то, что показано на рис. 9.
Рис. 9. Законченный веб-фрагмент Silverlight, способный вызывать сервис в Windows Azure
Заключение
Интеграция SharePoint и Windows Azure — новая возможность, открывающая широкие перспективы. В этом примере я показал, как создать собственный сервис Windows Azure, а затем использовать его из собственного веб-фрагмента на основе Silverlight. Даже в таком простом примере виден потенциал для гораздо более изощренных решений как в сервисах Windows Azure, так и веб-фрагментах, которые ими пользуются.
Дополнительные примеры и руководства см. в моем блоге blogs.msdn.com/b/steve_fox. Следите за другим кодом и документацией по интеграции SharePoint и Windows Azure.