diff --git a/.ci.settings.xml b/.ci.settings.xml deleted file mode 100644 index 8762a9e86..000000000 --- a/.ci.settings.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - maven-dev - ${env.ARTIFACTORY_USER} - ${env.ARTIFACTORY_TOKEN} - - - - maven-all-virtual - ${env.ARTIFACTORY_USER} - ${env.ARTIFACTORY_TOKEN} - - - - org.sonarsource.scanner.maven - - - - sonar - - true - - - java-client - ${env.SONARQUBE_HOST_URL} - ${env.SONAR_TOKEN} - . - pom.xml,src/main/** - . - src/test/** - .csv - **/matchers/**/*.* - https://travis-ci.com/splitio/java-client - https://github.com/splitio/java-client - - - - diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b43f4a5dc..bec6b7cc1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ on: - development concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number }} + group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event.pull_request.number || github.sha }} cancel-in-progress: true jobs: @@ -22,20 +22,10 @@ jobs: image: redis ports: - 6379:6379 - strategy: - fail-fast: false - matrix: - jdk: - - '8' - - '11' - - '19' env: SONARQUBE_HOST_URL: ${{ vars.SONARQUBE_HOST }} - ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} - ARTIFACTORY_TOKEN: ${{ secrets.ARTIFACTORY_TOKEN }} SONAR_TOKEN: ${{ secrets.SONARQUBE_TOKEN }} - MAVEN_OPTS: "-XX:InitialHeapSize=2G -XX:MaxHeapSize=2G -XX:+PrintCommandLineFlags -XX:ThreadStackSize=65536 -XX:-TieredCompilation -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn" - muteProps: "true" + CODEARTIFACT_AUTH_TOKEN: ${{ secrets.CODEARTIFACT_AUTH_TOKEN }} steps: - name: Checkout code @@ -43,37 +33,26 @@ jobs: with: fetch-depth: 0 - - name: Setup JDK ${{ matrix.jdk }} - uses: actions/setup-java@v3 + - name: Setup JDK 17 + uses: actions/setup-java@v4 with: - distribution: 'adopt' - java-version: ${{ matrix.jdk }} + distribution: 'temurin' + java-version: '17' - - name: Setup Maven - run: cp .ci.settings.xml ${HOME}/.m2/settings.xml + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 - - name: Test - if: matrix.jdk == '8' && github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && github.ref != 'refs/heads/development' - run: mvn --batch-mode clean install - - - name: Linter - if: matrix.jdk == '8' && github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && github.ref != 'refs/heads/development' - run: mvn checkstyle::check - -# - name: Deploy -# if: matrix.jdk == '8' && github.event_name == 'push' && github.ref != 'refs/heads/master' && github.ref != 'refs/heads/development' -# run: mvn --batch-mode deploy -P test + - name: Build + run: ./gradlew build - name: SonarQube Scan (Push) - if: matrix.jdk == '11' && github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/development') - run: | - mvn --batch-mode clean verify sonar:sonar \ - -Dsonar.branch.name=${{ github.ref_name }} + if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/development') + run: ./gradlew sonar -Dsonar.branch.name=${{ github.ref_name }} - name: SonarQube Scan (Pull Request) - if: matrix.jdk == '11' && github.event_name == 'pull_request' + if: github.event_name == 'pull_request' run: | - mvn --batch-mode clean verify sonar:sonar \ + ./gradlew sonar \ -Dsonar.pullrequest.key=${{ github.event.pull_request.number }} \ -Dsonar.pullrequest.branch=${{ github.event.pull_request.head.ref }} \ -Dsonar.pullrequest.base=${{ github.event.pull_request.base.ref }} diff --git a/.gitignore b/.gitignore index dc81d245b..851f3cfa5 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,8 @@ target .settings .DS_Store dependency-reduced-pom.xml + +# Gradle +.gradle/ +build/ +!gradle/wrapper/gradle-wrapper.jar diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 000000000..84b55e7f5 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,2 @@ +// Root project — no source code +// Convention plugins in buildSrc handle shared configuration diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 000000000..d365fa087 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,23 @@ +plugins { + `kotlin-dsl` +} + +repositories { + mavenLocal() + maven { + url = uri("https://harness0.harness.io/pkg/l7B_kbSEQD2wjrM7PShm5w/fme-mvn/maven") + } + maven { + url = uri("https://fme-079419646996.d.codeartifact.us-east-1.amazonaws.com/maven/maven-fme/") + credentials { + username = "aws" + password = System.getenv("CODEARTIFACT_AUTH_TOKEN") ?: "" + } + } + gradlePluginPortal() + mavenCentral() +} + +dependencies { + implementation("io.harness.fme:fme-gradle-plugin:0.5.0") +} diff --git a/buildSrc/src/main/kotlin/java-client.java-library.gradle.kts b/buildSrc/src/main/kotlin/java-client.java-library.gradle.kts new file mode 100644 index 000000000..047b14162 --- /dev/null +++ b/buildSrc/src/main/kotlin/java-client.java-library.gradle.kts @@ -0,0 +1,52 @@ +plugins { + `java-library` + id("fme.publishing") + id("fme.jacoco") + id("fme.spotless") + id("fme.sonarqube") +} + +fmeSpotless { + checkstyleConfigFile.set(rootProject.file(".github/linter/google-java-style.xml")) + enforceSpotlessCheck.set(false) +} + +java { + withJavadocJar() + withSourcesJar() +} + +tasks.withType { + manifest { + attributes( + "Implementation-Title" to project.name, + "Implementation-Version" to project.version + ) + } +} + +tasks.withType { + useJUnitPlatform() +} + +tasks.withType { + (options as StandardJavadocDocletOptions).addStringOption("Xdoclint:none", "-quiet") +} + +// Ensure consistent JVM environment attribute resolution for all modules. +// Required by libraries like Guava (-jre variant) that use Gradle's +// variant-aware dependency resolution. +sourceSets.all { + configurations.getByName(runtimeClasspathConfigurationName) { + attributes.attribute( + org.gradle.api.attributes.java.TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, + objects.named(org.gradle.api.attributes.java.TargetJvmEnvironment.STANDARD_JVM) + ) + } + configurations.getByName(compileClasspathConfigurationName) { + attributes.attribute( + org.gradle.api.attributes.java.TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, + objects.named(org.gradle.api.attributes.java.TargetJvmEnvironment.STANDARD_JVM) + ) + } +} diff --git a/buildSrc/src/main/kotlin/java-client.java17.gradle.kts b/buildSrc/src/main/kotlin/java-client.java17.gradle.kts new file mode 100644 index 000000000..34ec7fa74 --- /dev/null +++ b/buildSrc/src/main/kotlin/java-client.java17.gradle.kts @@ -0,0 +1,9 @@ +plugins { + id("java-client.java-library") +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(17)) + } +} diff --git a/client/build.gradle.kts b/client/build.gradle.kts new file mode 100644 index 000000000..e07a11def --- /dev/null +++ b/client/build.gradle.kts @@ -0,0 +1,71 @@ +plugins { + id("java-client.java17") + alias(libs.plugins.shadow) +} + +group = "io.split.client" +version = "4.18.3" +description = "Java SDK for Split" + +dependencies { + api(project(":pluggable-storage")) + implementation(libs.guava) + implementation(libs.slf4j.api) + implementation(libs.httpclient5) + implementation(libs.gson) + implementation(libs.snakeyaml) + + testImplementation(libs.junit4) + testRuntimeOnly(libs.junit.vintage.engine) + testImplementation("org.hamcrest:hamcrest-all:1.3") + testImplementation("org.mockito:mockito-core:1.10.19") // pinned to 1.x for legacy tests using MockitoJUnitRunner + testImplementation(libs.slf4j.log4j12) + testImplementation(libs.commons.lang3) + testImplementation(libs.awaitility) + testImplementation(libs.okhttp.mockwebserver) + + // Jersey test dependencies + testImplementation("org.glassfish.jersey.media:jersey-media-sse:2.31") + testImplementation("org.glassfish.jersey.inject:jersey-hk2:2.31") + testImplementation("org.glassfish.jersey.containers:jersey-container-grizzly2-http:2.26") + + // Powermock (legacy, needed for existing tests) + testImplementation("org.powermock:powermock-module-junit4:1.7.4") + testImplementation("org.powermock:powermock-api-mockito:1.7.4") +} + +// Resource filtering for splitversion.properties +tasks.processResources { + filesMatching("splitversion.properties") { + expand("project" to mapOf("version" to project.version)) + } +} + +// Shaded fat JAR — include transitive deps, relocate to avoid conflicts +tasks.shadowJar { + mergeServiceFiles() + + // Include only specific artifacts in the shadow jar + dependencies { + include(dependency(project(":pluggable-storage"))) + include(dependency("com.google.guava:guava")) + include(dependency("com.google.code.gson:gson")) + include(dependency("org.yaml:snakeyaml")) + include(dependency("org.apache.httpcomponents.client5:httpclient5")) + include(dependency("org.apache.httpcomponents.core5:httpcore5")) + include(dependency("org.apache.httpcomponents.core5:httpcore5-h2")) + include(dependency("org.checkerframework:checker-qual")) + include(dependency("commons-codec:commons-codec")) + include(dependency("com.google.errorprone:error_prone_annotations")) + include(dependency("com.google.guava:failureaccess")) + include(dependency("com.google.guava:listenablefuture")) + include(dependency("com.google.j2objc:j2objc-annotations")) + } + + relocate("org.apache", "split.org.apache") + relocate("org.checkerframework", "split.org.checkerframework") + relocate("org.yaml.snakeyaml", "split.org.yaml.snakeyaml") + relocate("com.google", "split.com.google") + + exclude("META-INF/**", "LICENSE", "NOTICE", "/*.txt", "build.properties") +} diff --git a/client/pom.xml b/client/pom.xml deleted file mode 100644 index e2343ace1..000000000 --- a/client/pom.xml +++ /dev/null @@ -1,274 +0,0 @@ - - - 4.0.0 - - io.split.client - java-client-parent - 4.18.3 - - - 4.18.3 - java-client - jar - Java Client - Java SDK for Split - - - - release - - - - org.sonatype.central - central-publishing-maven-plugin - 0.8.0 - true - - false - central - false - published - - - - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.3 - false - - ${maven.compiler.source} - ${maven.compiler.target} - - - - org.apache.maven.plugins - maven-jar-plugin - 3.3.0 - - - non-shaded-jar - package - - jar - - - non-shaded - - - - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.2.4 - - - package - - shade - - - false - true - - - io.split.engine:* - io.split.client:* - io.split.schemas:* - io.codigo.grammar:* - org.apache.httpcomponents.* - org.apache.hc.* - com.google.code.gson:gson - com.google.guava:guava - org.yaml:snakeyaml:* - - - org.checkerframework:* - - - commons-codec:* - - - - - - - - - org.apache - split.org.apache - - - org.checkerframework - split.org.checkerframework - - - org.yaml.snakeyaml - split.org.yaml.snakeyaml - - - com.google - split.com.google - - - - - *:* - - META-INF/** - LICENSE - NOTICE - /*.txt - build.properties - - - - - - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - - jar - - - - - - - src/main/resources/splitversion.properties - - - - src/main/resources - true - - - - - 1.7.36 - 8 - 8 - - - - - io.split.client - pluggable-storage - 2.1.0 - compile - - - com.google.guava - guava - 32.0.1-jre - - - org.slf4j - slf4j-api - ${slf4j.api.version} - - - org.apache.httpcomponents.client5 - httpclient5 - 5.5 - - - com.google.code.gson - gson - 2.13.1 - - - org.yaml - snakeyaml - 2.0 - - - - org.apache.commons - commons-lang3 - 3.18.0 - test - - - junit - junit - test - - - org.hamcrest - hamcrest-all - 1.3 - test - - - org.mockito - mockito-core - 1.10.19 - test - - - org.slf4j - slf4j-log4j12 - ${slf4j.api.version} - test - - - org.glassfish.jersey.media - jersey-media-sse - 2.31 - test - - - org.glassfish.jersey.inject - jersey-hk2 - 2.31 - test - - - org.glassfish.jersey.containers - jersey-container-grizzly2-http - 2.26 - test - - - com.squareup.okhttp3 - mockwebserver - 4.8.0 - test - - - org.awaitility - awaitility - 4.0.3 - test - - - org.powermock - powermock-module-junit4 - 1.7.4 - test - - - org.powermock - powermock-api-mockito - 1.7.4 - test - - - diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 000000000..a5cdeea22 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.caching=true +org.gradle.parallel=true +org.gradle.jvmargs=-Xmx2g -XX:+HeapDumpOnOutOfMemoryError diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..d997cfc60 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..e18bc253b --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 000000000..739907dfd --- /dev/null +++ b/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed 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 +# +# https://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. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/2d6327017519d23b96af35865dc997fcb544fb40/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +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 + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +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 ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + + + +# 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 + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + 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 +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +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" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + 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 + # 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 +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +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 new file mode 100644 index 000000000..e509b2dd8 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,93 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +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="-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% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/okhttp-modules/build.gradle.kts b/okhttp-modules/build.gradle.kts new file mode 100644 index 000000000..30814a136 --- /dev/null +++ b/okhttp-modules/build.gradle.kts @@ -0,0 +1,25 @@ +plugins { + id("java-client.java17") +} + +group = "io.split.client" +version = "4.18.3" +description = "Alternative Http Modules" + +dependencies { + implementation(project(":client")) + implementation(libs.okhttp) + implementation("com.squareup.okhttp3:logging-interceptor:4.12.0") + implementation(libs.httpclient5) + + testImplementation(libs.junit4) + testRuntimeOnly(libs.junit.vintage.engine) + testImplementation("org.mockito:mockito-core:1.10.19") // pinned to 1.x for legacy tests + testImplementation(libs.okhttp.mockwebserver) + testImplementation(libs.gson) // needed for Json class used in tests + testImplementation("org.hamcrest:hamcrest-all:1.3") + + // Powermock (legacy, needed for existing tests) + testImplementation("org.powermock:powermock-module-junit4:1.7.4") + testImplementation("org.powermock:powermock-api-mockito:1.7.4") +} diff --git a/okhttp-modules/pom.xml b/okhttp-modules/pom.xml deleted file mode 100644 index f5b1c19f3..000000000 --- a/okhttp-modules/pom.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - java-client-parent - io.split.client - 4.18.3 - - 4.0.0 - 4.18.3 - okhttp-modules - jar - http-modules - Alternative Http Modules - - - - release - - - - org.sonatype.central - central-publishing-maven-plugin - 0.8.0 - true - - false - central - false - published - - - - - - - - - com.squareup.okhttp3 - okhttp - 4.12.0 - - - com.squareup.okhttp3 - logging-interceptor - 4.12.0 - - - io.split.client - java-client - 4.14.0-rc1 - compile - - - org.apache.httpcomponents.client5 - httpclient5 - 5.5 - - - - junit - junit - test - - - org.mockito - mockito-core - 1.10.19 - test - - - org.powermock - powermock-module-junit4 - 1.7.4 - test - - - org.powermock - powermock-api-mockito - 1.7.4 - test - - - com.squareup.okhttp3 - mockwebserver - 4.8.0 - test - - - - diff --git a/pluggable-storage/build.gradle.kts b/pluggable-storage/build.gradle.kts new file mode 100644 index 000000000..fba284a80 --- /dev/null +++ b/pluggable-storage/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + id("java-client.java17") +} + +group = "io.split.client" +version = "2.1.0" +description = "Wrapper interface to implement Pluggable Storage" diff --git a/pluggable-storage/pom.xml b/pluggable-storage/pom.xml deleted file mode 100644 index b06db7cf1..000000000 --- a/pluggable-storage/pom.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - 4.0.0 - - java-client-parent - io.split.client - 4.18.3 - - - 2.1.0 - pluggable-storage - jar - Package for Pluggable Storage - Wrapper interface to implement Pluggable Storage - - - - release - - - - org.sonatype.central - central-publishing-maven-plugin - 0.8.0 - true - - true - central - false - published - - - - - - - - diff --git a/pom.xml b/pom.xml deleted file mode 100644 index b388caf0e..000000000 --- a/pom.xml +++ /dev/null @@ -1,213 +0,0 @@ - - - 4.0.0 - io.split.client - java-client-parent - 4.18.3 - - - - junit - junit - 4.13.1 - - - - pom - Java Client - Java SDK for Split - www.split.io - - - Adil Aijaz - adil@split.io - - - Patricio Echague - pato@split.io - - - Henry Jewkes - henry@split.io - - - Fernando Martin - fernando@split.io - - - - - Apache 2.0 - http://www.apache.org/licenses/LICENSE-2.0 - - - - scm:git:git@github.com:splitio/java-client.git - scm:git@github.com:splitio/java-client.git - git@github.com:splitio/java-client.git - - - - - ossrh - https://oss.sonatype.org/content/repositories/releases - - - - - - UTF-8 - UTF-8 - UTF-8 - 1.8 - 1.8 - - - pluggable-storage - redis-wrapper - testing - okhttp-modules - client - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.3 - - ${maven.compiler.source} - ${maven.compiler.target} - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - - jar - - - - - - org.jacoco - jacoco-maven-plugin - 0.8.4 - - - - prepare-agent - - - - - report - test - - report - - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - 3.3.0 - - - checkstyle - validate - - check - - - - - .github/linter/google-java-style.xml - warning - true - - - - - - - test - - - - org.apache.maven.plugins - maven-javadoc-plugin - - - attach-javadocs - - jar - - - -Xdoclint:none - 1.8 - - - - - - - - - - release - - - - - org.apache.maven.plugins - maven-javadoc-plugin - - - attach-javadocs - - jar - - - -Xdoclint:none - 1.8 - - - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.5 - - - sign-artifacts - verify - - sign - - - - - - - org.sonatype.central - central-publishing-maven-plugin - 0.8.0 - true - - central - false - published - - - - - - - diff --git a/redis-wrapper/build.gradle.kts b/redis-wrapper/build.gradle.kts new file mode 100644 index 000000000..5cd9a556e --- /dev/null +++ b/redis-wrapper/build.gradle.kts @@ -0,0 +1,31 @@ +plugins { + id("java-client.java17") + alias(libs.plugins.shadow) +} + +group = "io.split.client" +version = "3.1.2" +description = "Implements Redis Pluggable Storage" + +dependencies { + api(project(":pluggable-storage")) + implementation("redis.clients:jedis:4.4.8") + + testImplementation(libs.junit4) + testRuntimeOnly(libs.junit.vintage.engine) +} + +tasks.shadowJar { + mergeServiceFiles() + // jedis is intentionally NOT relocated — consumers depend on redis.clients.jedis types directly + exclude( + "META-INF/license/**", + "META-INF/*", + "META-INF/maven/**", + "META-INF/services/**", + "LICENSE", + "NOTICE", + "/*.txt", + "build.properties" + ) +} diff --git a/redis-wrapper/pom.xml b/redis-wrapper/pom.xml deleted file mode 100644 index 16f59a515..000000000 --- a/redis-wrapper/pom.xml +++ /dev/null @@ -1,112 +0,0 @@ - - - 4.0.0 - - java-client-parent - io.split.client - 4.18.3 - - redis-wrapper - 3.1.2 - jar - Package for Redis Wrapper Implementation - Implements Redis Pluggable Storage - - - 8 - 8 - - - - io.split.client - pluggable-storage - 2.1.0 - compile - - - redis.clients - jedis - 4.4.8 - - - junit - junit - test - - - - - - release - - - - org.sonatype.central - central-publishing-maven-plugin - 0.8.0 - true - - true - central - false - published - - - - - - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.2.4 - - - package - - shade - - - false - true - - - redis.clients:* - - - - - - - - - redis.clients.jedis - redis.clients.jedis - - - - - *:* - - META-INF/license/** - META-INF/* - META-INF/maven/** - META-INF/services/** - LICENSE - NOTICE - /*.txt - build.properties - - - - - - - - - - diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 000000000..d1a817343 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,57 @@ +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + } +} + +rootProject.name = "java-client" + +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + versionCatalogs { + create("libs") { + from("io.harness.fme:fme-version-catalog:0.6.0") + } + } + repositories { + mavenLocal { + content { + includeGroupByRegex("io\\.split\\..*") + includeGroupByRegex("io\\.harness\\.fme.*") + } + } + maven { + name = "HarnessMaven" + url = uri("https://harness0.harness.io/pkg/l7B_kbSEQD2wjrM7PShm5w/fme-mvn/maven") + content { + includeGroupByRegex("io\\.split\\..*") + includeGroupByRegex("io\\.harness\\.fme.*") + } + } + maven { + name = "CodeArtifact" + url = uri("https://fme-079419646996.d.codeartifact.us-east-1.amazonaws.com/maven/maven-fme/") + credentials { + username = "aws" + password = providers.environmentVariable("CODEARTIFACT_AUTH_TOKEN") + .orElse(providers.gradleProperty("codeArtifactToken")) + .getOrElse("") + } + content { + includeGroupByRegex("io\\.split\\..*") + includeGroupByRegex("io\\.harness\\.fme.*") + } + } + mavenCentral() + gradlePluginPortal() + } +} + +include( + "pluggable-storage", + "redis-wrapper", + "testing", + "okhttp-modules", + "client" +) diff --git a/testing/build.gradle.kts b/testing/build.gradle.kts new file mode 100644 index 000000000..f2c7d6b28 --- /dev/null +++ b/testing/build.gradle.kts @@ -0,0 +1,23 @@ +plugins { + id("java-client.java17") +} + +group = "io.split.client" +version = "4.18.3" +description = "Testing suite for Java SDK for Split" + +dependencies { + api(project(":client")) + compileOnly(libs.junit4) + + testImplementation(libs.junit4) + testRuntimeOnly(libs.junit.vintage.engine) + testImplementation("org.hamcrest:hamcrest-all:1.3") +} + +// Override the default artifactId to match the Maven artifact name +publishing { + publications.withType().configureEach { + artifactId = "java-client-testing" + } +} diff --git a/testing/pom.xml b/testing/pom.xml deleted file mode 100644 index 21b54f2ab..000000000 --- a/testing/pom.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - 4.0.0 - - io.split.client - java-client-parent - 4.18.3 - - java-client-testing - jar - 4.18.3 - Java Client For Testing - Testing suite for Java SDK for Split - - - io.split.client - java-client - ${project.version} - - - junit - junit - provided - - - - - - release - - - - org.sonatype.central - central-publishing-maven-plugin - 0.8.0 - true - - central - false - published - false - - - - - - - diff --git a/update_maven_settings.sh b/update_maven_settings.sh deleted file mode 100755 index 8bea975fb..000000000 --- a/update_maven_settings.sh +++ /dev/null @@ -1,161 +0,0 @@ -#!/bin/bash - -# Script to update Maven settings.xml with Central Repository credentials using xmlstarlet - -# ANSI color codes -GREEN='\033[0;32m' -YELLOW='\033[0;33m' -BLUE='\033[0;34m' -RED='\033[0;31m' -NC='\033[0m' # No Color - -# Check if xmlstarlet is installed -if ! command -v xmlstarlet &> /dev/null; then - echo -e "${RED}Error: xmlstarlet is not installed.${NC}" - echo "Please install xmlstarlet first:" - echo " macOS: brew install xmlstarlet" - echo " Debian/Ubuntu: sudo apt-get install xmlstarlet" - echo " RHEL/CentOS/Fedora: sudo yum install xmlstarlet" - echo "Then run this script again." - exit 1 -fi - -# Default values -DEFAULT_SETTINGS_PATH="$HOME/.m2/settings.xml" -DEFAULT_SERVER_ID="central" - -echo -e "${BLUE}Maven Settings.xml Update Script${NC}" -echo "This script will update your Maven settings.xml with Central Repository credentials." -echo - -# Ask for settings.xml path or use default -read -p "Path to settings.xml [$DEFAULT_SETTINGS_PATH]: " SETTINGS_PATH -SETTINGS_PATH=${SETTINGS_PATH:-$DEFAULT_SETTINGS_PATH} - -# Variables to store existing values -EXISTING_USERNAME="" -EXISTING_PASSWORD="" - -# Extract existing values if settings.xml exists -if [ -f "$SETTINGS_PATH" ] && command -v xmlstarlet &> /dev/null; then - # Check if the file is valid XML - if xmlstarlet val "$SETTINGS_PATH" &> /dev/null; then - echo -e "${YELLOW}Reading existing settings from ${SETTINGS_PATH}...${NC}" - - # Extract existing server ID - DEFAULT_SERVER_ID=$(xmlstarlet sel -t -v "/settings/servers/server[1]/id" "$SETTINGS_PATH" 2>/dev/null || echo "$DEFAULT_SERVER_ID") - - # Extract existing username and password for the server - EXISTING_USERNAME=$(xmlstarlet sel -t -v "/settings/servers/server[id='$DEFAULT_SERVER_ID']/username" "$SETTINGS_PATH" 2>/dev/null || echo "") - EXISTING_PASSWORD=$(xmlstarlet sel -t -v "/settings/servers/server[id='$DEFAULT_SERVER_ID']/password" "$SETTINGS_PATH" 2>/dev/null || echo "") - fi -fi - -# Ask for server ID or use default/existing -read -p "Server ID [$DEFAULT_SERVER_ID]: " SERVER_ID -SERVER_ID=${SERVER_ID:-$DEFAULT_SERVER_ID} - -# Ask for username (show existing if available) -USERNAME_PROMPT="Username" -if [ -n "$EXISTING_USERNAME" ]; then - USERNAME_PROMPT="Username (current: $EXISTING_USERNAME)" -fi -read -p "$USERNAME_PROMPT: " USERNAME -USERNAME=${USERNAME:-$EXISTING_USERNAME} - -# Ask for password (indicate if existing) -PASSWORD_PROMPT="Password" -if [ -n "$EXISTING_PASSWORD" ]; then - PASSWORD_PROMPT="Password (leave empty to keep current)" -fi -read -s -p "$PASSWORD_PROMPT: " PASSWORD -echo -# Only use existing password if the user didn't enter a new one -if [ -z "$PASSWORD" ] && [ -n "$EXISTING_PASSWORD" ]; then - PASSWORD="$EXISTING_PASSWORD" -fi - -# Create .m2 directory if it doesn't exist -M2_DIR=$(dirname "$SETTINGS_PATH") -mkdir -p "$M2_DIR" - -# No GPG configuration needed - -# Function to create a new settings.xml file -create_new_settings() { - echo -e "${YELLOW}Creating new settings.xml file...${NC}" - cat > "$SETTINGS_PATH" << EOF - - - - - $SERVER_ID - $USERNAME - $PASSWORD - - - -EOF -} - -# Check if settings.xml exists -if [ -f "$SETTINGS_PATH" ]; then - echo -e "${YELLOW}Existing settings.xml found. Backing up to ${SETTINGS_PATH}.bak${NC}" - cp "$SETTINGS_PATH" "${SETTINGS_PATH}.bak" - - # Check if the file is valid XML - if ! xmlstarlet val "$SETTINGS_PATH" &> /dev/null; then - echo -e "${RED}Warning: The existing settings.xml is not valid XML.${NC}" - read -p "Do you want to create a new settings.xml file? (y/n): " CREATE_NEW - if [[ $CREATE_NEW =~ ^[Yy]$ ]]; then - create_new_settings - else - echo -e "${RED}Exiting without making changes.${NC}" - exit 1 - fi - else - # Check if servers element exists - if ! xmlstarlet sel -t -v "/settings/servers" "$SETTINGS_PATH" &> /dev/null; then - echo -e "${YELLOW}No servers section found. Adding servers section...${NC}" - xmlstarlet ed --inplace \ - -s "/settings" -t elem -n "servers" \ - -s "/settings/servers" -t elem -n "server" \ - -s "/settings/servers/server" -t elem -n "id" -v "$SERVER_ID" \ - -s "/settings/servers/server" -t elem -n "username" -v "$USERNAME" \ - -s "/settings/servers/server" -t elem -n "password" -v "$PASSWORD" \ - "$SETTINGS_PATH" - else - # Check if server with this ID already exists - if xmlstarlet sel -t -v "/settings/servers/server[id='$SERVER_ID']" "$SETTINGS_PATH" &> /dev/null; then - echo -e "${YELLOW}Server with ID '$SERVER_ID' already exists. Updating credentials...${NC}" - # Update existing server credentials - xmlstarlet ed --inplace \ - -u "/settings/servers/server[id='$SERVER_ID']/username" -v "$USERNAME" \ - -u "/settings/servers/server[id='$SERVER_ID']/password" -v "$PASSWORD" \ - "$SETTINGS_PATH" - else - echo -e "${YELLOW}Adding new server with ID '$SERVER_ID'...${NC}" - # Add new server to existing servers section - xmlstarlet ed --inplace \ - -s "/settings/servers" -t elem -n "server" \ - -s "/settings/servers/server[last()]" -t elem -n "id" -v "$SERVER_ID" \ - -s "/settings/servers/server[last()]" -t elem -n "username" -v "$USERNAME" \ - -s "/settings/servers/server[last()]" -t elem -n "password" -v "$PASSWORD" \ - "$SETTINGS_PATH" - fi - fi - fi -else - create_new_settings -fi - -# Make sure the file has the right permissions -chmod 600 "$SETTINGS_PATH" - -echo -e "${GREEN}Maven settings.xml updated successfully at $SETTINGS_PATH${NC}" -echo -e "${GREEN}Server ID: $SERVER_ID${NC}" -echo -e "${GREEN}Username: $USERNAME${NC}" -echo -e "${GREEN}Password: ********${NC}" -