Приведенный ранее вариант решения содержит ряд подводных камней:
1. Используется механизм Direct Database Request, что потребует наличия прав на эту функциональность у всех пользователей BIEE – согласитесь, это не всегда хорошо.
2. Не применяются политики безопасности, ограничивающие доступ к странице. То есть вы видите все страницы информационной панели, даже если она для вас и не предназначена (хотя зайти на нее вы не сможете).
Исправим это.
Для начала немного модифицируем пакет, реализующий основную функциональность.
CREATE OR REPLACE PACKAGE BI_UTILS IS
FUNCTION GET_DASHBOARD_PAGES(P_USER_NAME IN VARCHAR2, P_DASHBOARD_PATH IN VARCHAR2)
RETURN bi_db_page_array
PIPELINED;
END BI_UTILS;
CREATE OR REPLACE PACKAGE BODY BI_UTILS IS
g_nqs_user varchar2(50) := 'Administrator';
g_nqs_password varchar2(50) := 'Administrator';
g_bi_wsdl_url varchar2(255) := 'http://localhost:9704/analytics/saw.dll?SoapImpl=';
g_wsdl_session_service varchar2(50) := 'nQSessionService';
g_wsdl_webcat_service varchar2(50) := 'webCatalogService';
G_RET_STS_SUCCESS constant varchar2(1) := 'S';
G_RET_STS_ERROR constant varchar2(1) := 'E';
G_RET_STS_UNEXP_ERROR constant varchar2(1) := 'U';
procedure http_post(p_url_in in varchar2,
p_data_in in varchar2,
p_data_type in varchar2 default 'text/xml',
p_action in varchar2 default null,
p_charset in varchar2 default null,
p_username_in in varchar2 default null,
p_password_in in varchar2 default null,
x_status_code out varchar2,
x_reason_phrase out varchar2,
x_response out varchar2) is
l_data_in varchar2(32767);
l_http_req utl_http.req;
l_http_resp utl_http.resp;
l_response varchar2(32767);
begin
utl_http.set_response_error_check(false);
l_http_req := utl_http.begin_request(p_url_in, 'POST');
utl_http.set_header(l_http_req, 'content-type', p_data_type);
l_data_in := convert(p_data_in, 'utf8');
utl_http.set_header(l_http_req, 'content-length', length(l_data_in));
utl_http.set_header(l_http_req, 'SOAPAction', p_action);
if p_username_in is not null then
utl_http.set_authentication(l_http_req, p_username_in, p_password_in);
end if;
utl_http.set_body_charset(l_http_req, null);
utl_http.write_text(l_http_req, l_data_in);
l_http_resp := utl_http.get_response(l_http_req);
if (l_http_resp.status_code = utl_http.HTTP_OK) then
x_status_code := G_RET_STS_SUCCESS;
else
x_status_code := G_RET_STS_ERROR;
end if;
x_reason_phrase := l_http_resp.reason_phrase;
utl_http.read_text(l_http_resp, l_response);
utl_http.end_response(l_http_resp);
x_response := l_response;
EXCEPTION
when others then
utl_http.end_response(l_http_resp);
x_status_code := G_RET_STS_UNEXP_ERROR;
x_reason_phrase := sqlerrm;
END http_post;
function get_error_response_text(p_response in varchar2) return varchar2 is
l_parser xmlparser.Parser;
l_domDoc xmldom.DOMDocument;
l_domNL xmldom.DOMNodeList;
l_domN xmldom.DOMNode;
l_ret varchar2(32767);
begin
l_parser := xmlparser.newParser;
xmlparser.parseclob(l_parser, p_response);
l_domDoc := xmlparser.getDocument(l_parser);
Xmlparser.Freeparser(l_parser);
l_domNL := xmldom.getElementsByTagName(l_domDoc, 'faultstring');
l_domN := xmldom.getFirstChild(xmldom.item(l_domNL, 0));
l_ret := xmldom.getNodeValue(l_domN);
xmldom.freeDocument(l_domDoc);
return l_ret;
end get_error_response_text;
FUNCTION GET_DASHBOARD_PAGES(P_USER_NAME IN VARCHAR2, P_DASHBOARD_PATH IN VARCHAR2)
RETURN bi_db_page_array
PIPELINED IS
l_session_id varchar2(150);
l_status_code varchar2(1);
l_reason_phrase varchar2(2000);
l_send_data varchar2(32767);
l_receive_data varchar2(32767);
l_error_explanation varchar2(2000);
l_receive_xml xmltype;
BEGIN
/*login*/
l_send_data :=
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v5="com.siebel.analytics.web/soap/v5">' ||
' <soapenv:Header/>' ||
' <soapenv:Body>' ||
' <v5:impersonate>' ||
' <v5:name>' || g_nqs_user || '</v5:name>' ||
' <v5:password>' || g_nqs_password || '</v5:password>' ||
' <v5:impersonateID>' || p_user_name ||'</v5:impersonateID>' ||
' </v5:impersonate>' ||
' </soapenv:Body>' ||
'</soapenv:Envelope>';
http_post(p_url_in => g_bi_wsdl_url || g_wsdl_session_service,
p_data_in => l_send_data,
p_action => 'impersonateRequest',
x_status_code => l_status_code,
x_reason_phrase => l_reason_phrase,
x_response => l_receive_data);
if (l_status_code = G_RET_STS_SUCCESS) then
l_receive_xml := XMLTYPE(l_receive_data);
SELECT EXTRACT(VALUE(xmlt),
'sessionID/text()',
'xmlns="com.siebel.analytics.web/soap/v5"') .getStringVal() AS session_id
into l_session_id
FROM TABLE(XMLSEQUENCE(EXTRACT(l_receive_xml,
'//sawsoap:sessionID[1]',
'xmlns:sawsoap="com.siebel.analytics.web/soap/v5"'))) xmlt;
else
begin
l_error_explanation := get_error_response_text(p_response => l_receive_data);
exception
when others then
l_error_explanation := l_reason_phrase ||
' (cannot parse BI response)';
return;
end;
--may be put it to log-table?
end if;
/*get pages info*/
l_send_data :=
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v5="com.siebel.analytics.web/soap/v5">' ||
' <soapenv:Header/>' ||
' <soapenv:Body>' ||
' <v5:getSubItems>' ||
' <v5:path>' || P_DASHBOARD_PATH || '</v5:path>' ||
' <v5:mask>*</v5:mask>' ||
' <v5:resolveLinks>true</v5:resolveLinks>' ||
' <v5:options>' ||
' <v5:includeACL>false</v5:includeACL>' ||
' <v5:withPermission>1</v5:withPermission>' ||
' <v5:withPermissionMask>1</v5:withPermissionMask>' ||
' <v5:withAttributes>0</v5:withAttributes>' ||
' <v5:withAttributesMask>0</v5:withAttributesMask>' ||
' </v5:options>' ||
' <v5:sessionID>' || l_session_id || '</v5:sessionID>' ||
' </v5:getSubItems>' ||
' </soapenv:Body>' ||
'</soapenv:Envelope>';
http_post(p_url_in => g_bi_wsdl_url || g_wsdl_webcat_service,
p_data_in => l_send_data,
p_action => 'getSubItemsRequest',
x_status_code => l_status_code,
x_reason_phrase => l_reason_phrase,
x_response => l_receive_data);
if (l_status_code = G_RET_STS_SUCCESS) then
l_receive_xml := XMLTYPE(l_receive_data);
for cur in (SELECT EXTRACT(VALUE(xmlt),
'itemInfo/path/text()',
'xmlns="com.siebel.analytics.web/soap/v5"') .getStringVal() AS path,
EXTRACT(VALUE(xmlt),
'itemInfo/caption/text()',
'xmlns="com.siebel.analytics.web/soap/v5"') .getStringVal() AS caption,
EXTRACT(VALUE(xmlt),
'itemInfo/signature/text()',
'xmlns="com.siebel.analytics.web/soap/v5"') .getStringVal() AS signature
FROM TABLE(XMLSEQUENCE(EXTRACT(l_receive_xml,
'//sawsoap:itemInfo',
'xmlns:sawsoap="com.siebel.analytics.web/soap/v5"'))) xmlt) loop
if (cur.signature = 'dashboardpageitem1') then
PIPE ROW(bi_db_page(cur.caption,rtrim(rtrim(cur.path, cur.caption),'/')));
end if;
end loop;
else
begin
l_error_explanation := get_error_response_text(p_response => l_receive_data);
exception
when others then
l_error_explanation := l_reason_phrase ||
' (cannot parse BI response)';
return;
end;
--may be put it to log-table?
end if;
/*logoff*/
l_send_data :=
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v5="com.siebel.analytics.web/soap/v5">'||
' <soapenv:Header/>'||
' <soapenv:Body>'||
' <v5:logoff>'||
' <v5:sessionID>' || l_session_id || '</v5:sessionID>'||
' </v5:logoff>'||
' </soapenv:Body>'||
'</soapenv:Envelope>';
http_post(p_url_in => g_bi_wsdl_url || g_wsdl_session_service,
p_data_in => l_send_data,
p_action => 'logoffRequest',
x_status_code => l_status_code,
x_reason_phrase => l_reason_phrase,
x_response => l_receive_data);
return;
END GET_DASHBOARD_PAGES;
END BI_UTILS;
Что изменилось: в основную функцию пакета добавлен параметр P_USER_NAME , содержащий логин пользователя, с настройками безопасности которого хотим получить список страниц панели.
Теперь мы не просто соединяемся с BI под Администратором, но также делаем имперсонацию в переданного пользователя.
Чтобы избежать использования Direct database request – создадим в репозитории BI две новые физические таблицы.
Первая – DUAL (если по каким-то причинам вы ее еще не используете).
Вторая – BI_UTILS_DB_PAGES - таблица с типом Select и текстом
select page, portalpath
from table(bi_utils.get_dashboard_pages('VALUEOF(NQ_SESSION.USER)', 'VALUEOF(NQ_SESSION.PORTAL_PATH)'))
Свяжем две эти таблицы на физическом уровне (BIEE не позволяет «протянуть» через репозиторий единичную таблицу).
На логическом слое репозитория создадим новый предметный каталог, в который поместим 2 новые таблицы. Свяжем их логической связью. И новый предметный каталог отразим в презентационном слое.
Можно определить в Variable Manager новую сессионную переменную PORTAL_PATH – ее мы используем внутри таблицы-запроса BI_UTILS_DB_PAGES. Но это не принципиально (хотя если вы перфекционист и любой warning репозитория вас коробит – обязательно создайте сессионную переменную и назначьте ей значение по умолчанию).
Теперь создадим новый BI Answer, но уже как «чистый» Answer, а не DDR.
В представлениях Answer’а нам нужно лишь Примечание (Narrative View)
Префикс остается старым:
<script language="javascript">
function getDBPagePath(sPortalPath, sPage)
{
var sCmd = sawCommandToURLImpl('Dashboard');
sCmd += "&PortalPath=" + saw.encodeURIComponent(sPortalPath);
sCmd += "&Page=" + saw.encodeURIComponent(sPage);
return sCmd
}
</script>
Тело немного меняется:
<a href="javascript:void(null);" onclick="return GuidedNav(getDBPagePath('@1','@2'),true);">@2</a>
Остается только сказать системе откуда брать значение сессионной переменной PORTAL_PATH.
На вкладке «Дополнительно» определим значение данной переменной:
P.S. Для сортировки страниц информационной панели можно использовать трюк: переименуйте какую-либо страницу – добавив пробел в начало имени, тем самым страница поднимется «вверх в списке».
Интересная статья. Попытался адаптировать для себя, и возникла пара вопросов:
ОтветитьУдалить1. Как быть с русскими буквами в пути ? У меня выдает:
soap:Client
Исключение в синтаксическом анализаторе Sax.
Сообщение: Expected end of tag 'soapenv:Envelope', publicId логического объекта: , systemId логического объекта: , номер строки: 1, номер столбца: 773
UH6MBRBC
Исключение в синтаксическом анализаторе Sax.
Сообщение: Expected end of tag 'soapenv:Envelope', publicId логического объекта: , systemId логического объекта: , номер строки: 1, номер столбца: 773
2. Можно ли с помощью веб сервиса получить список доступных дашбоардов ?
Oracle Bi По-Русски: Biee: Множество Страниц Дашборда - Часть2 >>>>> Download Now
ОтветитьУдалить>>>>> Download Full
Oracle Bi По-Русски: Biee: Множество Страниц Дашборда - Часть2 >>>>> Download LINK
>>>>> Download Now
Oracle Bi По-Русски: Biee: Множество Страниц Дашборда - Часть2 >>>>> Download Full
>>>>> Download LINK