вторник, 1 декабря 2015 г.

Бронирование переговорных комнат — интеграция SharePoint 2010 с Exchange 2010

Несколько недель назад от наших заказчиков мы получили задачу на создание сервиса бронирования переговорных комнат. Компания заказчика довольна крупная и весьма продвинутая в плане ИТ. У заказчика много филиалов по всей России и в каждом по 5-6 переговорных комнат, сотрудники часто летают проводить совещания из одного
филиала в другой, а найти свободную аудиторию «на месте» — это реальная проблема. Поэтому сотруднику было бы неплохо прямо со своего рабочего места в Москве «застолбить» переговорку, например, в Туле и со спокойной совестью лететь в командировку. Опытом создания подобного сервиса мы хотим поделится с хабросообществом.


Анализ

Мы знали, что в компании заказчика есть внутренний портал, сделанный на Microsoft SharePoint 2010, которым ежедневно пользуются около 1500 сотрудников. Плюс в компании настроен Exchange. 

Как известно в Exchange уже есть фича бронирования ресурсов в компании. Все это дело реализовано с помощью room mailbox’ов. По сути, каждой переговорной комнате присвоен свой почтовый адрес, и сотрудник должен планировать встречу с данной комнатой. Другие пользователи с помощью почтового клиента могут подключаться к календарям и смотреть на какое число, и время назначена встреча. К тому же в Outlook 2010 есть функционал Room Finder. 

Более подробно можно прочитать тут о mailbox в Exchange http://technet.microsoft.com/en-us/library/bb124952(v=exchg.141).aspx 

А тут — о Room Finder’e http://support.microsoft.com/kb/2673231

Вроде все выглядит круто и удобно. Однако есть несколько недостатков: во-первых, сотруднику нужен Outlook. Во-вторых, описание комнаты очень скудно, нельзя добавить описание ресурсов (доска, система конференц-связи и т.д.) в наглядном виде.

Соответственно возникла мысль: как бы нам все наглядное представление вынести в SharePoint и при этом не потерять функционал Exchange? При этом хотелось писать поменьше кода. Но как показала практика – без этого не обошлось :)

В общем, поехали!

SharePoint

Для создания сервиса мы сделали три списка: Подразделения, Комнаты совещаний, Бронирование комнат совещаний. 

Подразделения представляют собой филиалы в городах.

Комнаты совещаний – это список для хранения комнат и их характеристик, таких как: 
  • название;
  • подразделение;
  • вместимость;
  • наличие в комнате проектора, маркерной доски конференцсвязи и т.д.
  • почтовый адрес, используемый для интеграции с MS Exchange.

И наконец, список броней:
  • комната;
  • дата встречи;
  • время начала;
  • время конца;
  • автор брони.

Итак, списки у нас есть, но кто-то же должен эти списки заполнять, поэтому мы разделили пользователей по ролям:
  • Пользователи могут планировать свои встречи и совещания, бронировать комнаты или делать специализированный поиск по параметрам.
  • Администратор переговорных комнат подразделения может переносить \ отменять существующие брони в рамках своего подразделения.
  • Администратор создает и редактирует переговорные комнаты, а также справочник с их характеристиками – количество мест, проектор, доска и т.д. Имеет возможность переключаться между подразделениями и исполнять роль Администратора переговорных комнат.

UI

Т.к. у заказчика дизайн уже был натянут на портал, нашим дизайнерам нужно было поработать совсем чуть-чуть. С чем они отлично справилась:

1. Главная страница пользователя:



2. По отдельной ссылке можно перейти на список комнат. В данном списке выводится основная информация. Подробная информация о комнате отображается по клику на название комнаты.



3. По ссылке «Поиск аудиторий» отображается календарь на две недели. В каждой ячейке отображено время, кем комната забронирована и на какое время. 



4. Отдельным кликом на «плюсик» можно будет забронировать переговорную комнату.



Реализация

Чтобы сделать такую красоту нам потребовалось написать WCF-сервис, который возвращает json и при этом работает в контексте SharePoint’a. Данная проблема решается правильным web.config’ом и наличием SVC в папке ISAPI. О том, как правильно настроить web.config для отправки json’a, написано очень много. Например, тут:

http://www.codeproject.com/Articles/105273/Create-RESTful-WCF-Service-API-Step-By-Step-Guide

Далее мы сделали несколько ASPX-страниц, добавили их в модуль и реализовали всю логику работы с WCF-сервисом через javascript с использованием knockout-фрэймворка.

Основные проблемы у нас возникли с Exchange. Практически весь нужный функционал реализован через вызовы методов EWS Managed API. Однако нам нужно было автоматически создавать mailbox’ы при создании элемента в списке комнат. 

На просторах интернета было найдено, что mailbox можно создавать лишь через powershell, и вызвать команду из C#-кода в принципе не проблема.

На список комнат мы написали event receiver и попытались вызвать powershell команду на удаленном сервере через использование Runspace и WSManConnectionInfo. Однако, во-первых, это не безопасно, а во-вторых, сделать это у нас так и не получилось из-за проблем отказа доступа при соединении. 

В результате решили написать еще один WCF-сервис и развернуть его на сервере с Exchange. По сути, у этого сервиса есть только один метод:

public void CreateRoom(ExchangeRoom Room)
        {
            RunspaceConfiguration runspaceConfig = RunspaceConfiguration.Create();
            PSSnapInException snapEx = null;
            PSSnapInInfo psinfo = runspaceConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out snapEx);
            using (Runspace runSpace = RunspaceFactory.CreateRunspace(runspaceConfig))
            {
                runSpace.Open();

                if (!(MailBoxAlreadyExist(Room.Email, runSpace)))
                {
                    Command createMailbox = new Command("New-Mailbox");
                    createMailbox.Parameters.Add("UserPrincipalName", Room.Email);
                    createMailbox.Parameters.Add("Name", Room.Name);
                    createMailbox.Parameters.Add("Room");

                    using (Pipeline pipeLine = runSpace.CreatePipeline())
                    {
                        pipeLine.Commands.Add(createMailbox);
                        pipeLine.Invoke();
                    }                
                }
                else
                {
                    throw new Exception("Комната с таким адресом уже создана");
                }
            }
        }


Как мы писали выше, вся логика работы у нас реализована через WCF-сервис, поэтому логично было дополнить наш сервис методами для бронирования комнаты в Exchange. Для этого мы вызывали метод сервиса для создания нашей брони в Exchange. Всю необходимую информацию помещали в Microsoft.Exchange.Data.Appointment, а далее с помощью API создавалось собрание(meeting) в календаре Exchange. 

public static void CreateReservation(Reservation reservation)
        {        
            InitService();

            var appointment = new Appointment(service);
            appointment.Subject = "Meeting";
            appointment.Start = new DateTime(reservation.Date.Year, reservation.Date.Month, reservation.Date.Day, reservation.FromTime, 0, 0);
            appointment.End = new DateTime(reservation.Date.Year, reservation.Date.Month, reservation.Date.Day, reservation.ToTime, 0, 0);            
            
            string roomMailboxAddress = string.Format("room_{0}@{1}",reservation.RoomId, SharePointConstantString.MailDomain);
            appointment.Location = reservation.RoomName;            
            appointment.Resources.Add(roomMailboxAddress);
            appointment.RequiredAttendees.Add(reservation.User.Email);            

            appointment.Save(SendInvitationsMode.SendToAllAndSaveCopy);
        }


Проблему «обратной» синхронизации (т.е. когда сотрудник в своем календаре через Outlook забронировал комнату) было решено решить через задание (timer job). Данный job собирал всю информацию с Exchange и создавал недостающие брони, а отмененные удалял. 

Итого

Нам удалось создать такую архитектуру, которая позволяет получить масштабируемое и гибкое решение, построенное на стеке Microsoft технологий и использующее все преимущества комплексного решения. Система настраивается и сопровождается стандартными инструментами платформ. 

Таким образом, сегодня
  • руководство компании получает единые инструменты совместной работы, повышающие эффективность работы большого количества сотрудников;
  • сотрудники компании проще, быстрее и без нервов планируют свою работу и ключевые встречи и совещания;
  • ИТ-персонал получил в распоряжение гибкое, масштабируемое решение, которое сопровождается стандартными средствами и максимально использует функциональность “из коробки”. А значит, при переходе на новые версии SharePoint и Exchange проблем особых не возникнет.


Источник: http://habrahabr.ru/company/eastbanctech/blog/195110/

Комментариев нет:

Отправить комментарий