Apps: Java, Apache Maven, Ant, Tomcat, Nginx, PostgreSQL, patch.
Задача: описание этапов сборки из исходных кодов и развёртывания комплекса web-приложений ("сервлетов") репозитория цифровых документов "DSpace v6", в среде контейнеризатора "Apache Tomcat".
Это вторая часть развёрнутой инструкции, описывающая сборку и установку web-приложений "DSpace", а подготовка системного и прикладного программного окружения разбиралась в предыдущей публикации.
Последовательность дальнейших действий такова:
1. Получаем и вносим исправления в исходные коды проекта "DSpace".
2. Конфигурируем специфичные для инстанса параметры "DSpace".
3. Собираем и развёртываем Java-сервлеты web-приложений "DSpace".
4. Проверяем корректность работы компонентов запущенного web-сервиса.
2. Конфигурируем специфичные для инстанса параметры "DSpace".
3. Собираем и развёртываем Java-сервлеты web-приложений "DSpace".
4. Проверяем корректность работы компонентов запущенного web-сервиса.
Получение дистрибутива "DSpace" и наложение "патча".
На странице ленты релизов https://github.com/DSpace/DSpace/releases сайта проекта ищем то, что нас интересует - в частности, по состоянию на Март 2019 есть сборка "DSpace 6.3" от 27 Июня 2018 - последний стабильный релиз ветви "v6".
Обращаю внимание на то, что после официальной сборки "DSpace 6.3" от 27 Июня 2018 до Апреля 2019 в исходный код уже внесли около пятидесяти некритичных правок - есть смысл взять проект в его свежем состоянии, прямо из Git-репозитория:
# git clone --single-branch --branch dspace-6_x https://github.com/DSpace/DSpace.git
Для простоты я скопировал ветку "dspace-6_x" в свой Git-репозиторий и в дальнейшем работал уже с ней:
# cd /usr/local/src
# git clone --single-branch --branch dspace-6_x https://git.example.net/group/dspace.git
# chown -R dspace:dspace ./dspace
# git clone --single-branch --branch dspace-6_x https://git.example.net/group/dspace.git
# chown -R dspace:dspace ./dspace
Напоминаю, что здесь мы используем считающуюся стабильной ветку проекта "DSpace v6", активности в которой не наблюдается уже более полгода, в то время как усилия разработчиков сосредоточены на ветви "DSpace v7" (по состоянию на Апрель 2019 она - "master"), пока ещё не имеющей ни одного официального релиза.
Упреждая события подскажу, что запуск "DSpace v6" на "базе данных" от предыдущей версии (например "v5") вызовет автоматическую процедуру обновления структуры и переиндексации содержимого БД. Сразу отмечу, что автоматическое обновление структуры не отработает из-за некорректного скрипта "V6.0_2015.03.07__DS-2701_Hibernate_migration.sql", пытающегося создать "индекс", когда это сделать невозможно. Я сделал для исправления конфликтов и недочётов простейший "патч", меняющий порядок создания "индексов" и дополняющий логику удаления некоторых колонок таблиц каскадированием:
# git diff --no-index ./dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V6.0_2015.03.07__DS-2701_Hibernate_migration.sql ... > ./dspace/dspace-6-ds-2701-hibernate-migration.fix-key-and-cascade.patch
Применение "патча" элементарно:
# cd /usr/local/src/dspace
# patch --verbose --forward -d ./ -p1 < ./dspace-6-ds-2701-hibernate-migration.fix-key-and-cascade.patch
# patch --verbose --forward -d ./ -p1 < ./dspace-6-ds-2701-hibernate-migration.fix-key-and-cascade.patch
Using Plan A...
Hunk #1 succeeded at 27.
....
Hunk #8 succeeded at 154.
done
Hunk #1 succeeded at 27.
....
Hunk #8 succeeded at 154.
done
Учитывая простоту "патча" легко проверить, не налагался ли он уже на файл, запустив проверку возможности процедуры отката изменений (полезно в автоматизации) - например; далее мы видим результат прогона теста на файле с уже применённым к нему "патчем":
# patch --dry-run --verbose --force --reverse -d ./ -p1 < ./dspace-6-ds-2701-hibernate-migration.fix-key-and-cascade.patch
Предварительное конфигурирование web-проекта "DSpace".
Перед сборкой Java-приложений из комплекта модулей и исходного кода дистрибутива необходимо задать ряд специфичных для нашего инстанса сервиса параметров, которые будут применены к соответствующим компонентам проекта "DSpace" (обращаю внимание на то, что в именах параметров важен регистр символов):
# vi /usr/local/src/dspace/dspace/config/dspace.cfg
....
##### Basic information ######
# Месторасположение директории, от которой начинается иерархия исполняемых и файлов данных DSpace
dspace.dir = /var/lib/dspace
# FQDN web-сервиса DSpace, с точки зрения пользователей
dspace.hostname = dspace.example.net
# Полноценный URL web-сервиса, включая номер порта, но без указания подресурсов
# (учитываем то, что мы будем обслуживать только HTTPS-запросы, терминируемые Nginx)
dspace.baseUrl = https://dspace.example.net
# Используемый "по умолчанию" компонент web-интерфейса
dspace.ui = xmlui
# Заголовок web-проекта
dspace.name = "Example DSpace Library"
# Переводим web-сервис на язык большинства пользователей
default.language = ru_RU
default.locale = ru
# Включим поддержку переключения между языками в web-интерфейсе
webui.supported.locales = ru, en
....
# Указываем месторасположение хранилища загруженных файлов
assetstore.dir = ${dspace.dir}/assetstore
....
# Точка подключения к поисковому сервису "Apache Solr"
solr.server = http://localhost:8080/solr
....
##### Handle settings#####
# Задаём дискриптор URI-адресации документов в формате CNRI
# (в НГУ - "nsu")
handle.prefix = example
....
##### Database settings #####
# Параметры подключения с СУБД
db.driver = org.postgresql.Driver
db.url = jdbc:postgresql://localhost:5432/dspace
db.username = dspace
db.password = <password>
# Параметры "пула" подключений к СУБД
db.maxconnections = 120 # (default = 30)
db.maxidle = 30 # (default = 10)
....
##### Email settings ######
# FQDN mail-сервера для исходящих почтовых сообщений
mail.server = mx.example.net
# Явно задаём кодировку содержимого исходящих писем
mail.charset = UTF-8
# Адрес в заголовке "From:" для исходящей от DSpace почты
mail.from.address = dspace-noreply@example.net
# Почтовый адрес администратора сайта "DSpace"
mail.admin = admin@example.net
# Почтовый адрес для приёма сообщений с формы обратной связи
feedback.recipient = admin@example.net
# Почтовый адрес для уведомлений о регистрации новых пользователей
registration.notify = admin@example.net
....
##### Basic information ######
# Месторасположение директории, от которой начинается иерархия исполняемых и файлов данных DSpace
dspace.dir = /var/lib/dspace
# FQDN web-сервиса DSpace, с точки зрения пользователей
dspace.hostname = dspace.example.net
# Полноценный URL web-сервиса, включая номер порта, но без указания подресурсов
# (учитываем то, что мы будем обслуживать только HTTPS-запросы, терминируемые Nginx)
dspace.baseUrl = https://dspace.example.net
# Используемый "по умолчанию" компонент web-интерфейса
dspace.ui = xmlui
# Заголовок web-проекта
dspace.name = "Example DSpace Library"
# Переводим web-сервис на язык большинства пользователей
default.language = ru_RU
default.locale = ru
# Включим поддержку переключения между языками в web-интерфейсе
webui.supported.locales = ru, en
....
# Указываем месторасположение хранилища загруженных файлов
assetstore.dir = ${dspace.dir}/assetstore
....
# Точка подключения к поисковому сервису "Apache Solr"
solr.server = http://localhost:8080/solr
....
##### Handle settings#####
# Задаём дискриптор URI-адресации документов в формате CNRI
# (в НГУ - "nsu")
handle.prefix = example
....
##### Database settings #####
# Параметры подключения с СУБД
db.driver = org.postgresql.Driver
db.url = jdbc:postgresql://localhost:5432/dspace
db.username = dspace
db.password = <password>
# Параметры "пула" подключений к СУБД
db.maxconnections = 120 # (default = 30)
db.maxidle = 30 # (default = 10)
....
##### Email settings ######
# FQDN mail-сервера для исходящих почтовых сообщений
mail.server = mx.example.net
# Явно задаём кодировку содержимого исходящих писем
mail.charset = UTF-8
# Адрес в заголовке "From:" для исходящей от DSpace почты
mail.from.address = dspace-noreply@example.net
# Почтовый адрес администратора сайта "DSpace"
mail.admin = admin@example.net
# Почтовый адрес для приёма сообщений с формы обратной связи
feedback.recipient = admin@example.net
# Почтовый адрес для уведомлений о регистрации новых пользователей
registration.notify = admin@example.net
....
Скорректируем настройки журналирования web-приложений "DSpace", ограничив время их хранения:
# vi /usr/local/src/dspace/dspace/config/log4j.properties
....
# Задаём срок хранения журналов событий в течение недели (по умолчанию неограниченно)
# (обращаем внимание на то, что потоков журналирования может быть несколько)
#
log4j.appender.A1.MaxLogs=7
....
log4j.appender.A2.MaxLogs=7
....
log4j.appender.A3.MaxLogs=7
....
# Задаём срок хранения журналов событий в течение недели (по умолчанию неограниченно)
# (обращаем внимание на то, что потоков журналирования может быть несколько)
#
log4j.appender.A1.MaxLogs=7
....
log4j.appender.A2.MaxLogs=7
....
log4j.appender.A3.MaxLogs=7
....
Настройки журналирования входящего в дистрибутив "DSpace" сервера полнотекстового поиска "Solr" вынесены в отдельный файл конфигурации, в котором полезно внести унифицирующие правки для автоматизации ротации:
# vi /usr/local/src/dspace/dspace/config/log4j-solr.properties
....
# Заменяем модуль ротации с "ежедневного безлимитного" на "урезающий по размеру и удаляющий по количеству"
# ("DailyRollingFileAppender" не поддерживает удаление старых файлов - нет соответствующего критерия)
#log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
#log4j.appender.file.DatePattern='.'yyyy-MM-dd
#
log4j.appender.file=org.apache.log4j.RollingFileAppender
# Ограничиваем размер одного файла журнала и количество таковых
log4j.appender.file.MaxFileSize=10MB
log4j.appender.file.MaxBackupIndex=7
....
# Заменяем модуль ротации с "ежедневного безлимитного" на "урезающий по размеру и удаляющий по количеству"
# ("DailyRollingFileAppender" не поддерживает удаление старых файлов - нет соответствующего критерия)
#log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
#log4j.appender.file.DatePattern='.'yyyy-MM-dd
#
log4j.appender.file=org.apache.log4j.RollingFileAppender
# Ограничиваем размер одного файла журнала и количество таковых
log4j.appender.file.MaxFileSize=10MB
log4j.appender.file.MaxBackupIndex=7
....
Аналогично изменяем настройки журналирования входящего в дистрибутив "DSpace" сервиса согласований URI документов в CNRI:
# vi /usr/local/src/dspace/dspace/config/log4j-handle-plugin.properties
....
# Заменяем модуль ротации с "ежедневного безлимитного" на "урезающий по размеру и удаляющий по количеству"
# ("DailyRollingFileAppender" не поддерживает удаление старых файлов - нет соответствующего критерия)
#log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
#log4j.appender.A1.DatePattern='.'yyyy-MM-dd
#
log4j.appender.A1=org.apache.log4j.RollingFileAppender
# Ограничиваем размер одного файла журнала и количество таковых
log4j.appender.A1.MaxFileSize=10MB
log4j.appender.A1.MaxBackupIndex=7
....
# Заменяем модуль ротации с "ежедневного безлимитного" на "урезающий по размеру и удаляющий по количеству"
# ("DailyRollingFileAppender" не поддерживает удаление старых файлов - нет соответствующего критерия)
#log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
#log4j.appender.A1.DatePattern='.'yyyy-MM-dd
#
log4j.appender.A1=org.apache.log4j.RollingFileAppender
# Ограничиваем размер одного файла журнала и количество таковых
log4j.appender.A1.MaxFileSize=10MB
log4j.appender.A1.MaxBackupIndex=7
....
Я стараюсь разносить логику и содержимое, так что журналы событий web-приложений символической ссылкой направляю в более соответствующую им поддиректорию "/var/log":
# ln -s /var/log/dspace /var/lib/dspace/log
Cборка Java-приложений проекта посредством "Maven".
Сборка Java-компонентов проекта осуществляется инструментарием "Apache Maven", руководствующимся настройками из файлов "pom.xml". Результирующие файлы выкладываются в автоматически создаваемую для этого директорию "./dspace/target/dspace-installer/", заданную по умолчанию в применяемом при сборке плагине "Apache Maven Assembly" (при желании можно изменить месторасположение, изменив его в файле "assembly.xml").
Запускаем сборку компонентов проекта (по умолчанию в конфигурации с использованием СУБД "PostgreSQL"):
# cd /usr/local/src/dspace
# sudo -u dspace /opt/apache-maven/bin/mvn clean package
# sudo -u dspace /opt/apache-maven/bin/mvn clean package
[INFO] Scanning for projects...
....
[INFO] DSpace Parent Project [pom]
[INFO] DSpace Services Framework :: API and Implementation [jar]
....
[INFO] ----------------------< org.dspace:dspace-parent >---------------------
[INFO] Building DSpace Parent Project 6.3 [1/23]
....
[INFO] DSpace Parent Project ............................. SUCCESS [ 22.886 s]
[INFO] DSpace Services Framework :: API and Implementation SUCCESS [ 38.350 s]
....
[INFO] BUILD SUCCESS
[INFO] Total time: 05:34 min
....
[INFO] DSpace Parent Project [pom]
[INFO] DSpace Services Framework :: API and Implementation [jar]
....
[INFO] ----------------------< org.dspace:dspace-parent >---------------------
[INFO] Building DSpace Parent Project 6.3 [1/23]
....
[INFO] DSpace Parent Project ............................. SUCCESS [ 22.886 s]
[INFO] DSpace Services Framework :: API and Implementation SUCCESS [ 38.350 s]
....
[INFO] BUILD SUCCESS
[INFO] Total time: 05:34 min
В случае сбоя на этапе сборки какого-то конкретного модуля можно запустить его заново индивидуально:
# sudo -u dspace /opt/apache-maven/bin/mvn package -rf :dspace-solr
В нашем случае результаты предварительной сборки выкладываются в директорию "/usr/local/src/dspace/dspace/target/dspace-installer/", а исходные файлы остаются при этом неизменными.
Исправление недочётов сборки.
При сборке посредством "Maven" в соответствии с заданными разработчиками в "pom.xml" правилами в комплекте "DSpace" для подсистемы "Solr" не поставляется две Java-библиотеки, без которых "Apache Solr Webapp" даже не запустится, записав в журнал событий что-то вроде следующего:
# cat /var/lib/dspace/logs/console.log
... ERROR org.apache.solr.servlet.SolrDispatchFilter @ Could not start Solr
... ERROR org.apache.solr.core.SolrCore @ null:java.lang.ExceptionInInitializerError
....
Caused by: java.lang.ClassCastException: class org.elasticsearch.index.codec.postingsformat.BloomFilterPostingsFormat
....
... ERROR org.apache.solr.servlet.SolrDispatchFilter @ Could not start Solr
... ERROR org.apache.solr.core.SolrCore @ null:java.lang.ExceptionInInitializerError
....
Caused by: java.lang.ClassCastException: class org.apache.lucene.codecs.idversion.IDVersionPostingsFormat
....
... ERROR org.apache.solr.core.SolrCore @ null:java.lang.ExceptionInInitializerError
....
Caused by: java.lang.ClassCastException: class org.elasticsearch.index.codec.postingsformat.BloomFilterPostingsFormat
....
... ERROR org.apache.solr.servlet.SolrDispatchFilter @ Could not start Solr
... ERROR org.apache.solr.core.SolrCore @ null:java.lang.ExceptionInInitializerError
....
Caused by: java.lang.ClassCastException: class org.apache.lucene.codecs.idversion.IDVersionPostingsFormat
....
Необходимые Java-библиотеки имеются в пакете компонентов "DSpace XML-UI" - просто копируем их оттуда:
# find /usr/local/src/dspace/dspace/target/dspace-installer/webapps/xmlui/WEB-INF/lib -iname 'elasticsearch-*.jar' -exec cp {} /usr/local/src/dspace/dspace/target/dspace-installer/webapps/solr/WEB-INF/lib/ \;
# find /usr/local/src/dspace/dspace/target/dspace-installer/webapps/xmlui/WEB-INF/lib -iname 'lucene-sandbox-*.jar' -exec cp {} /usr/local/src/dspace/dspace/target/dspace-installer/webapps/solr/WEB-INF/lib/ \;
# find /usr/local/src/dspace/dspace/target/dspace-installer/webapps/xmlui/WEB-INF/lib -iname 'lucene-sandbox-*.jar' -exec cp {} /usr/local/src/dspace/dspace/target/dspace-installer/webapps/solr/WEB-INF/lib/ \;
В процессе проработки методики инсталляции "DSpace" и миграции данных между мажорными версиями я было начал строчить "патчи" для исходного кода, исправляющие подобные огрехи - но их количество росло, а проект по сути заброшен, так что показалось проще между этапами сборки наводить некоторый порядок.
Подготовка к инсталляции Java-приложений проекта посредством "Ant".
Вторым проходом инструментарием "Apache Ant" произведём финальную обработку настроек компонентов "DSpace" и выгрузку готовых web-приложений в указанное место файловой системы. Утилита "ant" руководствуется настройками из файлов "build.xml".
В соответствии с предопределённым разработчиками "DSpace" порядком вторым этапом предполагается инсталляция непосредственно в месторасположение web-приложения, заданное заранее в файле "dspace.conf". Я такого не люблю, предпочитая вначале полностью собирать приложение, а уже потом рассредотачивать файлы в соответствии с политикой обновления сервиса - потому направляем инсталлятор в удобное место.
Создаём подставную директорию для "инсталляции":
# sudo -u dspace mkdir -p /usr/local/src/dspace/ant-dspace-target
Переходим в директорию скомпилированных компонентов проекта и запускаем процедуру компоновки, заключающуюся в основном в адаптации конфигурационных файлов компонентов и очистке проекта от ненужного сопроводительного:
# cd /usr/local/src/dspace/dspace/target/dspace-installer
# sudo -u dspace /opt/apache-ant/bin/ant -Ddspace.dir=/usr/local/src/dspace/ant-dspace-target fresh_install
# sudo -u dspace /opt/apache-ant/bin/ant -Ddspace.dir=/usr/local/src/dspace/ant-dspace-target fresh_install
Обращаю внимание на то, что в команде выше опцией "-Ddspace.dir" мы указываем компоновщику на подставную директорию для условной инсталляции.
Buildfile: /usr/local/src/dspace-6.3-src-release/dspace/target/dspace-installer/build.xml
init_installation:
[mkdir] Created dir: /usr/local/src/dspace/ant-dspace-target/bin
[mkdir] Created dir: /usr/local/src/dspace/ant-dspace-target/config
....
init_configs:
[copy] Copying 160 files to /usr/local/src/dspace/ant-dspace-target/config
....
test_database:
....
[java] Attempting to connect to database
[java] Connected successfully!
....
[java] Database Driver: PostgreSQL JDBC Driver version 42.2.1
[java] PostgreSQL 'pgcrypto' extension installed/up-to-date? true (version=1.3)
....
install_code:
[copy] Copying 8 files to /usr/local/src/dspace/ant-dspace-target/bin
[copy] Copying 179 files to /usr/local/src/dspace/ant-dspace-target/lib
....
copy_webapps:
[copy] Copying 3024 files to /usr/local/src/dspace/ant-dspace-target/webapps
....
BUILD SUCCESSFUL
Total time: 30 seconds
init_installation:
[mkdir] Created dir: /usr/local/src/dspace/ant-dspace-target/bin
[mkdir] Created dir: /usr/local/src/dspace/ant-dspace-target/config
....
init_configs:
[copy] Copying 160 files to /usr/local/src/dspace/ant-dspace-target/config
....
test_database:
....
[java] Attempting to connect to database
[java] Connected successfully!
....
[java] Database Driver: PostgreSQL JDBC Driver version 42.2.1
[java] PostgreSQL 'pgcrypto' extension installed/up-to-date? true (version=1.3)
....
install_code:
[copy] Copying 8 files to /usr/local/src/dspace/ant-dspace-target/bin
[copy] Copying 179 files to /usr/local/src/dspace/ant-dspace-target/lib
....
copy_webapps:
[copy] Copying 3024 files to /usr/local/src/dspace/ant-dspace-target/webapps
....
BUILD SUCCESSFUL
Total time: 30 seconds
Сразу после завершения компоновки нужно найти в конфигурационных файлах готовых к применению компонентов проекта путь к подставной инсталляционной директории и заменить его на реальное месторасположение файлов проекта:
# cd /usr/local/src/dspace/ant-dspace-target
# grep -ril -e '/usr/local/src/dspace/ant-dspace-target' ./ | xargs sed -i 's/\/usr\/local\/src\/dspace\/ant-dspace-target/\/var\/lib\/dspace/gI'
# grep -ril -e '/usr/local/src/dspace/ant-dspace-target' ./ | xargs sed -i 's/\/usr\/local\/src\/dspace\/ant-dspace-target/\/var\/lib\/dspace/gI'
Исправление недочётов компоновки.
Важный нюанс - для "DSpace v6" в описаниях параметров сборки некоторых компонентов указывается обязательная зависимость от устаревшего уже в "Java 7" модуля "Servlet API v2.5", на замену которому пришёл "Servlet API v3". Так вот, в современных сборках на "Java v8-11" и "Tomcat v8/9", по умолчанию работающих на современном API и укомплектованных современным модулем "Servlet API v3", попытка инсталлятора "DSpace" подсунуть модуль предыдущей версии вызовет конфликт и отказ в работе, сопровождаемый примерно такими сообщениями в журнале событий:
# cat /var/lib/dspace/log/console.log
....
... SEVERE [localhost-startStop-1] org.apache.catalina.core.ContainerBase.addChildInternal ContainerBase.addChild: start:
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/xmlui]]
....
Caused by: java.lang.NoSuchMethodError: javax.servlet.ServletContext.getClassLoader()Ljava/lang/ClassLoader;
at org.apache.tomcat.util.scan.StandardJarScanner.doScanClassPath(StandardJarScanner.java:246)
....
... SEVERE [localhost-startStop-1] org.apache.catalina.core.ContainerBase.addChildInternal ContainerBase.addChild: start:
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/xmlui]]
....
Caused by: java.lang.NoSuchMethodError: javax.servlet.ServletContext.getClassLoader()Ljava/lang/ClassLoader;
at org.apache.tomcat.util.scan.StandardJarScanner.doScanClassPath(StandardJarScanner.java:246)
....
В "DSpace v7" эту проблему устранили "патчем" обновляющим требования к зависимостям для сборщика "Maven".
На первом этапе я решил проблему создав аналогичный "патч", указав в конфигурационном файле "./dspace/pom.xml" на то, что необходимая библиотека "Servlet API" будет предоставлена извне и нет необходимости в её сборке и включению в проект как таковой. Однако это повлекло за собой некоторые неудобства, в основном выражающиеся в том, что сборка посредством "Apache Ant" опиралась на эту самую библиотеку, и приходилось указывать утилите путь к внешним, что неудобно - проще оказалось удалять лишний файл Java-библиотеки после сборки, перед развёртыванием web-проекта:
# rm -f /usr/local/src/dspace/ant-dspace-target/lib/servlet-api-2.5.jar
Несмотря на то, что настройки "DSpace" уже с версии "v5" полностью вынесены в конфигурационный файл "dspace.conf", ему тем не менее очень хочется обнаружить файл "local.cfg" (хоть бы и пустой) - на обработку этой "сбойной" ситуации тратится время, так что просто создаём заглушку:
# touch /usr/local/src/dspace/ant-dspace-target/config/local.cfg
Подготовка к развёртыванию web-приложений и компонентов "DSpace".
По завершению сборки компонентов "DSpace" мы получим нижеперечисленный набор web-приложений, из которых не все могут понадобится в реальной эксплуатации:
1. "xmlui" - XML-based пользовательский web-интерфейс - применяемый в нашем случае;
2. "jspui" - JSP-based пользовательский web-интерфейс - более современный (мы его не используем, оставаясь на "xmlui");
3. "solr" - сервис фонового полнотекстового поиска "Apache Solr", обязательный к применению в любой конфигурации;
4. "oai" - API для обслуживания запросов по протоколам OAI-PMH и OAI-ORE;
5. "rest" - API для обслуживания специфичных DSpace-запросов по протоколу REST;
6. "rdf" - API для обслуживания запросов по протоколу RDF (мы его не используем);
7. "sword/swordv2" - API для обслуживания запросов по протоколам SWORD v1/2 (мы его не используем).
2. "jspui" - JSP-based пользовательский web-интерфейс - более современный (мы его не используем, оставаясь на "xmlui");
3. "solr" - сервис фонового полнотекстового поиска "Apache Solr", обязательный к применению в любой конфигурации;
4. "oai" - API для обслуживания запросов по протоколам OAI-PMH и OAI-ORE;
5. "rest" - API для обслуживания специфичных DSpace-запросов по протоколу REST;
6. "rdf" - API для обслуживания запросов по протоколу RDF (мы его не используем);
7. "sword/swordv2" - API для обслуживания запросов по протоколам SWORD v1/2 (мы его не используем).
Лично нам нужны только три web-приложения:
1. "xmlui" - пользовательский интерфейс как таковой;
2. "solr" - фоновый сервис полнотекстового поиска;
3. "rest" - API-для обслуживания внешних и внутренних сервисов;
4. "oai" - API-для обслуживания внешних сервисов.
2. "solr" - фоновый сервис полнотекстового поиска;
3. "rest" - API-для обслуживания внешних и внутренних сервисов;
4. "oai" - API-для обслуживания внешних сервисов.
Кроме размещаемых в "./webapps" web-приложений при сборке проекта "DSpace" создаётся несколько директорий, которые должны быть размещены в "/var/lib/dspace". Часть из них обязательные, а некоторые будут созданы автоматически по необходимости:
1. "bin" - CLI-утилиты для автоматизации фоновых задач;
2. "config" - конфигурационные файлы некоторых компонентов;
3. "exports" - директория для выгрузки наборов данных (создаётся автоматически);
4. "lib" - набор разделяемых библиотек web-приложений;
5. "{log|logs}" - директория для журналов web-приложений;
6. "reports" - директория для выгрузки отчётов (создаётся автоматически);
7. "solr" - корневая директория хранилища ресурсов сервера полнотекстового поиска;
8. "upload" - директория для загрузки наборов данных (создаётся автоматически);
9. "var" - директория хранения ресурсов web-приложений - пока только "oai" (создаётся автоматически);
10. "webapps" - директория для дистрибутивов публикуемых web-приложений.
2. "config" - конфигурационные файлы некоторых компонентов;
3. "exports" - директория для выгрузки наборов данных (создаётся автоматически);
4. "lib" - набор разделяемых библиотек web-приложений;
5. "{log|logs}" - директория для журналов web-приложений;
6. "reports" - директория для выгрузки отчётов (создаётся автоматически);
7. "solr" - корневая директория хранилища ресурсов сервера полнотекстового поиска;
8. "upload" - директория для загрузки наборов данных (создаётся автоматически);
9. "var" - директория хранения ресурсов web-приложений - пока только "oai" (создаётся автоматически);
10. "webapps" - директория для дистрибутивов публикуемых web-приложений.
Некоторые директории не нужны, если не задействован соответствующий функционал:
1. "etc" - вспомогательные скрипты (опционально);
2. "handle-server" - приложение для согласований URI в CNRI (опционально);
3. "triplestore" - директория хранения "триплетов" web-приложения "rdf" (опционально).
2. "handle-server" - приложение для согласований URI в CNRI (опционально);
3. "triplestore" - директория хранения "триплетов" web-приложения "rdf" (опционально).
Основной объём данных, которыми оперируют четыре нужным нам web-приложения "DSpace", сосредоточены в трёх местах:
1. "/var/lib/dspace/assetstore" - загружаемые пользователями файлы (75% от общего объёма данных сервисов "DSpace");
2. "/var/lib/dspace/solr" - индексы содержимого загруженных файлов (20%);
3. "база данных" PostgreSQL (5%).
2. "/var/lib/dspace/solr" - индексы содержимого загруженных файлов (20%);
3. "база данных" PostgreSQL (5%).
Развёртывание web-приложений "DSpace".
По умолчанию в "Apache Tomcat" включено автоматическое развёртывание web-приложений, дистрибутивы которых размещаются в типовой директории "./webapps" - если это не так, то следующие опции активируют автоматическую распаковку WAR/EAR-архивов, их развёртывание и последующее удаление предыдущих версий (если таковые обнаружены) с переводом трафика на новые web-приложения:
# vi /var/lib/dspace/conf/server.xml
....
<Server ...>
....
<Service name="Catalina">
....
<Engine name="Catalina" defaultHost="localhost">
....
<Host name="localhost" appBase="webapps"
unpackWARs="true"
autoDeploy="true"
undeployOldVersions="true">
....
<Server ...>
....
<Service name="Catalina">
....
<Engine name="Catalina" defaultHost="localhost">
....
<Host name="localhost" appBase="webapps"
unpackWARs="true"
autoDeploy="true"
undeployOldVersions="true">
....
Как вариант, учитывающий замену конфигурационных файлов вне web-приложений, можно остановить контейнеризатор, заменить файлы web-проекта целиком вручную и запустить "Tomcat", тем самым побудив его инициализировать приложения заново:
# systemctl stop dspace-tomcat
# cp -r ./ant-dspace-target/bin /var/lib/dspace
# cp -r ./ant-dspace-target/config /var/lib/dspace
# cp -r ./ant-dspace-target/lib /var/lib/dspace
# cp -r ./ant-dspace-target/solr /var/lib/dspace
# cp -r ./ant-dspace-target/webapps/xmlui /var/lib/dspace/webapps
# cp -r ./ant-dspace-target/webapps/rest /var/lib/dspace/webapps
# cp -r ./ant-dspace-target/webapps/solr /var/lib/dspace/webapps
# cp -r ./ant-dspace-target/webapps/oai /var/lib/dspace/webapps
# chown -R dspace:dspace /var/lib/dspace
# systemctl start dspace-tomcat
# cp -r ./ant-dspace-target/bin /var/lib/dspace
# cp -r ./ant-dspace-target/config /var/lib/dspace
# cp -r ./ant-dspace-target/lib /var/lib/dspace
# cp -r ./ant-dspace-target/solr /var/lib/dspace
# cp -r ./ant-dspace-target/webapps/xmlui /var/lib/dspace/webapps
# cp -r ./ant-dspace-target/webapps/rest /var/lib/dspace/webapps
# cp -r ./ant-dspace-target/webapps/solr /var/lib/dspace/webapps
# cp -r ./ant-dspace-target/webapps/oai /var/lib/dspace/webapps
# chown -R dspace:dspace /var/lib/dspace
# systemctl start dspace-tomcat
Процесс запуска "Tomcat" и развёртывания web-приложений небыстрый, обычно не менее двух-трёх минут - в это время можно заглянуть в журналы событий "Systemd" и контейнеризатора, а потом и самого "DSpace":
# journalctl -xe
# tail -100 /var/lib/dspace/log/console.log
# tail -100 /var/lib/dspace/log/dspace.log
# tail -100 /var/lib/dspace/log/console.log
# tail -100 /var/lib/dspace/log/dspace.log
Первичная настройка web-приложений "DSpace".
После инсталляции для доступа к web-панели администрирования "DSpace" необходимо создать локального пользователя (их может быть несколько), обладающего максимальными привилегиями - делается это посредством специализированной CLI-утилиты:
# sudo -u dspace CLASSPATH=/opt/dspace/tomcat/lib/* /var/lib/dspace/bin/dspace create-administrator
Creating an initial administrator account
E-mail address: admin@example.net
First name: Local DSpace Administrator
....
Password:
....
Administrator account created
E-mail address: admin@example.net
First name: Local DSpace Administrator
....
Password:
....
Administrator account created
Обращаю внимание на то, что в команде выше переменной окружения "CLASSPATH" мы указываем Java-приложению на месторасположение внешних модулей (в частности "servlet-api.jar", который мы вырезали из сопроводительного набора "DSpace", как конфликтующего с современными).
Сразу можно проверить успешность создания аккаунта пользователя, залогинившись в web-интерфейсе (по адресу вроде "https://dspace.example.net/xmlui/admin/panel?tab=Configuration") и ознакомившись с некоторыми параметрами конфигурации web-приложения.
Как правило для интеграции со сторонними информационными системами необходим "OAI-PMH Interface" - простейшим запросом "https://dspace.example.net/oai/request?verb=Identify" проверяем его доступность:
DSpace OAI-PMH Data Provider:
Repository Information:
Repository Name: Example DSpace Library
....
Repository Information:
Repository Name: Example DSpace Library
....
Налаживаем регулярное исполнение фоновых задач.
Некоторые задачи web-приложения "DSpace" должны исполнятся регулярно, по расписанию (ссылка на полный перечень рекомендаций) - например здесь мы настроим запуск процедуры обновления "карты сайта", выдаваемой в оптимизированном для поисковых машин XML-формате, а также оптимизацию "базы данных" полнотекстового поискового индекса "Apache Solr":
# crontab -u dspace -e
# Generate sitemaps at 6:00 am local time each day
0 6 * * * sudo -u dspace CLASSPATH=/opt/dspace/tomcat/lib/* /var/lib/dspace/bin/dspace generate-sitemaps &
# Discovery Solr Index Maintenance every 5 hours
0 */5 * * * sudo -u dspace CLASSPATH=/opt/dspace/tomcat/lib/* /var/lib/dspace/bin/dspace index-discovery -o &
....
0 6 * * * sudo -u dspace CLASSPATH=/opt/dspace/tomcat/lib/* /var/lib/dspace/bin/dspace generate-sitemaps &
# Discovery Solr Index Maintenance every 5 hours
0 */5 * * * sudo -u dspace CLASSPATH=/opt/dspace/tomcat/lib/* /var/lib/dspace/bin/dspace index-discovery -o &
....
Есть смысл один раз запустить первую процедуру вручную и проверить, обновилась ли "карта сайта":
XML Sitemaps: https://dspace.example.net/xmlui/sitemap
HTML Sitemaps: https://dspace.example.net/xmlui/htmlmap
HTML Sitemaps: https://dspace.example.net/xmlui/htmlmap
Нагрузочное тестирование.
После запуска web-сервиса возможно захочется протестировать, как скоро он сломается под возрастающей нагрузкой. Для этого можно воспользоваться утилиткой "Siege".
Тестируем "DSpace" в сценарии "250 пользователей 10 минут упорно ходят по сайту":
$ siege https://dspace.example.net/xmlui/ -c250 -t10m
Запускал в два-три потока, с разных компьютеров одновременно - через пару минут после начала "DSpace" почти перестал отзываться, потери составляли до 10%, но сервис в целом при этом не ломался и сразу после снятия нагрузки начинал работать нормально.