From a0f68e291f4db45fa6abc4d5c51f31e9979b4e90 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Sat, 15 Jan 2022 23:42:18 +0100 Subject: [PATCH 01/33] automatic conversion using 'gradle init' Signed-off-by: rs-eliatra --- build.gradle | 149 ++++++------ gradle/wrapper/gradle-wrapper.jar | Bin 56177 -> 59536 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 275 +++++++++++++---------- gradlew.bat | 39 +--- settings.gradle | 7 + 6 files changed, 241 insertions(+), 231 deletions(-) create mode 100644 settings.gradle diff --git a/build.gradle b/build.gradle index 42d4c70e3f..147992a7fa 100644 --- a/build.gradle +++ b/build.gradle @@ -1,97 +1,88 @@ /* - * SPDX-License-Identifier: Apache-2.0 + * This file was generated by the Gradle 'init' task. * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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. + * This project uses @Incubating APIs which are subject to change. */ -// Uses Gradle to build RPMs since that's what we use for the other plugins. When all you have is a hammer... plugins { - id "nebula.ospackage" version "5.3.0" + id 'java' + id 'maven-publish' } -// To prevent conflicts with maven build under build/ -buildDir = 'gradle-build' +repositories { + mavenLocal() + maven { + url = uri('https://aws.oss.sonatype.org/content/repositories/snapshots') + } -ext { - securityPluginVersion = '1.3.0.0' - isSnapshot = "true" == System.getProperty("build.snapshot", "true") + maven { + url = uri('https://repo.maven.apache.org/maven2/') + } } -group = "org.opensearch" -// Increment the final digit when there's a new plugin versions for the same opensearch version -// Reset the final digit to 0 when upgrading to a new opensearch version -version = "${securityPluginVersion}" + (isSnapshot ? "-SNAPSHOT" : "") - -if (!project.hasProperty("archivePath")) { - throw new GradleException("Missing -ParchivePath command line switch pointing to built plugin ZIP") -} -if (!project.file(archivePath).exists()) { - throw new GradleException("Missing plugin zip file: $archivePath") +dependencies { + implementation 'org.opensearch.plugin:transport-netty4-client:1.3.0-SNAPSHOT' + implementation 'com.google.guava:guava:25.1-jre' + implementation 'org.greenrobot:eventbus:3.2.0' + implementation 'commons-cli:commons-cli:1.3.1' + implementation 'org.bouncycastle:bcprov-jdk15on:1.67' + implementation 'com.fasterxml.jackson.core:jackson-databind:2.11.2' + implementation 'org.slf4j:slf4j-api:1.7.32' + implementation 'org.ldaptive:ldaptive:1.2.3' + implementation 'org.apache.httpcomponents:httpclient-cache:4.5.13' + implementation 'org.opensearch.client:opensearch-rest-high-level-client:1.3.0-SNAPSHOT' + implementation 'io.jsonwebtoken:jjwt-api:0.10.5' + implementation 'org.apache.cxf:cxf-rt-rs-security-jose:3.4.5' + implementation 'com.github.wnameless:json-flattener:0.5.0' + implementation 'com.flipkart.zjsonpatch:zjsonpatch:0.4.4' + implementation 'org.apache.kafka:kafka-clients:2.5.0' + implementation 'com.onelogin:java-saml:2.5.0' + implementation 'org.opensaml:opensaml-saml-impl:3.4.5' + implementation 'commons-collections:commons-collections:3.2.2' + implementation 'com.jayway.jsonpath:json-path:2.4.0' + implementation 'org.apache.httpcomponents:httpclient:4.5.13' + runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.10.5' + runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.10.5' + testImplementation 'org.apache.logging.log4j:log4j-core:2.17.1' + testImplementation 'commons-io:commons-io:2.7' + testImplementation 'org.hamcrest:hamcrest-all:1.3' + testImplementation 'junit:junit:4.13.1' + testImplementation 'org.apache.httpcomponents:fluent-hc:4.5.13' + testImplementation 'org.opensearch.plugin:reindex-client:1.3.0-SNAPSHOT' + testImplementation 'org.opensearch:opensearch-ssl-config:1.3.0-SNAPSHOT' + testImplementation 'org.opensearch.plugin:percolator-client:1.3.0-SNAPSHOT' + testImplementation 'org.opensearch.plugin:lang-mustache-client:1.3.0-SNAPSHOT' + testImplementation 'org.opensearch.plugin:parent-join-client:1.3.0-SNAPSHOT' + testImplementation 'org.opensearch.plugin:aggs-matrix-stats-client:1.3.0-SNAPSHOT' + testImplementation 'org.mockito:mockito-core:2.23.0' + testImplementation 'org.springframework.kafka:spring-kafka-test:2.5.4.RELEASE' + testImplementation 'org.apache.kafka:kafka-clients:2.0.1' + testImplementation 'javax.servlet:servlet-api:2.5' + testImplementation 'com.unboundid:unboundid-ldapsdk:4.0.9' + testImplementation 'com.github.stephenc.jcip:jcip-annotations:1.0-1' + compileOnly 'org.opensearch:opensearch:1.3.0-SNAPSHOT' + compileOnly 'io.netty:netty-tcnative:2.0.25.Final' } -ospackage { - packageName = "opensearch-security" - release = isSnapshot ? "0.1" : '1' - version = "${project.version}" - - into '/usr/share/opensearch/plugins' - from(zipTree(project.file(archivePath).absolutePath)) { - into "opensearch-security" - permissionGroup 'opensearch' - } - - user 'root' - permissionGroup 'root' - - requires('opensearch-oss', "1.3.0", EQUAL) - packager = 'Amazon' - vendor = 'Amazon' - os = 'LINUX' - prefix '/usr' +group = 'org.opensearch' +version = '1.3.0.0-SNAPSHOT' +description = 'OpenSearch Security' +java.sourceCompatibility = JavaVersion.VERSION_1_8 - license 'ASL-2.0' - maintainer 'OpenDistro for Elasticsearch Team ' - url 'https://opendistro.github.io/for-elasticsearch/downloads.html' - summary ''' - OpenSearch Security plugin. - Reference documentation can be found at https://opendistro.github.io/for-elasticsearch-docs/. - '''.stripIndent().replace('\n', ' ').trim() - - //TODO: Would be better if the install_demo_configuration.sh script is marked executable in the upstream plugin instead of running bash manually here - postInstall "exec /bin/bash /usr/share/opensearch/plugins/opensearch-security/tools/install_demo_configuration.sh -y -i -s" +tasks.register('testsJar', Jar) { + archiveClassifier = 'tests' + from(sourceSets.test.output) } -buildRpm { - arch = 'NOARCH' - addParentDirs = false - archiveName "${packageName}-${version}.rpm" +publishing { + publications { + maven(MavenPublication) { + from(components.java) + artifact(testsJar) + } + } } -buildDeb { - arch = 'all' - archiveName "${packageName}-${version}.deb" +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 29953ea141f55e3b8fc691d31b5ca8816d89fa87..7454180f2ae8848c63b8b4dea2cb829da983f2fa 100644 GIT binary patch delta 51385 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

8j~^e*5P?UYQ`^~!nLb#D_{DdBU_KYFbP>Bi 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%0A}15$O#mvChbGF@eh4Ar%3syAIE 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�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 \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME=${0##*/} # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -108,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -116,84 +140,95 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 4f62e097ce..ac1b06f938 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,15 +1,3 @@ - -@rem -@rem SPDX-License-Identifier: Apache-2.0 -@rem -@rem The OpenSearch Contributors require contributions made to -@rem this file be licensed under the Apache-2.0 license or a -@rem compatible open source license. -@rem -@rem Modifications Copyright OpenSearch Contributors. See -@rem GitHub history for details. -@rem - @rem @rem Copyright 2015 the original author or authors. @rem @@ -41,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -63,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -73,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000000..1c3e7ff5aa --- /dev/null +++ b/settings.gradle @@ -0,0 +1,7 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * This project uses @Incubating APIs which are subject to change. + */ + +rootProject.name = 'opensearch-security' From 5fd84a3611f3f57a25b4ad89ebb6211534c9f0d2 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Fri, 21 Jan 2022 02:40:09 +0100 Subject: [PATCH 02/33] configure gradle plugins and resources after automatic migration to gradle to be compatible fully with maven build Signed-off-by: rs-eliatra --- build.gradle | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 147992a7fa..35a6152f63 100644 --- a/build.gradle +++ b/build.gradle @@ -7,6 +7,8 @@ plugins { id 'java' id 'maven-publish' + id 'jacoco' + id "com.gorylenko.gradle-git-properties" version "2.3.2" } repositories { @@ -64,8 +66,14 @@ dependencies { compileOnly 'io.netty:netty-tcnative:2.0.25.Final' } + +ext { + securityPluginVersion = '1.3.0.0' + isSnapshot = "true" == System.getProperty("build.snapshot", "true") +} + group = 'org.opensearch' -version = '1.3.0.0-SNAPSHOT' +version = "${securityPluginVersion}" + (isSnapshot ? "-SNAPSHOT" : "") description = 'OpenSearch Security' java.sourceCompatibility = JavaVersion.VERSION_1_8 @@ -86,3 +94,9 @@ publishing { tasks.withType(JavaCompile) { options.encoding = 'UTF-8' } + +jar { + into '', { + from 'NOTICE.txt', "THIRD-PARTY.txt", "LICENSE" + } +} From 682aec90ce249110178bb97a4a00225fab874ab4 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Fri, 21 Jan 2022 18:48:03 +0100 Subject: [PATCH 03/33] configure git plugin to contains only needed fields and exclude KEYS from JAR Signed-off-by: rs-eliatra --- build.gradle | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/build.gradle b/build.gradle index 35a6152f63..bb1368c41c 100644 --- a/build.gradle +++ b/build.gradle @@ -99,4 +99,27 @@ jar { into '', { from 'NOTICE.txt', "THIRD-PARTY.txt", "LICENSE" } + processResources { + exclude("KEYS") + } } + + +gitProperties { + keys = [ + 'git.branch', + 'git.build.version', + 'git.closest.tag.commit.count', + 'git.closest.tag.name', + 'git.commit.id', + 'git.commit.id.abbrev', + 'git.commit.id.describe', + 'git.commit.message.full', + 'git.commit.message.short', + 'git.commit.time', + 'git.dirty', + 'git.remote.origin.url', + 'git.tags', + 'git.total.commit.count' + ] +} \ No newline at end of file From 3bdb5082e8057934c670989ccdd0d8aa2bf247c6 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Mon, 24 Jan 2022 21:06:05 +0100 Subject: [PATCH 04/33] configure dependencies and configure build to prepare artifacts Signed-off-by: rs-eliatra --- build.gradle | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index bb1368c41c..5d11a420ea 100644 --- a/build.gradle +++ b/build.gradle @@ -23,6 +23,19 @@ repositories { } dependencies { + + configurations.all { + resolutionStrategy { + force 'commons-codec:commons-codec:1.14' + force 'org.apache.santuario:xmlsec:2.2.3' + force 'org.cryptacular:cryptacular:1.1.4' + force 'net.minidev:json-smart:2.4.7' + force 'commons-cli:commons-cli:1.3.1' + force 'org.apache.httpcomponents:httpcore:4.4.12' + force "org.apache.commons:commons-lang3:3.4" + } + } + implementation 'org.opensearch.plugin:transport-netty4-client:1.3.0-SNAPSHOT' implementation 'com.google.guava:guava:25.1-jre' implementation 'org.greenrobot:eventbus:3.2.0' @@ -122,4 +135,67 @@ gitProperties { 'git.tags', 'git.total.commit.count' ] -} \ No newline at end of file +} + +// copied from: org.opensearch.gradle.dependencies.CompileOnlyResolvePlugin +project.getConfigurations().all(configuration -> { + if (configuration.getName().equals(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME)) { + NamedDomainObjectProvider resolvableCompileOnly = project.getConfigurations().register('resolveableCompileOnly'); + resolvableCompileOnly.configure((c) -> { + c.setCanBeResolved(true); + c.setCanBeConsumed(false); + c.extendsFrom(configuration); + }); + } +}); + + +task bundle(dependsOn: jar, type: Zip) { + from configurations.runtimeClasspath - project.configurations.getByName('resolveableCompileOnly') + from project.jar + from 'plugin-security.policy' + from 'plugin-descriptor.properties' + from('securityconfig') { + into 'securityconfig/' + } + from('tools') { + into 'tools/' + } +} +task bundleSecurityAdminStandalone(dependsOn: jar, type: Zip) { + archiveClassifier = 'securityadmin-standalone' + from(configurations.runtimeClasspath - project.configurations.getByName('resolveableCompileOnly')) { + into 'deps/' + } + from(project.jar) { + into 'deps/' + } + from('tools') { + into 'tools/' + } + from('securityconfig') { + into 'deps/securityconfig' + } +} +task bundleSecurityAdminStandaloneTarGz(dependsOn: jar, type: Tar) { + archiveClassifier = 'securityadmin-standalone' + archiveExtension = 'tar.gz' + compression = Compression.GZIP + from(configurations.runtimeClasspath - project.configurations.getByName('resolveableCompileOnly')) { + into 'deps/' + } + from(project.jar) { + into 'deps/' + } + from('tools') { + into 'tools/' + } + from('securityconfig') { + into 'deps/securityconfig' + } +} + +tasks.assemble.dependsOn(bundle) +tasks.assemble.dependsOn(bundleSecurityAdminStandalone) +tasks.assemble.dependsOn(bundleSecurityAdminStandaloneTarGz) + From f9703ed6ed98817867dbfc3963dd2dd1b7899cfd Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Mon, 24 Jan 2022 22:59:26 +0100 Subject: [PATCH 05/33] provide more replacement for maven plugins and configure jar and test jar Signed-off-by: rs-eliatra --- build.gradle | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 5d11a420ea..fec10dc770 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,9 @@ plugins { id 'maven-publish' id 'jacoco' id "com.gorylenko.gradle-git-properties" version "2.3.2" + id 'org.gradle.crypto.checksum' version '1.1.0' } +import org.gradle.crypto.checksum.Checksum repositories { mavenLocal() @@ -88,7 +90,9 @@ ext { group = 'org.opensearch' version = "${securityPluginVersion}" + (isSnapshot ? "-SNAPSHOT" : "") description = 'OpenSearch Security' -java.sourceCompatibility = JavaVersion.VERSION_1_8 + + +java.sourceCompatibility = JavaVersion.VERSION_11 tasks.register('testsJar', Jar) { archiveClassifier = 'tests' @@ -109,6 +113,7 @@ tasks.withType(JavaCompile) { } jar { + libsDirName = '.' into '', { from 'NOTICE.txt', "THIRD-PARTY.txt", "LICENSE" } @@ -116,7 +121,9 @@ jar { exclude("KEYS") } } - +testsJar { + libsDirName = '.' +} gitProperties { keys = [ @@ -199,3 +206,23 @@ tasks.assemble.dependsOn(bundle) tasks.assemble.dependsOn(bundleSecurityAdminStandalone) tasks.assemble.dependsOn(bundleSecurityAdminStandaloneTarGz) +clean { + delete 'data/' +} + + + +task createChecksums(type: Checksum) { + files = bundle.outputs.files + outputDir = new File(project.buildDir , "distributions") + algorithm = Checksum.Algorithm.SHA512 +} +tasks.assemble.finalizedBy(createChecksums) + + +jacoco { + reportsDirectory = file("$buildDir/jacoco") +} +tasks.test.finalizedBy(jacocoTestReport) // report is always generated after tests run +tasks.jacocoTestReport.dependsOn(test) // tests are required to run before generating the report + From 3ac0577fe41e12f98aeb541d5121207b9fff43ad Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Tue, 25 Jan 2022 00:26:40 +0100 Subject: [PATCH 06/33] configure 'test' plugin Signed-off-by: rs-eliatra --- build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle b/build.gradle index fec10dc770..302a109745 100644 --- a/build.gradle +++ b/build.gradle @@ -125,6 +125,11 @@ testsJar { libsDirName = '.' } +test { + maxParallelForks = 3 + jvmArgs "-Xmx3072m" +} + gitProperties { keys = [ 'git.branch', @@ -169,6 +174,7 @@ task bundle(dependsOn: jar, type: Zip) { into 'tools/' } } + task bundleSecurityAdminStandalone(dependsOn: jar, type: Zip) { archiveClassifier = 'securityadmin-standalone' from(configurations.runtimeClasspath - project.configurations.getByName('resolveableCompileOnly')) { From eab5ac8cb3f740884b8a747b55eb3f509433ed28 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Tue, 25 Jan 2022 11:12:23 +0100 Subject: [PATCH 07/33] configure build to package correct dependencies into seucirty admin standalone artifacts Signed-off-by: rs-eliatra --- build.gradle | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/build.gradle b/build.gradle index 302a109745..5a9b54bfbf 100644 --- a/build.gradle +++ b/build.gradle @@ -14,14 +14,14 @@ plugins { import org.gradle.crypto.checksum.Checksum repositories { + maven { url "https://aws.oss.sonatype.org/content/repositories/snapshots" } mavenLocal() - maven { - url = uri('https://aws.oss.sonatype.org/content/repositories/snapshots') - } + mavenCentral() + maven { url "https://plugins.gradle.org/m2/" } +} - maven { - url = uri('https://repo.maven.apache.org/maven2/') - } +ext { + opensearch_version = System.getProperty("opensearch_version", "1.3.0-SNAPSHOT") } dependencies { @@ -38,7 +38,8 @@ dependencies { } } - implementation 'org.opensearch.plugin:transport-netty4-client:1.3.0-SNAPSHOT' + implementation "org.opensearch.plugin:transport-netty4-client:${opensearch_version}" + implementation "org.opensearch.client:opensearch-rest-high-level-client:${opensearch_version}" implementation 'com.google.guava:guava:25.1-jre' implementation 'org.greenrobot:eventbus:3.2.0' implementation 'commons-cli:commons-cli:1.3.1' @@ -47,7 +48,6 @@ dependencies { implementation 'org.slf4j:slf4j-api:1.7.32' implementation 'org.ldaptive:ldaptive:1.2.3' implementation 'org.apache.httpcomponents:httpclient-cache:4.5.13' - implementation 'org.opensearch.client:opensearch-rest-high-level-client:1.3.0-SNAPSHOT' implementation 'io.jsonwebtoken:jjwt-api:0.10.5' implementation 'org.apache.cxf:cxf-rt-rs-security-jose:3.4.5' implementation 'com.github.wnameless:json-flattener:0.5.0' @@ -60,17 +60,17 @@ dependencies { implementation 'org.apache.httpcomponents:httpclient:4.5.13' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.10.5' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.10.5' + testImplementation "org.opensearch.plugin:reindex-client:${opensearch_version}" + testImplementation "org.opensearch:opensearch-ssl-config:${opensearch_version}" + testImplementation "org.opensearch.plugin:percolator-client:${opensearch_version}" + testImplementation "org.opensearch.plugin:lang-mustache-client:${opensearch_version}" + testImplementation "org.opensearch.plugin:parent-join-client:${opensearch_version}" + testImplementation "org.opensearch.plugin:aggs-matrix-stats-client:${opensearch_version}" testImplementation 'org.apache.logging.log4j:log4j-core:2.17.1' testImplementation 'commons-io:commons-io:2.7' testImplementation 'org.hamcrest:hamcrest-all:1.3' testImplementation 'junit:junit:4.13.1' testImplementation 'org.apache.httpcomponents:fluent-hc:4.5.13' - testImplementation 'org.opensearch.plugin:reindex-client:1.3.0-SNAPSHOT' - testImplementation 'org.opensearch:opensearch-ssl-config:1.3.0-SNAPSHOT' - testImplementation 'org.opensearch.plugin:percolator-client:1.3.0-SNAPSHOT' - testImplementation 'org.opensearch.plugin:lang-mustache-client:1.3.0-SNAPSHOT' - testImplementation 'org.opensearch.plugin:parent-join-client:1.3.0-SNAPSHOT' - testImplementation 'org.opensearch.plugin:aggs-matrix-stats-client:1.3.0-SNAPSHOT' testImplementation 'org.mockito:mockito-core:2.23.0' testImplementation 'org.springframework.kafka:spring-kafka-test:2.5.4.RELEASE' testImplementation 'org.apache.kafka:kafka-clients:2.0.1' @@ -177,7 +177,7 @@ task bundle(dependsOn: jar, type: Zip) { task bundleSecurityAdminStandalone(dependsOn: jar, type: Zip) { archiveClassifier = 'securityadmin-standalone' - from(configurations.runtimeClasspath - project.configurations.getByName('resolveableCompileOnly')) { + from(configurations.runtimeClasspath) { into 'deps/' } from(project.jar) { @@ -194,7 +194,7 @@ task bundleSecurityAdminStandaloneTarGz(dependsOn: jar, type: Tar) { archiveClassifier = 'securityadmin-standalone' archiveExtension = 'tar.gz' compression = Compression.GZIP - from(configurations.runtimeClasspath - project.configurations.getByName('resolveableCompileOnly')) { + from(configurations.runtimeClasspath) { into 'deps/' } from(project.jar) { @@ -217,10 +217,9 @@ clean { } - task createChecksums(type: Checksum) { files = bundle.outputs.files - outputDir = new File(project.buildDir , "distributions") + outputDir = new File(project.buildDir, "distributions") algorithm = Checksum.Algorithm.SHA512 } tasks.assemble.finalizedBy(createChecksums) From b163a2570aa896166008702083912abdaffcca07 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Tue, 25 Jan 2022 16:11:58 +0100 Subject: [PATCH 08/33] set java version in gradle script to 1.8 as it was for maven Signed-off-by: rs-eliatra --- build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5a9b54bfbf..2921f9d4c5 100644 --- a/build.gradle +++ b/build.gradle @@ -92,7 +92,8 @@ version = "${securityPluginVersion}" + (isSnapshot ? "-SNAPSHOT" : "") description = 'OpenSearch Security' -java.sourceCompatibility = JavaVersion.VERSION_11 +java.sourceCompatibility = JavaVersion.VERSION_1_8 +java.targetCompatibility = JavaVersion.VERSION_1_8 tasks.register('testsJar', Jar) { archiveClassifier = 'tests' From 130b7b8c5998e0dbe8edad749d0df98889b08919 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Sat, 29 Jan 2022 01:00:12 +0100 Subject: [PATCH 09/33] customize manifest Signed-off-by: rs-eliatra --- build.gradle | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 2921f9d4c5..685728dbdc 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,8 @@ plugins { } import org.gradle.crypto.checksum.Checksum +import java.text.SimpleDateFormat + repositories { maven { url "https://aws.oss.sonatype.org/content/repositories/snapshots" } mavenLocal() @@ -49,7 +51,9 @@ dependencies { implementation 'org.ldaptive:ldaptive:1.2.3' implementation 'org.apache.httpcomponents:httpclient-cache:4.5.13' implementation 'io.jsonwebtoken:jjwt-api:0.10.5' - implementation 'org.apache.cxf:cxf-rt-rs-security-jose:3.4.5' + implementation("org.apache.cxf:cxf-rt-rs-security-jose:3.4.5") { + exclude(group: 'jakarta.activation', module: 'jakarta.activation-api') + } implementation 'com.github.wnameless:json-flattener:0.5.0' implementation 'com.flipkart.zjsonpatch:zjsonpatch:0.4.4' implementation 'org.apache.kafka:kafka-clients:2.5.0' @@ -77,7 +81,7 @@ dependencies { testImplementation 'javax.servlet:servlet-api:2.5' testImplementation 'com.unboundid:unboundid-ldapsdk:4.0.9' testImplementation 'com.github.stephenc.jcip:jcip-annotations:1.0-1' - compileOnly 'org.opensearch:opensearch:1.3.0-SNAPSHOT' + compileOnly "org.opensearch:opensearch:${opensearch_version}" compileOnly 'io.netty:netty-tcnative:2.0.25.Final' } @@ -113,7 +117,34 @@ tasks.withType(JavaCompile) { options.encoding = 'UTF-8' } +static def getTimestamp() { + def df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") + df.setTimeZone(TimeZone.getTimeZone("UTC")) + return df.format(new Date()) +} + +static def gitCommitId() { + def cmd = "git rev-parse HEAD" + def proc = cmd.execute() + return proc.text.trim() +} + jar { + manifest { + attributes( + "Manifest-Version": "1.0", + "Created-By": "Gradle ${gradle.gradleVersion}", + "Build-Jdk": "${System.properties['java.version']}", + "Implementation-Title": "OpenSearch Security", + "Implementation-Version": archiveVersion, + "Implementation-Vendor-Id": "org.opensearch", + "Implementation-URL": "https://github.com/opensearch-project/security", + "Build-Time": getTimestamp(), + "Built-By": "OpenSearch Security Plugin", + "git-sha1": gitCommitId() + ) + } + libsDirName = '.' into '', { from 'NOTICE.txt', "THIRD-PARTY.txt", "LICENSE" @@ -123,6 +154,21 @@ jar { } } testsJar { + manifest { + attributes( + "Manifest-Version": "1.0", + "Created-By": "Gradle ${gradle.gradleVersion}", + "Build-Jdk": "${System.properties['java.version']}", + "Implementation-Title": "OpenSearch Security", + "Implementation-Version": archiveVersion, + "Implementation-Vendor-Id": "org.opensearch", + "Implementation-URL": "https://github.com/opensearch-project/security", + "Build-Time": getTimestamp(), + "Built-By": "OpenSearch Security Plugin", + "git-sha1": gitCommitId() + ) + } + libsDirName = '.' } From 1da3a7a0e5867c470480bf0c5d3b18cbd69e8bcc Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Sat, 29 Jan 2022 04:05:07 +0100 Subject: [PATCH 10/33] configure checkstyle gradle plugin Signed-off-by: rs-eliatra --- build.gradle | 10 ++ config/checkstyle/checkstyle.xml | 186 +++++++++++++++++++++++++++++++ 2 files changed, 196 insertions(+) create mode 100644 config/checkstyle/checkstyle.xml diff --git a/build.gradle b/build.gradle index 685728dbdc..edcdfc867d 100644 --- a/build.gradle +++ b/build.gradle @@ -8,6 +8,7 @@ plugins { id 'java' id 'maven-publish' id 'jacoco' + id 'checkstyle' id "com.gorylenko.gradle-git-properties" version "2.3.2" id 'org.gradle.crypto.checksum' version '1.1.0' } @@ -278,3 +279,12 @@ jacoco { tasks.test.finalizedBy(jacocoTestReport) // report is always generated after tests run tasks.jacocoTestReport.dependsOn(test) // tests are required to run before generating the report +tasks.withType(Checkstyle) { + reports { + showViolations false + ignoreFailures = true + xml.required = true + html.required = true + } +} + diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml new file mode 100644 index 0000000000..11a9eb2c71 --- /dev/null +++ b/config/checkstyle/checkstyle.xml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 41a25a14be904d19ff3da0389c2d7f0ec2cb753a Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Sat, 29 Jan 2022 11:54:21 +0100 Subject: [PATCH 11/33] add 'taskinfo' plugin to give possibility of printing gradle task graph Signed-off-by: rs-eliatra --- build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle b/build.gradle index edcdfc867d..db5601e529 100644 --- a/build.gradle +++ b/build.gradle @@ -11,6 +11,9 @@ plugins { id 'checkstyle' id "com.gorylenko.gradle-git-properties" version "2.3.2" id 'org.gradle.crypto.checksum' version '1.1.0' + + // Plugin prints gradle task graph, use following command: ./gradlew tiTree build + id 'org.barfuin.gradle.taskinfo' version '1.0.5' } import org.gradle.crypto.checksum.Checksum From 786eb743222f221a8c662e5906744f4eeba652be Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Sat, 29 Jan 2022 12:10:30 +0100 Subject: [PATCH 12/33] configure build to generate 'rpm' and 'deb' artifacts Signed-off-by: rs-eliatra --- build.gradle | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/build.gradle b/build.gradle index db5601e529..df8746b0bd 100644 --- a/build.gradle +++ b/build.gradle @@ -14,6 +14,8 @@ plugins { // Plugin prints gradle task graph, use following command: ./gradlew tiTree build id 'org.barfuin.gradle.taskinfo' version '1.0.5' + + id "nebula.ospackage" version "9.0.0" } import org.gradle.crypto.checksum.Checksum @@ -291,3 +293,12 @@ tasks.withType(Checkstyle) { } } +buildRpm { + arch = 'NOARCH' + addParentDirs = false + archiveName "${packageName}-${archiveVersion}.rpm" +} +buildDeb { + arch = 'all' + archiveName "${packageName}-${archiveVersion}.deb" +} \ No newline at end of file From 9e386380a6e606a5c6b0c173fdbe80b095b0c2eb Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Sat, 29 Jan 2022 12:32:06 +0100 Subject: [PATCH 13/33] change README.md and DEVELOPER_GUIDE.md after migration to gradle Signed-off-by: rs-eliatra --- DEVELOPER_GUIDE.md | 6 +++--- README.md | 14 +++++++------- build.gradle | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index 05df64f4fa..6ed6eea921 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -35,14 +35,14 @@ The `curl localhost:9200` call from before should also succeed now. Kill the ser First create a fork of this repo and clone it locally. Changing into the directory of the newly cloned repository, run the following to build the project: ```bash -mvn -B package -Padvanced -DskipTests +./gradlew clean assemble --no-daemon ``` Install the built plugin into the OpenSearch server: ```bash export OPENSEARCH_SECURITY_HOME=$OPENSEARCH_HOME/plugins/opensearch-security -cp target/releases/opensearch-security-1.3.0.0-SNAPSHOT.zip $OPENSEARCH_SECURITY_HOME +cp build/distributions/opensearch-security-1.3.0.0-SNAPSHOT.zip $OPENSEARCH_SECURITY_HOME cd $OPENSEARCH_SECURITY_HOME unzip opensearch-security-1.3.0.0-SNAPSHOT.zip rm opensearch-security-1.3.0.0-SNAPSHOT.zip @@ -115,7 +115,7 @@ curl -XGET https://localhost:9200/_plugins/_security/authinfo -u 'admin:admin' - ## Using IntelliJ IDEA -Launch IntelliJ IDEA, choose **Import Project**, and select the `pom.xml` file in the root of this package. +Launch IntelliJ IDEA, choose **Project from Existing Sources**, and select directory with Gradle build script (`build.gradle`). ## Submitting Changes diff --git a/README.md b/README.md index e7aa135f79..e82e498d61 100644 --- a/README.md +++ b/README.md @@ -62,22 +62,22 @@ You can also see the [developer guide](https://github.com/opensearch-project/sec Run all tests: ```bash -mvn clean test +./gradlew clean test --no-daemon ``` Build artifacts (zip, deb, rpm): ```bash -mvn clean package -Padvanced -DskipTests -artifact_zip=`ls $(pwd)/target/releases/opensearch-security-*.zip | grep -v admin-standalone` -./gradlew build buildDeb buildRpm --no-daemon -ParchivePath=$artifact_zip -Dbuild.snapshot=false +./gradlew clean assemble --no-daemon +artifact_zip=`ls $(pwd)/build/distributions/opensearch-security-*.zip | grep -v admin-standalone` +./gradlew buildDeb buildRpm --no-daemon -ParchivePath=$artifact_zip ``` This produces: ``` -target/releases/opensearch-security-.zip -gradle-build/distributions/opensearch-security-.deb -gradle-build/distributions/opensearch-security-.rpm +build/releases/opensearch-security-.zip +build/distributions/opensearch-security-.deb +build/distributions/opensearch-security-.rpm ``` ## Config hot reloading diff --git a/build.gradle b/build.gradle index df8746b0bd..6ce43b4df2 100644 --- a/build.gradle +++ b/build.gradle @@ -296,9 +296,9 @@ tasks.withType(Checkstyle) { buildRpm { arch = 'NOARCH' addParentDirs = false - archiveName "${packageName}-${archiveVersion}.rpm" + archiveName "${packageName}-${version}.rpm" } buildDeb { arch = 'all' - archiveName "${packageName}-${archiveVersion}.deb" + archiveName "${packageName}-${version}.deb" } \ No newline at end of file From 56fbb264e0320739f4ccc384783144802b4e1498 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Sat, 29 Jan 2022 18:08:15 +0100 Subject: [PATCH 14/33] rename checkstyle.xml to original name: sun_checks.xml Signed-off-by: rs-eliatra --- build.gradle | 4 ++++ config/checkstyle/{checkstyle.xml => sun_checks.xml} | 0 2 files changed, 4 insertions(+) rename config/checkstyle/{checkstyle.xml => sun_checks.xml} (100%) diff --git a/build.gradle b/build.gradle index 6ce43b4df2..29434f3886 100644 --- a/build.gradle +++ b/build.gradle @@ -284,6 +284,10 @@ jacoco { tasks.test.finalizedBy(jacocoTestReport) // report is always generated after tests run tasks.jacocoTestReport.dependsOn(test) // tests are required to run before generating the report +checkstyle { + configFile file("config/checkstyle/sun_checks.xml") +} + tasks.withType(Checkstyle) { reports { showViolations false diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/sun_checks.xml similarity index 100% rename from config/checkstyle/checkstyle.xml rename to config/checkstyle/sun_checks.xml From a0d01797e3a3fa2e3daa2427ced51dcf443c3f50 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Sat, 29 Jan 2022 18:15:46 +0100 Subject: [PATCH 15/33] fixup! automatic conversion using 'gradle init' Signed-off-by: rs-eliatra --- build.gradle | 28 ++++++++++++++++++++++++++-- gradlew | 13 ++++++++++++- gradlew.bat | 12 ++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 29434f3886..aca4a8213a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,31 @@ /* - * This file was generated by the Gradle 'init' task. + * SPDX-License-Identifier: Apache-2.0 * - * This project uses @Incubating APIs which are subject to change. + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch 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. */ plugins { diff --git a/gradlew b/gradlew index 1b6c787337..9794aa4f45 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,18 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# SPDX-License-Identifier: Apache-2.0 +# +# The OpenSearch Contributors require contributions made to +# this file be licensed under the Apache-2.0 license or a +# compatible open source license. +# +# Modifications Copyright OpenSearch Contributors. See +# GitHub history for details. +# + +# +# Copyright 2015-2021 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/gradlew.bat b/gradlew.bat index ac1b06f938..5d049c13ef 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,15 @@ + +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem +@rem The OpenSearch Contributors require contributions made to +@rem this file be licensed under the Apache-2.0 license or a +@rem compatible open source license. +@rem +@rem Modifications Copyright OpenSearch Contributors. See +@rem GitHub history for details. +@rem + @rem @rem Copyright 2015 the original author or authors. @rem From 9c04bbc2eace34a7cf8a729327da0ff390b815d4 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Sat, 29 Jan 2022 21:33:27 +0100 Subject: [PATCH 16/33] update dependencies in gradle script according to latest pom dependencies changes Signed-off-by: rs-eliatra --- build.gradle | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/build.gradle b/build.gradle index aca4a8213a..9f2abc296f 100644 --- a/build.gradle +++ b/build.gradle @@ -68,22 +68,22 @@ dependencies { force 'org.apache.httpcomponents:httpcore:4.4.12' force "org.apache.commons:commons-lang3:3.4" } + } + implementation 'jakarta.annotation:jakarta.annotation-api:1.3.5' implementation "org.opensearch.plugin:transport-netty4-client:${opensearch_version}" implementation "org.opensearch.client:opensearch-rest-high-level-client:${opensearch_version}" implementation 'com.google.guava:guava:25.1-jre' implementation 'org.greenrobot:eventbus:3.2.0' implementation 'commons-cli:commons-cli:1.3.1' implementation 'org.bouncycastle:bcprov-jdk15on:1.67' - implementation 'com.fasterxml.jackson.core:jackson-databind:2.11.2' + implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.6' implementation 'org.slf4j:slf4j-api:1.7.32' implementation 'org.ldaptive:ldaptive:1.2.3' implementation 'org.apache.httpcomponents:httpclient-cache:4.5.13' - implementation 'io.jsonwebtoken:jjwt-api:0.10.5' - implementation("org.apache.cxf:cxf-rt-rs-security-jose:3.4.5") { - exclude(group: 'jakarta.activation', module: 'jakarta.activation-api') - } + implementation 'io.jsonwebtoken:jjwt-api:0.10.8' + implementation "org.apache.cxf:cxf-rt-rs-security-jose:3.4.5" implementation 'com.github.wnameless:json-flattener:0.5.0' implementation 'com.flipkart.zjsonpatch:zjsonpatch:0.4.4' implementation 'org.apache.kafka:kafka-clients:2.5.0' @@ -92,8 +92,8 @@ dependencies { implementation 'commons-collections:commons-collections:3.2.2' implementation 'com.jayway.jsonpath:json-path:2.4.0' implementation 'org.apache.httpcomponents:httpclient:4.5.13' - runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.10.5' - runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.10.5' + runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.10.8' + runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.10.8' testImplementation "org.opensearch.plugin:reindex-client:${opensearch_version}" testImplementation "org.opensearch:opensearch-ssl-config:${opensearch_version}" testImplementation "org.opensearch.plugin:percolator-client:${opensearch_version}" @@ -111,8 +111,8 @@ dependencies { testImplementation 'javax.servlet:servlet-api:2.5' testImplementation 'com.unboundid:unboundid-ldapsdk:4.0.9' testImplementation 'com.github.stephenc.jcip:jcip-annotations:1.0-1' - compileOnly "org.opensearch:opensearch:${opensearch_version}" compileOnly 'io.netty:netty-tcnative:2.0.25.Final' + compileOnly "org.opensearch:opensearch:${opensearch_version}" } @@ -182,7 +182,9 @@ jar { processResources { exclude("KEYS") } + } + testsJar { manifest { attributes( From 374f5e621b7738fd6bf9304fc5bf346ce51cb12e Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Sat, 29 Jan 2022 13:12:09 +0100 Subject: [PATCH 17/33] migrate CI/CD scripts to use: 'gradle' Signed-off-by: rs-eliatra --- .github/workflows/cd.yml | 10 +++++----- .github/workflows/ci.yml | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 486eea6a27..ed02745f78 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -31,13 +31,13 @@ jobs: - name: Build run: | - mvn -B clean package -Padvanced -DskipTests - artifact_zip=`ls $(pwd)/target/releases/opensearch-security-*.zip | grep -v admin-standalone` - ./gradlew build buildDeb buildRpm --no-daemon -ParchivePath=$artifact_zip -Dbuild.snapshot=false + ./gradlew clean build --no-daemon -Dbuild.snapshot=false -x test + artifact_zip=`ls $(pwd)/build/distributions/opensearch-security-*.zip | grep -v admin-standalone` + ./gradlew build buildDeb buildRpm --no-daemon -ParchivePath=$artifact_zip -Dbuild.snapshot=false -x test mkdir artifacts cp $artifact_zip artifacts/ - cp gradle-build/distributions/*.deb artifacts/ - cp gradle-build/distributions/*.rpm artifacts/ + cp build/distributions/*.deb artifacts/ + cp build/distributions/*.rpm artifacts/ zip -r artifacts.zip artifacts echo "TAG_VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6a2ccd2d4b..c3fb3adf01 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,16 +44,16 @@ jobs: restore-keys: ${{ runner.os }}-m2 - name: Checkstyle - run: mvn -B checkstyle:checkstyle + run: ./gradlew clean checkstyleMain checkstyleTest --no-daemon - name: Package - run: mvn -B clean package -Padvanced -DskipTests + run: ./gradlew clean build --no-daemon -Dbuild.snapshot=false -x test - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v1 - name: Test - run: OPENDISTRO_SECURITY_TEST_OPENSSL_OPT=true mvn -B test + run: ./gradlew test --no-daemon - name: Coverage uses: codecov/codecov-action@v1 @@ -64,4 +64,4 @@ jobs: uses: actions/upload-artifact@v1 with: name: artifacts - path: target/releases/ + path: build/distributions/ From 54233ce7f5f45fd5bf229d8c8f32b2cf2da7f75b Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Mon, 31 Jan 2022 17:48:38 +0100 Subject: [PATCH 18/33] remove '--no-daemon' from commands Signed-off-by: rs-eliatra --- .github/workflows/cd.yml | 4 ++-- .github/workflows/ci.yml | 6 +++--- DEVELOPER_GUIDE.md | 2 +- README.md | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index ed02745f78..aa6ca10fe0 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -31,9 +31,9 @@ jobs: - name: Build run: | - ./gradlew clean build --no-daemon -Dbuild.snapshot=false -x test + ./gradlew clean build -Dbuild.snapshot=false -x test artifact_zip=`ls $(pwd)/build/distributions/opensearch-security-*.zip | grep -v admin-standalone` - ./gradlew build buildDeb buildRpm --no-daemon -ParchivePath=$artifact_zip -Dbuild.snapshot=false -x test + ./gradlew build buildDeb buildRpm -ParchivePath=$artifact_zip -Dbuild.snapshot=false -x test mkdir artifacts cp $artifact_zip artifacts/ cp build/distributions/*.deb artifacts/ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c3fb3adf01..2ecc0f6baf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,16 +44,16 @@ jobs: restore-keys: ${{ runner.os }}-m2 - name: Checkstyle - run: ./gradlew clean checkstyleMain checkstyleTest --no-daemon + run: ./gradlew clean checkstyleMain checkstyleTest - name: Package - run: ./gradlew clean build --no-daemon -Dbuild.snapshot=false -x test + run: ./gradlew clean build -Dbuild.snapshot=false -x test - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v1 - name: Test - run: ./gradlew test --no-daemon + run: ./gradlew test - name: Coverage uses: codecov/codecov-action@v1 diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index 6ed6eea921..af45a24d2c 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -35,7 +35,7 @@ The `curl localhost:9200` call from before should also succeed now. Kill the ser First create a fork of this repo and clone it locally. Changing into the directory of the newly cloned repository, run the following to build the project: ```bash -./gradlew clean assemble --no-daemon +./gradlew clean assemble ``` Install the built plugin into the OpenSearch server: diff --git a/README.md b/README.md index e82e498d61..2e5488786c 100644 --- a/README.md +++ b/README.md @@ -62,14 +62,14 @@ You can also see the [developer guide](https://github.com/opensearch-project/sec Run all tests: ```bash -./gradlew clean test --no-daemon +./gradlew clean test ``` Build artifacts (zip, deb, rpm): ```bash -./gradlew clean assemble --no-daemon +./gradlew clean assemble artifact_zip=`ls $(pwd)/build/distributions/opensearch-security-*.zip | grep -v admin-standalone` -./gradlew buildDeb buildRpm --no-daemon -ParchivePath=$artifact_zip +./gradlew buildDeb buildRpm -ParchivePath=$artifact_zip ``` This produces: From 01691cb409151def81f2c1c0153e348c6f6368d8 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Mon, 31 Jan 2022 19:32:16 +0100 Subject: [PATCH 19/33] add kafka clients test dependency Signed-off-by: rs-eliatra --- build.gradle | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/build.gradle b/build.gradle index 9f2abc296f..f4e3e4b79e 100644 --- a/build.gradle +++ b/build.gradle @@ -56,20 +56,26 @@ ext { opensearch_version = System.getProperty("opensearch_version", "1.3.0-SNAPSHOT") } -dependencies { - - configurations.all { - resolutionStrategy { - force 'commons-codec:commons-codec:1.14' - force 'org.apache.santuario:xmlsec:2.2.3' - force 'org.cryptacular:cryptacular:1.1.4' - force 'net.minidev:json-smart:2.4.7' - force 'commons-cli:commons-cli:1.3.1' - force 'org.apache.httpcomponents:httpcore:4.4.12' - force "org.apache.commons:commons-lang3:3.4" - } +configurations.testImplementation { + if (it.state != Configuration.State.UNRESOLVED) return + resolutionStrategy { + force 'org.apache.kafka:kafka-clients:2.5.0:test' + } +} +configurations.all { + resolutionStrategy { + force 'commons-codec:commons-codec:1.14' + force 'org.apache.santuario:xmlsec:2.2.3' + force 'org.cryptacular:cryptacular:1.1.4' + force 'net.minidev:json-smart:2.4.7' + force 'commons-cli:commons-cli:1.3.1' + force 'org.apache.httpcomponents:httpcore:4.4.12' + force "org.apache.commons:commons-lang3:3.4" } +} + +dependencies { implementation 'jakarta.annotation:jakarta.annotation-api:1.3.5' implementation "org.opensearch.plugin:transport-netty4-client:${opensearch_version}" @@ -83,7 +89,9 @@ dependencies { implementation 'org.ldaptive:ldaptive:1.2.3' implementation 'org.apache.httpcomponents:httpclient-cache:4.5.13' implementation 'io.jsonwebtoken:jjwt-api:0.10.8' - implementation "org.apache.cxf:cxf-rt-rs-security-jose:3.4.5" + implementation("org.apache.cxf:cxf-rt-rs-security-jose:3.4.5") { + exclude(group: 'jakarta.activation', module: 'jakarta.activation-api') + } implementation 'com.github.wnameless:json-flattener:0.5.0' implementation 'com.flipkart.zjsonpatch:zjsonpatch:0.4.4' implementation 'org.apache.kafka:kafka-clients:2.5.0' @@ -107,7 +115,6 @@ dependencies { testImplementation 'org.apache.httpcomponents:fluent-hc:4.5.13' testImplementation 'org.mockito:mockito-core:2.23.0' testImplementation 'org.springframework.kafka:spring-kafka-test:2.5.4.RELEASE' - testImplementation 'org.apache.kafka:kafka-clients:2.0.1' testImplementation 'javax.servlet:servlet-api:2.5' testImplementation 'com.unboundid:unboundid-ldapsdk:4.0.9' testImplementation 'com.github.stephenc.jcip:jcip-annotations:1.0-1' From c6695f633130e430a8e33fcc3981f8657877b75e Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Tue, 1 Feb 2022 12:29:07 +0100 Subject: [PATCH 20/33] build fix test Signed-off-by: rs-eliatra --- .github/workflows/cd.yml | 2 +- .github/workflows/ci.yml | 2 +- build.gradle | 16 +- pom.xml | 1053 -------------------------------------- 4 files changed, 12 insertions(+), 1061 deletions(-) delete mode 100644 pom.xml diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index aa6ca10fe0..1c2fb10c5c 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -26,7 +26,7 @@ jobs: uses: actions/cache@v1 with: path: ~/.m2/repository - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + key: ${{ runner.os }}-m2-${{ hashFiles('**/build.gradle') }} restore-keys: ${{ runner.os }}-m2 - name: Build diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2ecc0f6baf..4a78973d54 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: uses: actions/cache@v1 with: path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + key: ${{ runner.os }}-m2-${{ hashFiles('**/build.gradle') }} restore-keys: ${{ runner.os }}-m2 - name: Checkstyle diff --git a/build.gradle b/build.gradle index f4e3e4b79e..b5fdf2cfd6 100644 --- a/build.gradle +++ b/build.gradle @@ -46,10 +46,11 @@ import org.gradle.crypto.checksum.Checksum import java.text.SimpleDateFormat repositories { - maven { url "https://aws.oss.sonatype.org/content/repositories/snapshots" } mavenLocal() + maven { url "https://aws.oss.sonatype.org/content/repositories/snapshots" } mavenCentral() maven { url "https://plugins.gradle.org/m2/" } + jcenter() } ext { @@ -59,7 +60,7 @@ ext { configurations.testImplementation { if (it.state != Configuration.State.UNRESOLVED) return resolutionStrategy { - force 'org.apache.kafka:kafka-clients:2.5.0:test' + force 'org.apache.kafka:kafka-clients:2.0.1:test' } } @@ -80,7 +81,7 @@ dependencies { implementation 'jakarta.annotation:jakarta.annotation-api:1.3.5' implementation "org.opensearch.plugin:transport-netty4-client:${opensearch_version}" implementation "org.opensearch.client:opensearch-rest-high-level-client:${opensearch_version}" - implementation 'com.google.guava:guava:25.1-jre' + implementation 'com.google.guava:guava:30.0-jre' implementation 'org.greenrobot:eventbus:3.2.0' implementation 'commons-cli:commons-cli:1.3.1' implementation 'org.bouncycastle:bcprov-jdk15on:1.67' @@ -94,9 +95,12 @@ dependencies { } implementation 'com.github.wnameless:json-flattener:0.5.0' implementation 'com.flipkart.zjsonpatch:zjsonpatch:0.4.4' - implementation 'org.apache.kafka:kafka-clients:2.5.0' + implementation 'org.apache.kafka:kafka-clients:2.8.1' implementation 'com.onelogin:java-saml:2.5.0' - implementation 'org.opensaml:opensaml-saml-impl:3.4.5' + implementation ('org.opensaml:opensaml-saml-impl:3.4.5') { + exclude(group: 'org.apache.velocity', module: 'velocity') + } + implementation 'commons-collections:commons-collections:3.2.2' implementation 'commons-collections:commons-collections:3.2.2' implementation 'com.jayway.jsonpath:json-path:2.4.0' implementation 'org.apache.httpcomponents:httpclient:4.5.13' @@ -114,7 +118,7 @@ dependencies { testImplementation 'junit:junit:4.13.1' testImplementation 'org.apache.httpcomponents:fluent-hc:4.5.13' testImplementation 'org.mockito:mockito-core:2.23.0' - testImplementation 'org.springframework.kafka:spring-kafka-test:2.5.4.RELEASE' + testImplementation 'org.springframework.kafka:spring-kafka-test:2.7.9' testImplementation 'javax.servlet:servlet-api:2.5' testImplementation 'com.unboundid:unboundid-ldapsdk:4.0.9' testImplementation 'com.github.stephenc.jcip:jcip-annotations:1.0-1' diff --git a/pom.xml b/pom.xml deleted file mode 100644 index a56be4a736..0000000000 --- a/pom.xml +++ /dev/null @@ -1,1053 +0,0 @@ - - - - - - 4.0.0 - org.opensearch - opensearch-security - jar - 1.3.0.0-SNAPSHOT - OpenSearch Security - OpenSearch Security - https://github.com/opensearch-project/security - 2021 - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - - - - - - amazonwebservices - Amazon Web Services - https://aws.amazon.com - - developer - - - - - - UTF-8 - UTF-8 - https://oss.sonatype.org/content/repositories/snapshots/ - - false - 1.8 - 1.8 - - 1.3.0-SNAPSHOT - - - 2.0.25.Final - 1.67 - 2.17.1 - 1.7.32 - 30.0-jre - 1.3.1 - 2.12.6 - 0.10.8 - 1.2.3 - 4.5.13 - 3.4.5 - 2.8.1 - 2.5.0 - 3.4.5 - 1.14 - 2.2.3 - 1.1.4 - 2.7.9 - - - ${basedir}/src/main/assemblies/plugin.xml - ${basedir}/src/main/assemblies/securityadmin-standalone.xml - - - - 2.23.0 - 4.0.9 - 0.8.5 - - - - https://github.com/opensearch-project/security - scm:git:git@github.com:opensearch-project/security.git - scm:git:git@github.com:opensearch-project/security.git - 1.3.0.0 - - - - - snapshots-repo - https://aws.oss.sonatype.org/content/repositories/snapshots - false - true - - - - - GitHub - https://github.com/opensearch-project/security/issues - - - - - - commons-codec - commons-codec - ${commons-codec.version} - - - org.apache.santuario - xmlsec - ${xmlsec.version} - - - org.cryptacular - cryptacular - ${cryptacular.version} - - - net.minidev - json-smart - 2.4.7 - - - - - - - - - org.opensearch.plugin - transport-netty4-client - ${opensearch.version} - - - jna - org.opensearch - - - jts - com.vividsolutions - - - spatial4j - org.locationtech.spatial4j - - - - - - - com.google.guava - guava - ${guava.version} - - - - org.greenrobot - eventbus - 3.2.0 - - - - - commons-cli - commons-cli - ${commons.cli.version} - - - - - org.bouncycastle - bcprov-jdk15on - ${bc.version} - - - - - org.opensearch - opensearch - ${opensearch.version} - provided - - - - com.fasterxml.jackson.core - jackson-databind - ${jackson-databind.version} - - - jackson-core - com.fasterxml.jackson.core - - - - - - org.slf4j - slf4j-api - ${slf4j.version} - - - - org.apache.logging.log4j - log4j-core - ${log4j.version} - test - - - - org.ldaptive - ldaptive - ${ldaptive.version} - - - commons-cli - commons-cli - - - slf4j-api - org.slf4j - - - - - - org.apache.httpcomponents - httpclient-cache - ${http.commons.version} - - - org.apache.httpcomponents - httpcore - - - - - - org.opensearch.client - opensearch-rest-high-level-client - ${opensearch.version} - - - org.apache.httpcomponents - httpclient - - - - - - io.jsonwebtoken - jjwt-api - ${jjwt.version} - - - - io.jsonwebtoken - jjwt-impl - ${jjwt.version} - runtime - - - - io.jsonwebtoken - jjwt-jackson - ${jjwt.version} - runtime - - - jackson-databind - com.fasterxml.jackson.core - - - - - - org.apache.cxf - cxf-rt-rs-security-jose - ${cxf.version} - - - jakarta.activation - jakarta.activation-api - - - - - - com.github.wnameless - json-flattener - 0.5.0 - - - - com.flipkart.zjsonpatch - zjsonpatch - 0.4.4 - - - jackson-core - com.fasterxml.jackson.core - - - jackson-databind - com.fasterxml.jackson.core - - - - - org.apache.kafka - kafka-clients - ${kafka.version} - - - slf4j-api - org.slf4j - - - - - com.onelogin - java-saml - ${java-saml.version} - - - - org.codehaus.woodstox - woodstox-core-asl - - - joda-time - joda-time - - - org.apache.httpcomponents - httpclient - - - - - - org.opensaml - opensaml-saml-impl - ${opensaml.version} - - - joda-time - joda-time - - - commons-collections - commons-collections - - - org.apache.velocity - velocity - - - - - - commons-lang - commons-lang - 2.4 - - - - commons-collections - commons-collections - 3.2.2 - - - - - com.jayway.jsonpath - json-path - 2.4.0 - - - - - commons-io - commons-io - 2.7 - test - - - - org.hamcrest - hamcrest-all - 1.3 - test - - - - junit - junit - 4.13.1 - test - - - - org.apache.httpcomponents - fluent-hc - ${http.commons.version} - test - - - - org.opensearch.plugin - reindex-client - ${opensearch.version} - test - - - org.opensearch - opensearch-ssl-config - - - org.apache.httpcomponents - httpclient - - - - - - - org.apache.httpcomponents - httpclient - ${http.commons.version} - - - org.apache.httpcomponents - httpcore - - - - - - org.opensearch - opensearch-ssl-config - ${opensearch.version} - test - - - - org.opensearch.plugin - percolator-client - ${opensearch.version} - test - - - - org.opensearch.plugin - lang-mustache-client - ${opensearch.version} - test - - - - org.opensearch.plugin - parent-join-client - ${opensearch.version} - test - - - - org.opensearch.plugin - aggs-matrix-stats-client - ${opensearch.version} - test - - - - org.mockito - mockito-core - ${mockito.version} - test - - - - org.springframework.kafka - spring-kafka-test - ${spring.kafka.version} - test - - - - org.apache.kafka - kafka-clients - ${kafka.version} - test - test - - - - javax.servlet - servlet-api - 2.5 - test - - - - com.unboundid - unboundid-ldapsdk - ${unboundid-ldapsdk.version} - test - - - com.github.stephenc.jcip - jcip-annotations - 1.0-1 - test - - - - org.apache.kafka - kafka_2.13 - ${kafka.version} - test - - - - org.apache.kafka - kafka_2.13 - ${kafka.version} - test - test - - - - - - - - org.apache.maven.plugins - maven-enforcer-plugin - 3.0.0-M2 - - - enforce-maven - - enforce - - - - - [3.5.4,) - Maven 3.5.4 or later required - - - - - - enforce-java - - enforce - - - - - [1.8,) - Java 8 or later required to build the plugin - - - - - - - - maven-clean-plugin - 3.1.0 - - - - data - - - - - - pl.project13.maven - git-commit-id-plugin - 2.2.6 - - - get-the-git-infos - - revision - - - - validate-the-git-infos - - validateRevision - - package - - - - true - - git.build.host - git.commit.user.* - git.build.user.* - - - - - org.apache.maven.plugins - maven-jar-plugin - - - org.apache.maven.plugins - maven-compiler-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - - - -Xmx3072m - 5 - 3 - true - - - fork_${surefire.forkNumber} - - - - **/*.java - - ${argLine} - - - - - org.jacoco - jacoco-maven-plugin - ${jacoco.version} - - - - prepare-agent - - - - default-report - test - - report - - - - - - - - - org.apache.maven.plugins - maven-resources-plugin - 3.1.0 - - - org.apache.maven.plugins - maven-release-plugin - 2.5.3 - - v@{project.version} - false - true - true - false - release - - - - org.apache.maven.plugins - maven-source-plugin - 3.1.0 - - - attach-sources - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.1.0 - - ${project.build.sourceEncoding} - en - none - - - - attach-javadocs - - jar - - - -Xdoclint:none - - - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.6 - - - --pinentry-mode - loopback - - - - - sign-artifacts - verify - - sign - - - - - - org.apache.maven.plugins - maven-jar-plugin - 3.1.1 - - - **/*cobertura* - **/*jacoco* - - - - true - - - Amazon OpenDistro ElasticSearch Security Parent - ${maven.build.timestamp} - ${git.commit.id} - - - - - - - test-jar - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.0 - - 1.8 - 1.8 - true - true - -Xlint:unchecked - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M3 - - - **/*.java - - - - - org.jacoco - jacoco-maven-plugin - 0.8.3 - - - maven-assembly-plugin - 3.1.1 - - - - - - com.gkatzioura.maven.cloud - s3-storage-wagon - 1.8 - - - kr.motd.maven - os-maven-plugin - 1.5.0.Final - - - - - ${basedir}/src/test/resources - false - - **/* - - - - - - ${basedir} - false - - LICENSE - NOTICE.txt - THIRD-PARTY.txt - KEYS - - - - ${basedir}/src/main/resources - false - - static_config/**/*.yml - - - - - - - advanced - - - - org.apache.maven.plugins - maven-assembly-plugin - - - plugin - package - - false - posix - ${project.build.directory}/releases/ - - ${elasticsearch.assembly.descriptor} - - opensearch-security-${project.version} - - - single - - - - securityadmin - package - - true - posix - ${project.build.directory}/releases/ - - ${securitystandalone.descriptor} - - opensearch-security-${project.version} - - - single - - - - - - com.floragunn - checksum-maven-plugin - 1.7.1 - - - - files - - package - - - - - - ${project.build.directory}/releases/ - - opensearch-security-${project.version}.zip - - - - - SHA-512 - - true - true - true - false - - - - - - - org.opensearch.plugin - lang-mustache-client - ${opensearch.version} - - - - org.opensearch.plugin - parent-join-client - ${opensearch.version} - - - - org.opensearch.plugin - aggs-matrix-stats-client - ${opensearch.version} - - - - - with-static-openssl-linux-non-fedora - - - com.floragunn - search-guard-static-tcnative-beta - 1.1.1c-${netty-native.version}-non-fedora-linux-x86_64 - provided - - - - - with-static-openssl-linux-fedora - - - com.floragunn - search-guard-static-tcnative-beta - 1.1.1c-${netty-native.version}-fedora-linux-x86_64 - provided - - - - - with-dynamic-openssl - - true - - - - io.netty - netty-tcnative - ${netty-native.version} - ${os.detected.classifier} - provided - - - - - release - - - - org.apache.maven.plugins - maven-source-plugin - - - org.apache.maven.plugins - maven-javadoc-plugin - - - org.apache.maven.plugins - maven-gpg-plugin - - - - - - sonatype-nexus-staging - Sonatype Nexus Staging - https://aws.oss.sonatype.org/service/local/staging/deploy/maven2 - - - - - coverage - - - - org.jacoco - jacoco-maven-plugin - - true - - - - agent-for-ut - - prepare-agent - - - - agent-for-it - - prepare-agent-integration - - - - jacoco-site - verify - - report - - - - - - - - - From 713c3fa7c7205f3b467c13c2075d08688c39b5d6 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Wed, 2 Feb 2022 18:45:04 +0100 Subject: [PATCH 21/33] add something to build.gradle to check if hash is changing Signed-off-by: rs-eliatra --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index b5fdf2cfd6..63ae1351bf 100644 --- a/build.gradle +++ b/build.gradle @@ -64,6 +64,7 @@ configurations.testImplementation { } } + configurations.all { resolutionStrategy { force 'commons-codec:commons-codec:1.14' From f8feca537ac1d1235b96b5040cfe9639fa06a04a Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Wed, 2 Feb 2022 21:24:33 +0100 Subject: [PATCH 22/33] Add missing plugin: com.google.osdetector and use it's output in dependencies Signed-off-by: rs-eliatra --- build.gradle | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/build.gradle b/build.gradle index 63ae1351bf..0390145abd 100644 --- a/build.gradle +++ b/build.gradle @@ -40,6 +40,7 @@ plugins { id 'org.barfuin.gradle.taskinfo' version '1.0.5' id "nebula.ospackage" version "9.0.0" + id "com.google.osdetector" version "1.7.0" } import org.gradle.crypto.checksum.Checksum @@ -57,14 +58,6 @@ ext { opensearch_version = System.getProperty("opensearch_version", "1.3.0-SNAPSHOT") } -configurations.testImplementation { - if (it.state != Configuration.State.UNRESOLVED) return - resolutionStrategy { - force 'org.apache.kafka:kafka-clients:2.0.1:test' - } -} - - configurations.all { resolutionStrategy { force 'commons-codec:commons-codec:1.14' @@ -123,7 +116,9 @@ dependencies { testImplementation 'javax.servlet:servlet-api:2.5' testImplementation 'com.unboundid:unboundid-ldapsdk:4.0.9' testImplementation 'com.github.stephenc.jcip:jcip-annotations:1.0-1' - compileOnly 'io.netty:netty-tcnative:2.0.25.Final' + testImplementation 'org.apache.kafka:kafka-clients:2.0.1:test' + compileOnly "io.netty:netty-tcnative:${osdetector.classifier}" + testImplementation "io.netty:netty-tcnative:${osdetector.classifier}" compileOnly "org.opensearch:opensearch:${opensearch_version}" } From d3caddafb68b5e99f486ed3edb6c192e5cd5a509 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Wed, 2 Feb 2022 21:45:27 +0100 Subject: [PATCH 23/33] Add missing plugin: com.google.osdetector and use it's output in dependencies fix Signed-off-by: rs-eliatra --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 0390145abd..9bc250d2ae 100644 --- a/build.gradle +++ b/build.gradle @@ -117,8 +117,8 @@ dependencies { testImplementation 'com.unboundid:unboundid-ldapsdk:4.0.9' testImplementation 'com.github.stephenc.jcip:jcip-annotations:1.0-1' testImplementation 'org.apache.kafka:kafka-clients:2.0.1:test' - compileOnly "io.netty:netty-tcnative:${osdetector.classifier}" - testImplementation "io.netty:netty-tcnative:${osdetector.classifier}" + compileOnly "io.netty:netty-tcnative:2.0.25.Final:${osdetector.classifier}" + testImplementation "io.netty:netty-tcnative:2.0.25.Final:${osdetector.classifier}" compileOnly "org.opensearch:opensearch:${opensearch_version}" } From 714ba4e1848e9dbff4dd98d49004d9a42e6aeb85 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Wed, 2 Feb 2022 22:39:48 +0100 Subject: [PATCH 24/33] Set OPENDISTRO_SECURITY_TEST_OPENSSL_OPT in CI script Signed-off-by: rs-eliatra --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4a78973d54..4af3baf1cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,7 +53,7 @@ jobs: uses: github/codeql-action/analyze@v1 - name: Test - run: ./gradlew test + run: OPENDISTRO_SECURITY_TEST_OPENSSL_OPT=true ./gradlew test --info - name: Coverage uses: codecov/codecov-action@v1 From 5eab5e66686215b65fd2e67a614bf6c391f6e000 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Wed, 2 Feb 2022 23:35:56 +0100 Subject: [PATCH 25/33] change CI job logging Signed-off-by: rs-eliatra --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4af3baf1cc..de08cbe49f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,7 +53,7 @@ jobs: uses: github/codeql-action/analyze@v1 - name: Test - run: OPENDISTRO_SECURITY_TEST_OPENSSL_OPT=true ./gradlew test --info + run: OPENDISTRO_SECURITY_TEST_OPENSSL_OPT=true ./gradlew test - name: Coverage uses: codecov/codecov-action@v1 From c44165cf22b7313b1b490a9c998a03a64b97478f Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Thu, 3 Feb 2022 01:52:46 +0100 Subject: [PATCH 26/33] force to use scala-library as testImplementation to fix NoClassDefFoundError Signed-off-by: rs-eliatra --- build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle b/build.gradle index 9bc250d2ae..f45d4bc2c0 100644 --- a/build.gradle +++ b/build.gradle @@ -120,6 +120,9 @@ dependencies { compileOnly "io.netty:netty-tcnative:2.0.25.Final:${osdetector.classifier}" testImplementation "io.netty:netty-tcnative:2.0.25.Final:${osdetector.classifier}" compileOnly "org.opensearch:opensearch:${opensearch_version}" + testImplementation ('org.scala-lang:scala-library:2.12.10') { + force true + } } From 368965f064e756a4cd146f45ba1f97d1fc89804d Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Thu, 3 Feb 2022 18:35:21 +0100 Subject: [PATCH 27/33] configure test to retry for CI job Signed-off-by: rs-eliatra --- .github/workflows/ci.yml | 2 +- build.gradle | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index de08cbe49f..1795d017f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ on: - opendistro-* env: - MAVEN_OPTS: -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.http.retryHandler.class=standard -Dmaven.wagon.http.retryHandler.count=3 + GRADLE_OPTS: -Dhttp.keepAlive=false -DCI=true jobs: build: diff --git a/build.gradle b/build.gradle index f45d4bc2c0..4c9766799b 100644 --- a/build.gradle +++ b/build.gradle @@ -41,6 +41,7 @@ plugins { id "nebula.ospackage" version "9.0.0" id "com.google.osdetector" version "1.7.0" + id "org.gradle.test-retry" version "1.3.1" } import org.gradle.crypto.checksum.Checksum @@ -214,9 +215,18 @@ testsJar { libsDirName = '.' } +boolean isCI = System.getenv().containsKey("CI") + test { maxParallelForks = 3 jvmArgs "-Xmx3072m" + retry { + if (isCI) { + failOnPassedAfterRetry = false + maxFailures = 30 + maxRetries = 3 + } + } } gitProperties { From f5b2b5490cee6572ed694db9e8e23f1db8ab7fcd Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Sat, 5 Feb 2022 02:48:31 +0100 Subject: [PATCH 28/33] setup gradle cache (CI) Signed-off-by: rs-eliatra --- .github/workflows/cd.yml | 15 +++++++++------ .github/workflows/ci.yml | 14 +++++++++----- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 1c2fb10c5c..3a1c0c0a91 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -6,7 +6,7 @@ on: - '*' env: - MAVEN_OPTS: -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.http.retryHandler.class=standard -Dmaven.wagon.http.retryHandler.count=3 + GRADLE_OPTS: -Dhttp.keepAlive=false jobs: build: @@ -22,12 +22,15 @@ jobs: - name: Checkout security uses: actions/checkout@v2 - - name: Cache Maven packages - uses: actions/cache@v1 + - name: Cache Gradle packages + uses: actions/cache@v2 with: - path: ~/.m2/repository - key: ${{ runner.os }}-m2-${{ hashFiles('**/build.gradle') }} - restore-keys: ${{ runner.os }}-m2 + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- - name: Build run: | diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1795d017f9..87e1036522 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,12 +36,16 @@ jobs: with: languages: java - - name: Cache Maven packages - uses: actions/cache@v1 + - name: Cache Gradle packages + uses: actions/cache@v2 with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/build.gradle') }} - restore-keys: ${{ runner.os }}-m2 + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + - name: Checkstyle run: ./gradlew clean checkstyleMain checkstyleTest From 46c4eec8f2acb54b088712f7ffd92057e6ad9751 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Fri, 11 Feb 2022 18:57:44 +0100 Subject: [PATCH 29/33] resolve conflicts and address review feedback Signed-off-by: rs-eliatra --- .github/workflows/ci.yml | 2 +- build.gradle | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 87e1036522..a45e16ea50 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ on: - opendistro-* env: - GRADLE_OPTS: -Dhttp.keepAlive=false -DCI=true + GRADLE_OPTS: -Dhttp.keepAlive=false jobs: build: diff --git a/build.gradle b/build.gradle index 4c9766799b..f29333ef4c 100644 --- a/build.gradle +++ b/build.gradle @@ -117,7 +117,9 @@ dependencies { testImplementation 'javax.servlet:servlet-api:2.5' testImplementation 'com.unboundid:unboundid-ldapsdk:4.0.9' testImplementation 'com.github.stephenc.jcip:jcip-annotations:1.0-1' - testImplementation 'org.apache.kafka:kafka-clients:2.0.1:test' + testImplementation 'org.apache.kafka:kafka_2.13:2.8.1' + testImplementation 'org.apache.kafka:kafka_2.13:2.8.1:test' + testImplementation 'org.apache.kafka:kafka-clients:2.8.1:test' compileOnly "io.netty:netty-tcnative:2.0.25.Final:${osdetector.classifier}" testImplementation "io.netty:netty-tcnative:2.0.25.Final:${osdetector.classifier}" compileOnly "org.opensearch:opensearch:${opensearch_version}" @@ -215,17 +217,14 @@ testsJar { libsDirName = '.' } -boolean isCI = System.getenv().containsKey("CI") test { maxParallelForks = 3 jvmArgs "-Xmx3072m" retry { - if (isCI) { - failOnPassedAfterRetry = false - maxFailures = 30 - maxRetries = 3 - } + failOnPassedAfterRetry = false + maxFailures = 30 + maxRetries = 5 } } From 891c2a50114c8b540395d6dc559a16973a9355b1 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Fri, 11 Feb 2022 21:02:01 +0100 Subject: [PATCH 30/33] resolve conflicts and address review feedback v2 Signed-off-by: rs-eliatra --- build.gradle | 4 ---- 1 file changed, 4 deletions(-) diff --git a/build.gradle b/build.gradle index f29333ef4c..86184a26f4 100644 --- a/build.gradle +++ b/build.gradle @@ -123,12 +123,8 @@ dependencies { compileOnly "io.netty:netty-tcnative:2.0.25.Final:${osdetector.classifier}" testImplementation "io.netty:netty-tcnative:2.0.25.Final:${osdetector.classifier}" compileOnly "org.opensearch:opensearch:${opensearch_version}" - testImplementation ('org.scala-lang:scala-library:2.12.10') { - force true - } } - ext { securityPluginVersion = '1.3.0.0' isSnapshot = "true" == System.getProperty("build.snapshot", "true") From 9eed8360db9ee29190ce18eab2f1a8973539145e Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Tue, 15 Feb 2022 07:54:30 +0100 Subject: [PATCH 31/33] fix dependencies after conflict Signed-off-by: rs-eliatra --- build.gradle | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 86184a26f4..06af9e5e43 100644 --- a/build.gradle +++ b/build.gradle @@ -72,7 +72,6 @@ configurations.all { } dependencies { - implementation 'jakarta.annotation:jakarta.annotation-api:1.3.5' implementation "org.opensearch.plugin:transport-netty4-client:${opensearch_version}" implementation "org.opensearch.client:opensearch-rest-high-level-client:${opensearch_version}" @@ -95,7 +94,7 @@ dependencies { implementation ('org.opensaml:opensaml-saml-impl:3.4.5') { exclude(group: 'org.apache.velocity', module: 'velocity') } - implementation 'commons-collections:commons-collections:3.2.2' + implementation 'commons-lang:commons-lang:2.4' implementation 'commons-collections:commons-collections:3.2.2' implementation 'com.jayway.jsonpath:json-path:2.4.0' implementation 'org.apache.httpcomponents:httpclient:4.5.13' From 64528b901266a33d02c410dd9cb6ad03c0ceb391 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Tue, 15 Feb 2022 09:50:49 +0100 Subject: [PATCH 32/33] upgrade spring-core to 5.3.14 Signed-off-by: rs-eliatra --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 06af9e5e43..f0b0b3593d 100644 --- a/build.gradle +++ b/build.gradle @@ -68,6 +68,7 @@ configurations.all { force 'commons-cli:commons-cli:1.3.1' force 'org.apache.httpcomponents:httpcore:4.4.12' force "org.apache.commons:commons-lang3:3.4" + force "org.springframework:spring-core:5.3.14" } } From e59a7c60cd42e0cc3f5c8e14900ace9b555843b5 Mon Sep 17 00:00:00 2001 From: rs-eliatra Date: Tue, 15 Feb 2022 16:11:47 +0100 Subject: [PATCH 33/33] configure guava to use 30.0-jre also in buildscript (checkstyle plugin) Signed-off-by: rs-eliatra --- build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle b/build.gradle index f0b0b3593d..19115ec922 100644 --- a/build.gradle +++ b/build.gradle @@ -47,6 +47,7 @@ import org.gradle.crypto.checksum.Checksum import java.text.SimpleDateFormat + repositories { mavenLocal() maven { url "https://aws.oss.sonatype.org/content/repositories/snapshots" } @@ -69,6 +70,7 @@ configurations.all { force 'org.apache.httpcomponents:httpcore:4.4.12' force "org.apache.commons:commons-lang3:3.4" force "org.springframework:spring-core:5.3.14" + force "com.google.guava:guava:30.0-jre" } }