diff --git a/.github/workflows/on_pull_request.yml b/.github/workflows/on_pull_request.yml index 0155f33..b190abd 100644 --- a/.github/workflows/on_pull_request.yml +++ b/.github/workflows/on_pull_request.yml @@ -34,10 +34,13 @@ jobs: restore-keys: ${{ runner.os }}-gradle - name: Build and analyze + id: build_jar env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: ./gradlew build jacocoTestReport sonarqube --info + run: | + ./gradlew build jacocoTestReport sonarqube --info + echo current_version=$(echo $(./gradlew properties --no-daemon --console=plain -q | grep "^version:" | awk '{printf $2}')) >> $GITHUB_OUTPUT - name: Publish test report if: always() @@ -49,7 +52,7 @@ jobs: uses: actions/upload-artifact@v3 with: name: kafkactl-jar - path: ${{ github.workspace }}/build/libs/kafkactl-*.jar + path: ${{ github.workspace }}/build/libs/kafkactl-${{ steps.build_jar.outputs.current_version }}.jar build-linux: runs-on: ubuntu-latest @@ -62,7 +65,7 @@ jobs: - name: Set up GraalVM uses: graalvm/setup-graalvm@v1 with: - version: '21.1.0' + version: '22.3.0' java-version: '11' components: 'native-image' github-token: ${{ secrets.GITHUB_TOKEN }} @@ -81,14 +84,17 @@ jobs: key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} restore-keys: ${{ runner.os }}-gradle - - name: Native image - run: ./gradlew shadowJar nativeImage + - name: Build + id: build_native + run: | + ./gradlew nativeCompile + echo current_version=$(echo $(./gradlew properties --no-daemon --console=plain -q | grep "^version:" | awk '{printf $2}')) >> $GITHUB_OUTPUT - name: Upload uses: actions/upload-artifact@v3 with: name: kafkactl-linux - path: ${{ github.workspace }}/build/native-image/kafkactl-* + path: ${{ github.workspace }}/build/native/nativeCompile/kafkactl-${{ steps.build_native.outputs.current_version }} build-windows: runs-on: windows-latest @@ -101,7 +107,7 @@ jobs: - name: Set up GraalVM uses: graalvm/setup-graalvm@v1 with: - version: '20.3.2' + version: '22.3.0' java-version: '11' components: 'native-image' github-token: ${{ secrets.GITHUB_TOKEN }} @@ -118,12 +124,12 @@ jobs: - name: Build run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64 - gradlew.bat shadowJar nativeImage + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" + gradlew.bat nativeCompile shell: cmd - name: Upload uses: actions/upload-artifact@v3 with: name: kafkactl-windows - path: ${{ github.workspace }}/build/native-image/kafkactl-*.exe + path: ${{ github.workspace }}/build/native/nativeCompile/kafkactl-*.exe diff --git a/.github/workflows/on_push_main.yml b/.github/workflows/on_push_main.yml index a940aab..b56a861 100644 --- a/.github/workflows/on_push_main.yml +++ b/.github/workflows/on_push_main.yml @@ -40,10 +40,13 @@ jobs: restore-keys: ${{ runner.os }}-gradle - name: Build and analyze + id: build_jar env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: ./gradlew build jacocoTestReport sonarqube --info + run: | + ./gradlew build jacocoTestReport sonarqube --info + echo current_version=$(echo $(./gradlew properties --no-daemon --console=plain -q | grep "^version:" | awk '{printf $2}')) >> $GITHUB_OUTPUT - name: Publish test report if: always() @@ -58,7 +61,7 @@ jobs: uses: actions/upload-artifact@v3 with: name: kafkactl-jar - path: ${{ github.workspace }}/build/libs/kafkactl-*.jar + path: ${{ github.workspace }}/build/libs/kafkactl-${{ steps.build_jar.outputs.current_version }}.jar build-linux: runs-on: ubuntu-latest @@ -71,7 +74,7 @@ jobs: - name: Set up GraalVM uses: graalvm/setup-graalvm@v1 with: - version: '21.1.0' + version: '22.3.0' java-version: '11' components: 'native-image' github-token: ${{ secrets.GITHUB_TOKEN }} @@ -90,14 +93,17 @@ jobs: key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} restore-keys: ${{ runner.os }}-gradle - - name: Native image - run: ./gradlew shadowJar nativeImage + - name: Build + id: build_native + run: | + ./gradlew nativeCompile + echo current_version=$(echo $(./gradlew properties --no-daemon --console=plain -q | grep "^version:" | awk '{printf $2}')) >> $GITHUB_OUTPUT - name: Upload uses: actions/upload-artifact@v3 with: name: kafkactl-linux - path: ${{ github.workspace }}/build/native-image/kafkactl-* + path: ${{ github.workspace }}/build/native/nativeCompile/kafkactl-${{ steps.build_native.outputs.current_version }} build-windows: runs-on: windows-latest @@ -105,12 +111,12 @@ jobs: - name: Checkout project uses: actions/checkout@v3 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - name: Set up GraalVM uses: graalvm/setup-graalvm@v1 with: - version: '20.3.2' + version: '22.3.0' java-version: '11' components: 'native-image' github-token: ${{ secrets.GITHUB_TOKEN }} @@ -127,12 +133,12 @@ jobs: - name: Build run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64 - gradlew.bat shadowJar nativeImage + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" + gradlew.bat nativeCompile shell: cmd - name: Upload uses: actions/upload-artifact@v3 with: name: kafkactl-windows - path: ${{ github.workspace }}/build/native-image/kafkactl-*.exe + path: ${{ github.workspace }}/build/native/nativeCompile/kafkactl-*.exe diff --git a/.github/workflows/on_push_tag.yml b/.github/workflows/on_push_tag.yml index 9264cd4..bfac389 100644 --- a/.github/workflows/on_push_tag.yml +++ b/.github/workflows/on_push_tag.yml @@ -33,10 +33,10 @@ jobs: restore-keys: ${{ runner.os }}-gradle - name: Build and test - id: build_and_test + id: build_jar run: | - ./gradlew build check -Prelease - echo ::set-output name=current_version::$(echo $(./gradlew properties --no-daemon --console=plain -q | grep "^version:" | awk '{printf $2}')) + ./gradlew build check + echo current_version=$(echo $(./gradlew properties --no-daemon --console=plain -q | grep "^version:" | awk '{printf $2}')) >> $GITHUB_OUTPUT - name: Publish test report if: always() @@ -45,15 +45,9 @@ jobs: report_paths: '**/build/test-results/test/TEST-*.xml' - name: Docker - run: ./gradlew dockerBuild dockerPush -Prelease + run: ./gradlew dockerBuild dockerPush - - name: Upload - uses: actions/upload-artifact@v3 - with: - name: kafkactl-jar - path: ${{ github.workspace }}/build/libs/kafkactl-*.jar - - - name: Generate Release Changelog + - name: Generate release changelog uses: mikepenz/release-changelog-builder-action@v1 id: build_changelog with: @@ -66,7 +60,7 @@ jobs: with: token: ${{ secrets.GITHUB_TOKEN }} body: ${{ steps.build_changelog.outputs.changelog }} - artifacts: ${{ github.workspace }}/cli/build/libs/kafkactl-*.jar + artifacts: ${{ github.workspace }}/cli/build/libs/kafkactl-${{ steps.build_jar.outputs.current_version }}.jar draft: true prerelease: true allowUpdates: true @@ -82,7 +76,7 @@ jobs: - name: Set up GraalVM uses: graalvm/setup-graalvm@v1 with: - version: '21.1.0' + version: '22.3.0' java-version: '11' components: 'native-image' github-token: ${{ secrets.GITHUB_TOKEN }} @@ -95,20 +89,16 @@ jobs: restore-keys: ${{ runner.os }}-gradle - name: Build - run: ./gradlew shadowJar nativeImage -Prelease - - - name: Upload - uses: actions/upload-artifact@v3 - with: - name: kafkactl-linux - path: ${{ github.workspace }}/build/native-image/kafkactl-* + id: build_native + run: | + ./gradlew nativeCompile + echo current_version=$(echo $(./gradlew properties --no-daemon --console=plain -q | grep "^version:" | awk '{printf $2}')) >> $GITHUB_OUTPUT - name: Update release uses: ncipollo/release-action@v1 with: token: ${{ secrets.GITHUB_TOKEN }} - body: ${{ steps.build_changelog.outputs.changelog }} - artifacts: ${{ github.workspace }}/build/native-image/kafkactl-${{ steps.build_and_test.outputs.current_version }} + artifacts: ${{ github.workspace }}/build/native/nativeCompile/kafkactl-${{ steps.build_native.outputs.current_version }} draft: true prerelease: true allowUpdates: true @@ -125,7 +115,7 @@ jobs: - name: Set up GraalVM uses: graalvm/setup-graalvm@v1 with: - version: '20.3.2' + version: '22.3.0' java-version: '11' components: 'native-image' github-token: ${{ secrets.GITHUB_TOKEN }} @@ -142,22 +132,15 @@ jobs: - name: Build run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64 - gradlew.bat shadowJar nativeImage + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" + gradlew.bat nativeCompile shell: cmd - - name: Upload - uses: actions/upload-artifact@v3 - with: - name: kafkactl-windows - path: ${{ github.workspace }}/build/native-image/kafkactl-*.exe - - name: Update release uses: ncipollo/release-action@v1 with: token: ${{ secrets.GITHUB_TOKEN }} - body: ${{ steps.build_changelog.outputs.changelog }} - artifacts: ${{ github.workspace }}/cli/build/native-image/kafkactl-*.exe + artifacts: ${{ github.workspace }}/build/native/nativeCompile/kafkactl-*.exe draft: true prerelease: true allowUpdates: true diff --git a/build-native.md b/build-native.md deleted file mode 100644 index 66fd85e..0000000 --- a/build-native.md +++ /dev/null @@ -1,35 +0,0 @@ -# Linux -````shell -sdk use java 21.0.0.r11 -gu install native-image -./gradlew :cli:nativeImage -```` - -# Windows -Drink :coffee: - -## 1. GraalVM -Download GraalVM -https://github.com/graalvm/graalvm-ce-builds/releases/tag/vm-21.1.0 -````shell -setx /M PATH "C:\java\graalvm-ce-java11-21.1.0\bin;%PATH%" -setx /M JAVA_HOME "C:\java\graalvm-ce-java11-21.1.0\" -gu install native-image -```` - -## 2. VS 2019 -Download VS 2019 -https://visualstudio.microsoft.com/vs/ -Select individual components : -- C++/CLI support for v142 build tools (latest) -- MSVC v142 - VS 2019 C++ x64/x86 build tools (latest) -- Windows Universal CRT SDK -- Windows 10 SDK (10.0.19041.0 or later) - -Source (**thank you**) : https://leward.eu/2020/10/21/native-gui-app-with-javafx-windows.html - -## 3. Build -Run the new shell : **x64 Native Tools Command Prompt for VS 2019** -````shell -native-image -cp H:\projects\ns4kafka\cli\build\libs\kafkactl-0.1.jar -H:+ReportUnsupportedElementsAtRuntime -H:Name=kafkactl -H:IncludeResourceBundles=org.ocpsoft.prettytime.i18n.Resources --no-server com.michelin.ns4kafka.cli.KafkactlCommand -```` diff --git a/build.gradle b/build.gradle index e26a05b..8ecbe53 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,12 @@ plugins { - id("com.github.johnrengelman.shadow") version "7.0.0" - id("io.micronaut.application") version "1.5.0" - id 'jacoco' - id "org.sonarqube" version "3.5.0.2730" + id("com.github.johnrengelman.shadow") version "7.1.2" + id("io.micronaut.application") version "3.7.0" + id("jacoco") + id("org.sonarqube") version "3.5.0.2730" + id("pl.allegro.tech.build.axion-release") version "1.14.3" } +version = scmVersion.version group = "com.michelin.kafkactl" repositories { @@ -12,24 +14,23 @@ repositories { } dependencies { - compileOnly 'org.projectlombok:lombok:1.18.24' - compileOnly "org.graalvm.nativeimage:svm" + annotationProcessor("info.picocli:picocli-codegen") + annotationProcessor("org.projectlombok:lombok") - annotationProcessor 'org.projectlombok:lombok:1.18.24' - annotationProcessor("info.picocli:picocli-codegen:4.6.1") - annotationProcessor "io.micronaut:micronaut-graal" - - implementation("info.picocli:picocli:4.6.1") + implementation("info.picocli:picocli") implementation("io.micronaut.picocli:micronaut-picocli") + implementation("io.micronaut:micronaut-jackson-databind") implementation("io.micronaut:micronaut-validation") - implementation("io.micronaut:micronaut-runtime") - implementation("javax.annotation:javax.annotation-api") + implementation("jakarta.annotation:jakarta.annotation-api") implementation("io.micronaut:micronaut-http-client") - - implementation("org.ocpsoft.prettytime:prettytime:5.0.1.Final") - implementation("io.github.java-diff-utils:java-diff-utils:4.9") + implementation("org.ocpsoft.prettytime:prettytime:5.0.6.Final") + implementation("io.github.java-diff-utils:java-diff-utils:4.12") runtimeOnly("ch.qos.logback:logback-classic") + + compileOnly("org.projectlombok:lombok") + compileOnly("org.graalvm.nativeimage:svm") + testImplementation("io.micronaut:micronaut-http-client") } @@ -51,21 +52,30 @@ micronaut { } shadowJar { - archiveFileName = "kafkactl-${version}.jar" + archiveClassifier.set('') + dependsOn(distTar, distZip) +} + +graalvmNative { + binaries { + main { + imageName.set("kafkactl-" + project.version) + buildArgs.add("-H:Class=com.michelin.kafkactl.KafkactlCommand") + buildArgs.add("-H:IncludeResourceBundles=org.ocpsoft.prettytime.i18n.Resources") + buildArgs.add("-H:+ReportUnsupportedElementsAtRuntime") + buildArgs.add("-H:+ReportExceptionStackTraces") + buildArgs.add("-H:+TraceNativeToolUsage") + buildArgs.add("-H:Log=*ShimDLL:3,link:3,copy:3") + } + } } -nativeImage { - imageName('kafkactl-'+rootProject.version) - args = ['-H:Class=com.michelin.kafkactl.KafkactlCommand', - '-H:IncludeResourceBundles=org.ocpsoft.prettytime.i18n.Resources', - '-H:+ReportUnsupportedElementsAtRuntime', - '-H:+ReportExceptionStackTraces', - '-H:+TraceNativeToolUsage', - '-H:Log=*ShimDLL:3,link:3,copy:3'] +dockerfile { + baseImage = "eclipse-temurin:11-jre-alpine" } dockerBuild { - images = ["michelin/kafkactl:"+version] + images = ["michelin/kafkactl:" + version] } sonarqube { @@ -86,7 +96,7 @@ jacocoTestReport { import org.apache.tools.ant.filters.ReplaceTokens processResources { - filesMatching("application.yml"){ + filesMatching("application.yml") { filter(ReplaceTokens, tokens: [version: project.version]) } } diff --git a/gradle.properties b/gradle.properties index 9208dc2..18b9c39 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -micronautVersion=2.5.9 \ No newline at end of file +micronautVersion=3.8.1 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 62d4c05..249e583 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e5face9..ae04661 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Tue Apr 06 16:48:19 CEST 2021 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip diff --git a/micronaut-cli.yml b/micronaut-cli.yml index a37dda2..fa08239 100644 --- a/micronaut-cli.yml +++ b/micronaut-cli.yml @@ -3,4 +3,4 @@ defaultPackage: com.michelin.kafkactl testFramework: junit sourceLanguage: java buildTool: gradle -features: [annotation-api, app-name, gradle, java, junit, logback, picocli, picocli-java-application, picocli-junit, readme, shade, yaml] +features: [annotation-api, app-name, gradle, java, junit, logback, micronaut-build, picocli, picocli-java-application, picocli-junit, readme, shade, yaml] diff --git a/semantic-build-versioning.gradle b/semantic-build-versioning.gradle deleted file mode 100644 index db62fbc..0000000 --- a/semantic-build-versioning.gradle +++ /dev/null @@ -1 +0,0 @@ -tagPrefix = 'v' diff --git a/settings.gradle b/settings.gradle index 7f93bcb..8cb8b5c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,15 +1 @@ -rootProject.name="kafkactl" - -buildscript { - repositories { - maven { - url 'https://plugins.gradle.org/m2/' - } - } - dependencies { - classpath 'io.alcide:gradle-semantic-build-versioning:4.2.1' - } -} - -apply plugin: 'io.alcide.gradle-semantic-build-versioning' - +rootProject.name="kafkactl" \ No newline at end of file diff --git a/src/main/java/com/michelin/kafkactl/ApiResourcesSubcommand.java b/src/main/java/com/michelin/kafkactl/ApiResourcesSubcommand.java index 262910f..0ef7b0b 100644 --- a/src/main/java/com/michelin/kafkactl/ApiResourcesSubcommand.java +++ b/src/main/java/com/michelin/kafkactl/ApiResourcesSubcommand.java @@ -2,28 +2,19 @@ import com.michelin.kafkactl.services.ApiResourcesService; import com.michelin.kafkactl.services.LoginService; +import jakarta.inject.Inject; import picocli.CommandLine; -import javax.inject.Inject; import java.util.concurrent.Callable; @CommandLine.Command(name = "api-resources", description = "Print the supported API resources on the server") public class ApiResourcesSubcommand implements Callable { - /** - * API resources service - */ @Inject public ApiResourcesService apiResourcesService; - /** - * Login service - */ @Inject public LoginService loginService; - /** - * Current command - */ @CommandLine.Spec CommandLine.Model.CommandSpec commandSpec; diff --git a/src/main/java/com/michelin/kafkactl/ApplySubcommand.java b/src/main/java/com/michelin/kafkactl/ApplySubcommand.java index 9658b5d..894a87b 100644 --- a/src/main/java/com/michelin/kafkactl/ApplySubcommand.java +++ b/src/main/java/com/michelin/kafkactl/ApplySubcommand.java @@ -8,11 +8,11 @@ import com.michelin.kafkactl.services.ResourceService; import io.micronaut.core.util.StringUtils; import io.micronaut.http.HttpResponse; +import jakarta.inject.Inject; import picocli.CommandLine; import picocli.CommandLine.Command; import picocli.CommandLine.Option; -import javax.inject.Inject; import java.io.File; import java.nio.file.Files; import java.util.List; @@ -23,63 +23,33 @@ @Command(name = "apply", description = "Create or update a resource") public class ApplySubcommand implements Callable { - /** - * Login service - */ @Inject public LoginService loginService; - /** - * API resources service - */ @Inject public ApiResourcesService apiResourcesService; - /** - * File service - */ @Inject public FileService fileService; - /** - * Resource service - */ @Inject public ResourceService resourceService; - /** - * Kafkactl configuration - */ @Inject public KafkactlConfig kafkactlConfig; - /** - * Kafkactl command - */ @CommandLine.ParentCommand public KafkactlCommand kafkactlCommand; - /** - * YAML file or directory containing YAML resources to apply - */ @Option(names = {"-f", "--file"}, description = "YAML File or Directory containing YAML resources") public Optional file; - /** - * Enable recursive search of file - */ @Option(names = {"-R", "--recursive"}, description = "Enable recursive search of file") public boolean recursive; - /** - * Does not persist resources. Validate only - */ @Option(names = {"--dry-run"}, description = "Does not persist resources. Validate only") public boolean dryRun; - /** - * Current command - */ @CommandLine.Spec public CommandLine.Model.CommandSpec commandSpec; diff --git a/src/main/java/com/michelin/kafkactl/ConfigSubcommand.java b/src/main/java/com/michelin/kafkactl/ConfigSubcommand.java index 81139f9..0f8fa65 100644 --- a/src/main/java/com/michelin/kafkactl/ConfigSubcommand.java +++ b/src/main/java/com/michelin/kafkactl/ConfigSubcommand.java @@ -5,48 +5,30 @@ import com.michelin.kafkactl.services.ConfigService; import com.michelin.kafkactl.services.FormatService; import io.micronaut.core.util.StringUtils; +import jakarta.inject.Inject; import lombok.Getter; import picocli.CommandLine; -import javax.inject.Inject; import java.util.*; import java.util.concurrent.Callable; @CommandLine.Command(name = "config", description = "Manage configuration") public class ConfigSubcommand implements Callable { - /** - * Kafkactl configuration - */ @Inject public KafkactlConfig kafkactlConfig; - /** - * User configuration service - */ @Inject public ConfigService configService; - /** - * Format service - */ @Inject public FormatService formatService; - /** - * Kafkactl command - */ @CommandLine.ParentCommand public KafkactlCommand kafkactlCommand; - /** - * Action to perform - */ @CommandLine.Parameters(index = "0", description = "(get-contexts | current-context | use-context)", arity = "1") public ConfigAction action; - /** - * Context name to set on use-context - */ @CommandLine.Parameters(index="1", defaultValue = "", description = "Context", arity = "1") public String context; @@ -88,15 +70,15 @@ public Integer call() throws Exception { if (action.equals(ConfigAction.GET_CONTEXTS)) { List allContextsAsResources = new ArrayList<>(); - kafkactlConfig.getContexts().forEach(context -> { + kafkactlConfig.getContexts().forEach(userContext -> { Map specs = new HashMap<>(); - specs.put("namespace", context.getContext().getNamespace()); - specs.put("api", context.getContext().getApi()); - specs.put("token", context.getContext().getUserToken()); + specs.put("namespace", userContext.getDefinition().getNamespace()); + specs.put("api", userContext.getDefinition().getApi()); + specs.put("token", userContext.getDefinition().getUserToken()); Resource currentContextAsResource = Resource.builder() .metadata(ObjectMeta.builder() - .name(context.getName()) + .name(userContext.getName()) .build()) .spec(specs) .build(); diff --git a/src/main/java/com/michelin/kafkactl/ConnectorsSubcommand.java b/src/main/java/com/michelin/kafkactl/ConnectorsSubcommand.java index ff7e9e8..a581286 100644 --- a/src/main/java/com/michelin/kafkactl/ConnectorsSubcommand.java +++ b/src/main/java/com/michelin/kafkactl/ConnectorsSubcommand.java @@ -7,9 +7,9 @@ import com.michelin.kafkactl.services.FormatService; import com.michelin.kafkactl.services.LoginService; import com.michelin.kafkactl.services.ResourceService; +import jakarta.inject.Inject; import picocli.CommandLine; -import javax.inject.Inject; import java.util.List; import java.util.Map; import java.util.Objects; diff --git a/src/main/java/com/michelin/kafkactl/DeleteRecordsSubcommand.java b/src/main/java/com/michelin/kafkactl/DeleteRecordsSubcommand.java index 2ca0bc8..e543766 100644 --- a/src/main/java/com/michelin/kafkactl/DeleteRecordsSubcommand.java +++ b/src/main/java/com/michelin/kafkactl/DeleteRecordsSubcommand.java @@ -4,62 +4,38 @@ import com.michelin.kafkactl.services.FormatService; import com.michelin.kafkactl.services.LoginService; import com.michelin.kafkactl.services.ResourceService; +import jakarta.inject.Inject; import picocli.CommandLine; import picocli.CommandLine.Command; import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; -import javax.inject.Inject; import java.util.List; import java.util.concurrent.Callable; @Command(name = "delete-records", description = "Deletes all records within a topic") public class DeleteRecordsSubcommand implements Callable { - /** - * Login service - */ @Inject public LoginService loginService; - /** - * Resource service - */ @Inject public ResourceService resourceService; - /** - * Format service - */ @Inject public FormatService formatService; - /** - * Kafkactl configuration - */ @Inject public KafkactlConfig kafkactlConfig; - /** - * Kafkactl command - */ @CommandLine.ParentCommand public KafkactlCommand kafkactlCommand; - /** - * Topic from which delete records - */ @Parameters(description = "Name of the topic", arity = "1") public String topic; - /** - * Is the command run with dry run mode - */ @Option(names = {"--dry-run"}, description = "Does not persist resources. Validate only") public boolean dryRun; - /** - * Current command - */ @CommandLine.Spec public CommandLine.Model.CommandSpec commandSpec; diff --git a/src/main/java/com/michelin/kafkactl/DeleteSubcommand.java b/src/main/java/com/michelin/kafkactl/DeleteSubcommand.java index 0e62ad0..e67fe7f 100644 --- a/src/main/java/com/michelin/kafkactl/DeleteSubcommand.java +++ b/src/main/java/com/michelin/kafkactl/DeleteSubcommand.java @@ -7,13 +7,13 @@ import com.michelin.kafkactl.services.FileService; import com.michelin.kafkactl.services.LoginService; import com.michelin.kafkactl.services.ResourceService; +import jakarta.inject.Inject; import picocli.CommandLine; import picocli.CommandLine.ArgGroup; import picocli.CommandLine.Command; import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; -import javax.inject.Inject; import java.io.File; import java.util.List; import java.util.Optional; @@ -22,46 +22,25 @@ @Command(name = "delete", description = "Delete a resource") public class DeleteSubcommand implements Callable { - /** - * Kafkactl config - */ @Inject public KafkactlConfig kafkactlConfig; - /** - * Resource service - */ @Inject public ResourceService resourceService; - /** - * Login service - */ @Inject public LoginService loginService; - /** - * API resources service - */ @Inject public ApiResourcesService apiResourcesService; - /** - * File service - */ @Inject public FileService fileService; - /** - * Kafkactl command - */ @CommandLine.ParentCommand public KafkactlCommand kafkactlCommand; - /** - * Handle deletion either by resource name or by file - */ - @ArgGroup(exclusive = true, multiplicity = "1") + @ArgGroup(multiplicity = "1") public EitherOf config; static class EitherOf { @@ -87,15 +66,9 @@ static class ByFile { public boolean recursive; } - /** - * Does not persist resources. Validate only - */ @Option(names = {"--dry-run"}, description = "Does not persist operation. Validate only") public boolean dryRun; - /** - * Current command - */ @CommandLine.Spec public CommandLine.Model.CommandSpec commandSpec; diff --git a/src/main/java/com/michelin/kafkactl/DiffSubcommand.java b/src/main/java/com/michelin/kafkactl/DiffSubcommand.java index e7b96ee..a71a46c 100644 --- a/src/main/java/com/michelin/kafkactl/DiffSubcommand.java +++ b/src/main/java/com/michelin/kafkactl/DiffSubcommand.java @@ -11,6 +11,7 @@ import com.michelin.kafkactl.services.ResourceService; import io.micronaut.core.util.StringUtils; import io.micronaut.http.HttpResponse; +import jakarta.inject.Inject; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.nodes.Tag; @@ -19,7 +20,6 @@ import picocli.CommandLine.Command; import picocli.CommandLine.Option; -import javax.inject.Inject; import java.io.File; import java.nio.file.Files; import java.util.List; @@ -30,57 +30,30 @@ @Command(name = "diff", description = "Get differences between the new resources and the old resource") public class DiffSubcommand implements Callable { - /** - * Login service - */ @Inject public LoginService loginService; - /** - * API resources service - */ @Inject public ApiResourcesService apiResourcesService; - /** - * File service - */ @Inject public FileService fileService; - /** - * Resource service - */ @Inject public ResourceService resourceService; - /** - * Kafkactl configuration - */ @Inject public KafkactlConfig kafkactlConfig; - /** - * Kafkactl command - */ @CommandLine.ParentCommand public KafkactlCommand kafkactlCommand; - /** - * YAML file or directory containing YAML resources to diff - */ @Option(names = {"-f", "--file"}, description = "YAML File or Directory containing YAML resources") public Optional file; - /** - * Enable recursive search of file - */ @Option(names = {"-R", "--recursive"}, description = "Enable recursive search of file") public boolean recursive; - /** - * Current command - */ @CommandLine.Spec public CommandLine.Model.CommandSpec commandSpec; diff --git a/src/main/java/com/michelin/kafkactl/GetSubcommand.java b/src/main/java/com/michelin/kafkactl/GetSubcommand.java index 7f64159..146760b 100644 --- a/src/main/java/com/michelin/kafkactl/GetSubcommand.java +++ b/src/main/java/com/michelin/kafkactl/GetSubcommand.java @@ -9,12 +9,12 @@ import com.michelin.kafkactl.services.LoginService; import com.michelin.kafkactl.services.ResourceService; import io.micronaut.http.client.exceptions.HttpClientResponseException; +import jakarta.inject.Inject; import picocli.CommandLine; import picocli.CommandLine.Command; import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; -import javax.inject.Inject; import java.util.List; import java.util.Map; import java.util.Optional; @@ -30,75 +30,39 @@ "Parameters: " }) public class GetSubcommand implements Callable { - /** - * Namespaced resource client - */ @Inject public NamespacedResourceClient namespacedClient; - /** - * Cluster resource client - */ @Inject public ClusterResourceClient nonNamespacedClient; - /** - * Login service - */ @Inject public LoginService loginService; - /** - * API resources service - */ @Inject public ApiResourcesService apiResourcesService; - /** - * Resource service - */ @Inject public ResourceService resourceService; - /** - * Format service - */ @Inject public FormatService formatService; - /** - * Kafkactl configuration - */ @Inject public KafkactlConfig kafkactlConfig; - /** - * Kafkactl command - */ @CommandLine.ParentCommand public KafkactlCommand kafkactlCommand; - /** - * Resource type to get - */ @Parameters(index = "0", description = "Resource type or 'all' to display resources for all types", arity = "1") public String resourceType; - /** - * Resource name to get - */ @Parameters(index = "1", description = "Resource name", arity = "0..1") public Optional resourceName; - /** - * Output format - */ @Option(names = {"-o", "--output"}, description = "Output format. One of: yaml|table", defaultValue = "table") public String output; - /** - * Current command - */ @CommandLine.Spec CommandLine.Model.CommandSpec commandSpec; diff --git a/src/main/java/com/michelin/kafkactl/ImportSubcommand.java b/src/main/java/com/michelin/kafkactl/ImportSubcommand.java index cb949f4..cb118c2 100644 --- a/src/main/java/com/michelin/kafkactl/ImportSubcommand.java +++ b/src/main/java/com/michelin/kafkactl/ImportSubcommand.java @@ -6,12 +6,12 @@ import com.michelin.kafkactl.services.FormatService; import com.michelin.kafkactl.services.LoginService; import com.michelin.kafkactl.services.ResourceService; +import jakarta.inject.Inject; import picocli.CommandLine; import picocli.CommandLine.Command; import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; -import javax.inject.Inject; import java.util.List; import java.util.Map; import java.util.Optional; @@ -20,57 +20,30 @@ @Command(name = "import", description = "Import unsynchronized resources") public class ImportSubcommand implements Callable { - /** - * Login service - */ @Inject public LoginService loginService; - /** - * Resource service - */ @Inject public ResourceService resourceService; - /** - * API resources service - */ @Inject public ApiResourcesService apiResourcesService; - /** - * Format service - */ @Inject public FormatService formatService; - /** - * Kafkactl configuration - */ @Inject public KafkactlConfig kafkactlConfig; - /** - * Kafkactl command - */ @CommandLine.ParentCommand public KafkactlCommand kafkactlCommand; - /** - * Resource type to import - */ @Parameters(index = "0", description = "Resource type", arity = "1") public String resourceType; - /** - * Does not persist resources. Validate only - */ @Option(names = {"--dry-run"}, description = "Does not persist resources. Validate only") public boolean dryRun; - /** - * Current command - */ @CommandLine.Spec CommandLine.Model.CommandSpec commandSpec; diff --git a/src/main/java/com/michelin/kafkactl/KafkactlCommand.java b/src/main/java/com/michelin/kafkactl/KafkactlCommand.java index 733b8d9..73f1ef7 100644 --- a/src/main/java/com/michelin/kafkactl/KafkactlCommand.java +++ b/src/main/java/com/michelin/kafkactl/KafkactlCommand.java @@ -1,12 +1,12 @@ package com.michelin.kafkactl; import io.micronaut.configuration.picocli.PicocliRunner; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import picocli.CommandLine; import picocli.CommandLine.Command; import picocli.CommandLine.Option; -import javax.inject.Inject; -import javax.inject.Singleton; import java.util.Optional; import java.util.concurrent.Callable; @@ -29,14 +29,8 @@ versionProvider = KafkactlCommand.ConfigVersionProvider.class, mixinStandardHelpOptions = true) public class KafkactlCommand implements Callable { - /** - * Verbose mode - */ public static boolean VERBOSE = false; - /** - * Get Kafkactl version - */ @Inject public ConfigVersionProvider versionProvider; diff --git a/src/main/java/com/michelin/kafkactl/KafkactlConfig.java b/src/main/java/com/michelin/kafkactl/KafkactlConfig.java index 162fb1f..7e87ef8 100644 --- a/src/main/java/com/michelin/kafkactl/KafkactlConfig.java +++ b/src/main/java/com/michelin/kafkactl/KafkactlConfig.java @@ -1,7 +1,10 @@ package com.michelin.kafkactl; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonProperty; import io.micronaut.context.annotation.ConfigurationProperties; import io.micronaut.core.annotation.Introspected; +import io.micronaut.core.annotation.ReflectiveAccess; import io.micronaut.core.convert.format.MapFormat; import lombok.Getter; import lombok.Setter; @@ -11,76 +14,35 @@ @Getter @Setter +@Introspected @ConfigurationProperties("kafkactl") public class KafkactlConfig { - /** - * Configuration version - */ - public String version; + private String version; + private String configPath; + private String api; + private String userToken; + private String currentNamespace; + private List contexts; - /** - * Configuration file path - */ - public String configPath; - - /** - * Current API - */ - String api; - - /** - * Current user token - */ - String userToken; - - /** - * Current namespace - */ - String currentNamespace; - - /** - * List of available contexts - */ - List contexts; - - /** - * All table formats - */ @MapFormat(transformation = MapFormat.MapTransformation.FLAT) - public Map> tableFormat; + private Map> tableFormat; @Getter @Setter @Introspected public static class Context { - /** - * Context name - */ - String name; + private String name; - /** - * Context information - */ - ApiContext context; + @JsonProperty("context") + private ApiContext definition; @Getter @Setter @Introspected public static class ApiContext { - /** - * Context API - */ - String api; - - /** - * Context user token - */ - String userToken; - - /** - * Context namespace - */ - String namespace; + private String api; + private String userToken; + private String namespace; } } } diff --git a/src/main/java/com/michelin/kafkactl/ResetOffsetsSubcommand.java b/src/main/java/com/michelin/kafkactl/ResetOffsetsSubcommand.java index b24ad58..bbf8a2f 100644 --- a/src/main/java/com/michelin/kafkactl/ResetOffsetsSubcommand.java +++ b/src/main/java/com/michelin/kafkactl/ResetOffsetsSubcommand.java @@ -5,12 +5,12 @@ import com.michelin.kafkactl.services.FormatService; import com.michelin.kafkactl.services.LoginService; import com.michelin.kafkactl.services.ResourceService; +import jakarta.inject.Inject; import picocli.CommandLine; import picocli.CommandLine.ArgGroup; import picocli.CommandLine.Command; import picocli.CommandLine.Option; -import javax.inject.Inject; import java.time.Duration; import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; @@ -21,115 +21,61 @@ @Command(name = "reset-offsets", description = "Reset Consumer Group offsets") public class ResetOffsetsSubcommand implements Callable { - /** - * Login service - */ @Inject public LoginService loginService; - /** - * Resource service - */ @Inject public ResourceService resourceService; - /** - * Format service - */ @Inject public FormatService formatService; - /** - * Kafkactl configuration - */ @Inject public KafkactlConfig kafkactlConfig; - /** - * Kafkactl command - */ @CommandLine.ParentCommand public KafkactlCommand kafkactlCommand; - /** - * Consumer group to reset - */ @Option(names = {"--group"}, required = true, description = "Consumer group name") public String group; - /** - * Is the command run with dry run mode - */ @Option(names = {"--dry-run"}, description = "Does not persist resources. Validate only") public boolean dryRun; - /** - * Topic to reset the consumer group - */ - @ArgGroup(exclusive = true, multiplicity = "1") + @ArgGroup(multiplicity = "1") public TopicArgs topic; - /** - * The offset reset method - */ - @ArgGroup(exclusive = true, multiplicity = "1") + @ArgGroup(multiplicity = "1") public ResetMethod method; public static class TopicArgs { - /** - * Reset offsets on a single topic or topic:partition - */ @Option(names = {"--topic"}, required = true, description = "Topic or Topic:Partition [ topic[:partition] ]") public String topic; - /** - * Reset offsets of all topics - */ @Option(names = {"--all-topics"}, required = true, description = "All topics") public boolean allTopics; } public static class ResetMethod { - /** - * Reset offsets to earliest - */ @Option(names = {"--to-earliest"}, description = "Set offset to its earliest value [ reprocess all ]", required = true) public boolean earliest; - /** - * Reset offsets to latest - */ @Option(names = {"--to-latest"}, description = "Set offset to its latest value [ skip all ]", required = true) public boolean latest; - /** - * Reset offsets to given datetime - */ @Option(names = {"--to-datetime"}, description = "Set offset to a specific ISO 8601 DateTime with Time zone [ yyyy-MM-dd'T'HH:mm:ss.SSSXXX ]", required = true) public OffsetDateTime datetime; - /** - * Reset offsets by shifting a given number of offsets - */ @Option(names = {"--shift-by"}, description = "Shift offset by a number [ negative to reprocess, positive to skip ]", required = true) public Integer shiftBy; - /** - * Reset offsets by given duration - */ @Option(names = {"--by-duration"}, description = "Shift offset by a duration format [ PnDTnHnMnS ]", required = true) public Duration duration; - /** - * Reset offsets to a given offset - */ @Option(names = {"--to-offset"}, description = "Set offset to a specific index", required = true) public Integer offset; } - /** - * Current command - */ @CommandLine.Spec public CommandLine.Model.CommandSpec commandSpec; diff --git a/src/main/java/com/michelin/kafkactl/SchemaSubcommand.java b/src/main/java/com/michelin/kafkactl/SchemaSubcommand.java index 851c58d..4f007e8 100644 --- a/src/main/java/com/michelin/kafkactl/SchemaSubcommand.java +++ b/src/main/java/com/michelin/kafkactl/SchemaSubcommand.java @@ -5,9 +5,9 @@ import com.michelin.kafkactl.services.FormatService; import com.michelin.kafkactl.services.LoginService; import com.michelin.kafkactl.services.ResourceService; +import jakarta.inject.Inject; import picocli.CommandLine; -import javax.inject.Inject; import java.util.List; import java.util.Objects; import java.util.concurrent.Callable; @@ -15,53 +15,29 @@ @CommandLine.Command(name = "schemas", description = "Update schema compatibility mode") public class SchemaSubcommand implements Callable { - /** - * Login service - */ @Inject public LoginService loginService; - /** - * Resource service - */ @Inject public ResourceService resourceService; - /** - * Current command - */ @CommandLine.Spec public CommandLine.Model.CommandSpec commandSpec; - /** - * Kafkactl configuration - */ @Inject public KafkactlConfig kafkactlConfig; - /** - * Format service - */ @Inject public FormatService formatService; - /** - * Kafkactl command - */ @CommandLine.ParentCommand public KafkactlCommand kafkactlCommand; - /** - * Compatibility to set - */ @CommandLine.Parameters(index="0", description = "Compatibility mode to set [GLOBAL, BACKWARD, " + "BACKWARD_TRANSITIVE, FORWARD, FORWARD_TRANSITIVE, FULL, FULL_TRANSITIVE, NONE]. " + "GLOBAL will revert to Schema Registry's compatibility level", arity = "1") public SchemaCompatibility compatibility; - /** - * List of subjects to update - */ @CommandLine.Parameters(index="1..*", description = "Subject names separated by space", arity = "1..*") public List subjects; @@ -81,7 +57,7 @@ public Integer call() throws Exception { List updatedSchemas = subjects .stream() - .map(subject -> this.resourceService.changeSchemaCompatibility(namespace, subject, + .map(subject -> resourceService.changeSchemaCompatibility(namespace, subject, compatibility)) .filter(Objects::nonNull) .collect(Collectors.toList()); diff --git a/src/main/java/com/michelin/kafkactl/UsersSubcommand.java b/src/main/java/com/michelin/kafkactl/UsersSubcommand.java index f661d69..3e05ed3 100644 --- a/src/main/java/com/michelin/kafkactl/UsersSubcommand.java +++ b/src/main/java/com/michelin/kafkactl/UsersSubcommand.java @@ -4,9 +4,9 @@ import com.michelin.kafkactl.services.FormatService; import com.michelin.kafkactl.services.LoginService; import com.michelin.kafkactl.services.ResourceService; +import jakarta.inject.Inject; import picocli.CommandLine; -import javax.inject.Inject; import java.util.List; import java.util.concurrent.Callable; diff --git a/src/main/java/com/michelin/kafkactl/client/BearerAccessRefreshToken.java b/src/main/java/com/michelin/kafkactl/client/BearerAccessRefreshToken.java index 4d1e47e..9801334 100644 --- a/src/main/java/com/michelin/kafkactl/client/BearerAccessRefreshToken.java +++ b/src/main/java/com/michelin/kafkactl/client/BearerAccessRefreshToken.java @@ -2,14 +2,15 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.micronaut.core.annotation.Introspected; +import io.micronaut.core.annotation.ReflectiveAccess; import lombok.Getter; import lombok.Setter; import java.util.Collection; -@Introspected @Getter @Setter +@ReflectiveAccess public class BearerAccessRefreshToken { private String username; private Collection roles; diff --git a/src/main/java/com/michelin/kafkactl/client/UserInfoResponse.java b/src/main/java/com/michelin/kafkactl/client/UserInfoResponse.java index 768fa4a..02ffd14 100644 --- a/src/main/java/com/michelin/kafkactl/client/UserInfoResponse.java +++ b/src/main/java/com/michelin/kafkactl/client/UserInfoResponse.java @@ -1,12 +1,13 @@ package com.michelin.kafkactl.client; import io.micronaut.core.annotation.Introspected; +import io.micronaut.core.annotation.ReflectiveAccess; import lombok.Getter; import lombok.Setter; -@Introspected @Getter @Setter +@ReflectiveAccess public class UserInfoResponse { private boolean active; private String username; diff --git a/src/main/java/com/michelin/kafkactl/client/UsernameAndPasswordRequest.java b/src/main/java/com/michelin/kafkactl/client/UsernameAndPasswordRequest.java index 64c9837..ccf4026 100644 --- a/src/main/java/com/michelin/kafkactl/client/UsernameAndPasswordRequest.java +++ b/src/main/java/com/michelin/kafkactl/client/UsernameAndPasswordRequest.java @@ -1,15 +1,18 @@ package com.michelin.kafkactl.client; import io.micronaut.core.annotation.Introspected; +import io.micronaut.core.annotation.ReflectiveAccess; import lombok.Builder; import lombok.Getter; import lombok.Setter; -@Introspected @Getter @Setter @Builder +@ReflectiveAccess public class UsernameAndPasswordRequest { private String username; private String password; } + + diff --git a/src/main/java/com/michelin/kafkactl/models/ApiResource.java b/src/main/java/com/michelin/kafkactl/models/ApiResource.java index c98906b..cdc92dd 100644 --- a/src/main/java/com/michelin/kafkactl/models/ApiResource.java +++ b/src/main/java/com/michelin/kafkactl/models/ApiResource.java @@ -6,9 +6,9 @@ import java.util.List; -@Introspected @Getter @Setter +@Introspected public class ApiResource { private String kind; private boolean namespaced; diff --git a/src/main/java/com/michelin/kafkactl/models/ObjectMeta.java b/src/main/java/com/michelin/kafkactl/models/ObjectMeta.java index 3b0eccf..c525fef 100644 --- a/src/main/java/com/michelin/kafkactl/models/ObjectMeta.java +++ b/src/main/java/com/michelin/kafkactl/models/ObjectMeta.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonFormat; import io.micronaut.core.annotation.Introspected; +import io.micronaut.core.annotation.ReflectiveAccess; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -12,13 +13,13 @@ import java.util.Date; import java.util.Map; -@Introspected @Getter @Setter -@ToString @Builder -@AllArgsConstructor +@ToString +@ReflectiveAccess @NoArgsConstructor +@AllArgsConstructor public class ObjectMeta { private String name; private String namespace; diff --git a/src/main/java/com/michelin/kafkactl/models/Resource.java b/src/main/java/com/michelin/kafkactl/models/Resource.java index 29e9ca9..dffdd3c 100644 --- a/src/main/java/com/michelin/kafkactl/models/Resource.java +++ b/src/main/java/com/michelin/kafkactl/models/Resource.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import io.micronaut.core.annotation.Introspected; +import io.micronaut.core.annotation.ReflectiveAccess; import lombok.*; import java.util.Map; @@ -9,7 +10,7 @@ @Data @Getter @Builder -@Introspected +@ReflectiveAccess @NoArgsConstructor @AllArgsConstructor public class Resource { diff --git a/src/main/java/com/michelin/kafkactl/models/Status.java b/src/main/java/com/michelin/kafkactl/models/Status.java index c379750..bd2aa1d 100644 --- a/src/main/java/com/michelin/kafkactl/models/Status.java +++ b/src/main/java/com/michelin/kafkactl/models/Status.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import io.micronaut.core.annotation.Introspected; +import io.micronaut.core.annotation.ReflectiveAccess; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -10,11 +11,11 @@ import java.util.List; -@Introspected +@Data @Builder +@ReflectiveAccess @NoArgsConstructor @AllArgsConstructor -@Data public class Status { private String apiVersion = "v1"; private String kind = "Status"; @@ -24,16 +25,16 @@ public class Status { private StatusDetails details; private int code; + @Data @Builder @NoArgsConstructor - @Data public static class StatusDetails { private String name; private String kind; private List causes; + @JsonCreator - public StatusDetails(@JsonProperty("name") String name, @JsonProperty("kind") String kind, @JsonProperty("causes") List causes) - { + public StatusDetails(@JsonProperty("name") String name, @JsonProperty("kind") String kind, @JsonProperty("causes") List causes) { this.name = name; this.kind = kind; this.causes = causes; diff --git a/src/main/java/com/michelin/kafkactl/services/ApiResourcesService.java b/src/main/java/com/michelin/kafkactl/services/ApiResourcesService.java index c1409d8..964a592 100644 --- a/src/main/java/com/michelin/kafkactl/services/ApiResourcesService.java +++ b/src/main/java/com/michelin/kafkactl/services/ApiResourcesService.java @@ -3,9 +3,9 @@ import com.michelin.kafkactl.client.ClusterResourceClient; import com.michelin.kafkactl.models.ApiResource; import com.michelin.kafkactl.models.Resource; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; -import javax.inject.Inject; -import javax.inject.Singleton; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -19,7 +19,6 @@ public class ApiResourcesService { public LoginService loginService; public List getListResourceDefinition() { - //TODO Add Cache to reduce the number of http requests return resourceClient.listResourceDefinitions(loginService.getAuthorization()); } @@ -29,12 +28,14 @@ public Optional getResourceDefinitionFromKind(String kind) { .filter(resource -> resource.getKind().equals(kind)) .findFirst(); } + public Optional getResourceDefinitionFromCommandName(String name) { List apiResources = getListResourceDefinition(); return apiResources.stream() .filter(resource -> resource.getNames().contains(name)) .findFirst(); } + public List validateResourceTypes(List resources) { List allowedKinds = this.getListResourceDefinition() .stream() diff --git a/src/main/java/com/michelin/kafkactl/services/ConfigService.java b/src/main/java/com/michelin/kafkactl/services/ConfigService.java index c07cd00..a2ab80c 100644 --- a/src/main/java/com/michelin/kafkactl/services/ConfigService.java +++ b/src/main/java/com/michelin/kafkactl/services/ConfigService.java @@ -1,46 +1,35 @@ package com.michelin.kafkactl.services; import com.michelin.kafkactl.KafkactlConfig; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.nodes.Tag; -import org.yaml.snakeyaml.representer.Representer; -import picocli.CommandLine; -import javax.inject.Inject; -import javax.inject.Singleton; import java.io.*; import java.util.LinkedHashMap; import java.util.Map; import java.util.Optional; -import java.util.TreeMap; @Singleton public class ConfigService { - /** - * The current Kafkactl configuration - */ @Inject public KafkactlConfig kafkactlConfig; - /** - * Login service - */ @Inject public LoginService loginService; /** * Return the name of the current context according to the current api, namespace * and token properties - * * @return The current context name */ public String getCurrentContextName() { return kafkactlConfig.getContexts() .stream() - .filter(context -> context.getContext().getApi().equals(kafkactlConfig.getApi()) && - context.getContext().getNamespace().equals(kafkactlConfig.getCurrentNamespace()) && - context.getContext().getUserToken().equals(kafkactlConfig.getUserToken())) + .filter(context -> context.getDefinition().getApi().equals(kafkactlConfig.getApi()) && + context.getDefinition().getNamespace().equals(kafkactlConfig.getCurrentNamespace()) && + context.getDefinition().getUserToken().equals(kafkactlConfig.getUserToken())) .findFirst() .map(KafkactlConfig.Context::getName) .orElse(null); @@ -48,7 +37,6 @@ public String getCurrentContextName() { /** * Get the current context infos if it exists - * * @return The current context */ public Optional getContextByName(String name) { @@ -60,7 +48,6 @@ public Optional getContextByName(String name) { /** * Update the current configuration context with the given new context - * * @param contextToSet The context to set * @throws IOException Any exception during file writing */ @@ -71,9 +58,9 @@ public void updateConfigurationContext(KafkactlConfig.Context contextToSet) thro Map> rootNodeConfig = yaml.load(targetStream); LinkedHashMap kafkactlNodeConfig = rootNodeConfig.get("kafkactl"); - kafkactlNodeConfig.put("current-namespace", contextToSet.getContext().getNamespace()); - kafkactlNodeConfig.put("api", contextToSet.getContext().getApi()); - kafkactlNodeConfig.put("user-token", contextToSet.getContext().getUserToken()); + kafkactlNodeConfig.put("current-namespace", contextToSet.getDefinition().getNamespace()); + kafkactlNodeConfig.put("api", contextToSet.getDefinition().getApi()); + kafkactlNodeConfig.put("user-token", contextToSet.getDefinition().getUserToken()); DumperOptions options = new DumperOptions(); options.setIndent(2); diff --git a/src/main/java/com/michelin/kafkactl/services/FileService.java b/src/main/java/com/michelin/kafkactl/services/FileService.java index 369be78..f7b9090 100644 --- a/src/main/java/com/michelin/kafkactl/services/FileService.java +++ b/src/main/java/com/michelin/kafkactl/services/FileService.java @@ -1,10 +1,10 @@ package com.michelin.kafkactl.services; import com.michelin.kafkactl.models.Resource; +import jakarta.inject.Singleton; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.Constructor; -import javax.inject.Singleton; import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -16,7 +16,6 @@ @Singleton public class FileService { - public List computeYamlFileList(File fileOrDirectory, boolean recursive) { return listAllFiles(new File[]{fileOrDirectory}, recursive) .collect(Collectors.toList()); @@ -41,10 +40,11 @@ public List parseResourceListFromString(String content){ return parseResourceStreamFromString(content) .collect(Collectors.toList()); } + private Stream parseResourceStreamFromString(String content){ Yaml yaml = new Yaml(new Constructor(Resource.class)); return StreamSupport.stream(yaml.loadAll(content).spliterator(), false) - .map(o -> (Resource) o); + .map(Resource.class::cast); } private Stream listAllFiles(File[] rootDir, boolean recursive) { diff --git a/src/main/java/com/michelin/kafkactl/services/FormatService.java b/src/main/java/com/michelin/kafkactl/services/FormatService.java index 286c3a1..c0846a3 100644 --- a/src/main/java/com/michelin/kafkactl/services/FormatService.java +++ b/src/main/java/com/michelin/kafkactl/services/FormatService.java @@ -9,6 +9,8 @@ import io.micronaut.core.naming.conventions.StringConvention; import io.micronaut.core.util.StringUtils; import io.micronaut.http.client.exceptions.HttpClientResponseException; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import org.ocpsoft.prettytime.PrettyTime; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; @@ -16,8 +18,6 @@ import org.yaml.snakeyaml.representer.Representer; import picocli.CommandLine; -import javax.inject.Inject; -import javax.inject.Singleton; import java.text.ParseException; import java.util.*; import java.util.concurrent.TimeUnit; @@ -27,6 +27,7 @@ public class FormatService { private static final String YAML = "yaml"; private static final String TABLE = "table"; private final List defaults = List.of("KIND:/kind", "NAME:/metadata/name", "AGE:/metadata/creationTimestamp%AGO"); + @Inject public KafkactlConfig kafkactlConfig; @@ -63,10 +64,9 @@ public void displayError(HttpClientResponseException e, String kind, String name Optional statusOptional = e.getResponse().getBody(Status.class); if (statusOptional.isPresent() && statusOptional.get().getDetails() != null && !statusOptional.get().getDetails().getCauses().isEmpty()) { Status status = statusOptional.get(); - String causes = status.getDetails().getCauses().size() > 1 ? - "\n - " + String.join("\n - ", status.getDetails().getCauses()) : status.getDetails().getCauses().get(0); + String causes = "\n - " + String.join("\n - ", status.getDetails().getCauses()); - System.out.printf("Failed %s/%s %s for causes: %s%n", kind, name, status.getMessage(), causes); + System.out.printf("Failed %s/%s %s for cause(s): %s%n", kind, name, status.getMessage(), causes); } else { System.out.printf("Failed %s/%s %s%n", kind, name, e.getMessage()); } @@ -79,7 +79,7 @@ public void displayError(HttpClientResponseException e, String kind, String name */ private void printTable(String kind, List resources) { String hyphenatedKind = StringConvention.HYPHENATED.format(kind); - List formats = kafkactlConfig.tableFormat.getOrDefault(hyphenatedKind, defaults); + List formats = kafkactlConfig.getTableFormat().getOrDefault(hyphenatedKind, defaults); PrettyTextTable ptt = new PrettyTextTable(formats, resources); System.out.println(ptt); diff --git a/src/main/java/com/michelin/kafkactl/services/LoginService.java b/src/main/java/com/michelin/kafkactl/services/LoginService.java index c88a323..2ae0ea4 100644 --- a/src/main/java/com/michelin/kafkactl/services/LoginService.java +++ b/src/main/java/com/michelin/kafkactl/services/LoginService.java @@ -9,8 +9,8 @@ import com.michelin.kafkactl.client.UsernameAndPasswordRequest; import io.micronaut.http.HttpStatus; import io.micronaut.http.client.exceptions.HttpClientResponseException; +import jakarta.inject.Singleton; -import javax.inject.Singleton; import java.io.File; import java.io.IOException; import java.util.Calendar; @@ -40,14 +40,26 @@ public LoginService(KafkactlConfig kafkactlConfig, ClusterResourceClient cluster } } + /** + * Get the authorization header + * @return The authorization header + */ public String getAuthorization() { return "Bearer " + accessToken; } + /** + * Check if the user is authenticated, or authenticate him otherwise + * @return true if the user is authenticated, false otherwise + */ public boolean doAuthenticate() { return isAuthenticated() || login("gitlab", kafkactlConfig.getUserToken()); } + /** + * Is the user authenticated already + * @return true if he is, false otherwise + */ public boolean isAuthenticated() { try { if (!jwtFile.exists()) { @@ -60,7 +72,7 @@ public boolean isAuthenticated() { if (KafkactlCommand.VERBOSE) { Date expiry = new Date(userInfo.getExp() * 1000); System.out.println("Authentication reused, welcome " + userInfo.getUsername() + "!"); - System.out.println("Your session is valid until " + expiry); + System.out.println("Your session is valid until " + expiry + "."); } accessToken = token.getAccessToken(); @@ -75,14 +87,23 @@ public boolean isAuthenticated() { return false; } + /** + * Authenticate the user + * @param user The user + * @param password The password + * @return true if he is authenticated, false otherwise + */ public boolean login(String user, String password) { try { - System.out.print("Authenticating... "); + if (KafkactlCommand.VERBOSE) { + System.out.println("Authenticating..."); + } + BearerAccessRefreshToken tokenResponse = clusterResourceClient.login(UsernameAndPasswordRequest - .builder() - .username(user) - .password(password) - .build()); + .builder() + .username(user) + .password(password) + .build()); accessToken = tokenResponse.getAccessToken(); @@ -91,8 +112,6 @@ public boolean login(String user, String password) { calendar.add(Calendar.SECOND, tokenResponse.getExpiresIn()); System.out.println("Authentication successful, welcome " + tokenResponse.getUsername() + "!"); System.out.println("Your session is valid until " + calendar.getTime() + "."); - } else { - System.out.println("Done."); } try { diff --git a/src/main/java/com/michelin/kafkactl/services/ResourceService.java b/src/main/java/com/michelin/kafkactl/services/ResourceService.java index cd4cd16..8b8e9f3 100644 --- a/src/main/java/com/michelin/kafkactl/services/ResourceService.java +++ b/src/main/java/com/michelin/kafkactl/services/ResourceService.java @@ -9,9 +9,9 @@ import io.micronaut.http.HttpResponse; import io.micronaut.http.HttpStatus; import io.micronaut.http.client.exceptions.HttpClientResponseException; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; -import javax.inject.Inject; -import javax.inject.Singleton; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -205,6 +205,7 @@ public Resource changeSchemaCompatibility(String namespace, String subject, Sche } return null; } + public Resource resetPassword(String namespace, String user) { try { Resource resource = namespacedClient.resetPassword(namespace, user, loginService.getAuthorization()); diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 5e1fc73..43de956 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,10 +4,14 @@ micronaut: http: client: read-timeout: 30s + ssl: + insecure-trust-all-certificates: true + logger: levels: ROOT: OFF - io.micronaut.http.client.netty.DefaultHttpClient: OFF # TRACE to see http requests and responses + io.micronaut.http.client.netty.DefaultHttpClient: OFF # See HTTP requests and responses + io.micronaut.http.client.netty.ssl.NettyClientSslBuilder: OFF # Disable warns about trust all certificates kafkactl: version: @version@