From 166ef63d1b00f4fe513116b0e57c95fc1db9e402 Mon Sep 17 00:00:00 2001 From: Sebastian Hofmann <7668803+sebhofmann@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:39:18 +0200 Subject: [PATCH] MIR-1320 MIR support for Solr authentication and Solr cloud (#1012) * mir support for solr authentication and solr cloud * add tika server to wizard * allow admin and indexer to search and admin to index --------- Co-authored-by: Thomas Scheffler --- .env | 9 ++ .gitmodules | 4 - README.md | 14 ++- docker-compose.yml | 21 ++++ docker-entrypoint.sh | 59 ++++++++++ mir-cli/src/main/config/setup-solrcloud.txt | 4 + mir-it/pom.xml | 12 ++ mir-it/src/test/integration/mycore.properties | 12 ++ .../org/mycore/mir/it/tests/MIRITBase.java | 1 + mir-webapp/src/main/solr | 1 - mir-webapp/src/main/solr/Dockerfile | 7 ++ mir-webapp/src/main/solr/docker-entrypoint.sh | 108 ++++++++++++++++++ mir-webapp/src/main/solr/security.json | 42 +++++++ mir-webapp/src/main/solr/solr.xml | 60 ++++++++++ mir-webapp/src/main/solr/zoo.cfg | 33 ++++++ .../mir/wizard/command/MIRWizardSolr.java | 23 +++- .../META-INF/resources/wizard/index.xed | 36 ++++++ .../META-INF/resources/wizard/js/wizard.js | 64 ++++++++++- .../config/mir-wizard/messages_de.properties | 13 +++ .../config/mir-wizard/messages_en.properties | 13 +++ pom.xml | 4 +- 21 files changed, 528 insertions(+), 12 deletions(-) delete mode 100644 .gitmodules create mode 100644 mir-cli/src/main/config/setup-solrcloud.txt delete mode 160000 mir-webapp/src/main/solr create mode 100644 mir-webapp/src/main/solr/Dockerfile create mode 100644 mir-webapp/src/main/solr/docker-entrypoint.sh create mode 100644 mir-webapp/src/main/solr/security.json create mode 100644 mir-webapp/src/main/solr/solr.xml create mode 100644 mir-webapp/src/main/solr/zoo.cfg diff --git a/.env b/.env index b69e5b734c..4379f0f752 100644 --- a/.env +++ b/.env @@ -17,3 +17,12 @@ MIR_XMS=1024m SOLR_HTTP=8290 SOLR_DATA=./docker/solr-data/ +SOLR_ADMIN_USER=admin +SOLR_ADMIN_PASSWORD=alleswirdgut +SOLR_SEARCH_USER=searcher +SOLR_SEARCH_PASSWORD=Alleswirdgut!? +SOLR_INDEX_USER=indexer +SOLR_INDEX_PASSWORD=Alleswirdgut!? + + +TIKA_PORT=8294 diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 1e396c1ece..0000000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "mir-solr"] - path = mir-webapp/src/main/solr - url = ../mir-solr.git - branch = main diff --git a/README.md b/README.md index 930b799eba..addee60d12 100644 --- a/README.md +++ b/README.md @@ -20,10 +20,12 @@ This guide addresses developers. Thats why you run it in 'dev' profile! ``` - - initialize solr configuration using `git submodule update --init --recursive` - to start solr, go to mir-webapp - install solr with the command: `mvn -Pdev solr-runner:copyHome` - run solr with the command: `mvn -Pdev solr-runner:start` + - The default users are `admin`, `indexer` and `searcher` with password `alleswirdgut` + - In the wizard of the application you need to check `Erstelle SOLR-Kerne per Solr-Cloud rest-API` and the configure + user options with the above-mentioned users and passwords. - stop solr with the command: `mvn -Pdev solr-runner:stop` - update solr with the command: `mvn -Pdev solr-runner:stop solr-runner:copyHome solr-runner:start` - to starting up a servlet container in development environment go back to mir folder @@ -48,6 +50,14 @@ The docker container has its own install script which uses the environment varia ### Environment Variables | Property | Default, required | Description | |--------------------------|---------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| ENABLE_SOLR_CLOUD | false | If true the Solr Cloud mode is enabled. (solr cores will be created on install) | +| SOLR_ADMIN_USER | none | The username for the Solr Admin. (will be used for admin commands like creating cores) | +| SOLR_ADMIN_PASSWORD | none | The password for the Solr Admin. | +| SOLR_INDEX_USER | none | The username for the Solr Indexer. (will be used for indexing) | +| SOLR_INDEX_PASSWORD | none | The password for the Solr Indexer. | +| SOLR_SEARCH_USER | none | The username for the Solr Searcher. (will be used for searching) | +| SOLR_SEARCH_PASSWORD | none | The password for the Solr Searcher. | +| TIKASERVER_URL | none | The URL to the Tika Server. Same as MCR.Solr.Tika.ServerURL in mycore.properties. (also sets `MCR.Solr.FileIndexStrategy` to `org.mycore.solr.index.file.tika.MCRTikaSolrFileStrategy`) | | SOLR_URL | none, required | The URL to the SOLR Server. Same as MCR.Solr.ServerURL in mycore.properties. | | SOLR_CORE | mir | The name of the Solr main core. Same as MCR.Solr.Core.main.Name in mycore.properties. | | SOLR_CLASSIFICATION_CORE | mir-classifications | The name of the Solr classification core. Same as MCR.Solr.Core.classification.Name in mycore.properties. | @@ -74,7 +84,7 @@ To fix this you can set the docker property `FIX_FILE_SYSTEM_RIGHTS` to `true`. mounted volumes to `mcr` and the container will start without errors. ## `mir-solr` Docker-Container -The docker container creates the required solr cores if they do not exist. +The docker container starts solr in cloud mode. It preconfigures the users with the environment variables (see table above). ### Mount Points diff --git a/docker-compose.yml b/docker-compose.yml index ac44a6a081..9417f4a1e2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,6 +21,19 @@ services: - ${SOLR_DATA}:/var/solr/data ports: - ${SOLR_HTTP}:8983 + environment: + - SOLR_ADMIN_USER=${SOLR_ADMIN_USER} + - SOLR_ADMIN_PASSWORD=${SOLR_ADMIN_PASSWORD} + - SOLR_SEARCH_USER=${SOLR_SEARCH_USER} + - SOLR_SEARCH_PASSWORD=${SOLR_SEARCH_PASSWORD} + - SOLR_INDEX_USER=${SOLR_INDEX_USER} + - SOLR_INDEX_PASSWORD=${SOLR_INDEX_PASSWORD} + tika: + container_name: ${NAME}-tika + image: apache/tika:2.9.2.1-full + restart: unless-stopped + ports: + - ${TIKA_PORT}:9998 mir: container_name: ${NAME}-mir build: ./ @@ -34,6 +47,14 @@ services: - SOLR_URL=http://solr:8983 - SOLR_CORE=mir - SOLR_CLASSIFICATION_CORE=mir-classifications + - ENABLE_SOLR_CLOUD=true + - SOLR_ADMIN_USER=${SOLR_ADMIN_USER} + - SOLR_ADMIN_PASSWORD=${SOLR_ADMIN_PASSWORD} + - SOLR_SEARCH_USER=${SOLR_SEARCH_USER} + - SOLR_SEARCH_PASSWORD=${SOLR_SEARCH_PASSWORD} + - SOLR_INDEX_USER=${SOLR_INDEX_USER} + - SOLR_INDEX_PASSWORD=${SOLR_INDEX_PASSWORD} + - TIKASERVER_URL=http://tika:9998/ - XMX=${MIR_XMX} - XMS=${MIR_XMS} - MIR_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8295 diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index a458fd46bf..366df57897 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -72,6 +72,15 @@ function setOrAddProperty() { KEY=$1 VALUE=$2 + if [ -z "$VALUE" ]; then + # remove property + sed -ri "/$KEY/d" "${MYCORE_PROPERTIES}" + return + elif [ -z "$KEY" ]; then + echo "No Key given. Skip setting property." + return + fi + if grep -q "$KEY=" "${MYCORE_PROPERTIES}" ; then ESCAPED_KEY=$(echo "${KEY}" | sed 's/\//\\\//g') ESCAPED_VALUE=$(echo "${VALUE}" | sed 's/\//\\\//g') @@ -116,6 +125,45 @@ function setDockerValues() { setOrAddProperty "MCR.JPA.DefaultSchema" "${HIBERNATE_SCHEMA}" fi + if [ -n "${SOLR_ADMIN_USER}" ]; then + setOrAddProperty "MCR.Solr.Server.Auth.Admin.Class" "org.mycore.solr.auth.MCRSolrBasicPropertyAuthentication" + setOrAddProperty "MCR.Solr.Server.Auth.Admin.Username" "${SOLR_ADMIN_USER}" + setOrAddProperty "MCR.Solr.Server.Auth.Admin.Password" "${SOLR_ADMIN_PASSWORD}" + else + setOrAddProperty "MCR.Solr.Server.Auth.Admin.Class" + setOrAddProperty "MCR.Solr.Server.Auth.Admin.Username" + setOrAddProperty "MCR.Solr.Server.Auth.Admin.Password" + fi + + + if [ -n "${SOLR_INDEX_USER}" ]; then + setOrAddProperty "MCR.Solr.Server.Auth.Index.Class" "org.mycore.solr.auth.MCRSolrBasicPropertyAuthentication" + setOrAddProperty "MCR.Solr.Server.Auth.Index.Username" "${SOLR_INDEX_USER}" + setOrAddProperty "MCR.Solr.Server.Auth.Index.Password" "${SOLR_INDEX_PASSWORD}" + else + setOrAddProperty "MCR.Solr.Server.Auth.Index.Class" + setOrAddProperty "MCR.Solr.Server.Auth.Index.Username" + setOrAddProperty "MCR.Solr.Server.Auth.Index.Password" + fi + + if [ -n "${SOLR_SEARCH_USER}" ]; then + setOrAddProperty "MCR.Solr.Server.Auth.Search.Class" "org.mycore.solr.auth.MCRSolrBasicPropertyAuthentication" + setOrAddProperty "MCR.Solr.Server.Auth.Search.Username" "${SOLR_SEARCH_USER}" + setOrAddProperty "MCR.Solr.Server.Auth.Search.Password" "${SOLR_SEARCH_PASSWORD}" + else + setOrAddProperty "MCR.Solr.Server.Auth.Search.Class" + setOrAddProperty "MCR.Solr.Server.Auth.Search.Username" + setOrAddProperty "MCR.Solr.Server.Auth.Search.Password" + fi + + if [ -n "${TIKASERVER_URL}" ]; then + setOrAddProperty "MCR.Solr.Tika.ServerURL" "${TIKASERVER_URL}" + setOrAddProperty "MCR.Solr.FileIndexStrategy" "org.mycore.solr.index.file.tika.MCRTikaSolrFileStrategy" + else + setOrAddProperty "MCR.Solr.Tika.ServerURL" + setOrAddProperty "MCR.Solr.FileIndexStrategy" + fi + setOrAddProperty "MCR.JPA.Hbm2ddlAuto" "update" setOrAddProperty "MCR.JPA.PersistenceUnit.mir.Class" "org.mycore.backend.jpa.MCRSimpleConfigPersistenceUnitDescriptor" setOrAddProperty "MCR.JPA.PersistenceUnitName" "mir" @@ -164,6 +212,17 @@ function setUpMyCoRe { /opt/mir/mir/bin/mir.sh create configuration directory setDockerValues setupLog4jConfig + + # ENABLE_SOLR_CLOUD + if [[ "$ENABLE_SOLR_CLOUD" == "true" ]] + then + echo "upload local config set for main" >> "${MCR_CONFIG_DIR}setup-solr-cloud.txt" + echo "upload local config set for classification" >> "${MCR_CONFIG_DIR}setup-solr-cloud.txt" + echo "create collection for core main" >> "${MCR_CONFIG_DIR}setup-solr-cloud.txt" + echo "create collection for core classification" >> "${MCR_CONFIG_DIR}setup-solr-cloud.txt" + /opt/mir/mir/bin/mir.sh process /mcr/home/setup-solr-cloud.txt + fi + /opt/mir/mir/bin/setup.sh } diff --git a/mir-cli/src/main/config/setup-solrcloud.txt b/mir-cli/src/main/config/setup-solrcloud.txt new file mode 100644 index 0000000000..49f1517221 --- /dev/null +++ b/mir-cli/src/main/config/setup-solrcloud.txt @@ -0,0 +1,4 @@ +upload local config set for main +upload local config set for classification +create collection for core main +create collection for core classification \ No newline at end of file diff --git a/mir-it/pom.xml b/mir-it/pom.xml index a081200b35..1bb791468c 100644 --- a/mir-it/pom.xml +++ b/mir-it/pom.xml @@ -163,6 +163,18 @@ + + setup-solr-cloud + + exec + + pre-integration-test + + ${project.build.directory}/dependency/mir-cli-${project.version} + bin${file.separator}mir.${script.suffix} + process ${project.build.directory}/dependency/mir-cli-${project.version}/config/setup-solrcloud.txt + + setup-cli diff --git a/mir-it/src/test/integration/mycore.properties b/mir-it/src/test/integration/mycore.properties index c34ab80ac6..a2f8d06a5c 100644 --- a/mir-it/src/test/integration/mycore.properties +++ b/mir-it/src/test/integration/mycore.properties @@ -1,2 +1,14 @@ MCR.Solr.ServerURL=http\://localhost\:${solr.port}/ MCR.Solr.DelayIndexing_inMS=200 + +MCR.Solr.Server.Auth.Admin.Class=org.mycore.solr.auth.MCRSolrBasicPropertyAuthentication +MCR.Solr.Server.Auth.Admin.Password=alleswirdgut +MCR.Solr.Server.Auth.Admin.Username=admin +MCR.Solr.Server.Auth.Index.Class=org.mycore.solr.auth.MCRSolrBasicPropertyAuthentication +MCR.Solr.Server.Auth.Index.Password=alleswirdgut +MCR.Solr.Server.Auth.Index.Username=indexer +MCR.Solr.Server.Auth.Search.Class=org.mycore.solr.auth.MCRSolrBasicPropertyAuthentication +MCR.Solr.Server.Auth.Search.Password=alleswirdgut +MCR.Solr.Server.Auth.Search.Username=searcher + + diff --git a/mir-it/src/test/java/org/mycore/mir/it/tests/MIRITBase.java b/mir-it/src/test/java/org/mycore/mir/it/tests/MIRITBase.java index 93d0701d57..17c9f4528c 100644 --- a/mir-it/src/test/java/org/mycore/mir/it/tests/MIRITBase.java +++ b/mir-it/src/test/java/org/mycore/mir/it/tests/MIRITBase.java @@ -68,6 +68,7 @@ protected SolrClient getSolrClient() { protected static LukeResponse getLukeResponse(Core core) throws IOException, SolrServerException { LukeRequest request = new LukeRequest(); + request.setBasicAuthCredentials("admin", "alleswirdgut"); request.setNumTerms(0); request.setShowSchema(false); final LukeResponse lukeResponse = request.process(SOLR_CLIENT, core.getCoreName()); diff --git a/mir-webapp/src/main/solr b/mir-webapp/src/main/solr deleted file mode 160000 index 1f1a298e15..0000000000 --- a/mir-webapp/src/main/solr +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1f1a298e1570b96e063796ca5e7bf234757bcdb4 diff --git a/mir-webapp/src/main/solr/Dockerfile b/mir-webapp/src/main/solr/Dockerfile new file mode 100644 index 0000000000..c904e77d16 --- /dev/null +++ b/mir-webapp/src/main/solr/Dockerfile @@ -0,0 +1,7 @@ +FROM solr:8.11 +USER root +RUN apt-get update && \ + apt-get -y install sudo +COPY --chown=root:root docker-entrypoint.sh ./ +RUN chmod 555 docker-entrypoint.sh +CMD ["bash", "docker-entrypoint.sh"] diff --git a/mir-webapp/src/main/solr/docker-entrypoint.sh b/mir-webapp/src/main/solr/docker-entrypoint.sh new file mode 100644 index 0000000000..bb34079164 --- /dev/null +++ b/mir-webapp/src/main/solr/docker-entrypoint.sh @@ -0,0 +1,108 @@ +#!/usr/bin/bash +# +# This file is part of *** M y C o R e *** +# See http://www.mycore.de/ for details. +# +# MyCoRe is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# MyCoRe is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with MyCoRe. If not, see . +# + +set -e +unset SOLR_USER SOLR_UID SOLR_GROUP SOLR_GID \ + SOLR_CLOSER_URL SOLR_DIST_URL SOLR_ARCHIVE_URL SOLR_DOWNLOAD_URL SOLR_DOWNLOAD_SERVER SOLR_KEYS SOLR_SHA512 + +function fixDirectoryRights() { + find "$1" \! -user "$2" -exec chown "$2:$2" '{}' + +} + +echo "Running solr entry script as user: $(whoami)" +if [ "$(id -u)" -eq 0 ]; then + fixDirectoryRights /var/solr/ solr + exec /usr/bin/sudo -E -u solr "PATH=$PATH" "$(pwd)/$0"; + exit 0; +fi + +function solrpass() { + printf "%s %s" "$(echo -n "$2$1"|openssl dgst -sha256 -binary|openssl dgst -sha256 -binary|openssl base64)" "$(echo -n "$2"|openssl base64)" +} + +secruity_json=/var/solr/data/security.json; + + +echo "{" > $secruity_json +echo " \"authentication\":{" >> $secruity_json +echo " \"blockUnknown\": true," >> $secruity_json +echo " \"class\":\"solr.BasicAuthPlugin\"," >> $secruity_json +echo " \"credentials\": {" >> $secruity_json + +if [ -n "$SOLR_SEARCH_USER" ]; then + echo " \"${SOLR_SEARCH_USER}\":\"$(solrpass $SOLR_SEARCH_PASSWORD $(openssl rand 10))\"," >> $secruity_json +fi + +if [ -n "$SOLR_INDEX_USER" ]; then + echo " \"${SOLR_INDEX_USER}\":\"$(solrpass $SOLR_INDEX_PASSWORD $(openssl rand 10))\"," >> $secruity_json +fi + +if [ -n "$SOLR_ADMIN_USER" ]; then + echo " \"${SOLR_ADMIN_USER}\":\"$(solrpass $SOLR_ADMIN_PASSWORD $(openssl rand 10))\"" >> $secruity_json +fi + +echo " }," >> $secruity_json +echo " \"realm\":\"My Solr users\"," >> $secruity_json +echo " \"forwardCredentials\": false" >> $secruity_json +echo " }," >> $secruity_json +echo " \"authorization\":{" >> $secruity_json +echo " \"class\":\"solr.RuleBasedAuthorizationPlugin\"," >> $secruity_json +echo " \"permissions\":[" >> $secruity_json + +if [ -n "$SOLR_SEARCH_USER" ]; then + echo " {" >> $secruity_json + echo " \"name\":\"read\"," >> $secruity_json + echo " \"role\":[\"searcher\",\"indexer\",\"admin\"]" >> $secruity_json + echo " }," >> $secruity_json +fi + +if [ -n "$SOLR_INDEX_USER" ]; then + echo " {" >> $secruity_json + echo " \"name\":\"update\"," >> $secruity_json + echo " \"role\":[\"indexer\",\"admin\"]" >> $secruity_json + echo " }," >> $secruity_json +fi + +if [ -n "$SOLR_ADMIN_USER" ]; then + echo " {" >> $secruity_json + echo " \"name\":\"all\"," >> $secruity_json + echo " \"role\":\"admin\"" >> $secruity_json + echo " }" >> $secruity_json +fi +echo "]," >> $secruity_json +echo " \"user-role\":{" >> $secruity_json + +if [ -n "$SOLR_SEARCH_USER" ]; then + echo " \"${SOLR_SEARCH_USER}\":\"searcher\"," >> $secruity_json +fi + +if [ -n "$SOLR_INDEX_USER" ]; then + echo " \"${SOLR_INDEX_USER}\":\"indexer\"," >> $secruity_json +fi + +if [ -n "$SOLR_ADMIN_USER" ]; then + echo " \"${SOLR_ADMIN_USER}\":\"admin\"" >> $secruity_json +fi + +echo " }" >> $secruity_json +echo " }" >> $secruity_json +echo "}" >> $secruity_json + +(/opt/docker-solr/scripts/wait-for-solr.sh;/opt/solr/bin/solr zk cp $secruity_json zk:security.json -z localhost:9983)& +/opt/docker-solr/scripts/solr-foreground -c; diff --git a/mir-webapp/src/main/solr/security.json b/mir-webapp/src/main/solr/security.json new file mode 100644 index 0000000000..315bb92e48 --- /dev/null +++ b/mir-webapp/src/main/solr/security.json @@ -0,0 +1,42 @@ +{ + "authentication": { + "blockUnknown": true, + "class": "solr.BasicAuthPlugin", + "credentials": { + "searcher": "0QWhQdOGUMTkjxqE0rPodHKa2gUEnRZnZ837YP/L4aw= 7A==", + "indexer": "0QWhQdOGUMTkjxqE0rPodHKa2gUEnRZnZ837YP/L4aw= 7A==", + "admin": "0QWhQdOGUMTkjxqE0rPodHKa2gUEnRZnZ837YP/L4aw= 7A==" + }, + "realm": "My Solr users", + "forwardCredentials": false + }, + "authorization": { + "class": "solr.RuleBasedAuthorizationPlugin", + "permissions": [ + { + "name": "read", + "role": [ + "searcher", + "indexer", + "admin" + ] + }, + { + "name": "update", + "role": [ + "indexer", + "admin" + ] + }, + { + "name": "all", + "role": "admin" + } + ], + "user-role": { + "searcher": "searcher", + "indexer": "indexer", + "admin": "admin" + } + } +} diff --git a/mir-webapp/src/main/solr/solr.xml b/mir-webapp/src/main/solr/solr.xml new file mode 100644 index 0000000000..7fefe0b115 --- /dev/null +++ b/mir-webapp/src/main/solr/solr.xml @@ -0,0 +1,60 @@ + + + + + + + + ${solr.max.booleanClauses:1024} + ${solr.sharedLib:} + ${solr.allowPaths:} + + + + ${host:} + ${solr.port.advertise:0} + ${hostContext:solr} + + ${genericCoreNodeNames:true} + + ${zkClientTimeout:30000} + ${distribUpdateSoTimeout:600000} + ${distribUpdateConnTimeout:60000} + ${zkCredentialsProvider:org.apache.solr.common.cloud.DefaultZkCredentialsProvider} + ${zkACLProvider:org.apache.solr.common.cloud.DefaultZkACLProvider} + + + + + ${socketTimeout:600000} + ${connTimeout:60000} + ${solr.shardsWhitelist:} + + + + + diff --git a/mir-webapp/src/main/solr/zoo.cfg b/mir-webapp/src/main/solr/zoo.cfg new file mode 100644 index 0000000000..2c26cae616 --- /dev/null +++ b/mir-webapp/src/main/solr/zoo.cfg @@ -0,0 +1,33 @@ +# The number of milliseconds of each tick +tickTime=2000 +# The number of ticks that the initial +# synchronization phase can take +initLimit=10 +# The number of ticks that can pass between +# sending a request and getting an acknowledgement +syncLimit=5 + +# the directory where the snapshot is stored. +# dataDir=/opt/zookeeper/data +# NOTE: Solr defaults the dataDir to /zoo_data + +# the port at which the clients will connect +# clientPort=2181 +# NOTE: Solr sets this based on zkRun / zkHost params + +# the maximum number of client connections. +# increase this if you need to handle more clients +#maxClientCnxns=60 +# +# Be sure to read the maintenance section of the +# administrator guide before turning on autopurge. +# +# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance +# +# The number of snapshots to retain in dataDir +#autopurge.snapRetainCount=3 +# Purge task interval in hours +# Set to "0" to disable auto purge feature +#autopurge.purgeInterval=1 + +# Disable ZK AdminServer since we do not use it diff --git a/mir-wizard/src/main/java/org/mycore/mir/wizard/command/MIRWizardSolr.java b/mir-wizard/src/main/java/org/mycore/mir/wizard/command/MIRWizardSolr.java index 87b6c8f3b7..428cf8eaa9 100644 --- a/mir-wizard/src/main/java/org/mycore/mir/wizard/command/MIRWizardSolr.java +++ b/mir-wizard/src/main/java/org/mycore/mir/wizard/command/MIRWizardSolr.java @@ -22,10 +22,14 @@ */ package org.mycore.mir.wizard.command; +import java.util.Optional; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.jdom2.Element; import org.mycore.mir.wizard.MIRWizardCommand; -import org.mycore.solr.commands.MCRSolrCommands; +import org.mycore.solr.commands.MCRSolrCloudCommands; +import org.mycore.solr.commands.MCRSolrCoreAdminCommands; /** * @author René Adler (eagle) @@ -57,8 +61,21 @@ private MIRWizardSolr(final String name) { @Override public void doExecute() { try { - MCRSolrCommands.reloadSolrConfiguration(DEFAULT_CORE, DEFAULT_CORE); - MCRSolrCommands.reloadSolrConfiguration(DEFAULT_CLASSIFICATION, DEFAULT_CLASSIFICATION); + Optional createCores = Optional.ofNullable(getInputXML()) + .map(input -> input.getChild("solr")) + .map(input -> input.getChild("createCores")) + .filter(input -> input.getTextTrim().equals("true")); + + if (createCores.isPresent()) { + MCRSolrCloudCommands.uploadLocalConfig(DEFAULT_CORE); + MCRSolrCloudCommands.uploadLocalConfig(DEFAULT_CLASSIFICATION); + + MCRSolrCloudCommands.createCollection(DEFAULT_CORE); + MCRSolrCloudCommands.createCollection(DEFAULT_CLASSIFICATION); + } + + MCRSolrCoreAdminCommands.reloadSolrConfiguration(DEFAULT_CORE, DEFAULT_CORE); + MCRSolrCoreAdminCommands.reloadSolrConfiguration(DEFAULT_CLASSIFICATION, DEFAULT_CLASSIFICATION); this.result.setSuccess(true); } catch (final Exception ex) { diff --git a/mir-wizard/src/main/resources/META-INF/resources/wizard/index.xed b/mir-wizard/src/main/resources/META-INF/resources/wizard/index.xed index 4a9ecb8a71..f3aa781ead 100644 --- a/mir-wizard/src/main/resources/META-INF/resources/wizard/index.xed +++ b/mir-wizard/src/main/resources/META-INF/resources/wizard/index.xed @@ -52,6 +52,42 @@ i18n="component.mir.wizard.solr.mainCore" /> + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/mir-wizard/src/main/resources/META-INF/resources/wizard/js/wizard.js b/mir-wizard/src/main/resources/META-INF/resources/wizard/js/wizard.js index 785ecd6881..8914ae8128 100644 --- a/mir-wizard/src/main/resources/META-INF/resources/wizard/js/wizard.js +++ b/mir-wizard/src/main/resources/META-INF/resources/wizard/js/wizard.js @@ -81,4 +81,66 @@ jQuery(document).ready(function() { * Description: Initialize all Bootstrap Tooltips. */ $('*[data-toggle="tooltip"]').tooltip(); -}); \ No newline at end of file + + const formGroupSelector = '.form-group.row'; + + /** + * Set the visibility of the closest form group of the given element ID. + * @param {string} containedElementID + * @param {boolean} visible + * @returns {void} + */ + const setFormGroupVisible = (containedElementID, visible) => { + document.querySelector(`#${containedElementID}`) + .closest(formGroupSelector).style.display = visible ? '' : 'none'; + }; + + const adminAuthCheckbox = document.getElementById('adminUserEnabled'); + const indexAuthCheckbox = document.getElementById('indexUserEnabled'); + const searchAuthCheckbox = document.getElementById('searchUserEnabled'); + const tikaServerCheckbox = document.getElementById('tikaServer'); + + const updateAdminAuthForms = () => { + setFormGroupVisible('solrAdminUsername', adminAuthCheckbox.checked); + setFormGroupVisible('solrAdminPassword', adminAuthCheckbox.checked); + } + + adminAuthCheckbox.addEventListener('change', () => { + updateAdminAuthForms(); + }); + + updateAdminAuthForms(); + + const updateIndexAuthForms = () => { + setFormGroupVisible('solrIndexUsername', indexAuthCheckbox.checked); + setFormGroupVisible('solrIndexPassword', indexAuthCheckbox.checked); + } + + indexAuthCheckbox.addEventListener('change', () => { + updateIndexAuthForms(); + }); + + updateIndexAuthForms(); + + const updateSearchAuthForms = () => { + setFormGroupVisible('solrSearchUsername', searchAuthCheckbox.checked); + setFormGroupVisible('solrSearchPassword', searchAuthCheckbox.checked); + } + + searchAuthCheckbox.addEventListener('change', () => { + updateSearchAuthForms(); + }); + + updateSearchAuthForms(); + + const updateTikaServerForms = () => { + setFormGroupVisible('tikaServerURL', tikaServerCheckbox.checked); + } + + tikaServerCheckbox.addEventListener('change', () => { + updateTikaServerForms(); + }); + + updateTikaServerForms(); + +}); diff --git a/mir-wizard/src/main/resources/config/mir-wizard/messages_de.properties b/mir-wizard/src/main/resources/config/mir-wizard/messages_de.properties index de86e267bd..d96fe35ced 100644 --- a/mir-wizard/src/main/resources/config/mir-wizard/messages_de.properties +++ b/mir-wizard/src/main/resources/config/mir-wizard/messages_de.properties @@ -42,6 +42,19 @@ component.mir.wizard.smtp.title = SMTP-Einstellungen component.mir.wizard.smtp.user = Benutzername component.mir.wizard.solr.classificationCore = Klassifikationen Kern component.mir.wizard.solr.mainCore = Anwendungs Kern +component.mir.wizard.solr.createCores = Erstelle Solr-Kerne per SolrCloud REST-API +component.mir.wizard.solr.adminUserEnabled = Konfiguriere einen Benutzer f\u00FCr die Solr-Administration +component.mir.wizard.solr.admin.username = Benutzername +component.mir.wizard.solr.admin.password = Passwort +component.mir.wizard.solr.indexUserEnabled = Konfiguriere einen Benutzer f\u00FCr die Solr-Indexierung +component.mir.wizard.solr.index.username = Benutzername +component.mir.wizard.solr.index.password = Passwort +component.mir.wizard.solr.searchUserEnabled = Konfiguriere einen Benutzer f\u00FCr die Solr-Suche +component.mir.wizard.solr.search.username = Benutzername +component.mir.wizard.solr.search.password = Passwort +component.mir.wizard.solr.useTika = Verwende einen externen Tika-Server f\u00FCr die Volltext-Extraktion +component.mir.wizard.solr.tikaUrl = Tika-Server URL + component.mir.wizard.solr.title = SOLR-Server component.mir.wizard.solr.url = URL component.mir.wizard.solr.url.required = Bitte tragen Sie eine g\u00FCltiger SOLR-Server-URL ein! diff --git a/mir-wizard/src/main/resources/config/mir-wizard/messages_en.properties b/mir-wizard/src/main/resources/config/mir-wizard/messages_en.properties index a63289889c..3cc127d5da 100644 --- a/mir-wizard/src/main/resources/config/mir-wizard/messages_en.properties +++ b/mir-wizard/src/main/resources/config/mir-wizard/messages_en.properties @@ -42,6 +42,19 @@ component.mir.wizard.smtp.title = SMTP settings component.mir.wizard.smtp.user = Username component.mir.wizard.solr.classificationCore = Classification Core component.mir.wizard.solr.mainCore = Main Core +component.mir.wizard.solr.createCores = Create cores in SOLR server via SolrCloud API +component.mir.wizard.solr.adminUserEnabled = Configure a user for Solr administration +component.mir.wizard.solr.admin.username = Username +component.mir.wizard.solr.admin.password = Password +component.mir.wizard.solr.indexUserEnabled = Configure a user for indexing in Solr +component.mir.wizard.solr.index.username = Username +component.mir.wizard.solr.index.password = Password +component.mir.wizard.solr.searchUserEnabled = Configure a user for searching in Solr +component.mir.wizard.solr.search.username = Username +component.mir.wizard.solr.search.password = Password +component.mir.wizard.solr.useTika = Use an external Tika server for full-text extraction +component.mir.wizard.solr.tikaUrl = Tika server URL + component.mir.wizard.solr.title = SOLR Server component.mir.wizard.solr.url = URL component.mir.wizard.solr.url.required = Please input a valid SOLR Server URL! diff --git a/pom.xml b/pom.xml index 9ca18a5ef4..73b23f3db8 100644 --- a/pom.xml +++ b/pom.xml @@ -65,10 +65,12 @@ org.mycore.plugins solr-runner-maven-plugin - 1.3 + 1.4-SNAPSHOT ${solr-runner.solrMirrorURL} ${solr-runner.solrVersionString} + true + true