mirror of
https://github.com/apache/lucene.git
synced 2025-02-10 20:15:18 +00:00
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/lucene-solr
This commit is contained in:
commit
896270d132
@ -93,7 +93,6 @@ Other
|
||||
(Daniel Jelinski via Adrien Grand)
|
||||
|
||||
======================= Lucene 6.7.0 =======================
|
||||
(No Changes)
|
||||
|
||||
======================= Lucene 6.6.0 =======================
|
||||
|
||||
@ -134,6 +133,11 @@ Bug Fixes
|
||||
* LUCENE-7824: Fix graph query analysis for multi-word synonym rules with common terms (eg. new york, new york city).
|
||||
(Jim Ferenczi)
|
||||
|
||||
* LUCENE-7817: Pass cached query to onQueryCache instead of null.
|
||||
(Christoph Kaser via Adrien Grand)
|
||||
|
||||
* LUCENE-7831: CodecUtil should not seek to negative offsets. (Adrien Grand)
|
||||
|
||||
Improvements
|
||||
|
||||
* LUCENE-7782: OfflineSorter now passes the total number of items it
|
||||
|
@ -331,6 +331,9 @@ public final class CodecUtil {
|
||||
/** Retrieves the full footer from the provided {@link IndexInput}. This throws
|
||||
* {@link CorruptIndexException} if this file does not have a valid footer. */
|
||||
public static byte[] readFooter(IndexInput in) throws IOException {
|
||||
if (in.length() < footerLength()) {
|
||||
throw new CorruptIndexException("misplaced codec footer (file truncated?): length=" + in.length() + " but footerLength==" + footerLength(), in);
|
||||
}
|
||||
in.seek(in.length() - footerLength());
|
||||
validateFooter(in);
|
||||
in.seek(in.length() - footerLength());
|
||||
@ -516,6 +519,9 @@ public final class CodecUtil {
|
||||
clone.seek(0);
|
||||
ChecksumIndexInput in = new BufferedChecksumIndexInput(clone);
|
||||
assert in.getFilePointer() == 0;
|
||||
if (in.length() < footerLength()) {
|
||||
throw new CorruptIndexException("misplaced codec footer (file truncated?): length=" + in.length() + " but footerLength==" + footerLength(), input);
|
||||
}
|
||||
in.seek(in.length() - footerLength());
|
||||
return checkFooter(in);
|
||||
}
|
||||
|
@ -303,4 +303,17 @@ public class TestCodecUtil extends LuceneTestCase {
|
||||
fakeChecksum.set((1L << 32) - 1); // ok
|
||||
CodecUtil.writeCRC(fakeOutput);
|
||||
}
|
||||
|
||||
public void testTruncatedFileThrowsCorruptIndexException() throws IOException {
|
||||
RAMFile file = new RAMFile();
|
||||
IndexOutput output = new RAMOutputStream(file, false);
|
||||
output.close();
|
||||
IndexInput input = new RAMInputStream("file", file);
|
||||
CorruptIndexException e = expectThrows(CorruptIndexException.class,
|
||||
() -> CodecUtil.checksumEntireFile(input));
|
||||
assertEquals("misplaced codec footer (file truncated?): length=0 but footerLength==16 (resource=RAMInputStream(name=file))", e.getMessage());
|
||||
e = expectThrows(CorruptIndexException.class,
|
||||
() -> CodecUtil.retrieveChecksum(input));
|
||||
assertEquals("misplaced codec footer (file truncated?): length=0 but footerLength==16 (resource=RAMInputStream(name=file))", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
@ -70,6 +70,9 @@ Upgrading from Solr 6.x
|
||||
query text will not be split on whitespace before analysis. See
|
||||
https://lucidworks.com/2017/04/18/multi-word-synonyms-solr-adds-query-time-support/ .
|
||||
|
||||
* Setting <solrQueryParser defaultOperator="..."/> in schema is no longer allowed and will cause an exception.
|
||||
Please use "q.op" parameter on the request instead. For more details, see SOLR-10584.
|
||||
|
||||
New Features
|
||||
----------------------
|
||||
* SOLR-9857, SOLR-9858: Collect aggregated metrics from nodes and shard leaders in overseer. (ab)
|
||||
@ -102,7 +105,7 @@ Bug Fixes
|
||||
|
||||
* SOLR-10408: v2 API introspect should return useful message for non-existent command (Cao Manh Dat)
|
||||
|
||||
* SOLR-10411: v2 Collection API "modify" command specification's replicationFactor property is incorrectly typed as string,
|
||||
* SOLR-10411: v2 Collection API "modify" command specification's replicationFactor property is incorrectly typed as string,
|
||||
should be integer (Cao Manh Dat)
|
||||
|
||||
* SOLR-10405: v2 API introspect response contains multiple copies of the experimental format WARNING (Cao Manh Dat)
|
||||
@ -128,6 +131,7 @@ Optimizations
|
||||
(yonik)
|
||||
|
||||
Other Changes
|
||||
----------------------
|
||||
* SOLR-10236: Removed FieldType.getNumericType(). Use getNumberType() instead. (Tomás Fernández Löbbe)
|
||||
|
||||
* SOLR-10347: Removed index level boost support from "documents" section of the admin UI (Amrit Sarkar via
|
||||
@ -148,6 +152,11 @@ Other Changes
|
||||
|
||||
* SOLR-10647: Move the V1 <-> V2 API mapping to SolrJ (noble)
|
||||
|
||||
* SOLR-10584: We'll now always throw an exception if defaultOperator is found in schema. This config has
|
||||
been deprecated since 3.6, and enforced for new configs since 6.6 (janhoy)
|
||||
|
||||
* SOLR-10414: RecoveryStrategy is now a Runnable instead of a Thread. (Tomás Fernández Löbbe)
|
||||
|
||||
================== 6.7.0 ==================
|
||||
|
||||
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.
|
||||
@ -164,13 +173,18 @@ Jetty 9.3.14.v20161028
|
||||
Detailed Change List
|
||||
----------------------
|
||||
|
||||
New Features
|
||||
----------------------
|
||||
|
||||
* SOLR-10307: Allow Passing SSL passwords through environment variables. (Mano Kovacs via Mark Miller)
|
||||
|
||||
Other Changes
|
||||
----------------------
|
||||
|
||||
* SOLR-10617: JDBCStream accepts columns of type TIME, DATE & TIMESTAMP as well as CLOBs and decimal
|
||||
numeric types (James Dyer)
|
||||
|
||||
* SOLR-10400: Replace (instanceof TrieFooField || instanceof FooPointField) constructs with
|
||||
|
||||
* SOLR-10400: Replace (instanceof TrieFooField || instanceof FooPointField) constructs with
|
||||
FieldType.getNumberType() or SchemaField.getSortField() where appropriate. (hossman, Steve Rowe)
|
||||
|
||||
================== 6.6.0 ==================
|
||||
@ -361,9 +375,9 @@ Bug Fixes
|
||||
|
||||
* SOLR-10549: The new 'large' attribute had been forgotten in /schema/fieldtypes?showDefaults=true (David Smiley)
|
||||
|
||||
* SOLR-10615: requests are suspended until SolrDispatchFilter initialization is completed.
|
||||
After core container shutdown or severe initialization problem Solr responds with
|
||||
http stauts 404 Not Found instead of 500 as it was before (Mikhail Khludnev)
|
||||
* SOLR-10615: requests are suspended until SolrDispatchFilter initialization is completed.
|
||||
After core container shutdown or severe initialization problem Solr responds with
|
||||
http stauts 404 Not Found instead of 500 as it was before (Mikhail Khludnev)
|
||||
|
||||
* SOLR-8149: Admin UI - Plugins / Stats - active item is now highlighted (Labuzov Dmitriy via janhoy)
|
||||
|
||||
@ -438,9 +452,9 @@ Other Changes
|
||||
|
||||
* SOLR-10601: StreamExpressionParser should handle white space around = in named parameters (Joel Bernstein)
|
||||
|
||||
* SOLR-10614: Static fields have turned to instance's field in SimplePostTool.
|
||||
* SOLR-10614: Static fields have turned to instance's field in SimplePostTool.
|
||||
Enabled TestSolrCLIRunExample.testTechproductsExample(). (Andrey Kudryavtsev, Mikhail Khludnev)
|
||||
|
||||
|
||||
* SOLR-10522: Revert SpellCheckComponent response format change from SOLR-9972 (rel. 6.5.0). While this
|
||||
was an improvement for the json "arrntv" format, it caused problems for the default json format.
|
||||
(James Dyer, reported by Nikita Pchelintsev)
|
||||
|
@ -251,9 +251,9 @@ solr_uid="`id -u "$SOLR_USER"`"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Creating new user: $SOLR_USER"
|
||||
if [ "$distro" == "RedHat" ] || [ "$distro" == "CentOS" ] ; then
|
||||
adduser "$SOLR_USER"
|
||||
adduser --system -U -m --home-dir "$SOLR_VAR_DIR" "$SOLR_USER"
|
||||
elif [ "$distro" == "SUSE" ]; then
|
||||
useradd -m "$SOLR_USER"
|
||||
useradd --system -U -m --home-dir "$SOLR_VAR_DIR" "$SOLR_USER"
|
||||
else
|
||||
adduser --system --shell /bin/bash --group --disabled-password --home "$SOLR_VAR_DIR" "$SOLR_USER"
|
||||
fi
|
||||
@ -331,8 +331,8 @@ SOLR_LOGS_DIR=\"$SOLR_VAR_DIR/logs\"
|
||||
SOLR_PORT=\"$SOLR_PORT\"
|
||||
" >> "/etc/default/$SOLR_SERVICE.in.sh"
|
||||
fi
|
||||
chown ${SOLR_USER}: "/etc/default/$SOLR_SERVICE.in.sh"
|
||||
chmod 0660 "/etc/default/$SOLR_SERVICE.in.sh"
|
||||
chown root:${SOLR_USER} "/etc/default/$SOLR_SERVICE.in.sh"
|
||||
chmod 0640 "/etc/default/$SOLR_SERVICE.in.sh"
|
||||
|
||||
# install data directories and files
|
||||
mkdir -p "$SOLR_VAR_DIR/data"
|
||||
|
198
solr/bin/solr
198
solr/bin/solr
@ -163,13 +163,20 @@ fi
|
||||
SOLR_URL_SCHEME=http
|
||||
SOLR_JETTY_CONFIG=()
|
||||
SOLR_SSL_OPTS=""
|
||||
if [ -n "$SOLR_SSL_KEY_STORE" ]; then
|
||||
if [ -z "$SOLR_SSL_ENABLED" ]; then
|
||||
if [ -n "$SOLR_SSL_KEY_STORE" ]; then
|
||||
SOLR_SSL_ENABLED="true" # implicitly from earlier behaviour
|
||||
else
|
||||
SOLR_SSL_ENABLED="false"
|
||||
fi
|
||||
fi
|
||||
if [ "$SOLR_SSL_ENABLED" == "true" ]; then
|
||||
SOLR_JETTY_CONFIG+=("--module=https")
|
||||
SOLR_URL_SCHEME=https
|
||||
SOLR_SSL_OPTS+=" -Dsolr.jetty.keystore=$SOLR_SSL_KEY_STORE"
|
||||
if [ -n "$SOLR_SSL_KEY_STORE_PASSWORD" ]; then
|
||||
SOLR_SSL_OPTS+=" -Dsolr.jetty.keystore.password=$SOLR_SSL_KEY_STORE_PASSWORD"
|
||||
if [ -n "$SOLR_SSL_KEY_STORE" ]; then
|
||||
SOLR_SSL_OPTS+=" -Dsolr.jetty.keystore=$SOLR_SSL_KEY_STORE"
|
||||
fi
|
||||
|
||||
if [ -n "$SOLR_SSL_KEY_STORE_TYPE" ]; then
|
||||
SOLR_SSL_OPTS+=" -Dsolr.jetty.keystore.type=$SOLR_SSL_KEY_STORE_TYPE"
|
||||
fi
|
||||
@ -177,9 +184,6 @@ if [ -n "$SOLR_SSL_KEY_STORE" ]; then
|
||||
if [ -n "$SOLR_SSL_TRUST_STORE" ]; then
|
||||
SOLR_SSL_OPTS+=" -Dsolr.jetty.truststore=$SOLR_SSL_TRUST_STORE"
|
||||
fi
|
||||
if [ -n "$SOLR_SSL_TRUST_STORE_PASSWORD" ]; then
|
||||
SOLR_SSL_OPTS+=" -Dsolr.jetty.truststore.password=$SOLR_SSL_TRUST_STORE_PASSWORD"
|
||||
fi
|
||||
if [ -n "$SOLR_SSL_TRUST_STORE_TYPE" ]; then
|
||||
SOLR_SSL_OPTS+=" -Dsolr.jetty.truststore.type=$SOLR_SSL_TRUST_STORE_TYPE"
|
||||
fi
|
||||
@ -194,9 +198,6 @@ if [ -n "$SOLR_SSL_KEY_STORE" ]; then
|
||||
if [ -n "$SOLR_SSL_CLIENT_KEY_STORE" ]; then
|
||||
SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStore=$SOLR_SSL_CLIENT_KEY_STORE"
|
||||
|
||||
if [ -n "$SOLR_SSL_CLIENT_KEY_STORE_PASSWORD" ]; then
|
||||
SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStorePassword=$SOLR_SSL_CLIENT_KEY_STORE_PASSWORD"
|
||||
fi
|
||||
if [ -n "$SOLR_SSL_CLIENT_KEY_STORE_TYPE" ]; then
|
||||
SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStoreType=$SOLR_SSL_CLIENT_KEY_STORE_TYPE"
|
||||
fi
|
||||
@ -204,9 +205,6 @@ if [ -n "$SOLR_SSL_KEY_STORE" ]; then
|
||||
if [ -n "$SOLR_SSL_KEY_STORE" ]; then
|
||||
SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStore=$SOLR_SSL_KEY_STORE"
|
||||
fi
|
||||
if [ -n "$SOLR_SSL_KEY_STORE_PASSWORD" ]; then
|
||||
SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStorePassword=$SOLR_SSL_KEY_STORE_PASSWORD"
|
||||
fi
|
||||
if [ -n "$SOLR_SSL_KEY_STORE_TYPE" ]; then
|
||||
SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStoreType=$SOLR_SSL_KEYSTORE_TYPE"
|
||||
fi
|
||||
@ -215,10 +213,6 @@ if [ -n "$SOLR_SSL_KEY_STORE" ]; then
|
||||
if [ -n "$SOLR_SSL_CLIENT_TRUST_STORE" ]; then
|
||||
SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStore=$SOLR_SSL_CLIENT_TRUST_STORE"
|
||||
|
||||
if [ -n "$SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD" ]; then
|
||||
SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStorePassword=$SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD"
|
||||
fi
|
||||
|
||||
if [ -n "$SOLR_SSL_CLIENT_TRUST_STORE_TYPE" ]; then
|
||||
SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStoreType=$SOLR_SSL_CLIENT_TRUST_STORE_TYPE"
|
||||
fi
|
||||
@ -227,10 +221,6 @@ if [ -n "$SOLR_SSL_KEY_STORE" ]; then
|
||||
SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStore=$SOLR_SSL_TRUST_STORE"
|
||||
fi
|
||||
|
||||
if [ -n "$SOLR_SSL_TRUST_STORE_PASSWORD" ]; then
|
||||
SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStorePassword=$SOLR_SSL_TRUST_STORE_PASSWORD"
|
||||
fi
|
||||
|
||||
if [ -n "$SOLR_SSL_TRUST_STORE_TYPE" ]; then
|
||||
SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStoreType=$SOLR_SSL_TRUST_STORE_TYPE"
|
||||
fi
|
||||
@ -294,7 +284,7 @@ function print_usage() {
|
||||
if [ -z "$CMD" ]; then
|
||||
echo ""
|
||||
echo "Usage: solr COMMAND OPTIONS"
|
||||
echo " where COMMAND is one of: start, stop, restart, status, healthcheck, create, create_core, create_collection, delete, version, zk"
|
||||
echo " where COMMAND is one of: start, stop, restart, status, healthcheck, create, create_core, create_collection, delete, version, zk, auth"
|
||||
echo ""
|
||||
echo " Standalone server example (start Solr running in the background on port 8984):"
|
||||
echo ""
|
||||
@ -544,6 +534,35 @@ function print_usage() {
|
||||
echo " <path>: The Zookeeper path to create. Leading slash is assumed if not present."
|
||||
echo " Intermediate nodes are created as needed if not present."
|
||||
echo ""
|
||||
elif [ "$CMD" == "auth" ]; then
|
||||
echo ""
|
||||
echo "Usage: solr auth enable [-type basicAuth] -credentials user:pass [-blockUnknown <true|false>] [-updateIncludeFileOnly <true|false>]"
|
||||
echo " solr auth enable [-type basicAuth] -prompt <true|false> [-blockUnknown <true|false>] [-updateIncludeFileOnly <true|false>]"
|
||||
echo " solr auth disable [-updateIncludeFileOnly <true|false>]"
|
||||
echo ""
|
||||
echo " -type <type> The authentication mechanism to enable. Defaults to 'basicAuth'."
|
||||
echo ""
|
||||
echo " -credentials <user:pass> The username and password of the initial user"
|
||||
echo " Note: only one of -prompt or -credentials must be provided"
|
||||
echo ""
|
||||
echo " -prompt <true|false> Prompts the user to provide the credentials"
|
||||
echo " Note: only one of -prompt or -credentials must be provided"
|
||||
echo ""
|
||||
echo " -blockUnknown <true|false> When true, this blocks out access to unauthenticated users. When not provided,"
|
||||
echo " this defaults to false (i.e. unauthenticated users can access all endpoints, except the"
|
||||
echo " operations like collection-edit, security-edit, core-admin-edit etc.). Check the reference"
|
||||
echo " guide for Basic Authentication for more details."
|
||||
echo ""
|
||||
echo " -updateIncludeFileOnly <true|false> Only update the solr.in.sh or solr.in.cmd file, and skip actual enabling/disabling"
|
||||
echo " authentication (i.e. don't update security.json)"
|
||||
echo ""
|
||||
echo " -z zkHost Zookeeper connection string"
|
||||
echo ""
|
||||
echo " -d <dir> Specify the Solr server directory"
|
||||
echo ""
|
||||
echo " -s <dir> Specify the Solr home directory. This is where any credentials or authentication"
|
||||
echo " configuration files (e.g. basicAuth.conf) would be placed."
|
||||
echo ""
|
||||
fi
|
||||
} # end print_usage
|
||||
|
||||
@ -1187,19 +1206,130 @@ if [[ "$SCRIPT_CMD" == "zk" ]]; then
|
||||
fi
|
||||
|
||||
if [[ "$SCRIPT_CMD" == "auth" ]]; then
|
||||
if [ -z "$AUTH_PORT" ]; then
|
||||
for ID in `ps auxww | grep java | grep start\.jar | awk '{print $2}' | sort -r`
|
||||
do
|
||||
port=`jetty_port "$ID"`
|
||||
if [ "$port" != "" ]; then
|
||||
AUTH_PORT=$port
|
||||
declare -a AUTH_PARAMS
|
||||
if [ $# -gt 0 ]; then
|
||||
while true; do
|
||||
case "$1" in
|
||||
enable|disable)
|
||||
AUTH_OP=$1
|
||||
AUTH_PARAMS=("${AUTH_PARAMS[@]}" "$AUTH_OP")
|
||||
shift
|
||||
;;
|
||||
-z|-zkhost|zkHost)
|
||||
ZK_HOST="$2"
|
||||
AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-zkHost" "$ZK_HOST")
|
||||
shift 2
|
||||
;;
|
||||
-t|-type)
|
||||
AUTH_TYPE="$2"
|
||||
AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-type" "$AUTH_TYPE")
|
||||
shift 2
|
||||
;;
|
||||
-credentials)
|
||||
AUTH_CREDENTIALS="$2"
|
||||
AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-credentials" "$AUTH_CREDENTIALS")
|
||||
shift 2
|
||||
;;
|
||||
-solrIncludeFile)
|
||||
SOLR_INCLUDE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-prompt)
|
||||
AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-prompt" "$2")
|
||||
shift
|
||||
;;
|
||||
-blockUnknown)
|
||||
AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-blockUnknown" "$2")
|
||||
shift
|
||||
break
|
||||
fi
|
||||
done
|
||||
;;
|
||||
-updateIncludeFileOnly)
|
||||
AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-updateIncludeFileOnly" "$2")
|
||||
shift
|
||||
break
|
||||
;;
|
||||
-d|-dir)
|
||||
if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
|
||||
print_usage "$SCRIPT_CMD" "Server directory is required when using the $1 option!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$2" == "." || "$2" == "./" || "$2" == ".." || "$2" == "../" ]]; then
|
||||
SOLR_SERVER_DIR="$(pwd)/$2"
|
||||
else
|
||||
# see if the arg value is relative to the tip vs full path
|
||||
if [[ "$2" != /* ]] && [[ -d "$SOLR_TIP/$2" ]]; then
|
||||
SOLR_SERVER_DIR="$SOLR_TIP/$2"
|
||||
else
|
||||
SOLR_SERVER_DIR="$2"
|
||||
fi
|
||||
fi
|
||||
# resolve it to an absolute path
|
||||
SOLR_SERVER_DIR="$(cd "$SOLR_SERVER_DIR"; pwd)"
|
||||
shift 2
|
||||
;;
|
||||
-s|-solr.home)
|
||||
if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
|
||||
print_usage "$SCRIPT_CMD" "Solr home directory is required when using the $1 option!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SOLR_HOME="$2"
|
||||
shift 2
|
||||
;;
|
||||
-help|-usage|-h)
|
||||
print_usage "$SCRIPT_CMD"
|
||||
exit 0
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$SOLR_SERVER_DIR" ]; then
|
||||
SOLR_SERVER_DIR="$DEFAULT_SERVER_DIR"
|
||||
fi
|
||||
if [ ! -e "$SOLR_SERVER_DIR" ]; then
|
||||
echo -e "\nSolr server directory $SOLR_SERVER_DIR not found!\n"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$SOLR_HOME" ]; then
|
||||
SOLR_HOME="$SOLR_SERVER_DIR/solr"
|
||||
else
|
||||
if [[ $SOLR_HOME != /* ]] && [[ -d "$SOLR_SERVER_DIR/$SOLR_HOME" ]]; then
|
||||
SOLR_HOME="$SOLR_SERVER_DIR/$SOLR_HOME"
|
||||
SOLR_PID_DIR="$SOLR_HOME"
|
||||
elif [[ $SOLR_HOME != /* ]] && [[ -d "`pwd`/$SOLR_HOME" ]]; then
|
||||
SOLR_HOME="$(pwd)/$SOLR_HOME"
|
||||
fi
|
||||
solr_include_file=$SOLR_INCLUDE
|
||||
run_tool auth "$@" -solrUrl "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$AUTH_PORT/solr" -solrIncludeFile "$solr_include_file"
|
||||
exit $?
|
||||
fi
|
||||
|
||||
if [ -z "$AUTH_OP" ]; then
|
||||
print_usage "$SCRIPT_CMD"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-solrIncludeFile" "$SOLR_INCLUDE")
|
||||
|
||||
if [ -z "$AUTH_PORT" ]; then
|
||||
for ID in `ps auxww | grep java | grep start\.jar | awk '{print $2}' | sort -r`
|
||||
do
|
||||
port=`jetty_port "$ID"`
|
||||
if [ "$port" != "" ]; then
|
||||
AUTH_PORT=$port
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
run_tool auth ${AUTH_PARAMS[@]} -solrUrl "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$AUTH_PORT/solr" -authConfDir "$SOLR_HOME"
|
||||
exit $?
|
||||
fi
|
||||
|
||||
|
||||
@ -1696,7 +1826,7 @@ function launch_solr() {
|
||||
|
||||
|
||||
# If SSL-related system props are set, add them to SOLR_OPTS
|
||||
if [ -n "$SOLR_SSL_OPTS" ]; then
|
||||
if [ "$SOLR_SSL_ENABLED" ]; then
|
||||
# If using SSL and solr.jetty.https.port not set explicitly, use the jetty.port
|
||||
SSL_PORT_PROP="-Dsolr.jetty.https.port=$SOLR_PORT"
|
||||
SOLR_OPTS+=($SOLR_SSL_OPTS "$SSL_PORT_PROP")
|
||||
|
@ -42,13 +42,21 @@ REM Select HTTP OR HTTPS related configurations
|
||||
set SOLR_URL_SCHEME=http
|
||||
set "SOLR_JETTY_CONFIG=--module=http"
|
||||
set "SOLR_SSL_OPTS= "
|
||||
IF DEFINED SOLR_SSL_KEY_STORE (
|
||||
|
||||
IF NOT DEFINED SOLR_SSL_ENABLED (
|
||||
IF DEFINED SOLR_SSL_KEY_STORE (
|
||||
set "SOLR_SSL_ENABLED=true"
|
||||
) ELSE (
|
||||
set "SOLR_SSL_ENABLED=false"
|
||||
)
|
||||
)
|
||||
IF "%SOLR_SSL_ENABLED%"=="true" (
|
||||
set "SOLR_JETTY_CONFIG=--module=https"
|
||||
set SOLR_URL_SCHEME=https
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.keystore=%SOLR_SSL_KEY_STORE%"
|
||||
IF DEFINED SOLR_SSL_KEY_STORE_PASSWORD (
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.keystore.password=%SOLR_SSL_KEY_STORE_PASSWORD%"
|
||||
IF DEFINED SOLR_SSL_KEY_STORE (
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.keystore=%SOLR_SSL_KEY_STORE%"
|
||||
)
|
||||
|
||||
IF DEFINED SOLR_SSL_KEY_STORE_TYPE (
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.keystore.type=%SOLR_SSL_KEY_STORE_TYPE%"
|
||||
)
|
||||
@ -56,9 +64,6 @@ IF DEFINED SOLR_SSL_KEY_STORE (
|
||||
IF DEFINED SOLR_SSL_TRUST_STORE (
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.truststore=%SOLR_SSL_TRUST_STORE%"
|
||||
)
|
||||
IF DEFINED SOLR_SSL_TRUST_STORE_PASSWORD (
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.truststore.password=%SOLR_SSL_TRUST_STORE_PASSWORD%"
|
||||
)
|
||||
IF DEFINED SOLR_SSL_TRUST_STORE_TYPE (
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.truststore.type=%SOLR_SSL_TRUST_STORE_TYPE%"
|
||||
)
|
||||
@ -73,9 +78,6 @@ IF DEFINED SOLR_SSL_KEY_STORE (
|
||||
IF DEFINED SOLR_SSL_CLIENT_KEY_STORE (
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStore=%SOLR_SSL_CLIENT_KEY_STORE%"
|
||||
|
||||
IF DEFINED SOLR_SSL_CLIENT_KEY_STORE_PASSWORD (
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStorePassword=%SOLR_SSL_CLIENT_KEY_STORE_PASSWORD%"
|
||||
)
|
||||
IF DEFINED SOLR_SSL_CLIENT_KEY_STORE_TYPE (
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStoreType=%SOLR_SSL_CLIENT_KEY_STORE_TYPE%"
|
||||
)
|
||||
@ -83,9 +85,6 @@ IF DEFINED SOLR_SSL_KEY_STORE (
|
||||
IF DEFINED SOLR_SSL_KEY_STORE (
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStore=%SOLR_SSL_KEY_STORE%"
|
||||
)
|
||||
IF DEFINED SOLR_SSL_KEY_STORE_PASSWORD (
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStorePassword=%SOLR_SSL_KEY_STORE_PASSWORD%"
|
||||
)
|
||||
IF DEFINED SOLR_SSL_KEY_STORE_TYPE (
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStoreType=%SOLR_SSL_KEY_STORE_TYPE%"
|
||||
)
|
||||
@ -94,10 +93,6 @@ IF DEFINED SOLR_SSL_KEY_STORE (
|
||||
IF DEFINED SOLR_SSL_CLIENT_TRUST_STORE (
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStore=%SOLR_SSL_CLIENT_TRUST_STORE%"
|
||||
|
||||
IF DEFINED SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD (
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStorePassword=%SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD%"
|
||||
)
|
||||
|
||||
IF DEFINED SOLR_SSL_CLIENT_TRUST_STORE_TYPE (
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStoreType=%SOLR_SSL_CLIENT_TRUST_STORE_TYPE%"
|
||||
)
|
||||
@ -105,9 +100,6 @@ IF DEFINED SOLR_SSL_KEY_STORE (
|
||||
IF DEFINED SOLR_SSL_TRUST_STORE (
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStore=%SOLR_SSL_TRUST_STORE%"
|
||||
)
|
||||
IF DEFINED SOLR_SSL_TRUST_STORE_PASSWORD (
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStorePassword=%SOLR_SSL_TRUST_STORE_PASSWORD%"
|
||||
)
|
||||
IF DEFINED SOLR_SSL_TRUST_STORE_TYPE (
|
||||
set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStoreType=%SOLR_SSL_TRUST_STORE_TYPE%"
|
||||
)
|
||||
@ -276,7 +268,7 @@ goto done
|
||||
:script_usage
|
||||
@echo.
|
||||
@echo Usage: solr COMMAND OPTIONS
|
||||
@echo where COMMAND is one of: start, stop, restart, healthcheck, create, create_core, create_collection, delete, version, zk
|
||||
@echo where COMMAND is one of: start, stop, restart, healthcheck, create, create_core, create_collection, delete, version, zk, auth
|
||||
@echo.
|
||||
@echo Standalone server example (start Solr running in the background on port 8984):
|
||||
@echo.
|
||||
@ -554,6 +546,35 @@ IF "%ZK_FULL%"=="true" (
|
||||
)
|
||||
goto done
|
||||
|
||||
:auth_usage
|
||||
echo Usage: solr auth enable [-type basicAuth] -credentials user:pass [-blockUnknown ^<true|false^>] [-updateIncludeFileOnly ^<true|false^>]
|
||||
echo solr auth enable [-type basicAuth] -prompt ^<true|false^> [-blockUnknown ^<true|false^>] [-updateIncludeFileOnly ^<true|false^>]
|
||||
echo solr auth disable [-updateIncludeFileOnly ^<true|false^>]
|
||||
echo
|
||||
echo -type ^<type^> The authentication mechanism to enable. Defaults to 'basicAuth'.
|
||||
echo
|
||||
echo -credentials ^<user:pass^> The username and password of the initial user
|
||||
echo Note: only one of -prompt or -credentials must be provided
|
||||
echo
|
||||
echo -prompt ^<true|false^> Prompts the user to provide the credentials
|
||||
echo Note: only one of -prompt or -credentials must be provided
|
||||
echo
|
||||
echo -blockUnknown ^<true|false^> When true, this blocks out access to unauthenticated users. When not provided,
|
||||
echo this defaults to false (i.e. unauthenticated users can access all endpoints, except the
|
||||
echo operations like collection-edit, security-edit, core-admin-edit etc.). Check the reference
|
||||
echo guide for Basic Authentication for more details.
|
||||
echo
|
||||
echo -updateIncludeFileOnly ^<true|false^> Only update the solr.in.sh or solr.in.cmd file, and skip actual enabling/disabling"
|
||||
echo authentication (i.e. don't update security.json)"
|
||||
echo
|
||||
echo -z zkHost Zookeeper connection string
|
||||
echo
|
||||
echo -d <dir> Specify the Solr server directory"
|
||||
echo
|
||||
echo -s <dir> Specify the Solr home directory. This is where any credentials or authentication"
|
||||
echo configuration files (e.g. basicAuth.conf) would be placed."
|
||||
echo
|
||||
goto done
|
||||
|
||||
REM Really basic command-line arg parsing
|
||||
:parse_args
|
||||
@ -1110,7 +1131,7 @@ IF NOT "%REMOTE_JMX_OPTS%"=="" set "START_OPTS=%START_OPTS% %REMOTE_JMX_OPTS%"
|
||||
IF NOT "%SOLR_ADDL_ARGS%"=="" set "START_OPTS=%START_OPTS% %SOLR_ADDL_ARGS%"
|
||||
IF NOT "%SOLR_HOST_ARG%"=="" set "START_OPTS=%START_OPTS% %SOLR_HOST_ARG%"
|
||||
IF NOT "%SOLR_OPTS%"=="" set "START_OPTS=%START_OPTS% %SOLR_OPTS%"
|
||||
IF NOT "%SOLR_SSL_OPTS%"=="" (
|
||||
IF "%SOLR_SSL_ENABLED%"=="true" (
|
||||
set "SSL_PORT_PROP=-Dsolr.jetty.https.port=%SOLR_PORT%"
|
||||
set "START_OPTS=%START_OPTS% %SOLR_SSL_OPTS% !SSL_PORT_PROP!"
|
||||
)
|
||||
@ -1648,6 +1669,44 @@ goto done
|
||||
|
||||
|
||||
:run_auth
|
||||
IF "%1"=="-help" goto usage
|
||||
IF "%1"=="-usage" goto usage
|
||||
|
||||
REM Options parsing.
|
||||
REM Note: With the following technique of parsing, it is not possible
|
||||
REM to have an option without a value.
|
||||
set "AUTH_PARAMS=%1"
|
||||
set "option="
|
||||
for %%a in (%*) do (
|
||||
if not defined option (
|
||||
set arg=%%a
|
||||
if "!arg:~0,1!" equ "-" set "option=!arg!"
|
||||
) else (
|
||||
set "option!option!=%%a"
|
||||
if "!option!" equ "-d" set "SOLR_SERVER_DIR=%%a"
|
||||
if "!option!" equ "-s" set "SOLR_HOME=%%a"
|
||||
if not "!option!" equ "-s" if not "!option!" equ "-d" (
|
||||
set "AUTH_PARAMS=!AUTH_PARAMS! !option! %%a"
|
||||
)
|
||||
set "option="
|
||||
)
|
||||
)
|
||||
IF "%SOLR_SERVER_DIR%"=="" set "SOLR_SERVER_DIR=%DEFAULT_SERVER_DIR%"
|
||||
IF NOT EXIST "%SOLR_SERVER_DIR%" (
|
||||
set "SCRIPT_ERROR=Solr server directory %SOLR_SERVER_DIR% not found!"
|
||||
goto err
|
||||
)
|
||||
IF "%SOLR_HOME%"=="" set "SOLR_HOME=%SOLR_SERVER_DIR%\solr"
|
||||
IF EXIST "%cd%\%SOLR_HOME%" set "SOLR_HOME=%cd%\%SOLR_HOME%"
|
||||
IF NOT EXIST "%SOLR_HOME%\" (
|
||||
IF EXIST "%SOLR_SERVER_DIR%\%SOLR_HOME%" (
|
||||
set "SOLR_HOME=%SOLR_SERVER_DIR%\%SOLR_HOME%"
|
||||
) ELSE (
|
||||
set "SCRIPT_ERROR=Solr home directory %SOLR_HOME% not found!"
|
||||
goto err
|
||||
)
|
||||
)
|
||||
|
||||
if "!AUTH_PORT!"=="" (
|
||||
for /f "usebackq" %%i in (`dir /b "%SOLR_TIP%\bin" ^| findstr /i "^solr-.*\.port$"`) do (
|
||||
set SOME_SOLR_PORT=
|
||||
@ -1659,11 +1718,10 @@ if "!AUTH_PORT!"=="" (
|
||||
)
|
||||
)
|
||||
)
|
||||
for /f "tokens=1,* delims= " %%a in ("%*") do set auth_params=%%b
|
||||
"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
|
||||
-Dlog4j.configuration="file:%DEFAULT_SERVER_DIR%\scripts\cloud-scripts\log4j.properties" ^
|
||||
-classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
|
||||
org.apache.solr.util.SolrCLI auth %auth_params% -solrIncludeFile "%SOLR_INCLUDE%" ^
|
||||
org.apache.solr.util.SolrCLI auth %AUTH_PARAMS% -solrIncludeFile "%SOLR_INCLUDE%" -authConfDir "%SOLR_HOME%" ^
|
||||
-solrUrl !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!AUTH_PORT!/solr
|
||||
goto done
|
||||
|
||||
|
@ -87,6 +87,9 @@ REM set SOLR_JETTY_HOST=0.0.0.0
|
||||
REM Sets the port Solr binds to, default is 8983
|
||||
REM set SOLR_PORT=8983
|
||||
|
||||
REM Enables HTTPS. It is implictly true if you set SOLR_SSL_KEY_STORE. Use this config
|
||||
REM to enable https module with custom jetty configuration.
|
||||
REM set SOLR_SSL_ENABLED=true
|
||||
REM Uncomment to set SSL-related system properties
|
||||
REM Be sure to update the paths to the correct keystore for your environment
|
||||
REM set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.jks
|
||||
|
@ -106,6 +106,9 @@
|
||||
# Sets the port Solr binds to, default is 8983
|
||||
#SOLR_PORT=8983
|
||||
|
||||
# Enables HTTPS. It is implictly true if you set SOLR_SSL_KEY_STORE. Use this config
|
||||
# to enable https module with custom jetty configuration.
|
||||
#SOLR_SSL_ENABLED=true
|
||||
# Uncomment to set SSL-related system properties
|
||||
# Be sure to update the paths to the correct keystore for your environment
|
||||
#SOLR_SSL_KEY_STORE=/home/shalin/work/oss/shalin-lusolr/solr/server/etc/solr-ssl.keystore.jks
|
||||
|
@ -74,7 +74,7 @@ import org.slf4j.LoggerFactory;
|
||||
* between versions in terms of API or back compat behaviour.
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class RecoveryStrategy extends Thread implements Closeable {
|
||||
public class RecoveryStrategy implements Runnable, Closeable {
|
||||
|
||||
public static class Builder implements NamedListInitializedPlugin {
|
||||
private NamedList args;
|
||||
@ -124,7 +124,6 @@ public class RecoveryStrategy extends Thread implements Closeable {
|
||||
this.cc = cc;
|
||||
this.coreName = cd.getName();
|
||||
this.recoveryListener = recoveryListener;
|
||||
setName("RecoveryThread-"+this.coreName);
|
||||
zkController = cc.getZkController();
|
||||
zkStateReader = zkController.getZkStateReader();
|
||||
baseUrl = zkController.getBaseUrl();
|
||||
@ -370,7 +369,7 @@ public class RecoveryStrategy extends Thread implements Closeable {
|
||||
}
|
||||
|
||||
Future<RecoveryInfo> replayFuture = null;
|
||||
while (!successfulRecovery && !isInterrupted() && !isClosed()) { // don't use interruption or it will close channels though
|
||||
while (!successfulRecovery && !Thread.currentThread().isInterrupted() && !isClosed()) { // don't use interruption or it will close channels though
|
||||
try {
|
||||
CloudDescriptor cloudDesc = core.getCoreDescriptor().getCloudDescriptor();
|
||||
ZkNodeProps leaderprops = zkStateReader.getLeaderRetry(
|
||||
|
@ -146,12 +146,6 @@ public class SchemaHandler extends RequestHandlerBase implements SolrCoreAware,
|
||||
rsp.add(IndexSchema.DEFAULT_SEARCH_FIELD, defaultSearchFieldName);
|
||||
break;
|
||||
}
|
||||
case "/schema/solrqueryparser": {
|
||||
SimpleOrderedMap<Object> props = new SimpleOrderedMap<>();
|
||||
props.add(IndexSchema.DEFAULT_OPERATOR, req.getSchema().getQueryParserDefaultOperator());
|
||||
rsp.add(IndexSchema.SOLR_QUERY_PARSER, props);
|
||||
break;
|
||||
}
|
||||
case "/schema/zkversion": {
|
||||
int refreshIfBelowVersion = -1;
|
||||
Object refreshParam = req.getParams().get("refreshIfBelowVersion");
|
||||
@ -175,10 +169,6 @@ public class SchemaHandler extends RequestHandlerBase implements SolrCoreAware,
|
||||
rsp.add("zkversion", zkVersion);
|
||||
break;
|
||||
}
|
||||
case "/schema/solrqueryparser/defaultoperator": {
|
||||
rsp.add(IndexSchema.DEFAULT_OPERATOR, req.getSchema().getQueryParserDefaultOperator());
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
List<String> parts = StrUtils.splitSmart(path, '/');
|
||||
if (parts.get(0).isEmpty()) parts.remove(0);
|
||||
|
@ -174,6 +174,13 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
|
||||
.withFunctionName("conv", ConvolutionEvaluator.class)
|
||||
.withFunctionName("normalize", NormalizeEvaluator.class)
|
||||
.withFunctionName("rev", ReverseEvaluator.class)
|
||||
.withFunctionName("length", LengthEvaluator.class)
|
||||
.withFunctionName("rank", RankEvaluator.class)
|
||||
.withFunctionName("scale", ScaleEvaluator.class)
|
||||
.withFunctionName("distance", DistanceEvaluator.class)
|
||||
.withFunctionName("copyOf", CopyOfEvaluator.class)
|
||||
.withFunctionName("percentile", PercentileEvaluator.class)
|
||||
.withFunctionName("empiricalDistribution", EmpiricalDistributionEvaluator.class)
|
||||
|
||||
// metrics
|
||||
.withFunctionName("min", MinMetric.class)
|
||||
|
@ -103,10 +103,6 @@ public class SchemaXmlWriter extends TextResponseWriter {
|
||||
closeStartTag(false);
|
||||
writer.write(val.toString());
|
||||
endTag(IndexSchema.DEFAULT_SEARCH_FIELD, false);
|
||||
} else if (schemaPropName.equals(IndexSchema.SOLR_QUERY_PARSER)) {
|
||||
openStartTag(IndexSchema.SOLR_QUERY_PARSER);
|
||||
writeAttr(IndexSchema.DEFAULT_OPERATOR, ((Map<String ,Object>) val).get(IndexSchema.DEFAULT_OPERATOR).toString());
|
||||
closeStartTag(true);
|
||||
} else if (schemaPropName.equals(IndexSchema.SIMILARITY)) {
|
||||
writeSimilarity((SimpleOrderedMap<Object>) val);
|
||||
} else if (schemaPropName.equals(IndexSchema.FIELD_TYPES)) {
|
||||
|
@ -94,7 +94,6 @@ import static java.util.Collections.singletonMap;
|
||||
public class IndexSchema {
|
||||
public static final String COPY_FIELD = "copyField";
|
||||
public static final String COPY_FIELDS = COPY_FIELD + "s";
|
||||
public static final String DEFAULT_OPERATOR = "defaultOperator";
|
||||
public static final String DEFAULT_SCHEMA_FILE = "schema.xml";
|
||||
public static final String DEFAULT_SEARCH_FIELD = "defaultSearchField";
|
||||
public static final String DESTINATION = "dest";
|
||||
@ -112,7 +111,6 @@ public class IndexSchema {
|
||||
public static final String SCHEMA = "schema";
|
||||
public static final String SIMILARITY = "similarity";
|
||||
public static final String SLASH = "/";
|
||||
public static final String SOLR_QUERY_PARSER = "solrQueryParser";
|
||||
public static final String SOURCE = "source";
|
||||
public static final String TYPE = "type";
|
||||
public static final String TYPES = "types";
|
||||
@ -148,9 +146,6 @@ public class IndexSchema {
|
||||
protected List<SchemaAware> schemaAware = new ArrayList<>();
|
||||
|
||||
protected String defaultSearchFieldName=null;
|
||||
protected String queryParserDefaultOperator = "OR";
|
||||
protected boolean isExplicitQueryParserDefaultOperator = false;
|
||||
|
||||
|
||||
protected Map<String, List<CopyField>> copyFieldsMap = new HashMap<>();
|
||||
public Map<String,List<CopyField>> getCopyFieldsMap() { return Collections.unmodifiableMap(copyFieldsMap); }
|
||||
@ -312,13 +307,6 @@ public class IndexSchema {
|
||||
return defaultSearchFieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* default operator ("AND" or "OR") for QueryParser
|
||||
*/
|
||||
public String getQueryParserDefaultOperator() {
|
||||
return queryParserDefaultOperator;
|
||||
}
|
||||
|
||||
protected SchemaField uniqueKeyField;
|
||||
|
||||
/**
|
||||
@ -540,15 +528,10 @@ public class IndexSchema {
|
||||
}
|
||||
|
||||
// /schema/solrQueryParser/@defaultOperator
|
||||
expression = stepsToPath(SCHEMA, SOLR_QUERY_PARSER, AT + DEFAULT_OPERATOR);
|
||||
expression = stepsToPath(SCHEMA, "solrQueryParser", AT + "defaultOperator");
|
||||
node = (Node) xpath.evaluate(expression, document, XPathConstants.NODE);
|
||||
if (node==null) {
|
||||
log.debug("Default query parser operator not set in Schema");
|
||||
} else {
|
||||
isExplicitQueryParserDefaultOperator = true;
|
||||
queryParserDefaultOperator=node.getNodeValue().trim();
|
||||
log.warn("[{}] query parser default operator is {}. WARNING: Deprecated, please use 'q.op' on request instead.",
|
||||
coreName, queryParserDefaultOperator);
|
||||
if (node != null) {
|
||||
throw new SolrException(ErrorCode.SERVER_ERROR, "Setting default operator in schema (solrQueryParser/@defaultOperator) not supported");
|
||||
}
|
||||
|
||||
// /schema/uniqueKey/text()
|
||||
@ -1402,9 +1385,6 @@ public class IndexSchema {
|
||||
VERSION(IndexSchema.VERSION, sp -> sp.schema.getVersion()),
|
||||
UNIQUE_KEY(IndexSchema.UNIQUE_KEY, sp -> sp.schema.uniqueKeyFieldName),
|
||||
DEFAULT_SEARCH_FIELD(IndexSchema.DEFAULT_SEARCH_FIELD, sp -> sp.schema.defaultSearchFieldName),
|
||||
SOLR_QUERY_PARSER(IndexSchema.SOLR_QUERY_PARSER, sp -> sp.schema.isExplicitQueryParserDefaultOperator ?
|
||||
singletonMap(DEFAULT_OPERATOR, sp.schema.queryParserDefaultOperator) :
|
||||
null),
|
||||
SIMILARITY(IndexSchema.SIMILARITY, sp -> sp.schema.isExplicitSimilarity ?
|
||||
sp.schema.similarityFactory.getNamedPropertyValues() :
|
||||
null),
|
||||
|
@ -1358,8 +1358,6 @@ public final class ManagedIndexSchema extends IndexSchema {
|
||||
newSchema.name = name;
|
||||
newSchema.version = version;
|
||||
newSchema.defaultSearchFieldName = defaultSearchFieldName;
|
||||
newSchema.queryParserDefaultOperator = queryParserDefaultOperator;
|
||||
newSchema.isExplicitQueryParserDefaultOperator = isExplicitQueryParserDefaultOperator;
|
||||
newSchema.similarity = similarity;
|
||||
newSchema.similarityFactory = similarityFactory;
|
||||
newSchema.isExplicitSimilarity = isExplicitSimilarity;
|
||||
|
@ -156,7 +156,7 @@ public class ComplexPhraseQParserPlugin extends QParserPlugin {
|
||||
|
||||
lparser.setInOrder(inOrder);
|
||||
|
||||
QueryParser.Operator defaultOperator = QueryParsing.getQueryParserDefaultOperator(getReq().getSchema(), getParam(QueryParsing.OP));
|
||||
QueryParser.Operator defaultOperator = QueryParsing.parseOP(getParam(QueryParsing.OP));
|
||||
|
||||
if (QueryParser.Operator.AND.equals(defaultOperator))
|
||||
lparser.setDefaultOperator(org.apache.lucene.queryparser.classic.QueryParser.Operator.AND);
|
||||
|
@ -52,14 +52,13 @@ public class DisMaxQParser extends QParser {
|
||||
* Applies the appropriate default rules for the "mm" param based on the
|
||||
* effective value of the "q.op" param
|
||||
*
|
||||
* @see QueryParsing#getQueryParserDefaultOperator
|
||||
* @see QueryParsing#OP
|
||||
* @see DisMaxParams#MM
|
||||
*/
|
||||
public static String parseMinShouldMatch(final IndexSchema schema,
|
||||
final SolrParams params) {
|
||||
org.apache.solr.parser.QueryParser.Operator op = QueryParsing.getQueryParserDefaultOperator
|
||||
(schema, params.get(QueryParsing.OP));
|
||||
org.apache.solr.parser.QueryParser.Operator op = QueryParsing.parseOP(params.get(QueryParsing.OP));
|
||||
|
||||
return params.get(DisMaxParams.MM,
|
||||
op.equals(QueryParser.Operator.AND) ? "100%" : "0%");
|
||||
}
|
||||
|
@ -990,8 +990,7 @@ public class ExtendedDismaxQParser extends QParser {
|
||||
super(parser, defaultField);
|
||||
// Respect the q.op parameter before mm will be applied later
|
||||
SolrParams defaultParams = SolrParams.wrapDefaults(parser.getLocalParams(), parser.getParams());
|
||||
QueryParser.Operator defaultOp = QueryParsing.getQueryParserDefaultOperator(
|
||||
parser.getReq().getSchema(), defaultParams.get(QueryParsing.OP));
|
||||
QueryParser.Operator defaultOp = QueryParsing.parseOP(defaultParams.get(QueryParsing.OP));
|
||||
setDefaultOperator(defaultOp);
|
||||
}
|
||||
|
||||
|
@ -44,9 +44,7 @@ public class LuceneQParser extends QParser {
|
||||
}
|
||||
lparser = new SolrQueryParser(this, defaultField);
|
||||
|
||||
lparser.setDefaultOperator
|
||||
(QueryParsing.getQueryParserDefaultOperator(getReq().getSchema(),
|
||||
getParam(QueryParsing.OP)));
|
||||
lparser.setDefaultOperator(QueryParsing.parseOP(getParam(QueryParsing.OP)));
|
||||
lparser.setSplitOnWhitespace(StrUtils.parseBool
|
||||
(getParam(QueryParsing.SPLIT_ON_WHITESPACE), SolrQueryParser.DEFAULT_SPLIT_ON_WHITESPACE));
|
||||
|
||||
|
@ -59,18 +59,15 @@ public class QueryParsing {
|
||||
|
||||
|
||||
/**
|
||||
* Returns the "preferred" default operator for use by Query Parsers,
|
||||
* based on the settings in the IndexSchema which may be overridden using
|
||||
* an optional String override value.
|
||||
*
|
||||
* @see IndexSchema#getQueryParserDefaultOperator()
|
||||
* @see #OP
|
||||
* Returns the default operator for use by Query Parsers, parsed from the df string
|
||||
* @param notUsed is not used, but is there for back compat with 3rd party QParsers
|
||||
* @param df the df string from request
|
||||
* @deprecated this method is here purely not to break code back compat in 7.x
|
||||
*/
|
||||
public static QueryParser.Operator getQueryParserDefaultOperator(final IndexSchema sch,
|
||||
final String override) {
|
||||
String val = override;
|
||||
if (null == val) val = sch.getQueryParserDefaultOperator();
|
||||
return "AND".equals(val) ? QueryParser.Operator.AND : QueryParser.Operator.OR;
|
||||
@Deprecated
|
||||
public static QueryParser.Operator getQueryParserDefaultOperator(final IndexSchema notUsed,
|
||||
final String df) {
|
||||
return parseOP(df);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -396,4 +393,12 @@ public class QueryParsing {
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses default operator string into Operator object
|
||||
* @param operator the string from request
|
||||
* @return Operator.AND if string equals "AND", else return Operator.OR (default)
|
||||
*/
|
||||
public static QueryParser.Operator parseOP(String operator) {
|
||||
return "and".equalsIgnoreCase(operator) ? QueryParser.Operator.AND : QueryParser.Operator.OR;
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ public class SimpleQParserPlugin extends QParserPlugin {
|
||||
parser = new SolrSimpleQueryParser(req.getSchema().getQueryAnalyzer(), queryFields, enabledOps, this, schema);
|
||||
|
||||
// Set the default operator to be either 'AND' or 'OR' for the query.
|
||||
QueryParser.Operator defaultOp = QueryParsing.getQueryParserDefaultOperator(req.getSchema(), defaultParams.get(QueryParsing.OP));
|
||||
QueryParser.Operator defaultOp = QueryParsing.parseOP(defaultParams.get(QueryParsing.OP));
|
||||
|
||||
if (defaultOp == QueryParser.Operator.AND) {
|
||||
parser.setDefaultOperator(BooleanClause.Occur.MUST);
|
||||
|
@ -73,6 +73,7 @@ import org.apache.solr.request.SolrRequestInfo;
|
||||
import org.apache.solr.security.AuthenticationPlugin;
|
||||
import org.apache.solr.security.PKIAuthenticationPlugin;
|
||||
import org.apache.solr.util.SolrFileCleaningTracker;
|
||||
import org.apache.solr.util.configuration.SSLConfigurationsFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -139,6 +140,7 @@ public class SolrDispatchFilter extends BaseSolrFilter {
|
||||
@Override
|
||||
public void init(FilterConfig config) throws ServletException
|
||||
{
|
||||
SSLConfigurationsFactory.current().init();
|
||||
log.trace("SolrDispatchFilter.init(): {}", this.getClass().getClassLoader());
|
||||
CoreContainer coresInit = null;
|
||||
try{
|
||||
|
@ -278,7 +278,7 @@ public final class DefaultSolrCoreState extends SolrCoreState implements Recover
|
||||
@Override
|
||||
public void doRecovery(CoreContainer cc, CoreDescriptor cd) {
|
||||
|
||||
Thread thread = new Thread() {
|
||||
Runnable recoveryTask = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
MDCLoggingContext.setCoreDescriptor(cc, cd);
|
||||
@ -355,7 +355,7 @@ public final class DefaultSolrCoreState extends SolrCoreState implements Recover
|
||||
// The recovery executor is not interrupted on shutdown.
|
||||
//
|
||||
// avoid deadlock: we can't use the recovery executor here
|
||||
cc.getUpdateShardHandler().getUpdateExecutor().submit(thread);
|
||||
cc.getUpdateShardHandler().getUpdateExecutor().submit(recoveryTask);
|
||||
} catch (RejectedExecutionException e) {
|
||||
// fine, we are shutting down
|
||||
}
|
||||
|
@ -61,6 +61,8 @@ import java.util.stream.Stream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import javax.net.ssl.SSLPeerUnverifiedException;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.GnuParser;
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
@ -114,6 +116,7 @@ import org.apache.solr.common.params.ModifiableSolrParams;
|
||||
import org.apache.solr.common.util.ContentStreamBase;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
import org.apache.solr.security.Sha256AuthenticationProvider;
|
||||
import org.apache.solr.util.configuration.SSLConfigurationsFactory;
|
||||
import org.noggit.CharArr;
|
||||
import org.noggit.JSONParser;
|
||||
import org.noggit.JSONWriter;
|
||||
@ -253,6 +256,8 @@ public class SolrCLI {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
SSLConfigurationsFactory.current().init();
|
||||
|
||||
Tool tool = findTool(args);
|
||||
CommandLine cli = parseCmdLine(args, tool.getOptions());
|
||||
System.exit(tool.runTool(cli));
|
||||
@ -867,6 +872,8 @@ public class SolrCLI {
|
||||
while (System.nanoTime() < timeout) {
|
||||
try {
|
||||
return getStatus(solrUrl);
|
||||
} catch (SSLPeerUnverifiedException exc) {
|
||||
throw exc;
|
||||
} catch (Exception exc) {
|
||||
if (exceptionIsAuthRelated(exc)) {
|
||||
throw exc;
|
||||
@ -3526,49 +3533,59 @@ public class SolrCLI {
|
||||
public Option[] getOptions() {
|
||||
return new Option[]{
|
||||
OptionBuilder
|
||||
.withArgName("enable")
|
||||
.withDescription("Enable authentication.")
|
||||
.create("enable"),
|
||||
.withArgName("type")
|
||||
.hasArg()
|
||||
.withDescription("The authentication mechanism to enable. Defaults to 'basicAuth'.")
|
||||
.create("type"),
|
||||
OptionBuilder
|
||||
.withArgName("disable")
|
||||
.withDescription("Disable existing authentication.")
|
||||
.create("disable"),
|
||||
.withArgName("credentials")
|
||||
.hasArg()
|
||||
.withDescription("Credentials in the format username:password. Example: -credentials solr:SolrRocks")
|
||||
.create("credentials"),
|
||||
OptionBuilder
|
||||
.withArgName("type")
|
||||
.hasArg()
|
||||
.withDescription("basicAuth")
|
||||
.create("type"),
|
||||
.withArgName("prompt")
|
||||
.hasArg()
|
||||
.withDescription("Prompts the user to provide the credentials. Use either -credentials or -prompt, not both")
|
||||
.create("prompt"),
|
||||
OptionBuilder
|
||||
.withArgName("credentials")
|
||||
.hasArg()
|
||||
.withDescription("Credentials in the format username:password. Example: -credentials solr:SolrRocks")
|
||||
.create("credentials"),
|
||||
.withArgName("blockUnknown")
|
||||
.withDescription("Blocks all access for unknown users (requires authentication for all endpoints)")
|
||||
.hasArg()
|
||||
.create("blockUnknown"),
|
||||
OptionBuilder
|
||||
.withArgName("prompt")
|
||||
.withDescription("Prompt for credentials. Use either -credentials or -prompt, not both")
|
||||
.create("prompt"),
|
||||
.withArgName("solrIncludeFile")
|
||||
.hasArg()
|
||||
.withDescription("The Solr include file which contains overridable environment variables for configuring Solr configurations")
|
||||
.create("solrIncludeFile"),
|
||||
OptionBuilder
|
||||
.withArgName("blockUnknown")
|
||||
.withDescription("Blocks all access for unknown users (requires authentication for all endpoints)")
|
||||
.hasOptionalArg()
|
||||
.create("blockUnknown"),
|
||||
.withArgName("updateIncludeFileOnly")
|
||||
.withDescription("Only update the solr.in.sh or solr.in.cmd file, and skip actual enabling/disabling"
|
||||
+ " authentication (i.e. don't update security.json)")
|
||||
.hasArg()
|
||||
.create("updateIncludeFileOnly"),
|
||||
OptionBuilder
|
||||
.withArgName("solrIncludeFile")
|
||||
.hasArg()
|
||||
.withDescription("The Solr include file which contains overridable environment variables for configuring Solr configurations")
|
||||
.create("solrIncludeFile"),
|
||||
.withArgName("authConfDir")
|
||||
.hasArg()
|
||||
.isRequired()
|
||||
.withDescription("This is where any authentication related configuration files, if any, would be placed.")
|
||||
.create("authConfDir"),
|
||||
OptionBuilder
|
||||
.withArgName("solrUrl")
|
||||
.hasArg()
|
||||
.withDescription("Solr URL")
|
||||
.create("solrUrl"),
|
||||
.withArgName("solrUrl")
|
||||
.hasArg()
|
||||
.withDescription("Solr URL")
|
||||
.create("solrUrl"),
|
||||
OptionBuilder
|
||||
.withArgName("zkHost")
|
||||
.hasArg()
|
||||
.withDescription("ZooKeeper host")
|
||||
.create("zkHost"),
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int runTool(CommandLine cli) throws Exception {
|
||||
if (cli.getOptions().length == 0 || cli.getArgs().length > 0 || cli.hasOption("h")) {
|
||||
new HelpFormatter().printHelp("bin/solr auth [OPTIONS]", getToolOptions(this));
|
||||
if (cli.getOptions().length == 0 || cli.getArgs().length == 0 || cli.getArgs().length > 1 || cli.hasOption("h")) {
|
||||
new HelpFormatter().printHelp("bin/solr auth <enable|disable> [OPTIONS]", getToolOptions(this));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -3578,128 +3595,153 @@ public class SolrCLI {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (cli.hasOption("enable") && cli.hasOption("disable")) {
|
||||
System.out.println("You have specified both -enable and -disable. Only one should be provided.");
|
||||
return 1;
|
||||
}
|
||||
if (cli.hasOption("enable")) {
|
||||
String zkHost = getZkHost(cli);
|
||||
if (zkHost == null) {
|
||||
System.out.println("ZK Host not found. Solr should be running in cloud mode");
|
||||
exit(1);
|
||||
}
|
||||
String cmd = cli.getArgs()[0];
|
||||
boolean prompt = Boolean.parseBoolean(cli.getOptionValue("prompt", "false"));
|
||||
boolean updateIncludeFileOnly = Boolean.parseBoolean(cli.getOptionValue("updateIncludeFileOnly", "false"));
|
||||
switch (cmd) {
|
||||
case "enable":
|
||||
if (!prompt && !cli.hasOption("credentials")) {
|
||||
System.out.println("Option -credentials or -prompt is required with enable.");
|
||||
new HelpFormatter().printHelp("bin/solr auth <enable|disable> [OPTIONS]", getToolOptions(this));
|
||||
exit(1);
|
||||
} else if (!prompt && (cli.getOptionValue("credentials") == null || !cli.getOptionValue("credentials").contains(":"))) {
|
||||
System.out.println("Option -credentials is not in correct format.");
|
||||
new HelpFormatter().printHelp("bin/solr auth <enable|disable> [OPTIONS]", getToolOptions(this));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if (cli.hasOption("credentials") == false && cli.hasOption("prompt") == false) {
|
||||
System.out.println("Option -credentials or -prompt is required with -enable.");
|
||||
new HelpFormatter().printHelp("bin/solr auth [OPTIONS]", getToolOptions(this));
|
||||
exit(1);
|
||||
} else if (cli.hasOption("prompt") == false &&
|
||||
(cli.getOptionValue("credentials") == null || !cli.getOptionValue("credentials").contains(":"))) {
|
||||
System.out.println("Option -credentials is not in correct format.");
|
||||
new HelpFormatter().printHelp("bin/solr auth [OPTIONS]", getToolOptions(this));
|
||||
exit(1);
|
||||
}
|
||||
String zkHost = null;
|
||||
|
||||
String username, password;
|
||||
if (cli.hasOption("credentials")) {
|
||||
String credentials = cli.getOptionValue("credentials");
|
||||
username = credentials.split(":")[0];
|
||||
password = credentials.split(":")[1];
|
||||
} else {
|
||||
Console console = System.console();
|
||||
username = console.readLine("Enter username: ");
|
||||
password = new String(console.readPassword("Enter password: "));
|
||||
}
|
||||
// check if security is already enabled or not
|
||||
try (SolrZkClient zkClient = new SolrZkClient(zkHost, 10000)) {
|
||||
if (zkClient.exists("/security.json", true)) {
|
||||
byte oldSecurityBytes[] = zkClient.getData("/security.json", null, null, true);
|
||||
if (!"{}".equals(new String(oldSecurityBytes, StandardCharsets.UTF_8).trim())) {
|
||||
System.out.println("Security is already enabled. You can disable it with 'bin/solr auth -disable'. Existing security.json: \n"
|
||||
+ new String(oldSecurityBytes, StandardCharsets.UTF_8));
|
||||
if (!updateIncludeFileOnly) {
|
||||
try {
|
||||
zkHost = getZkHost(cli);
|
||||
} catch (Exception ex) {
|
||||
if (cli.hasOption("zkHost")) {
|
||||
System.out.println("Couldn't get ZooKeeper host. Please make sure that ZooKeeper is running and the correct zkHost has been passed in.");
|
||||
} else {
|
||||
System.out.println("Couldn't get ZooKeeper host. Please make sure Solr is running in cloud mode, or a zkHost has been passed in.");
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
if (zkHost == null) {
|
||||
if (cli.hasOption("zkHost")) {
|
||||
System.out.println("Couldn't get ZooKeeper host. Please make sure that ZooKeeper is running and the correct zkHost has been passed in.");
|
||||
} else {
|
||||
System.out.println("Couldn't get ZooKeeper host. Please make sure Solr is running in cloud mode, or a zkHost has been passed in.");
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// check if security is already enabled or not
|
||||
try (SolrZkClient zkClient = new SolrZkClient(zkHost, 10000)) {
|
||||
if (zkClient.exists("/security.json", true)) {
|
||||
byte oldSecurityBytes[] = zkClient.getData("/security.json", null, null, true);
|
||||
if (!"{}".equals(new String(oldSecurityBytes, StandardCharsets.UTF_8).trim())) {
|
||||
System.out.println("Security is already enabled. You can disable it with 'bin/solr auth disable'. Existing security.json: \n"
|
||||
+ new String(oldSecurityBytes, StandardCharsets.UTF_8));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean blockUnknown = cli.getOptionValue("blockUnknown") == null ?
|
||||
cli.hasOption("blockUnknown"): Boolean.valueOf(cli.getOptionValue("blockUnknown"));
|
||||
String username, password;
|
||||
if (cli.hasOption("credentials")) {
|
||||
String credentials = cli.getOptionValue("credentials");
|
||||
username = credentials.split(":")[0];
|
||||
password = credentials.split(":")[1];
|
||||
} else {
|
||||
Console console = System.console();
|
||||
username = console.readLine("Enter username: ");
|
||||
password = new String(console.readPassword("Enter password: "));
|
||||
}
|
||||
|
||||
String securityJson = "{" +
|
||||
"\n \"authentication\":{" +
|
||||
"\n \"blockUnknown\": " + blockUnknown + "," +
|
||||
"\n \"class\":\"solr.BasicAuthPlugin\"," +
|
||||
"\n \"credentials\":{\""+username+"\":\"" + Sha256AuthenticationProvider.getSaltedHashedValue(password) + "\"}" +
|
||||
"\n }," +
|
||||
"\n \"authorization\":{" +
|
||||
"\n \"class\":\"solr.RuleBasedAuthorizationPlugin\"," +
|
||||
"\n \"permissions\":[" +
|
||||
"\n {\"name\":\"security-edit\", \"role\":\"admin\"}," +
|
||||
"\n {\"name\":\"collection-admin-edit\", \"role\":\"admin\"}," +
|
||||
"\n {\"name\":\"core-admin-edit\", \"role\":\"admin\"}" +
|
||||
"\n ]," +
|
||||
"\n \"user-role\":{\""+username+"\":\"admin\"}" +
|
||||
"\n }" +
|
||||
"\n}";
|
||||
boolean blockUnknown = Boolean.valueOf(cli.getOptionValue("blockUnknown", "false"));
|
||||
|
||||
String securityJson = "{" +
|
||||
"\n \"authentication\":{" +
|
||||
"\n \"blockUnknown\": " + blockUnknown + "," +
|
||||
"\n \"class\":\"solr.BasicAuthPlugin\"," +
|
||||
"\n \"credentials\":{\"" + username + "\":\"" + Sha256AuthenticationProvider.getSaltedHashedValue(password) + "\"}" +
|
||||
"\n }," +
|
||||
"\n \"authorization\":{" +
|
||||
"\n \"class\":\"solr.RuleBasedAuthorizationPlugin\"," +
|
||||
"\n \"permissions\":[" +
|
||||
"\n {\"name\":\"security-edit\", \"role\":\"admin\"}," +
|
||||
"\n {\"name\":\"collection-admin-edit\", \"role\":\"admin\"}," +
|
||||
"\n {\"name\":\"core-admin-edit\", \"role\":\"admin\"}" +
|
||||
"\n ]," +
|
||||
"\n \"user-role\":{\"" + username + "\":\"admin\"}" +
|
||||
"\n }" +
|
||||
"\n}";
|
||||
|
||||
if (!updateIncludeFileOnly) {
|
||||
System.out.println("Uploading following security.json: " + securityJson);
|
||||
|
||||
try (SolrZkClient zkClient = new SolrZkClient(zkHost, 10000)) {
|
||||
zkClient.setData("/security.json", securityJson.getBytes(StandardCharsets.UTF_8), true);
|
||||
}
|
||||
}
|
||||
|
||||
String solrIncludeFilename = cli.getOptionValue("solrIncludeFile");
|
||||
File includeFile = new File(solrIncludeFilename);
|
||||
if (includeFile.exists() == false || includeFile.canWrite() == false) {
|
||||
System.out.println("Solr include file " + solrIncludeFilename + " doesn't exist or is not writeable.");
|
||||
printAuthEnablingInstructions(username, password);
|
||||
System.exit(0);
|
||||
}
|
||||
File basicAuthConfFile = new File(includeFile.getParent() + File.separator + "basicAuth.conf");
|
||||
|
||||
if (basicAuthConfFile.getParentFile().canWrite() == false) {
|
||||
System.out.println("Cannot write to file: " + basicAuthConfFile.getAbsolutePath());
|
||||
printAuthEnablingInstructions(username, password);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
FileUtils.writeStringToFile(basicAuthConfFile,
|
||||
"httpBasicAuthUser=" + username + "\nhttpBasicAuthPassword=" + password, StandardCharsets.UTF_8);
|
||||
String solrIncludeFilename = cli.getOptionValue("solrIncludeFile");
|
||||
File includeFile = new File(solrIncludeFilename);
|
||||
if (includeFile.exists() == false || includeFile.canWrite() == false) {
|
||||
System.out.println("Solr include file " + solrIncludeFilename + " doesn't exist or is not writeable.");
|
||||
printAuthEnablingInstructions(username, password);
|
||||
System.exit(0);
|
||||
}
|
||||
String authConfDir = cli.getOptionValue("authConfDir");
|
||||
File basicAuthConfFile = new File(authConfDir + File.separator + "basicAuth.conf");
|
||||
|
||||
// update the solr.in.sh file to contain the necessary authentication lines
|
||||
updateIncludeFileEnableAuth(includeFile, basicAuthConfFile.getAbsolutePath(), username, password);
|
||||
return 0;
|
||||
} else if (cli.hasOption("disable")) {
|
||||
String zkHost = getZkHost(cli);
|
||||
if (zkHost == null) {
|
||||
stdout.print("ZK Host not found. Solr should be running in cloud mode");
|
||||
if (basicAuthConfFile.getParentFile().canWrite() == false) {
|
||||
System.out.println("Cannot write to file: " + basicAuthConfFile.getAbsolutePath());
|
||||
printAuthEnablingInstructions(username, password);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
FileUtils.writeStringToFile(basicAuthConfFile,
|
||||
"httpBasicAuthUser=" + username + "\nhttpBasicAuthPassword=" + password, StandardCharsets.UTF_8);
|
||||
|
||||
// update the solr.in.sh file to contain the necessary authentication lines
|
||||
updateIncludeFileEnableAuth(includeFile, basicAuthConfFile.getAbsolutePath());
|
||||
return 0;
|
||||
|
||||
case "disable":
|
||||
if (!updateIncludeFileOnly) {
|
||||
zkHost = getZkHost(cli);
|
||||
if (zkHost == null) {
|
||||
stdout.print("ZK Host not found. Solr should be running in cloud mode");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
System.out.println("Uploading following security.json: {}");
|
||||
|
||||
try (SolrZkClient zkClient = new SolrZkClient(zkHost, 10000)) {
|
||||
zkClient.setData("/security.json", "{}".getBytes(StandardCharsets.UTF_8), true);
|
||||
}
|
||||
}
|
||||
|
||||
solrIncludeFilename = cli.getOptionValue("solrIncludeFile");
|
||||
includeFile = new File(solrIncludeFilename);
|
||||
if (!includeFile.exists() || !includeFile.canWrite()) {
|
||||
System.out.println("Solr include file " + solrIncludeFilename + " doesn't exist or is not writeable.");
|
||||
System.out.println("Security has been disabled. Please remove any SOLR_AUTH_TYPE or SOLR_AUTHENTICATION_OPTS configuration from solr.in.sh/solr.in.cmd.\n");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
// update the solr.in.sh file to comment out the necessary authentication lines
|
||||
updateIncludeFileDisableAuth(includeFile);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
System.out.println("Valid auth commands are: enable, disable");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
System.out.println("Uploading following security.json: {}");
|
||||
|
||||
try (SolrZkClient zkClient = new SolrZkClient(zkHost, 10000)) {
|
||||
zkClient.setData("/security.json", "{}".getBytes(StandardCharsets.UTF_8), true);
|
||||
}
|
||||
|
||||
String solrIncludeFilename = cli.getOptionValue("solrIncludeFile");
|
||||
File includeFile = new File(solrIncludeFilename);
|
||||
if (includeFile.exists() == false || includeFile.canWrite() == false) {
|
||||
System.out.println("Solr include file " + solrIncludeFilename + " doesn't exist or is not writeable.");
|
||||
System.out.println("Security has been disabled. Please remove any SOLR_AUTH_TYPE or SOLR_AUTHENTICATION_OPTS configuration from solr.in.sh/solr.in.cmd.\n");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
// update the solr.in.sh file to comment out the necessary authentication lines
|
||||
updateIncludeFileDisableAuth(includeFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
System.out.println("Options not understood (should be -enable or -disable).");
|
||||
new HelpFormatter().printHelp("bin/solr auth [OPTIONS]", getToolOptions(this));
|
||||
System.out.println("Options not understood.");
|
||||
new HelpFormatter().printHelp("bin/solr auth <enable|disable> [OPTIONS]", getToolOptions(this));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
private void printAuthEnablingInstructions(String username, String password) {
|
||||
if (SystemUtils.IS_OS_WINDOWS) {
|
||||
System.out.println("\nAdd the following lines to the solr.in.cmd file so that the solr.cmd script can use subsequently.\n");
|
||||
@ -3708,11 +3750,11 @@ public class SolrCLI {
|
||||
} else {
|
||||
System.out.println("\nAdd the following lines to the solr.in.sh file so that the ./solr script can use subsequently.\n");
|
||||
System.out.println("SOLR_AUTH_TYPE=\"basic\"\n"
|
||||
+ "SOLR_AUTHENTICATION_OPTS=\"-DbasicAuth=" + username + ":" + password + "\"\n");
|
||||
+ "SOLR_AUTHENTICATION_OPTS=\"-Dbasicauth=" + username + ":" + password + "\"\n");
|
||||
}
|
||||
}
|
||||
|
||||
private void updateIncludeFileEnableAuth(File includeFile, String basicAuthConfFile, String username, String password) throws IOException {
|
||||
private void updateIncludeFileEnableAuth(File includeFile, String basicAuthConfFile) throws IOException {
|
||||
List<String> includeFileLines = FileUtils.readLines(includeFile, StandardCharsets.UTF_8);
|
||||
for (int i=0; i<includeFileLines.size(); i++) {
|
||||
String line = includeFileLines.get(i);
|
||||
@ -3738,7 +3780,7 @@ public class SolrCLI {
|
||||
|
||||
System.out.println("Written out credentials file: " + basicAuthConfFile + ", updated Solr include file: " + includeFile.getAbsolutePath() + ".");
|
||||
}
|
||||
|
||||
|
||||
private void updateIncludeFileDisableAuth(File includeFile) throws IOException {
|
||||
List<String> includeFileLines = FileUtils.readLines(includeFile, StandardCharsets.UTF_8);
|
||||
boolean hasChanged = false;
|
||||
@ -3762,7 +3804,7 @@ public class SolrCLI {
|
||||
@Override
|
||||
protected void runImpl(CommandLine cli) throws Exception {}
|
||||
}
|
||||
|
||||
|
||||
public static class UtilsTool extends ToolBase {
|
||||
private Path serverPath;
|
||||
private Path logsPath;
|
||||
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.solr.util.configuration;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.solr.common.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Dedicated object to handle Solr configurations
|
||||
*/
|
||||
public class SSLConfigurations {
|
||||
private final Map<String, String> envVars;
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
||||
|
||||
public static class SysProps {
|
||||
public static final String SSL_KEY_STORE_PASSWORD = "javax.net.ssl.keyStorePassword";
|
||||
public static final String SSL_TRUST_STORE_PASSWORD = "javax.net.ssl.trustStorePassword";
|
||||
}
|
||||
|
||||
public static class EnvVars {
|
||||
public static final String SOLR_SSL_CLIENT_KEY_STORE_PASSWORD = "SOLR_SSL_CLIENT_KEY_STORE_PASSWORD";
|
||||
public static final String SOLR_SSL_KEY_STORE_PASSWORD = "SOLR_SSL_KEY_STORE_PASSWORD";
|
||||
public static final String SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD = "SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD";
|
||||
public static final String SOLR_SSL_TRUST_STORE_PASSWORD = "SOLR_SSL_TRUST_STORE_PASSWORD";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param envVars Map of environment variables to use
|
||||
*/
|
||||
public SSLConfigurations(Map<String, String> envVars) {
|
||||
this.envVars = envVars;
|
||||
}
|
||||
|
||||
/** Initiates javax.net.ssl.* system properties from the proper sources. */
|
||||
public void init() {
|
||||
|
||||
String clientKeystorePassword = envVars.get(EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD);
|
||||
String keystorePassword = envVars.get(EnvVars.SOLR_SSL_KEY_STORE_PASSWORD);
|
||||
|
||||
String clientTruststorePassword = envVars.get(EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD);
|
||||
String truststorePassword = envVars.get(EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD);
|
||||
|
||||
if (isEmpty(System.getProperty(SysProps.SSL_KEY_STORE_PASSWORD))
|
||||
&& !(isEmpty(clientKeystorePassword) && isEmpty(keystorePassword))) {
|
||||
log.debug("Setting {} based on env var", SysProps.SSL_KEY_STORE_PASSWORD);
|
||||
System.setProperty(SysProps.SSL_KEY_STORE_PASSWORD, clientKeystorePassword != null ? clientKeystorePassword : keystorePassword);
|
||||
}
|
||||
if (isEmpty(System.getProperty(SysProps.SSL_TRUST_STORE_PASSWORD))
|
||||
&& !(isEmpty(clientTruststorePassword) && isEmpty(truststorePassword))) {
|
||||
log.debug("Setting {} based on env var", SysProps.SSL_TRUST_STORE_PASSWORD);
|
||||
System.setProperty(SysProps.SSL_TRUST_STORE_PASSWORD, clientTruststorePassword != null ? clientTruststorePassword : truststorePassword);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEmpty(String str) {
|
||||
return StringUtils.isEmpty(str);
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.solr.util.configuration;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
public class SSLConfigurationsFactory {
|
||||
static private SSLConfigurations currentConfigurations;
|
||||
|
||||
/**
|
||||
* Creates if necessary and returns singleton object of Configurations. Can be used for
|
||||
* static accessor of application-wide instance.
|
||||
* @return Configurations object
|
||||
*/
|
||||
static public SSLConfigurations current() {
|
||||
if (currentConfigurations == null) {
|
||||
synchronized (SSLConfigurationsFactory.class) {
|
||||
if (currentConfigurations == null) {
|
||||
currentConfigurations = getInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
return currentConfigurations;
|
||||
}
|
||||
|
||||
private static SSLConfigurations getInstance() {
|
||||
return new SSLConfigurations(System.getenv());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static public synchronized void setCurrent(SSLConfigurations configurations) {
|
||||
currentConfigurations = configurations;
|
||||
}
|
||||
}
|
@ -14,16 +14,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.solr.rest.schema;
|
||||
import org.apache.solr.rest.SolrRestletTestBase;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Common Util APIs related to Solr configuration.
|
||||
*/
|
||||
package org.apache.solr.util.configuration;
|
||||
|
||||
public class TestSolrQueryParserDefaultOperatorResource extends SolrRestletTestBase {
|
||||
|
||||
@Test
|
||||
public void testGetDefaultOperator() throws Exception {
|
||||
assertQ("/schema/solrqueryparser/defaultoperator?indent=on&wt=xml",
|
||||
"count(/response/str[@name='defaultOperator']) = 1",
|
||||
"/response/str[@name='defaultOperator'][.='OR']");
|
||||
}
|
||||
}
|
@ -11,8 +11,7 @@
|
||||
"/schema/version",
|
||||
"/schema/similarity",
|
||||
"/schema/solrqueryparser",
|
||||
"/schema/zkversion",
|
||||
"/schema/solrqueryparser/defaultoperator"
|
||||
"/schema/zkversion"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" ?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<schema name="bad-schema-default-operator" version="1.6">
|
||||
<fieldType name="string" class="solr.StrField"/>
|
||||
<field name="id" type="string" indexed="true" stored="true" multiValued="false" required="false"/>
|
||||
<uniqueKey>id</uniqueKey>
|
||||
<!-- BEGIN BAD STUFF: not allowed anymore -->
|
||||
<solrQueryParser defaultOperator="OR"/>
|
||||
<!-- END BAD STUFF -->
|
||||
</schema>
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.solr.rest.schema;
|
||||
import org.apache.solr.rest.SolrRestletTestBase;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestSolrQueryParserResource extends SolrRestletTestBase {
|
||||
|
||||
@Test
|
||||
public void testGetSolrQueryParser() throws Exception {
|
||||
assertQ("/schema/solrqueryparser?indent=on&wt=xml",
|
||||
"count(/response/lst[@name='solrQueryParser']) = 1",
|
||||
"count(/response/lst[@name='solrQueryParser']/str[@name='defaultOperator']) = 1",
|
||||
"/response/lst[@name='solrQueryParser']/str[@name='defaultOperator'][.='OR']");
|
||||
}
|
||||
}
|
@ -127,5 +127,9 @@ public class BadIndexSchemaTest extends AbstractBadConfigTestBase {
|
||||
doTest("bad-schema-sim-default-does-not-exist.xml",
|
||||
"ft-does-not-exist");
|
||||
}
|
||||
|
||||
|
||||
public void testDefaultOperatorBanned() throws Exception {
|
||||
doTest("bad-schema-default-operator.xml",
|
||||
"default operator in schema (solrQueryParser/@defaultOperator) not supported");
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ public class TestUseDocValuesAsStored extends AbstractBadConfigTestBase {
|
||||
@After
|
||||
private void afterTest() throws Exception {
|
||||
clearIndex();
|
||||
commit();
|
||||
assertU(commit());
|
||||
deleteCore();
|
||||
System.clearProperty("managed.schema.mutable");
|
||||
System.clearProperty("enable.update.log");
|
||||
|
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.solr.util.configuration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.lucene.util.TestRuleRestoreSystemProperties;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TestRule;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class SSLConfigurationsTest {
|
||||
private Map<String, String> envs;
|
||||
private SSLConfigurations sut;
|
||||
|
||||
public static final String SAMPLE_PW1 = "pw123";
|
||||
public static final String SAMPLE_PW2 = "pw456";
|
||||
public static final String SAMPLE_PW3 = "pw789";
|
||||
public static final String KEY_STORE_PASSWORD = SSLConfigurations.SysProps.SSL_KEY_STORE_PASSWORD;
|
||||
public static final String TRUST_STORE_PASSWORD = SSLConfigurations.SysProps.SSL_TRUST_STORE_PASSWORD;
|
||||
|
||||
@Rule
|
||||
public TestRule syspropRestore = new TestRuleRestoreSystemProperties(
|
||||
SSLConfigurations.SysProps.SSL_KEY_STORE_PASSWORD,
|
||||
SSLConfigurations.SysProps.SSL_TRUST_STORE_PASSWORD
|
||||
);
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
envs = new HashMap<>();
|
||||
}
|
||||
|
||||
private SSLConfigurations createSut() {
|
||||
sut = new SSLConfigurations(envs);
|
||||
return sut;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSslConfigKeystorePwFromKeystoreEnvVar() {
|
||||
envs.put(SSLConfigurations.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, SAMPLE_PW1);
|
||||
createSut().init();
|
||||
assertThat(System.getProperty(KEY_STORE_PASSWORD), is(SAMPLE_PW1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSslConfigKeystorePwFromClientKeystoreEnvVar() {
|
||||
envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW2);
|
||||
createSut().init();
|
||||
assertThat(System.getProperty(KEY_STORE_PASSWORD), is(SAMPLE_PW2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSslConfigKeystorePwFromBothEnvVars() {
|
||||
envs.put(SSLConfigurations.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, SAMPLE_PW1);
|
||||
envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW2);
|
||||
createSut().init();
|
||||
assertThat(System.getProperty(KEY_STORE_PASSWORD), is(SAMPLE_PW2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSslConfigKeystorePwNotOverwrittenIfExists() {
|
||||
System.setProperty(KEY_STORE_PASSWORD, SAMPLE_PW3);
|
||||
envs.put(SSLConfigurations.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, SAMPLE_PW1);
|
||||
envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW2);
|
||||
createSut().init();
|
||||
assertThat(System.getProperty(KEY_STORE_PASSWORD), is(SAMPLE_PW3)); // unchanged
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSslConfigTruststorePwFromKeystoreEnvVar() {
|
||||
envs.put(SSLConfigurations.EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD, SAMPLE_PW1);
|
||||
createSut().init();
|
||||
assertThat(System.getProperty(TRUST_STORE_PASSWORD), is(SAMPLE_PW1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSslConfigTruststorePwFromClientKeystoreEnvVar() {
|
||||
envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD, SAMPLE_PW2);
|
||||
createSut().init();
|
||||
assertThat(System.getProperty(TRUST_STORE_PASSWORD), is(SAMPLE_PW2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSslConfigTruststorePwFromBothEnvVars() {
|
||||
envs.put(SSLConfigurations.EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD, SAMPLE_PW1);
|
||||
envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD, SAMPLE_PW2);
|
||||
createSut().init();
|
||||
assertThat(System.getProperty(TRUST_STORE_PASSWORD), is(SAMPLE_PW2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSslConfigTruststorePwNotOverwrittenIfExists() {
|
||||
System.setProperty(TRUST_STORE_PASSWORD, SAMPLE_PW3);
|
||||
envs.put(SSLConfigurations.EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD, SAMPLE_PW1);
|
||||
envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD, SAMPLE_PW2);
|
||||
createSut().init();
|
||||
assertThat(System.getProperty(TRUST_STORE_PASSWORD), is(SAMPLE_PW3)); // unchanged
|
||||
}
|
||||
|
||||
}
|
@ -8,9 +8,9 @@
|
||||
<!-- ============================================================= -->
|
||||
<Configure id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
|
||||
<Set name="KeyStorePath"><Property name="solr.jetty.keystore" default="./etc/solr-ssl.keystore.jks"/></Set>
|
||||
<Set name="KeyStorePassword"><Property name="solr.jetty.keystore.password" default="secret"/></Set>
|
||||
<Set name="KeyStorePassword"><Env name="SOLR_SSL_KEY_STORE_PASSWORD" default="secret"/></Set>
|
||||
<Set name="TrustStorePath"><Property name="solr.jetty.truststore" default="./etc/solr-ssl.keystore.jks"/></Set>
|
||||
<Set name="TrustStorePassword"><Property name="solr.jetty.truststore.password" default="secret"/></Set>
|
||||
<Set name="TrustStorePassword"><Env name="SOLR_SSL_TRUST_STORE_PASSWORD" default="secret"/></Set>
|
||||
<Set name="NeedClientAuth"><Property name="solr.jetty.ssl.needClientAuth" default="false"/></Set>
|
||||
<Set name="WantClientAuth"><Property name="solr.jetty.ssl.wantClientAuth" default="false"/></Set>
|
||||
<Set name="KeyStoreType"><Property name="solr.jetty.keystore.type" default="JKS"/></Set>
|
||||
|
@ -1,6 +0,0 @@
|
||||
---
|
||||
title: "Page Not Found"
|
||||
search: exclude
|
||||
---
|
||||
|
||||
Sorry, but the page you were trying to view does not exist. Try searching for it or looking at the URL to see if it looks correct.
|
@ -36,18 +36,6 @@ exclude:
|
||||
- .gitignore
|
||||
- pdf/
|
||||
|
||||
# if you uncomment the next line, the Feedback link gets removed
|
||||
feedback_disable: true
|
||||
|
||||
# used as a contact email for the Feedback link in the top navigation bar
|
||||
# feedback_email: an_email@apache.org
|
||||
|
||||
# if you uncomment the next line, it changes the Feedback text
|
||||
# feedback_text: "Need help?"
|
||||
|
||||
# if you uncomment the next line, it changes where the feedback link points to
|
||||
# feedback_link: "http://helpy.io/"
|
||||
|
||||
# these are defaults used for the frontmatter for these file types
|
||||
defaults:
|
||||
-
|
||||
|
@ -1,15 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
type: archive
|
||||
---
|
||||
|
||||
<div class="post-header">
|
||||
<h1 class="post-title-main">{{ page.title }}</h1>
|
||||
</div>
|
||||
<div class="post-content">
|
||||
|
||||
{{ content }}
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
<!-- Send feedback function -->
|
||||
<script>
|
||||
function SendLinkByMail(href) {
|
||||
var subject= "{{site.site_title}} feedback";
|
||||
var body = "I have some feedback about the {{page.title}} page: ";
|
||||
body += window.location.href;
|
||||
body += "";
|
||||
var uri = "mailto:{{site.feedback_email}}?subject=";
|
||||
uri += encodeURIComponent(subject);
|
||||
uri += "&body=";
|
||||
uri += encodeURIComponent(body);
|
||||
window.location.href = uri;
|
||||
}
|
||||
</script>
|
||||
|
||||
<li><a href="{% if site.feedback_link %}{{site.feedback_link}}{% else %}javascript:(function()%7BSendLinkByMail()%3B%7D)()%3B{% endif %}" target="_blank">{% if site.feedback_link == null %}<i class="fa fa-envelope-o"></i>{% endif %} {% if site.feedback_text %}{{site.feedback_text}}{% else %}Feedback{% endif %}</a></li>
|
@ -3,7 +3,7 @@
|
||||
<div class="col-lg-12 footer">
|
||||
©{{ site.solr-attributes.build-year }} {{site.company_name}}. All rights reserved. <br />
|
||||
{% if page.last_updated %}<p>Page last updated:</span> {{page.last_updated}}<br/>{% endif %} Site Version: {{ site.solr-attributes.solr-guide-version }} <br />Site last generated: {{ site.solr-attributes.build-date }} <br />
|
||||
<p><img src="{{ "solr-sunOnly-small.png" }}" alt="Apache Solr"/></p>
|
||||
<p><img src="{{ "images/solr-sunOnly-small.png" }}" alt="Apache Solr"/></p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -1 +0,0 @@
|
||||
<figure>{% if {{include.url}} %}<a class="no_icon" target="_blank" href="{{include.url}}">{% endif %}<img class="docimage" src="images/{{include.file}}" alt="{{include.alt}}" {% if {{include.max-width}} %}style="max-width: {{include.max-width}}px"{% endif %} />{% if {{include.url}} %}</a>{% endif %}{% if {{include.caption}} %}<figcaption>{{include.caption}}</figcaption></figure>{% endif %}
|
@ -1 +0,0 @@
|
||||
<img class="inline" src="images/{{include.file}}" alt="{{include.alt}}" />
|
@ -1,44 +0,0 @@
|
||||
{% comment %}Get links from each sidebar, as listed in the _config.yml file under sidebars{% endcomment %}
|
||||
|
||||
{% for sidebar in site.sidebars %}
|
||||
{% for entry in site.data.sidebars[sidebar].entries %}
|
||||
{% for folder in entry.folders %}
|
||||
{% for folderitem in folder.folderitems %}
|
||||
{% if folderitem.url contains "html#" %}
|
||||
[{{folderitem.url | remove: "/" }}]: {{folderitem.url | remove: "/"}}
|
||||
{% else %}
|
||||
[{{folderitem.url | remove: "/" | remove: ".html"}}]: {{folderitem.url | remove: "/"}}
|
||||
{% endif %}
|
||||
{% for subfolders in folderitem.subfolders %}
|
||||
{% for subfolderitem in subfolders.subfolderitems %}
|
||||
[{{subfolderitem.url | remove: "/" | remove: ".html"}}]: {{subfolderitem.url | remove: "/"}}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
{% comment %} Get links from topnav {% endcomment %}
|
||||
|
||||
{% for entry in site.data.topnav.topnav %}
|
||||
{% for item in entry.items %}
|
||||
{% if item.external_url == null %}
|
||||
[{{item.url | remove: "/" | remove: ".html"}}]: {{item.url | remove: "/"}}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
{% comment %}Get links from topnav dropdowns {% endcomment %}
|
||||
|
||||
{% for entry in site.data.topnav.topnav_dropdowns %}
|
||||
{% for folder in entry.folders %}
|
||||
{% for folderitem in folder.folderitems %}
|
||||
{% if folderitem.external_url == null %}
|
||||
[{{folderitem.url | remove: "/" | remove: ".html"}}]: {{folderitem.url | remove: "/"}}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
@ -33,9 +33,6 @@
|
||||
<li><a href="https://lucene.apache.org/solr/community.html" target="_blank">Solr Community Links</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
{% if site.feedback_disable == null or site.feedback_disable == false %}
|
||||
{% include feedback.html %}
|
||||
{% endif %}
|
||||
<!--comment out this block if you want to hide search-->
|
||||
<li>
|
||||
<!--start search-->
|
||||
|
@ -1,41 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
<article class="post" itemscope itemtype="http://schema.org/BlogPosting">
|
||||
|
||||
<header class="post-header">
|
||||
<h1 class="post-title" itemprop="name headline">{{ page.title }}</h1>
|
||||
<p class="post-meta"><time datetime="{{ page.date | date_to_xmlschema }}" itemprop="datePublished">{{ page.date | date: "%b %-d, %Y" }}</time> {% if page.author %}<span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">/ {{ page.author }}</span></span>{% endif %}{% if page.tags != null %}/
|
||||
{% assign projectTags = site.data.tags.allowed-tags %}
|
||||
{% for tag in page.tags %}
|
||||
{% if projectTags contains tag %}
|
||||
<a href="{{ "../tag_" | append: tag | append: ".html" }}">{{tag}}</a>{% unless forloop.last %}, {% endunless%}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
</header>
|
||||
|
||||
<div class="post-content" itemprop="articleBody">
|
||||
|
||||
{% if page.summary %}
|
||||
<div class="summary">{{page.summary}}</div>
|
||||
{% endif %}
|
||||
|
||||
{{ content }}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</article>
|
||||
|
||||
{% if site.disqus %}
|
||||
{% include disqus.html %}
|
||||
{% endif %}
|
||||
|
||||
{{site.data.alerts.hr_shaded}}
|
||||
|
||||
{% include footer.html %}
|
@ -77,7 +77,7 @@ body
|
||||
}
|
||||
|
||||
body.DRAFT {
|
||||
background-image: url("../draft-background.png");
|
||||
background-image: url("../images/draft-background.png");
|
||||
}
|
||||
|
||||
a
|
||||
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
@ -21,12 +21,12 @@ Schema defaults and `copyFields` cannot be used to populate the `uniqueKey` fiel
|
||||
Further, the operation will fail if the `uniqueKey` field is used, but is multivalued (or inherits the multivalue-ness from the `fieldtype`). However, `uniqueKey` will continue to work, as long as the field is properly used.
|
||||
|
||||
|
||||
[[OtherSchemaElements-DefaultSearchField_QueryOperator]]
|
||||
== Default Search Field & Query Operator
|
||||
[[OtherSchemaElements-DefaultSearchField]]
|
||||
== Default Search Field
|
||||
|
||||
Although they have been deprecated for quite some time, Solr still has support for Schema based configuration of a `<defaultSearchField/>` (which is superseded by the <<the-standard-query-parser.adoc#the-standard-query-parser,`df parameter`>>) and `<solrQueryParser defaultOperator="OR"/>` (which is superseded by the <<the-standard-query-parser.adoc#the-standard-query-parser,`q.op` parameter>>.
|
||||
Although it has been deprecated for quite some time, Solr still has support for Schema based configuration of a `<defaultSearchField/>` (which is superseded by the <<the-standard-query-parser.adoc#the-standard-query-parser,`df parameter`>>).
|
||||
|
||||
If you have these options specified in your Schema, you are strongly encouraged to replace them with request parameters (or <<request-parameters-api.adoc#request-parameters-api,request parameter defaults>>) as support for them may be removed from future Solr release.
|
||||
If you have this option specified in your Schema, you are strongly encouraged to replace it with request parameters (or <<request-parameters-api.adoc#request-parameters-api,request parameter defaults>>) as support for it will be removed from future Solr release.
|
||||
|
||||
[[OtherSchemaElements-Similarity]]
|
||||
== Similarity
|
||||
|
@ -92,7 +92,7 @@ title_page:
|
||||
align: right
|
||||
logo:
|
||||
top: 10%
|
||||
image: image:../../solr-sunOnly-small.png[pdfwidth=10%]
|
||||
image: image:../../images/solr-sunOnly-small.png[pdfwidth=10%]
|
||||
align: right
|
||||
title:
|
||||
top: 55%
|
||||
|
@ -47,7 +47,6 @@ bin/solr -e cloud -noprompt
|
||||
* `/schema/version`: <<SchemaAPI-ShowtheSchemaVersion,retrieve>> the schema version
|
||||
* `/schema/uniquekey`: <<SchemaAPI-ListUniqueKey,retrieve>> the defined uniqueKey
|
||||
* `/schema/similarity`: <<SchemaAPI-ShowGlobalSimilarity,retrieve>> the global similarity definition
|
||||
* `/schema/solrqueryparser/defaultoperator`: <<SchemaAPI-GettheDefaultQueryOperator,retrieve>> the default operator
|
||||
|
||||
[[SchemaAPI-ModifytheSchema]]
|
||||
== Modify the Schema
|
||||
@ -1165,63 +1164,6 @@ curl http://localhost:8983/solr/gettingstarted/schema/similarity?wt=json
|
||||
----
|
||||
|
||||
|
||||
[[SchemaAPI-GettheDefaultQueryOperator]]
|
||||
=== Get the Default Query Operator
|
||||
|
||||
`GET /_collection_/schema/solrqueryparser/defaultoperator`
|
||||
|
||||
[[SchemaAPI-INPUT.9]]
|
||||
==== INPUT
|
||||
|
||||
*Path Parameters*
|
||||
|
||||
// TODO: Change column width to %autowidth.spread when https://github.com/asciidoctor/asciidoctor-pdf/issues/599 is fixed
|
||||
|
||||
[cols="30,70",options="header"]
|
||||
|===
|
||||
|Key |Description
|
||||
|collection |The collection (or core) name.
|
||||
|===
|
||||
|
||||
*Query Parameters*
|
||||
|
||||
The query parameters can be added to the API request after a '?'.
|
||||
|
||||
// TODO: Change column width to %autowidth.spread when https://github.com/asciidoctor/asciidoctor-pdf/issues/599 is fixed
|
||||
|
||||
[cols="15,10,10,10,55",options="header"]
|
||||
|===
|
||||
|Key |Type |Required |Default |Description
|
||||
|wt |string |No |json |Defines the format of the response. The options are *json* or *xml*. If not specified, JSON will be returned by default.
|
||||
|===
|
||||
|
||||
[[SchemaAPI-OUTPUT.9]]
|
||||
==== OUTPUT
|
||||
|
||||
*Output Content*
|
||||
|
||||
The output will include simply the default operator if none is defined by the user.
|
||||
|
||||
[[SchemaAPI-EXAMPLES.9]]
|
||||
==== EXAMPLES
|
||||
|
||||
Get the default operator.
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
curl http://localhost:8983/solr/gettingstarted/schema/solrqueryparser/defaultoperator?wt=json
|
||||
----
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"responseHeader":{
|
||||
"status":0,
|
||||
"QTime":2},
|
||||
"defaultOperator":"OR"}
|
||||
----
|
||||
|
||||
|
||||
[[SchemaAPI-ManageResourceData]]
|
||||
== Manage Resource Data
|
||||
|
||||
|
@ -30,7 +30,7 @@ In addition to the common request parameter, highlighting parameters, and simple
|
||||
|<<TheDisMaxQueryParser-TheqParameter,q>> |Defines the raw input strings for the query.
|
||||
|<<TheDisMaxQueryParser-Theq.altParameter,q.alt>> |Calls the standard query parser and defines query input strings, when the q parameter is not used.
|
||||
|<<TheDisMaxQueryParser-Theqf_QueryFields_Parameter,qf>> |Query Fields: specifies the fields in the index on which to perform the query. If absent, defaults to `df`.
|
||||
|<<TheDisMaxQueryParser-Themm_MinimumShouldMatch_Parameter,mm>> |Minimum "Should" Match: specifies a minimum number of clauses that must match in a query. If no 'mm' parameter is specified in the query, or as a default in `solrconfig.xml`, the effective value of the `q.op` parameter (either in the query, as a default in `solrconfig.xml`, or from the `defaultOperator` option in the Schema) is used to influence the behavior. If `q.op` is effectively AND'ed, then mm=100%; if `q.op` is OR'ed, then mm=1. Users who want to force the legacy behavior should set a default value for the 'mm' parameter in their `solrconfig.xml` file. Users should add this as a configured default for their request handlers. This parameter tolerates miscellaneous white spaces in expressions (e.g., `" 3 < -25% 10 < -3\n", " \n-25%\n ", " \n3\n "`).
|
||||
|<<TheDisMaxQueryParser-Themm_MinimumShouldMatch_Parameter,mm>> |Minimum "Should" Match: specifies a minimum number of clauses that must match in a query. If no 'mm' parameter is specified in the query, or as a default in `solrconfig.xml`, the effective value of the `q.op` parameter (either in the query or as a default in `solrconfig.xml`) is used to influence the behavior. If `q.op` is effectively AND'ed, then mm=100%; if `q.op` is OR'ed, then mm=1. Users who want to force the legacy behavior should set a default value for the 'mm' parameter in their `solrconfig.xml` file. Users should add this as a configured default for their request handlers. This parameter tolerates miscellaneous white spaces in expressions (e.g., `" 3 < -25% 10 < -3\n", " \n-25%\n ", " \n3\n "`).
|
||||
|<<TheDisMaxQueryParser-Thepf_PhraseFields_Parameter,pf>> |Phrase Fields: boosts the score of documents in cases where all of the terms in the q parameter appear in close proximity.
|
||||
|<<TheDisMaxQueryParser-Theps_PhraseSlop_Parameter,ps>> |Phrase Slop: specifies the number of positions two terms can be apart in order to match the specified phrase.
|
||||
|<<TheDisMaxQueryParser-Theqs_QueryPhraseSlop_Parameter,qs>> |Query Phrase Slop: specifies the number of positions two terms can be apart in order to match the specified phrase. Used specifically with the `qf` parameter.
|
||||
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.solr.client.solrj.io.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.solr.client.solrj.io.Tuple;
|
||||
import org.apache.solr.client.solrj.io.eval.ComplexEvaluator;
|
||||
import org.apache.solr.client.solrj.io.eval.StreamEvaluator;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Explanation;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Explanation.ExpressionType;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Expressible;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionParameter;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
|
||||
|
||||
public class CopyOfEvaluator extends ComplexEvaluator implements Expressible {
|
||||
|
||||
private static final long serialVersionUID = 1;
|
||||
|
||||
public CopyOfEvaluator(StreamExpression expression, StreamFactory factory) throws IOException {
|
||||
super(expression, factory);
|
||||
}
|
||||
|
||||
public List<Number> evaluate(Tuple tuple) throws IOException {
|
||||
StreamEvaluator colEval1 = subEvaluators.get(0);
|
||||
|
||||
List<Number> numbers1 = (List<Number>)colEval1.evaluate(tuple);
|
||||
double[] vals = new double[numbers1.size()];
|
||||
|
||||
for(int i=0; i<vals.length; i++) {
|
||||
vals[i] = numbers1.get(i).doubleValue();
|
||||
}
|
||||
|
||||
if(subEvaluators.size() == 2) {
|
||||
StreamEvaluator lengthEval = subEvaluators.get(1);
|
||||
Number lengthNum = (Number)lengthEval.evaluate(tuple);
|
||||
int length = lengthNum.intValue();
|
||||
vals = Arrays.copyOf(vals, length);
|
||||
} else {
|
||||
vals = Arrays.copyOf(vals, vals.length);
|
||||
}
|
||||
|
||||
List<Number> copyOf = new ArrayList(vals.length);
|
||||
|
||||
for(int i=0; i<vals.length; i++) {
|
||||
copyOf.add(vals[i]);
|
||||
}
|
||||
|
||||
return copyOf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamExpressionParameter toExpression(StreamFactory factory) throws IOException {
|
||||
StreamExpression expression = new StreamExpression(factory.getFunctionName(getClass()));
|
||||
return expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Explanation toExplanation(StreamFactory factory) throws IOException {
|
||||
return new Explanation(nodeId.toString())
|
||||
.withExpressionType(ExpressionType.EVALUATOR)
|
||||
.withFunctionName(factory.getFunctionName(getClass()))
|
||||
.withImplementingClass(getClass().getName())
|
||||
.withExpression(toExpression(factory).toString());
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.solr.client.solrj.io.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.math3.ml.distance.EuclideanDistance;
|
||||
import org.apache.solr.client.solrj.io.Tuple;
|
||||
import org.apache.solr.client.solrj.io.eval.ComplexEvaluator;
|
||||
import org.apache.solr.client.solrj.io.eval.StreamEvaluator;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Explanation;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Explanation.ExpressionType;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Expressible;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionParameter;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
|
||||
|
||||
public class DistanceEvaluator extends ComplexEvaluator implements Expressible {
|
||||
|
||||
private static final long serialVersionUID = 1;
|
||||
|
||||
public DistanceEvaluator(StreamExpression expression, StreamFactory factory) throws IOException {
|
||||
super(expression, factory);
|
||||
}
|
||||
|
||||
public Number evaluate(Tuple tuple) throws IOException {
|
||||
StreamEvaluator colEval1 = subEvaluators.get(0);
|
||||
StreamEvaluator colEval2 = subEvaluators.get(1);
|
||||
|
||||
List<Number> numbers1 = (List<Number>)colEval1.evaluate(tuple);
|
||||
List<Number> numbers2 = (List<Number>)colEval2.evaluate(tuple);
|
||||
double[] column1 = new double[numbers1.size()];
|
||||
double[] column2 = new double[numbers2.size()];
|
||||
|
||||
for(int i=0; i<numbers1.size(); i++) {
|
||||
column1[i] = numbers1.get(i).doubleValue();
|
||||
}
|
||||
|
||||
for(int i=0; i<numbers2.size(); i++) {
|
||||
column2[i] = numbers2.get(i).doubleValue();
|
||||
}
|
||||
|
||||
EuclideanDistance distance = new EuclideanDistance();
|
||||
return distance.compute(column1, column2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamExpressionParameter toExpression(StreamFactory factory) throws IOException {
|
||||
StreamExpression expression = new StreamExpression(factory.getFunctionName(getClass()));
|
||||
return expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Explanation toExplanation(StreamFactory factory) throws IOException {
|
||||
return new Explanation(nodeId.toString())
|
||||
.withExpressionType(ExpressionType.EVALUATOR)
|
||||
.withFunctionName(factory.getFunctionName(getClass()))
|
||||
.withImplementingClass(getClass().getName())
|
||||
.withExpression(toExpression(factory).toString());
|
||||
}
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.solr.client.solrj.io.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.commons.math3.random.EmpiricalDistribution;
|
||||
import org.apache.commons.math3.stat.descriptive.StatisticalSummary;
|
||||
import org.apache.solr.client.solrj.io.Tuple;
|
||||
import org.apache.solr.client.solrj.io.eval.ComplexEvaluator;
|
||||
import org.apache.solr.client.solrj.io.eval.StreamEvaluator;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Explanation;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Explanation.ExpressionType;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Expressible;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionParameter;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
|
||||
|
||||
public class EmpiricalDistributionEvaluator extends ComplexEvaluator implements Expressible {
|
||||
|
||||
private static final long serialVersionUID = 1;
|
||||
|
||||
public EmpiricalDistributionEvaluator(StreamExpression expression, StreamFactory factory) throws IOException {
|
||||
super(expression, factory);
|
||||
}
|
||||
|
||||
public Tuple evaluate(Tuple tuple) throws IOException {
|
||||
|
||||
if(subEvaluators.size() != 1) {
|
||||
throw new IOException("Empirical dist expects 1 column as a parameters");
|
||||
}
|
||||
|
||||
StreamEvaluator colEval1 = subEvaluators.get(0);
|
||||
|
||||
List<Number> numbers1 = (List<Number>)colEval1.evaluate(tuple);
|
||||
double[] column1 = new double[numbers1.size()];
|
||||
|
||||
for(int i=0; i<numbers1.size(); i++) {
|
||||
column1[i] = numbers1.get(i).doubleValue();
|
||||
}
|
||||
|
||||
Arrays.sort(column1);
|
||||
EmpiricalDistribution empiricalDistribution = new EmpiricalDistribution();
|
||||
empiricalDistribution.load(column1);
|
||||
|
||||
Map map = new HashMap();
|
||||
StatisticalSummary statisticalSummary = empiricalDistribution.getSampleStats();
|
||||
|
||||
map.put("max", statisticalSummary.getMax());
|
||||
map.put("mean", statisticalSummary.getMean());
|
||||
map.put("min", statisticalSummary.getMin());
|
||||
map.put("stdev", statisticalSummary.getStandardDeviation());
|
||||
map.put("sum", statisticalSummary.getSum());
|
||||
map.put("N", statisticalSummary.getN());
|
||||
map.put("var", statisticalSummary.getVariance());
|
||||
|
||||
return new EmpiricalDistributionTuple(empiricalDistribution, column1, map);
|
||||
}
|
||||
|
||||
public static class EmpiricalDistributionTuple extends Tuple {
|
||||
|
||||
private EmpiricalDistribution empiricalDistribution;
|
||||
private double[] backingArray;
|
||||
|
||||
public EmpiricalDistributionTuple(EmpiricalDistribution empiricalDistribution, double[] backingArray, Map map) {
|
||||
super(map);
|
||||
this.empiricalDistribution = empiricalDistribution;
|
||||
this.backingArray = backingArray;
|
||||
}
|
||||
|
||||
public double percentile(double d) {
|
||||
int slot = Arrays.binarySearch(backingArray, d);
|
||||
|
||||
if(slot == 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
if(slot < 0) {
|
||||
if(slot == -1) {
|
||||
return 0.0D;
|
||||
} else {
|
||||
//Not a direct hit
|
||||
slot = Math.abs(slot);
|
||||
--slot;
|
||||
if(slot == backingArray.length) {
|
||||
return 1.0D;
|
||||
} else {
|
||||
return (this.empiricalDistribution.cumulativeProbability(backingArray[slot]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return this.empiricalDistribution.cumulativeProbability(backingArray[slot]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamExpressionParameter toExpression(StreamFactory factory) throws IOException {
|
||||
StreamExpression expression = new StreamExpression(factory.getFunctionName(getClass()));
|
||||
return expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Explanation toExplanation(StreamFactory factory) throws IOException {
|
||||
return new Explanation(nodeId.toString())
|
||||
.withExpressionType(ExpressionType.EVALUATOR)
|
||||
.withFunctionName(factory.getFunctionName(getClass()))
|
||||
.withImplementingClass(getClass().getName())
|
||||
.withExpression(toExpression(factory).toString());
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.solr.client.solrj.io.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.solr.client.solrj.io.Tuple;
|
||||
import org.apache.solr.client.solrj.io.eval.ComplexEvaluator;
|
||||
import org.apache.solr.client.solrj.io.eval.StreamEvaluator;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Explanation;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Explanation.ExpressionType;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Expressible;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionParameter;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
|
||||
|
||||
public class LengthEvaluator extends ComplexEvaluator implements Expressible {
|
||||
|
||||
private static final long serialVersionUID = 1;
|
||||
|
||||
public LengthEvaluator(StreamExpression expression, StreamFactory factory) throws IOException {
|
||||
super(expression, factory);
|
||||
}
|
||||
|
||||
public Number evaluate(Tuple tuple) throws IOException {
|
||||
StreamEvaluator colEval1 = subEvaluators.get(0);
|
||||
List<Number> numbers = (List<Number>)colEval1.evaluate(tuple);
|
||||
return numbers.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamExpressionParameter toExpression(StreamFactory factory) throws IOException {
|
||||
StreamExpression expression = new StreamExpression(factory.getFunctionName(getClass()));
|
||||
return expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Explanation toExplanation(StreamFactory factory) throws IOException {
|
||||
return new Explanation(nodeId.toString())
|
||||
.withExpressionType(ExpressionType.EVALUATOR)
|
||||
.withFunctionName(factory.getFunctionName(getClass()))
|
||||
.withImplementingClass(getClass().getName())
|
||||
.withExpression(toExpression(factory).toString());
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.solr.client.solrj.io.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.solr.client.solrj.io.Tuple;
|
||||
import org.apache.solr.client.solrj.io.eval.ComplexEvaluator;
|
||||
import org.apache.solr.client.solrj.io.eval.StreamEvaluator;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Explanation;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Explanation.ExpressionType;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Expressible;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionParameter;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
|
||||
|
||||
public class PercentileEvaluator extends ComplexEvaluator implements Expressible {
|
||||
|
||||
private static final long serialVersionUID = 1;
|
||||
|
||||
public PercentileEvaluator(StreamExpression expression, StreamFactory factory) throws IOException {
|
||||
super(expression, factory);
|
||||
}
|
||||
|
||||
public Number evaluate(Tuple tuple) throws IOException {
|
||||
|
||||
if(subEvaluators.size() != 2) {
|
||||
throw new IOException("Percentile expects 2 parameters: a regression result and a number");
|
||||
}
|
||||
|
||||
StreamEvaluator r = subEvaluators.get(0);
|
||||
StreamEvaluator d = subEvaluators.get(1);
|
||||
|
||||
EmpiricalDistributionEvaluator.EmpiricalDistributionTuple e = (EmpiricalDistributionEvaluator.EmpiricalDistributionTuple)r.evaluate(tuple);
|
||||
Number n = (Number)d.evaluate(tuple);
|
||||
return e.percentile(n.doubleValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamExpressionParameter toExpression(StreamFactory factory) throws IOException {
|
||||
StreamExpression expression = new StreamExpression(factory.getFunctionName(getClass()));
|
||||
return expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Explanation toExplanation(StreamFactory factory) throws IOException {
|
||||
return new Explanation(nodeId.toString())
|
||||
.withExpressionType(ExpressionType.EVALUATOR)
|
||||
.withFunctionName(factory.getFunctionName(getClass()))
|
||||
.withImplementingClass(getClass().getName())
|
||||
.withExpression(toExpression(factory).toString());
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.solr.client.solrj.io.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.math3.stat.ranking.NaturalRanking;
|
||||
import org.apache.solr.client.solrj.io.Tuple;
|
||||
import org.apache.solr.client.solrj.io.eval.ComplexEvaluator;
|
||||
import org.apache.solr.client.solrj.io.eval.StreamEvaluator;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Explanation;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Explanation.ExpressionType;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Expressible;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionParameter;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
|
||||
|
||||
public class RankEvaluator extends ComplexEvaluator implements Expressible {
|
||||
|
||||
private static final long serialVersionUID = 1;
|
||||
|
||||
public RankEvaluator(StreamExpression expression, StreamFactory factory) throws IOException {
|
||||
super(expression, factory);
|
||||
}
|
||||
|
||||
public List<Number> evaluate(Tuple tuple) throws IOException {
|
||||
StreamEvaluator colEval = subEvaluators.get(0);
|
||||
|
||||
List<Number> numbers = (List<Number>)colEval.evaluate(tuple);
|
||||
double[] values = new double[numbers.size()];
|
||||
for(int i=0; i<numbers.size(); i++) {
|
||||
values[i] = numbers.get(i).doubleValue();
|
||||
}
|
||||
|
||||
NaturalRanking rank = new NaturalRanking();
|
||||
double[] ranked = rank.rank(values);
|
||||
List<Number> rankedList = new ArrayList();
|
||||
for(int i=0; i<numbers.size(); i++) {
|
||||
rankedList.add(ranked[i]);
|
||||
}
|
||||
|
||||
return rankedList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamExpressionParameter toExpression(StreamFactory factory) throws IOException {
|
||||
StreamExpression expression = new StreamExpression(factory.getFunctionName(getClass()));
|
||||
return expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Explanation toExplanation(StreamFactory factory) throws IOException {
|
||||
return new Explanation(nodeId.toString())
|
||||
.withExpressionType(ExpressionType.EVALUATOR)
|
||||
.withFunctionName(factory.getFunctionName(getClass()))
|
||||
.withImplementingClass(getClass().getName())
|
||||
.withExpression(toExpression(factory).toString());
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.solr.client.solrj.io.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.math3.util.MathArrays;
|
||||
import org.apache.solr.client.solrj.io.Tuple;
|
||||
import org.apache.solr.client.solrj.io.eval.ComplexEvaluator;
|
||||
import org.apache.solr.client.solrj.io.eval.StreamEvaluator;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Explanation;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Explanation.ExpressionType;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.Expressible;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionParameter;
|
||||
import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
|
||||
|
||||
public class ScaleEvaluator extends ComplexEvaluator implements Expressible {
|
||||
|
||||
private static final long serialVersionUID = 1;
|
||||
|
||||
public ScaleEvaluator(StreamExpression expression, StreamFactory factory) throws IOException {
|
||||
super(expression, factory);
|
||||
}
|
||||
|
||||
public List<Number> evaluate(Tuple tuple) throws IOException {
|
||||
StreamEvaluator numEval = subEvaluators.get(0);
|
||||
StreamEvaluator colEval1 = subEvaluators.get(1);
|
||||
|
||||
Number num = (Number)numEval.evaluate(tuple);
|
||||
List<Number> numbers1 = (List<Number>)colEval1.evaluate(tuple);
|
||||
double[] column1 = new double[numbers1.size()];
|
||||
|
||||
for(int i=0; i<numbers1.size(); i++) {
|
||||
column1[i] = numbers1.get(i).doubleValue();
|
||||
}
|
||||
|
||||
double[] scaled = MathArrays.scale(num.doubleValue(), column1);
|
||||
|
||||
List<Number> scaledList = new ArrayList(scaled.length);
|
||||
for(double d : scaled) {
|
||||
scaledList.add(d);
|
||||
}
|
||||
|
||||
return scaledList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamExpressionParameter toExpression(StreamFactory factory) throws IOException {
|
||||
StreamExpression expression = new StreamExpression(factory.getFunctionName(getClass()));
|
||||
return expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Explanation toExplanation(StreamFactory factory) throws IOException {
|
||||
return new Explanation(nodeId.toString())
|
||||
.withExpressionType(ExpressionType.EVALUATOR)
|
||||
.withFunctionName(factory.getFunctionName(getClass()))
|
||||
.withImplementingClass(getClass().getName())
|
||||
.withExpression(toExpression(factory).toString());
|
||||
}
|
||||
}
|
@ -354,25 +354,6 @@ public class SchemaRequest extends AbstractSchemaRequest<SchemaResponse> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the default operator if it is defined in the schema.
|
||||
*/
|
||||
public static class DefaultQueryOperator extends AbstractSchemaRequest<SchemaResponse.DefaultQueryOperatorResponse> {
|
||||
public DefaultQueryOperator() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public DefaultQueryOperator(SolrParams q) {
|
||||
super(METHOD.GET, "/schema/solrqueryparser/defaultoperator", q);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SchemaResponse.DefaultQueryOperatorResponse createResponse(SolrClient client) {
|
||||
return new SchemaResponse.DefaultQueryOperatorResponse();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a new field definition to the schema.
|
||||
* If the field already exists, the method {@link #process(SolrClient, String)} will fail.
|
||||
|
@ -31,8 +31,6 @@ public class SchemaRepresentation {
|
||||
|
||||
private String defaultSearchField;
|
||||
|
||||
private String defaultOperator;
|
||||
|
||||
private Map<String, Object> similarity;
|
||||
|
||||
private List<Map<String, Object>> fields;
|
||||
@ -76,14 +74,6 @@ public class SchemaRepresentation {
|
||||
this.defaultSearchField = defaultSearchField;
|
||||
}
|
||||
|
||||
public String getDefaultOperator() {
|
||||
return defaultOperator;
|
||||
}
|
||||
|
||||
public void setDefaultOperator(String defaultOperator) {
|
||||
this.defaultOperator = defaultOperator;
|
||||
}
|
||||
|
||||
public Map<String, Object> getSimilarity() {
|
||||
return similarity;
|
||||
}
|
||||
|
@ -138,7 +138,6 @@ public class SchemaResponse extends SolrResponseBase {
|
||||
schemaRepresentation.setVersion(getSchemaVersion(schemaObj));
|
||||
schemaRepresentation.setUniqueKey(getSchemaUniqueKey(schemaObj));
|
||||
schemaRepresentation.setDefaultSearchField(getDefaultSearchField(schemaObj));
|
||||
schemaRepresentation.setDefaultOperator(getDefaultOperator(schemaObj));
|
||||
schemaRepresentation.setSimilarity(getSimilarity(schemaObj));
|
||||
schemaRepresentation.setFields(getFields(schemaObj));
|
||||
schemaRepresentation.setDynamicFields(getDynamicFields(schemaObj));
|
||||
@ -170,14 +169,6 @@ public class SchemaResponse extends SolrResponseBase {
|
||||
return similarity;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static String getDefaultOperator(Map schemaNamedList) {
|
||||
String defaultOperator = null;
|
||||
NamedList<Object> solrQueryParserProperties = (NamedList<Object>) schemaNamedList.get("solrQueryParser");
|
||||
if (solrQueryParserProperties != null) defaultOperator = (String) solrQueryParserProperties.get("defaultOperator");
|
||||
return defaultOperator;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static List<Map<String, Object>> getFields(Map schemaNamedList) {
|
||||
List<Map<String, Object>> fieldsAttributes = new LinkedList<>();
|
||||
@ -416,25 +407,6 @@ public class SchemaResponse extends SolrResponseBase {
|
||||
|
||||
}
|
||||
|
||||
public static class DefaultQueryOperatorResponse extends SolrResponseBase {
|
||||
private String defaultOperator;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setResponse(NamedList<Object> response) {
|
||||
super.setResponse(response);
|
||||
|
||||
defaultOperator = (String) response.get("defaultOperator");
|
||||
}
|
||||
|
||||
public String getDefaultOperator() {
|
||||
return defaultOperator;
|
||||
}
|
||||
}
|
||||
|
||||
public static class CopyFieldsResponse extends SolrResponseBase {
|
||||
List<Map<String, Object>> copyFields;
|
||||
|
||||
|
@ -5299,6 +5299,55 @@ public class StreamExpressionTest extends SolrCloudTestCase {
|
||||
assertTrue(tuples.get(0).getDouble("cov").equals(-625.0D));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDistance() throws Exception {
|
||||
UpdateRequest updateRequest = new UpdateRequest();
|
||||
|
||||
int i=0;
|
||||
while(i<50) {
|
||||
updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2016", "5", "1"), "price_f", "400.00");
|
||||
}
|
||||
|
||||
while(i<100) {
|
||||
updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2015", "5", "1"), "price_f", "300.0");
|
||||
}
|
||||
|
||||
while(i<150) {
|
||||
updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2014", "5", "1"), "price_f", "500.0");
|
||||
}
|
||||
|
||||
while(i<250) {
|
||||
updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2013", "5", "1"), "price_f", "100.00");
|
||||
}
|
||||
|
||||
updateRequest.commit(cluster.getSolrClient(), COLLECTIONORALIAS);
|
||||
|
||||
String expr = "timeseries("+COLLECTIONORALIAS+", q=\"*:*\", start=\"2013-01-01T01:00:00.000Z\", " +
|
||||
"end=\"2016-12-01T01:00:00.000Z\", " +
|
||||
"gap=\"+1YEAR\", " +
|
||||
"field=\"test_dt\", " +
|
||||
"count(*), sum(price_f), max(price_f), min(price_f))";
|
||||
|
||||
String cexpr = "let(a="+expr+", b=select("+expr+",mult(-1, count(*)) as nvalue), c=col(a, count(*)), d=col(b, nvalue), tuple(colc=c, cold=d, cov=cov(c,d), dist=distance(c,d)))";
|
||||
|
||||
ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
|
||||
paramsLoc.set("expr", cexpr);
|
||||
paramsLoc.set("qt", "/stream");
|
||||
|
||||
String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString()+"/"+COLLECTIONORALIAS;
|
||||
TupleStream solrStream = new SolrStream(url, paramsLoc);
|
||||
|
||||
StreamContext context = new StreamContext();
|
||||
solrStream.setStreamContext(context);
|
||||
List<Tuple> tuples = getTuples(solrStream);
|
||||
assertTrue(tuples.size() == 1);
|
||||
assertTrue(tuples.get(0).getDouble("cov").equals(-625.0D));
|
||||
assertTrue(tuples.get(0).getDouble("dist").equals(264.5751311064591D));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testReverse() throws Exception {
|
||||
UpdateRequest updateRequest = new UpdateRequest();
|
||||
@ -5350,6 +5399,235 @@ public class StreamExpressionTest extends SolrCloudTestCase {
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCopyOf() throws Exception {
|
||||
UpdateRequest updateRequest = new UpdateRequest();
|
||||
|
||||
int i=0;
|
||||
while(i<50) {
|
||||
updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2016", "5", "1"), "price_f", "400.00");
|
||||
}
|
||||
|
||||
while(i<100) {
|
||||
updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2015", "5", "1"), "price_f", "300.0");
|
||||
}
|
||||
|
||||
while(i<150) {
|
||||
updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2014", "5", "1"), "price_f", "500.0");
|
||||
}
|
||||
|
||||
while(i<250) {
|
||||
updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2013", "5", "1"), "price_f", "100.00");
|
||||
}
|
||||
|
||||
updateRequest.commit(cluster.getSolrClient(), COLLECTIONORALIAS);
|
||||
|
||||
String expr = "timeseries("+COLLECTIONORALIAS+", q=\"*:*\", start=\"2013-01-01T01:00:00.000Z\", " +
|
||||
"end=\"2016-12-01T01:00:00.000Z\", " +
|
||||
"gap=\"+1YEAR\", " +
|
||||
"field=\"test_dt\", " +
|
||||
"count(*), sum(price_f), max(price_f), min(price_f))";
|
||||
|
||||
String cexpr = "let(a="+expr+", c=col(a, max(price_f)), tuple(copy1=copyOf(c, 10), copy2=copyOf(c), copy3=copyOf(c, 2) ))";
|
||||
|
||||
ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
|
||||
paramsLoc.set("expr", cexpr);
|
||||
paramsLoc.set("qt", "/stream");
|
||||
|
||||
String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString()+"/"+COLLECTIONORALIAS;
|
||||
TupleStream solrStream = new SolrStream(url, paramsLoc);
|
||||
|
||||
StreamContext context = new StreamContext();
|
||||
solrStream.setStreamContext(context);
|
||||
List<Tuple> tuples = getTuples(solrStream);
|
||||
assertTrue(tuples.size() == 1);
|
||||
List<Number> copy1 = (List<Number>)tuples.get(0).get("copy1");
|
||||
assertTrue(copy1.size() == 10);
|
||||
assertTrue(copy1.get(0).doubleValue() == 100D);
|
||||
assertTrue(copy1.get(1).doubleValue() == 500D);
|
||||
assertTrue(copy1.get(2).doubleValue() == 300D);
|
||||
assertTrue(copy1.get(3).doubleValue() == 400D);
|
||||
assertTrue(copy1.get(4).doubleValue() == 0D);
|
||||
assertTrue(copy1.get(5).doubleValue() == 0D);
|
||||
assertTrue(copy1.get(6).doubleValue() == 0D);
|
||||
assertTrue(copy1.get(7).doubleValue() == 0D);
|
||||
assertTrue(copy1.get(8).doubleValue() == 0D);
|
||||
assertTrue(copy1.get(9).doubleValue() == 0D);
|
||||
|
||||
List<Number> copy2 = (List<Number>)tuples.get(0).get("copy2");
|
||||
assertTrue(copy2.size() == 4);
|
||||
assertTrue(copy2.get(0).doubleValue() == 100D);
|
||||
assertTrue(copy2.get(1).doubleValue() == 500D);
|
||||
assertTrue(copy2.get(2).doubleValue() == 300D);
|
||||
assertTrue(copy2.get(3).doubleValue() == 400D);
|
||||
|
||||
List<Number> copy3 = (List<Number>)tuples.get(0).get("copy3");
|
||||
assertTrue(copy3.size() == 2);
|
||||
assertTrue(copy3.get(0).doubleValue() == 100D);
|
||||
assertTrue(copy3.get(1).doubleValue() == 500D);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testPercentiles() throws Exception {
|
||||
UpdateRequest updateRequest = new UpdateRequest();
|
||||
|
||||
int i=0;
|
||||
while(i<100) {
|
||||
i=i+2;
|
||||
updateRequest.add(id, "id_"+(i), "price_f", Integer.toString(i));
|
||||
}
|
||||
|
||||
updateRequest.commit(cluster.getSolrClient(), COLLECTIONORALIAS);
|
||||
|
||||
String expr = "search("+COLLECTIONORALIAS+", q=\"*:*\", fl=\"price_f\", sort=\"price_f asc\", rows=\"200\")";
|
||||
String cexpr = "let(a="+expr+", c=col(a, price_f), e=empiricalDistribution(c), " +
|
||||
"tuple(p1=percentile(e, 88), " +
|
||||
"p2=percentile(e, 2), " +
|
||||
"p3=percentile(e, 99), " +
|
||||
"p4=percentile(e, 77), " +
|
||||
"p5=percentile(e, 98)))";
|
||||
|
||||
ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
|
||||
paramsLoc.set("expr", cexpr);
|
||||
paramsLoc.set("qt", "/stream");
|
||||
|
||||
String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString()+"/"+COLLECTIONORALIAS;
|
||||
TupleStream solrStream = new SolrStream(url, paramsLoc);
|
||||
|
||||
StreamContext context = new StreamContext();
|
||||
solrStream.setStreamContext(context);
|
||||
List<Tuple> tuples = getTuples(solrStream);
|
||||
assertTrue(tuples.size() == 1);
|
||||
double percentile1 = tuples.get(0).getDouble("p1");
|
||||
double percentile2 = tuples.get(0).getDouble("p2");
|
||||
double percentile3 = tuples.get(0).getDouble("p3");
|
||||
double percentile4 = tuples.get(0).getDouble("p4");
|
||||
double percentile5 = tuples.get(0).getDouble("p5");
|
||||
|
||||
|
||||
assertEquals(.88D, percentile1, 0.001);
|
||||
assertEquals(.0D, percentile2, 0.001);
|
||||
assertEquals(1.0D, percentile3, 0.001);
|
||||
assertEquals(.78D, percentile4, 0.001);
|
||||
assertEquals(.98D, percentile5, 0.001);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRankTransform() throws Exception {
|
||||
UpdateRequest updateRequest = new UpdateRequest();
|
||||
|
||||
int i=0;
|
||||
while(i<50) {
|
||||
updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2016", "5", "1"), "price_f", "400.00");
|
||||
}
|
||||
|
||||
while(i<100) {
|
||||
updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2015", "5", "1"), "price_f", "300.0");
|
||||
}
|
||||
|
||||
while(i<150) {
|
||||
updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2014", "5", "1"), "price_f", "500.0");
|
||||
}
|
||||
|
||||
while(i<250) {
|
||||
updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2013", "5", "1"), "price_f", "100.00");
|
||||
}
|
||||
|
||||
updateRequest.commit(cluster.getSolrClient(), COLLECTIONORALIAS);
|
||||
|
||||
String expr = "timeseries("+COLLECTIONORALIAS+", q=\"*:*\", start=\"2013-01-01T01:00:00.000Z\", " +
|
||||
"end=\"2016-12-01T01:00:00.000Z\", " +
|
||||
"gap=\"+1YEAR\", " +
|
||||
"field=\"test_dt\", " +
|
||||
"count(*), sum(price_f), max(price_f), min(price_f))";
|
||||
|
||||
String cexpr = "let(a="+expr+", c=col(a, max(price_f)), tuple(reverse=rev(c), ranked=rank(c)))";
|
||||
|
||||
ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
|
||||
paramsLoc.set("expr", cexpr);
|
||||
paramsLoc.set("qt", "/stream");
|
||||
|
||||
String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString()+"/"+COLLECTIONORALIAS;
|
||||
TupleStream solrStream = new SolrStream(url, paramsLoc);
|
||||
|
||||
StreamContext context = new StreamContext();
|
||||
solrStream.setStreamContext(context);
|
||||
List<Tuple> tuples = getTuples(solrStream);
|
||||
assertTrue(tuples.size() == 1);
|
||||
List<Number> reverse = (List<Number>)tuples.get(0).get("reverse");
|
||||
assertTrue(reverse.size() == 4);
|
||||
assertTrue(reverse.get(0).doubleValue() == 400D);
|
||||
assertTrue(reverse.get(1).doubleValue() == 300D);
|
||||
assertTrue(reverse.get(2).doubleValue() == 500D);
|
||||
assertTrue(reverse.get(3).doubleValue() == 100D);
|
||||
|
||||
List<Number> ranked = (List<Number>)tuples.get(0).get("ranked");
|
||||
assertTrue(ranked.size() == 4);
|
||||
assertTrue(ranked.get(0).doubleValue() == 1D);
|
||||
assertTrue(ranked.get(1).doubleValue() == 4D);
|
||||
assertTrue(ranked.get(2).doubleValue() == 2D);
|
||||
assertTrue(ranked.get(3).doubleValue() == 3D);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScale() throws Exception {
|
||||
UpdateRequest updateRequest = new UpdateRequest();
|
||||
|
||||
int i=0;
|
||||
while(i<50) {
|
||||
updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2016", "5", "1"), "price_f", "400.00");
|
||||
}
|
||||
|
||||
while(i<100) {
|
||||
updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2015", "5", "1"), "price_f", "300.0");
|
||||
}
|
||||
|
||||
while(i<150) {
|
||||
updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2014", "5", "1"), "price_f", "500.0");
|
||||
}
|
||||
|
||||
while(i<250) {
|
||||
updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2013", "5", "1"), "price_f", "100.00");
|
||||
}
|
||||
|
||||
updateRequest.commit(cluster.getSolrClient(), COLLECTIONORALIAS);
|
||||
|
||||
String expr = "timeseries("+COLLECTIONORALIAS+", q=\"*:*\", start=\"2013-01-01T01:00:00.000Z\", " +
|
||||
"end=\"2016-12-01T01:00:00.000Z\", " +
|
||||
"gap=\"+1YEAR\", " +
|
||||
"field=\"test_dt\", " +
|
||||
"count(*), sum(price_f), max(price_f), min(price_f))";
|
||||
|
||||
String cexpr = "let(a="+expr+", c=col(a, max(price_f)), tuple(reverse=rev(c), scaled=scale(2, c)))";
|
||||
|
||||
ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
|
||||
paramsLoc.set("expr", cexpr);
|
||||
paramsLoc.set("qt", "/stream");
|
||||
|
||||
String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString()+"/"+COLLECTIONORALIAS;
|
||||
TupleStream solrStream = new SolrStream(url, paramsLoc);
|
||||
|
||||
StreamContext context = new StreamContext();
|
||||
solrStream.setStreamContext(context);
|
||||
List<Tuple> tuples = getTuples(solrStream);
|
||||
assertTrue(tuples.size() == 1);
|
||||
List<Number> reverse = (List<Number>)tuples.get(0).get("reverse");
|
||||
assertTrue(reverse.size() == 4);
|
||||
assertTrue(reverse.get(0).doubleValue() == 400D);
|
||||
assertTrue(reverse.get(1).doubleValue() == 300D);
|
||||
assertTrue(reverse.get(2).doubleValue() == 500D);
|
||||
assertTrue(reverse.get(3).doubleValue() == 100D);
|
||||
|
||||
List<Number> ranked = (List<Number>)tuples.get(0).get("scaled");
|
||||
assertTrue(ranked.size() == 4);
|
||||
assertTrue(ranked.get(0).doubleValue() == 200D);
|
||||
assertTrue(ranked.get(1).doubleValue() == 1000D);
|
||||
assertTrue(ranked.get(2).doubleValue() == 600D);
|
||||
assertTrue(ranked.get(3).doubleValue() == 800D);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testConvolution() throws Exception {
|
||||
@ -5453,6 +5731,58 @@ public class StreamExpressionTest extends SolrCloudTestCase {
|
||||
assertTrue(prediction == 600.0D);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLength() throws Exception {
|
||||
UpdateRequest updateRequest = new UpdateRequest();
|
||||
|
||||
|
||||
updateRequest.add(id, "1", "price_f", "100.0", "col_s", "a", "order_i", "1");
|
||||
updateRequest.add(id, "2", "price_f", "200.0", "col_s", "a", "order_i", "2");
|
||||
updateRequest.add(id, "3", "price_f", "300.0", "col_s", "a", "order_i", "3");
|
||||
updateRequest.add(id, "4", "price_f", "100.0", "col_s", "a", "order_i", "4");
|
||||
updateRequest.add(id, "5", "price_f", "200.0", "col_s", "a", "order_i", "5");
|
||||
updateRequest.add(id, "6", "price_f", "400.0", "col_s", "a", "order_i", "6");
|
||||
updateRequest.add(id, "7", "price_f", "600.0", "col_s", "a", "order_i", "7");
|
||||
|
||||
updateRequest.add(id, "8", "price_f", "200.0", "col_s", "b", "order_i", "1");
|
||||
updateRequest.add(id, "9", "price_f", "400.0", "col_s", "b", "order_i", "2");
|
||||
updateRequest.add(id, "10", "price_f", "600.0", "col_s", "b", "order_i", "3");
|
||||
updateRequest.add(id, "11", "price_f", "200.0", "col_s", "b", "order_i", "4");
|
||||
updateRequest.add(id, "12", "price_f", "400.0", "col_s", "b", "order_i", "5");
|
||||
updateRequest.add(id, "13", "price_f", "800.0", "col_s", "b", "order_i", "6");
|
||||
updateRequest.add(id, "14", "price_f", "1200.0", "col_s", "b", "order_i", "7");
|
||||
updateRequest.commit(cluster.getSolrClient(), COLLECTIONORALIAS);
|
||||
|
||||
String expr1 = "search("+COLLECTIONORALIAS+", q=\"col_s:a\", fl=\"price_f, order_i\", sort=\"order_i asc\")";
|
||||
String expr2 = "search("+COLLECTIONORALIAS+", q=\"col_s:b\", fl=\"price_f, order_i\", sort=\"order_i asc\")";
|
||||
|
||||
String cexpr = "let(a="+expr1+", b="+expr2+", c=col(a, price_f), d=col(b, price_f), e=regress(c, d), tuple(regress=e, p=predict(e, 300), l=length(d)))";
|
||||
|
||||
ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
|
||||
paramsLoc.set("expr", cexpr);
|
||||
paramsLoc.set("qt", "/stream");
|
||||
|
||||
String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString()+"/"+COLLECTIONORALIAS;
|
||||
TupleStream solrStream = new SolrStream(url, paramsLoc);
|
||||
|
||||
StreamContext context = new StreamContext();
|
||||
solrStream.setStreamContext(context);
|
||||
List<Tuple> tuples = getTuples(solrStream);
|
||||
assertTrue(tuples.size() == 1);
|
||||
Tuple tuple = tuples.get(0);
|
||||
Map regression = (Map)tuple.get("regress");
|
||||
double slope = (double)regression.get("slope");
|
||||
double intercept= (double) regression.get("intercept");
|
||||
double length = tuple.getDouble("l");
|
||||
|
||||
assertTrue(slope == 2.0D);
|
||||
assertTrue(intercept == 0.0D);
|
||||
double prediction = tuple.getDouble("p");
|
||||
assertTrue(prediction == 600.0D);
|
||||
assertTrue(length == 7);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalize() throws Exception {
|
||||
UpdateRequest updateRequest = new UpdateRequest();
|
||||
|
@ -242,16 +242,6 @@ public class SchemaTest extends RestTestBase {
|
||||
globalSimilarityResponse.getSimilarity().get("class"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDefaultQueryOperatorAccuracy() throws Exception {
|
||||
SchemaRequest.DefaultQueryOperator defaultQueryOperatorRequest =
|
||||
new SchemaRequest.DefaultQueryOperator();
|
||||
SchemaResponse.DefaultQueryOperatorResponse defaultQueryOperatorResponse =
|
||||
defaultQueryOperatorRequest.process(getSolrClient());
|
||||
assertValidSchemaResponse(defaultQueryOperatorResponse);
|
||||
assertEquals("OR", defaultQueryOperatorResponse.getDefaultOperator());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddFieldAccuracy() throws Exception {
|
||||
SchemaRequest.Fields fieldsSchemaRequest = new SchemaRequest.Fields();
|
||||
|
Loading…
x
Reference in New Issue
Block a user