Возникла необходимость обеспечения взаимодействия БД Oracle с внешней системой, которая не умеет работать с Oracle, но умеет класть файлы на FTP-сервер и в файловую систему. Решил задействовать Oracle XML DB. С FTP-сервером фокус не удался, т.к. система задействовала какие-то неподдерживаемые сервером команды. Вспомнил, что Windows умеет подключать WebDAV-ресурс в виде буквы диска. С этим получилось. Итак…
В Oracle Standard Edition One, установленном по-умолчанию, уже предустановлено всё необходимое для работы XML DB (Если что, можно подсмотреть здесь). Необходимо донастроить.
Настраиваем ACL для пользователя TEST_USER (обязательно в верхнем регистре!):
DECLARE aclxml VARCHAR2 ( 4000 ) := ' <acl description="All privileges to TEST_USER" xmlns="http://xmlns.oracle.com/xdb/acl.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd http://xmlns.oracle.com/xdb/acl.xsd" shared="true" > <ace> <grant>true</grant> <principal>TEST_USER</principal> <privilege> <all/> </privilege> </ace> </acl> ' ; retb BOOLEAN; BEGIN retb := DBMS_XDB.CREATERESOURCE ( '/sys/acls/all_test_user_acl.xml', aclxml ) ; END; /
Создаём папку:
DECLARE retb BOOLEAN; BEGIN retb := DBMS_XDB.CREATEFOLDER ( '/home' ); retb := DBMS_XDB.CREATEFOLDER ( '/home/test_user' ); END; /
Назначаем ACL созданному ресурсу (папке):
exec DBMS_XDB.SETACL ( '/home/test_user', '/sys/acls/all_test_user_acl.xml');
Создать ресурс (файл) с определённым содержимым можно так:
DECLARE retb BOOLEAN; BEGIN retb := DBMS_XDB.CREATERESOURCE ( '/home/test_user/intest/2.txt', 'The contents of the new file.' ); END; / commit;
Удалить ресурс (файл):
exec DBMS_XDB.DELETERESOURCE ( '/home/test_user/intest/2.txt'); commit;
Увидеть все ресурсы в "/home/test_user
" можно следующим запросом:
SQL> select path(1) from resource_view where under_path ( res, '/home/test_user', 1 ) = 1; PATH(1) ---------------------------------------------------------------------------------------------------- intest intest/1.txt
Просмотреть содержимое ресурса (файла) можно следующим запросом:
SQL> select r.res.extract ( 'Resource/Contents/text/text()' ) as text 2 from resource_view r 3 where equals_path ( res, '/home/test_user/intest/1.txt' ) = 1; TEXT ---------------------------------------------------------- 12312312312
Если пользователь не имеет полномочий на ресурс, результат будет пустым.
Включаем поддержку HTTP на порту, например, 8080:
exec dbms_xdb.SETHTTPPORT(8080);
Для FTP:
exec dbms_xdb.SETFTPPORT(2121);
Посмотреть FTP- и HTTP-порты можно запросом:
SQL> select dbms_xdb.GETFTPPORT() ftp, dbms_xdb.GETHTTPPORT http from dual; FTP HTTP ---------- ---------- 2121 8080
На стороне сервера в командной строке можно выполнить следующую команду:
lsnrctl status
Если в выводе присутствует указание на порт 8080, значит БД слушает этот порт. Вывод должен выглядеть примерно следующим образом:
... Listening Endpoints Summary... (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=dbhost)(PORT=1521))) (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=dbhost)(PORT=2121))(Presentation=FTP)(Session=RAW)) (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=dbhost)(PORT=8080))(Presentation=HTTP)(Session=RAW)) Services Summary... ...
Если есть возможность, HTTP-порт лучше настроить на порт 80, т.к. WebClient (WebDAV-клиент для под Windows) не умеет работать с нестандартными портами. (По крайней мере, мне не удалось его заставить работать.)
Если такой возможости нет, то нужно использовать какой-нибудь reverse-proxy. У нас был nginx…
Дописываем location в конфигурационный файл:
location /home { proxy_pass http://127.0.0.1:8080$request_uri; }
В нашем случае oracle и nginx установлены на одном компьютере.
Теперь настраиваем поддержку WebDAV в Windows на сервере, на котором нам необходимо подключать WebDAV-ресурс. Для этого нужно добавить Features. В Windows Server 2012 R2 это делается так:
Затем необходимо разрешить Basic Authorization. Для этого правим реестр:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WebClient\Parameters
"BasicAuthLevel
" присваиваем значение 2.
Многие сервисы запущены от имени "SYSTEM
" и для них нужно монтировать диск особым образом: создаём в Task Scheduler новое расписание, например, "Mount WebDAV
", с запуском "At startup
" и выполнением файла, например, "C:\map_webdav_drive.bat
", содержимое которого выглядит так:
@echo on net use /delete Z: net use Z: "http://dbhost/home/test_user" password /USER:test_user
Подключить к диску "Z:
" ресурс "http://dbhost/home/test_user
" c паролем "password
" из-под пользователя "test_user
".
Перегружаем сервер. После перезагрузки будет подключен диск, но он будет доступен только для "SYSTEM
". Соответственно, все сервисы будут иметь к доступ к нему.