Введение в SQL Server Analysis Services для разработчика. Доступ по SOAP

Содержание предыдущей серии

Можно не пользоваться SSMS, как это делалось в постах MDX и XMLA или XMLA DDL, а написать свое собственное кастомное приложение по отправке SOAP-запросов. Способов для этого бездна. Чтобы не терять лес за деревьями, я не буду пользоваться SoapHttpClientProtocol, а просто по рабоче-крестьянски зашлю на OLAP-сервер XMLA-запрос (см. Скрипт 1 из поста MDX и XMLA), который фактически представляет собой готовый SOAP. Чтобы OLAP-сервер принимал запросы по HTTP, требуется IIS, на котором нужно создать виртуальную директорию и сказать, что все, что туда валится, обрабатывает соответствующий ISAPI-фильтр. Мы разбирали этот процесс в посте Доступ по HTTP. Сейчас воспользуемся полученными результатами. Создадим HTTP POST-запрос к http://192.168.0.29/msolap/msmdpump.dll (это тот самый ISAPI). В запрос положим строку xmla, которая в точности равна SOAP-запросу из Скрипта 1 из упомянутого поста. Получим отклик HttpWebResponse. Превратим стрим с отклика в строку и увидим, что это в точности тот XML, который мы видели в SSMS в панели результатов.

using System; 
using System.Net; 
using System.Text; 
using System.IO; 
using System.Diagnostics; 

class Program 
{ 
    static void Main(string[] args) 
    { 
        string xmla = @"<soap:Envelope xmlns:soap='https://schemas.xmlsoap.org/soap/envelope/'> 
                          <soap:Body> 
                            <Execute xmlns='urn:schemas-microsoft-com:xml-analysis'> 
                              <Command> 
                                <Statement>SELECT Measures.MEMBERS ON COLUMNS FROM [Adventure Works]</Statement> 
                              </Command> 
                              <Properties> 
                                <PropertyList> 
                                  <DataSourceInfo/> 
                                  <Catalog>Adventure Works DW 2008R2</Catalog> 
                                  <Format>Multidimensional</Format> 
                                  <AxisFormat>TupleFormat</AxisFormat> 
                                </PropertyList> 
                              </Properties> 
                            </Execute> 
                          </soap:Body> 
                        </soap:Envelope>"; 

        HttpWebRequest req = WebRequest.Create("http://192.168.0.29/msolap/msmdpump.dll") as HttpWebRequest; 
        req.Credentials = new NetworkCredential("192.168.0.29\\Administrator", "PoDolinam01"); 
        req.Method = "POST"; 
        byte[] reqBytes = Encoding.ASCII.GetBytes(xmla); 
        Stream stream = req.GetRequestStream(); 
        stream.Write(reqBytes, 0, reqBytes.Length); 
        stream.Close(); 

        HttpWebResponse rsp = req.GetResponse() as HttpWebResponse; 
        byte[] rspBuffer = new byte[8192]; int count = 0; string strBuffer; StringBuilder res = new StringBuilder(); 
        stream = rsp.GetResponseStream(); 
        while (true) 
        { 
            count = stream.Read(rspBuffer, 0, rspBuffer.Length); //чтение сразу до stream.Length не прокатывает, т.к. для этого стрим должен поддерживать Seek, а он, зараза, не хочет. Приходится читать ответ по кускам. 
            if (count == 0) break; 
            strBuffer = Encoding.ASCII.GetString(rspBuffer, 0, count); 
            res.Append(strBuffer); 
        } 
        Debug.WriteLine(res.ToString()); 
    } 
}

Скрипт 1

Рис. 1

Дальше пишется парсер, который вытаскивает из результата описания осей, строит соответствующий cellset, вытаскивает данные и набивает ячейки cellset’a. Мы сейчас этим заниматься не будем.

Аналогично, не будем рассматривать, как заслать SOAP-запрос в случае, когда все находится в пределах локальной сетки. Создавать виртуальную директорию в этом случае не нужно и вместо ISAPI можно адресоваться непосредственно по имени OLAP-сервера. Техника SOAP с использованием TcpClient разбирается здесь. Таким образом, вне зависимости от транспорта имеется возможность отправить полноценный XMLA в виде SOAP-запроса на OLAP-сервер и получить результат по схеме MDX и XMLA\Рис.4. Данный способ дает наиболее полный контроль, т.к., как уже неоднократно говорилось, XMLA является родным языком общения с MS AS, однако он сопряжен с накладными расходами для разработчика: вначале приходится составлять SOAP-конверт, затем парсить XML, возвращенный в качестве результата, вытаскивая из него полезную нагрузку.

Существуют средства доступа, берущие на себя накладные расходы, но, как и в любой программной модели, за это приходится платить снижением гибкости и полноты контроля. Наиболее популярным таким средством является ADOMD.NET – аналог ADO.NET для многомерных данных, который мы рассмотрим дальше.

Автор: Алексей Шуленин