From e0bb7d62de1b45ff3970175f87828b64a64b2ea5 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Sun, 19 Jul 2026 21:22:42 +0200 Subject: [PATCH 01/28] issue #7547: marketplace plugin, lean client, optional Wave 1 plugins Split heavy plugins out of the default client so ASF Artifactory stays under the ~850MB package limit. Add a bundled marketplace plugin with CLI install/list/uninstall, keep lib/beam in core while making the Beam engine plugin optional, and add local Artifactory tooling plus a CI assembly size check. --- Jenkinsfile | 9 + assemblies/client/pom.xml | 10 +- assemblies/client/src/assembly/assembly.xml | 2 +- assemblies/plugins/pom.xml | 77 +---- assemblies/plugins/src/assembly/assembly.xml | 11 + docker/marketplace-artifactory/README.md | 91 ++++++ .../docker-compose.yml | 36 +++ .../publish-wave1-plugins.sh | 78 +++++ plugins/engines/beam/pom.xml | 43 +++ .../beam/src/assembly/assembly-libs.xml | 291 ++++++++++++++++++ .../engines/beam/src/assembly/assembly.xml | 265 +--------------- plugins/misc/marketplace/README.md | 66 ++++ plugins/misc/marketplace/pom.xml | 35 +++ .../marketplace/src/assembly/assembly.xml | 39 +++ .../command/MarketplaceCommand.java | 202 ++++++++++++ .../marketplace/config/MarketplaceConfig.java | 84 +++++ .../config/MarketplaceRepository.java | 37 +++ .../hop/marketplace/install/HopHome.java | 64 ++++ .../marketplace/install/InstallReceipt.java | 38 +++ .../marketplace/install/PluginInstaller.java | 264 ++++++++++++++++ .../install/PluginUninstaller.java | 108 +++++++ .../marketplace/resolve/MavenCoordinates.java | 71 +++++ .../resolve/MavenRepositoryClient.java | 80 +++++ .../src/main/resources/version.xml | 20 ++ .../install/PluginInstallerTest.java | 122 ++++++++ .../resolve/MavenCoordinatesTest.java | 68 ++++ plugins/misc/pom.xml | 1 + tools/check-assembly-size.sh | 57 ++++ 28 files changed, 1939 insertions(+), 330 deletions(-) create mode 100644 docker/marketplace-artifactory/README.md create mode 100644 docker/marketplace-artifactory/docker-compose.yml create mode 100755 docker/marketplace-artifactory/publish-wave1-plugins.sh create mode 100644 plugins/engines/beam/src/assembly/assembly-libs.xml create mode 100644 plugins/misc/marketplace/README.md create mode 100644 plugins/misc/marketplace/pom.xml create mode 100644 plugins/misc/marketplace/src/assembly/assembly.xml create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/HopHome.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/InstallReceipt.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginUninstaller.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenCoordinates.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java create mode 100644 plugins/misc/marketplace/src/main/resources/version.xml create mode 100644 plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/PluginInstallerTest.java create mode 100644 plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/resolve/MavenCoordinatesTest.java create mode 100755 tools/check-assembly-size.sh diff --git a/Jenkinsfile b/Jenkinsfile index d604d787c08..b551226d30d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -113,6 +113,15 @@ pipeline { } } } + stage('Assembly size check') { + when { + anyOf { changeset pattern: "^(?!docs).*^(?!integration-tests).*" , comparator: "REGEXP" ; equals expected: true, actual: params.FORCE_BUILD } + } + steps { + // ASF Artifactory rejects packages over ~850MB; fail early with margin. + sh "./tools/check-assembly-size.sh" + } + } stage('Unzip Apache Hop'){ when { anyOf { changeset pattern: "^(?!docs).*^(?!integration-tests).*" , comparator: "REGEXP" ; equals expected: true, actual: params.FORCE_BUILD } diff --git a/assemblies/client/pom.xml b/assemblies/client/pom.xml index c7e1dd1c21e..11b808b5eaa 100644 --- a/assemblies/client/pom.xml +++ b/assemblies/client/pom.xml @@ -61,18 +61,16 @@ ${project.version} zip + org.apache.hop hop-engines-beam ${project.version} + libs zip - - org.apache.hop - hop-engines-spark - ${project.version} - zip - + org.apache.hop hop-ui diff --git a/assemblies/client/src/assembly/assembly.xml b/assemblies/client/src/assembly/assembly.xml index d25f356db3c..405a244f878 100644 --- a/assemblies/client/src/assembly/assembly.xml +++ b/assemblies/client/src/assembly/assembly.xml @@ -40,7 +40,7 @@ org.apache.hop:hop-core:zip org.apache.hop:hop-engine:zip org.apache.hop:hop-ui:zip - org.apache.hop:hop-engines-beam:zip + org.apache.hop:hop-engines-beam:zip:libs org.apache.hop:hop-ui-rcp:zip true diff --git a/assemblies/plugins/pom.xml b/assemblies/plugins/pom.xml index 30d0e6d0f52..84c35c81464 100644 --- a/assemblies/plugins/pom.xml +++ b/assemblies/plugins/pom.xml @@ -618,12 +618,7 @@ ${project.version} zip - - org.apache.hop - hop-engines-spark - ${project.version} - zip - + org.apache.hop hop-misc-async @@ -660,6 +655,12 @@ ${project.version} zip + + org.apache.hop + hop-misc-marketplace + ${project.version} + zip + org.apache.hop hop-misc-passwords @@ -708,13 +709,7 @@ 2.19.0-SNAPSHOT zip - - - org.apache.hop - hop-tech-arrow - ${project.version} - zip - + org.apache.hop hop-tech-avro @@ -733,24 +728,14 @@ ${project.version} zip - - org.apache.hop - hop-tech-cassandra - ${project.version} - zip - + org.apache.hop hop-tech-databricks ${project.version} zip - - org.apache.hop - hop-tech-dropbox - ${project.version} - zip - + org.apache.hop hop-tech-elastic @@ -787,12 +772,7 @@ ${project.version} zip - - org.apache.hop - hop-tech-parquet - ${project.version} - zip - + org.apache.hop hop-tech-salesforce @@ -1009,24 +989,14 @@ ${project.version} zip - - org.apache.hop - hop-transform-drools - ${project.version} - zip - + org.apache.hop hop-transform-dynamicsqlrow ${project.version} zip - - org.apache.hop - hop-transform-edi2xml - ${project.version} - zip - + org.apache.hop hop-transform-excel @@ -1417,12 +1387,7 @@ ${project.version} zip - - org.apache.hop - hop-transform-script - ${project.version} - zip - + org.apache.hop hop-transform-selectvalues @@ -1507,12 +1472,7 @@ ${project.version} zip - - org.apache.hop - hop-transform-stanfordnlp - ${project.version} - zip - + org.apache.hop hop-transform-streamlookup @@ -1591,12 +1551,7 @@ ${project.version} zip - - org.apache.hop - hop-transform-tika - ${project.version} - zip - + org.apache.hop hop-transform-tokenreplacement diff --git a/assemblies/plugins/src/assembly/assembly.xml b/assemblies/plugins/src/assembly/assembly.xml index ed458154b5b..199b54fa4c5 100644 --- a/assemblies/plugins/src/assembly/assembly.xml +++ b/assemblies/plugins/src/assembly/assembly.xml @@ -35,24 +35,35 @@ false + databases **/*.zip + + **/target/** + transforms **/*.zip + + **/target/** + actions **/*.zip + + **/target/** + \ No newline at end of file diff --git a/docker/marketplace-artifactory/README.md b/docker/marketplace-artifactory/README.md new file mode 100644 index 00000000000..a42f849d5bb --- /dev/null +++ b/docker/marketplace-artifactory/README.md @@ -0,0 +1,91 @@ + + +# Local Artifactory for Hop Marketplace testing + +Use this stack to exercise plugin install/uninstall **without** ASF Nexus permissions. + +## Start + +```bash +docker compose -f docker/marketplace-artifactory/docker-compose.yml up -d +``` + +Open http://localhost:8082 and complete first-time Artifactory setup (admin password). + +Create a **local** Maven repository, for example: + +| Field | Value | +|-------|--------| +| Package type | Maven | +| Repository Key | `hop-plugins-local` | +| Repository Layout | maven-2-default | + +Public URL base (typical OSS default): + +```text +http://localhost:8082/artifactory/hop-plugins-local/ +``` + +## Publish Wave 1 plugin zips + +Build Hop plugins first, then: + +```bash +export ARTIFACTORY_URL=http://localhost:8082/artifactory/hop-plugins-local +export ARTIFACTORY_USER=admin +export ARTIFACTORY_PASSWORD=… # from first-time setup +./docker/marketplace-artifactory/publish-wave1-plugins.sh +``` + +The script deploys each Wave 1 `*.zip` with Maven layout under `org/apache/hop/…`. + +## Point Hop marketplace at local Artifactory + +In `config/hop-config.json` (or via GUI later): + +```json +{ + "marketplace": { + "enabled": true, + "groupId": "org.apache.hop", + "defaultVersion": "2.19.0-SNAPSHOT", + "repositories": [ + { + "id": "local-artifactory", + "url": "http://localhost:8082/artifactory/hop-plugins-local/" + } + ] + } +} +``` + +Then from the Hop install directory: + +```bash +export HOP_HOME=/path/to/hop +./hop marketplace install hop-tech-parquet +./hop marketplace install hop-engines-beam +./hop marketplace list +``` + +Notes: + +- `hop-engines-beam` marketplace zip is the **plugin only**; `lib/beam` stays in the default client. +- Restart Hop after install/uninstall so the plugin registry reloads. diff --git a/docker/marketplace-artifactory/docker-compose.yml b/docker/marketplace-artifactory/docker-compose.yml new file mode 100644 index 00000000000..c9c2d89431f --- /dev/null +++ b/docker/marketplace-artifactory/docker-compose.yml @@ -0,0 +1,36 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Local Artifactory OSS for Hop marketplace plugin testing (no ASF Nexus credentials required). +# Usage: +# docker compose -f docker/marketplace-artifactory/docker-compose.yml up -d +# # open http://localhost:8082 (default admin / password — set on first UI login) +# ./docker/marketplace-artifactory/publish-wave1-plugins.sh +# +services: + artifactory: + image: releases-docker.jfrog.io/jfrog/artifactory-oss:7.104.14 + container_name: hop-marketplace-artifactory + ports: + - "8082:8082" + - "8081:8081" + volumes: + - hop-artifactory-data:/var/opt/jfrog/artifactory + environment: + # Reduce memory for local dev + EXTRA_JAVA_OPTIONS: -Xms512m -Xmx1g + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8082/artifactory/api/system/ping"] + interval: 30s + timeout: 10s + retries: 20 + start_period: 120s + +volumes: + hop-artifactory-data: diff --git a/docker/marketplace-artifactory/publish-wave1-plugins.sh b/docker/marketplace-artifactory/publish-wave1-plugins.sh new file mode 100755 index 00000000000..beaf9e6548c --- /dev/null +++ b/docker/marketplace-artifactory/publish-wave1-plugins.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Deploy Wave 1 marketplace plugin zips to a local Maven repository +# (Artifactory, Nexus, or any HTTP Maven layout endpoint that accepts deploy-file). +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +REPO_URL="${ARTIFACTORY_URL:-http://localhost:8082/artifactory/hop-plugins-local}" +REPO_ID="${ARTIFACTORY_REPO_ID:-hop-plugins-local}" +USER="${ARTIFACTORY_USER:-admin}" +PASS="${ARTIFACTORY_PASSWORD:-}" +VERSION="${HOP_VERSION:-2.19.0-SNAPSHOT}" +GROUP_ID="org.apache.hop" + +# artifactId → path to built zip (relative to repo root) +declare -A ZIPS=( + [hop-engines-spark]="plugins/engines/spark/target/hop-engines-spark-${VERSION}.zip" + [hop-engines-beam]="plugins/engines/beam/target/hop-engines-beam-${VERSION}.zip" + [hop-transform-script]="plugins/transforms/script/target/hop-transform-script-${VERSION}.zip" + [hop-tech-cassandra]="plugins/tech/cassandra/target/hop-tech-cassandra-${VERSION}.zip" + [hop-transform-tika]="plugins/transforms/tika/target/hop-transform-tika-${VERSION}.zip" + [hop-transform-drools]="plugins/transforms/drools/target/hop-transform-drools-${VERSION}.zip" + [hop-tech-parquet]="plugins/tech/parquet/target/hop-tech-parquet-${VERSION}.zip" + [hop-transform-stanfordnlp]="plugins/transforms/stanfordnlp/target/hop-transform-stanfordnlp-${VERSION}.zip" + [hop-tech-arrow]="plugins/tech/arrow/target/hop-tech-arrow-${VERSION}.zip" + [hop-tech-dropbox]="plugins/tech/dropbox/target/hop-tech-dropbox-${VERSION}.zip" + [hop-transform-edi2xml]="plugins/transforms/edi2xml/target/hop-transform-edi2xml-${VERSION}.zip" +) + +if [[ -z "$PASS" ]]; then + echo "Set ARTIFACTORY_PASSWORD (and optionally ARTIFACTORY_USER / ARTIFACTORY_URL)" >&2 + exit 1 +fi + +MVN="${ROOT}/mvnw" +if [[ ! -x "$MVN" ]]; then + MVN=mvn +fi + +deploy_one() { + local artifactId="$1" + local rel="$2" + local file="$ROOT/$rel" + if [[ ! -f "$file" ]]; then + echo "SKIP (not built): $artifactId — missing $rel" >&2 + return 0 + fi + echo "Deploying $artifactId → $REPO_URL" + "$MVN" -q org.apache.maven.plugins:maven-deploy-plugin:3.1.3:deploy-file \ + -DgroupId="$GROUP_ID" \ + -DartifactId="$artifactId" \ + -Dversion="$VERSION" \ + -Dpackaging=zip \ + -Dfile="$file" \ + -DrepositoryId="$REPO_ID" \ + -Durl="$REPO_URL" \ + -DgeneratePom=true \ + -DretryFailedDeploymentCount=2 +} + +# Allow password via settings or wagon; deploy-file uses server credentials from settings.xml +# when repositoryId matches. Also support inline for local-only: +export MAVEN_OPTS="${MAVEN_OPTS:-}" + +for artifactId in "${!ZIPS[@]}"; do + deploy_one "$artifactId" "${ZIPS[$artifactId]}" +done + +echo "Done. Configure hop marketplace repositories[0].url to: ${REPO_URL%/}/" +echo "Example: hop marketplace install hop-tech-parquet" diff --git a/plugins/engines/beam/pom.xml b/plugins/engines/beam/pom.xml index 13714cfa613..266a4f5e674 100644 --- a/plugins/engines/beam/pom.xml +++ b/plugins/engines/beam/pom.xml @@ -1659,4 +1659,47 @@ + + + + + + maven-assembly-plugin + + + assembly-beam-libs + + single + + package + + true + + ${project.basedir}/src/assembly/assembly-libs.xml + + + + + + assembly_package + + single + + package + + false + + ${project.basedir}/src/assembly/assembly.xml + + + + + + + + diff --git a/plugins/engines/beam/src/assembly/assembly-libs.xml b/plugins/engines/beam/src/assembly/assembly-libs.xml new file mode 100644 index 00000000000..901d8b1ea19 --- /dev/null +++ b/plugins/engines/beam/src/assembly/assembly-libs.xml @@ -0,0 +1,291 @@ + + + + + libs + + zip + + . + + + + + runtime + + org.apache.hop:hop-engines-beam:jar + org.apache.hadoop:*:jar + org.apache.hadoop.thirdparty:*:jar + org.yaml:snakeyaml:jar + com.google.protobuf:protobuf-java:jar + com.google.protobuf:protobuf-java-util:jar + org.jetbrains:annotations:jar + com.google.auto.value:auto-value-annotations:jar + org.apache.beam:beam-vendor-guava-32_1_2-jre:jar + com.github.luben:zstd-jni:jar + com.google.auth:google-auth-library-oauth2-http:jar + com.google.oauth-client:google-oauth-client:jar + com.google.api-client:google-api-client:jar + com.google.http-client:google-http-client:jar + com.google.http-client:google-http-client-apache-v2:jar + com.google.http-client:google-http-client-appengine:jar + google-http-client-gson:jar + com.google.http-client:google-http-client-jackson2:jar + com.google.android:annotations:jar + org.codehaus.mojo:animal-sniffer-annotations:jar + com.google.api:api-common:jar + com.google.auto.value:auto-value-annotations:jar + com.google.guava::jar + org.jetbrains.kotlin::jar + io.netty::jar + org.codehaus.mojo:animal-sniffer-annotations:jar + io.projectreactor.netty::jar + io.grpc:grpc-netty-shaded:jar + io.grpc:grpc-xds:jar + org.apache.kafka::jar + org.xerial.snappy:snappy-java:jar + org.eclipse.jetty::jar + org.eclipse.jetty.compression::jar + com.google.cloud:google-cloud-storage:jar + io.grpc::jar + com.google.cloud:google-cloud-core-grpc:jar + com.google.api.grpc:grpc-google-cloud-storage-v2:jar + com.google.api:gax-grpc:jar + com.google.api.grpc::jar + org.checkerframework:checker-qual:jar + io.confluent:common-utils:jar + commons-cli:commons-cli:jar + commons-codec:commons-codec:jar + commons-logging:commons-logging:jar + org.apache.commons:commons-text:jar + com.google.cloud.opentelemetry:detector-resources-support:jar + com.google.errorprone:error_prone_annotations:jar + com.google.cloud.opentelemetry:exporter-metrics:jar + com.google.api:gax:jar + com.google.api:gax-httpjson:jar + com.google.apis:google-api-services-storage:jar + com.google.auth:google-auth-library-credentials:jar + com.google.auth:google-auth-library-oauth2-http:jar + com.google.cloud:google-cloud-core:jar + com.google.cloud:google-cloud-core-http:jar + com.google.cloud:google-cloud-monitoring:jar + com.google.http-client:google-http-client-gson:jar + org.apache.httpcomponents:httpclient:jar + org.apache.httpcomponents:httpcore:jar + com.google.j2objc:j2objc-annotations:jar + com.fasterxml.jackson.core::jar + com.fasterxml.jackson.dataformat::jar + com.fasterxml.jackson.datatype::jar + com.fasterxml.jackson::jar + com.github.stephenc.jcip:jcip-annotations:jar + net.java.dev.jna::jar + com.google.code.findbugs:jsr305:jar + com.squareup.okhttp3:okhttp:jar + com.squareup.okio::jar + io.opentelemetry::jar + com.google.cloud.opentelemetry:shared-resourcemapping:jar + org.codehaus.woodstox:stax2-api:jar + org.threeten::jar + org.lz4:lz4-java:jar + io.opentelemetry.contrib::jar + io.opentelemetry.semconv::jar + io.perfmark:perfmark-api:jar + com.google.re2j:re2j:jar + org.reactivestreams:reactive-streams:jar + io.projectreactor:reactor-core:jar + org.bouncycastle::jar + com.microsoft.azure:msal4j:jar + com.microsoft.azure:msal4j-persistence-extension:jar + com.amazonaws:aws-java-sdk-core:jar + com.amazonaws:aws-java-sdk-kms:jar + com.amazonaws:aws-java-sdk-s3:jar + com.nimbusds:oauth2-oidc-sdk:jar + com.azure:azure-core:jar + com.azure:azure-identity:jar + com.azure:azure-core-http-netty:jar + com.azure:azure-json:jar + com.microsoft.azure:azure-keyvault-core:jar + com.azure:azure-security-keyvault-secrets:jar + com.azure:azure-storage-blob:jar + com.azure:azure-storage-common:jar + com.azure:azure-storage-internal-avro:jar + com.azure:azure-xml:jar + com.nimbusds:nimbus-jose-jwt:jar + io.confluent::jar + com.google.code.gson:gson:jar + org.apache.commons:commons-collections4:jar + org.jspecify:jspecify:jar + org.apache.commons:commons-lang3:jar + commons-collections:commons-collections:jar + com.fasterxml.woodstox:woodstox-core:jar + com.ibm.icu:icu4j:jar + com.fasterxml.jackson.core:jackson-annotations:jar + software.amazon.awssdk:*:jar + software.amazon.eventstream:eventstream:jar + javax.annotation:javax.annotation-api:jar + javax.inject:javax.inject:jar + org.jctools:jctools-core:jar + com.nimbusds:lang-tag:jar + io.dropwizard.metrics:*:jar + com.eclipsesource.minimal-json:minimal-json:jar + org.slf4j:slf4j-api:jar + + org.apache.spark:spark-core_2.12:jar + org.apache.spark:spark-streaming_2.12:jar + org.apache.spark:spark-launcher_2.12:jar + org.apache.spark:spark-kvstore_2.12:jar + org.apache.spark:spark-network-common_2.12:jar + org.apache.spark:spark-network-shuffle_2.12:jar + org.apache.spark:spark-unsafe_2.12:jar + org.apache.spark:spark-tags_2.12:jar + + lib/beam + + + + runtime + + org.apache.spark:spark-core_2.12:jar + org.apache.spark:spark-streaming_2.12:jar + org.apache.spark:spark-launcher_2.12:jar + org.apache.spark:spark-kvstore_2.12:jar + org.apache.spark:spark-network-common_2.12:jar + org.apache.spark:spark-network-shuffle_2.12:jar + org.apache.spark:spark-unsafe_2.12:jar + org.apache.spark:spark-tags_2.12:jar + + lib/spark-client + + + runtime + + org.apache.hadoop:*:jar + org.apache.hadoop.thirdparty:*:jar + org.yaml:snakeyaml:jar + org.jetbrains:annotations:jar + com.google.auto.value:auto-value-annotations:jar + org.apache.beam:beam-vendor-guava-32_1_2-jre:jar + com.github.luben:zstd-jni:jar + com.google.auth:google-auth-library-oauth2-http:jar + com.google.oauth-client:google-oauth-client:jar + com.google.api-client:google-api-client:jar + com.google.http-client:google-http-client:jar + com.google.http-client:google-http-client-apache-v2:jar + com.google.http-client:google-http-client-appengine:jar + google-http-client-gson:jar + com.google.http-client:google-http-client-jackson2:jar + com.google.android:annotations:jar + org.codehaus.mojo:animal-sniffer-annotations:jar + com.google.api:api-common:jar + com.google.auto.value:auto-value-annotations:jar + org.jetbrains.kotlin::jar + io.netty::jar + io.projectreactor.netty::jar + io.projectreactor:reactor-core:jar + io.grpc:grpc-netty-shaded:jar + org.apache.kafka::jar + com.google.cloud:google-cloud-storage:jar + io.grpc::jar + com.google.cloud:google-cloud-core-grpc:jar + com.google.api.grpc:grpc-google-cloud-storage-v2:jar + com.google.api:gax-grpc:jar + com.google.api:gax:jar + com.google.api.grpc::jar + org.checkerframework:checker-qual:jar + io.confluent:common-utils:jar + commons-cli:commons-cli:jar + commons-codec:commons-codec:jar + commons-logging:commons-logging:jar + org.apache.commons:commons-text:jar + com.google.cloud.opentelemetry:detector-resources-support:jar + com.google.errorprone:error_prone_annotations:jar + com.google.cloud.opentelemetry:exporter-metrics:jar + com.google.api:gax-httpjson:jar + com.google.apis:google-api-services-storage:jar + com.google.auth:google-auth-library-credentials:jar + com.google.auth:google-auth-library-oauth2-http:jar + com.google.cloud:google-cloud-core:jar + com.google.cloud:google-cloud-core-http:jar + com.google.cloud:google-cloud-monitoring:jar + com.google.http-client:google-http-client-gson:jar + org.apache.httpcomponents:httpclient:jar + org.apache.httpcomponents:httpcore:jar + com.google.j2objc:j2objc-annotations:jar + com.fasterxml.jackson.core::jar + com.fasterxml.jackson.dataformat::jar + com.fasterxml.jackson.datatype::jar + com.fasterxml.jackson::jar + com.github.stephenc.jcip:jcip-annotations:jar + net.java.dev.jna::jar + com.google.code.findbugs:jsr305:jar + com.squareup.okhttp3:okhttp:jar + com.squareup.okio::jar + io.opentelemetry::jar + io.opentelemetry.contrib::jar + io.opentelemetry.semconv::jar + com.google.cloud.opentelemetry:shared-resourcemapping:jar + org.codehaus.woodstox:stax2-api:jar + org.threeten::jar + org.lz4:lz4-java:jar + io.perfmark:perfmark-api:jar + com.google.re2j:re2j:jar + org.reactivestreams:reactive-streams:jar + org.bouncycastle::jar + com.microsoft.azure:msal4j:jar + com.microsoft.azure:msal4j-persistence-extension:jar + com.amazonaws:aws-java-sdk-core:jar + com.amazonaws:aws-java-sdk-kms:jar + com.amazonaws:aws-java-sdk-s3:jar + com.nimbusds:oauth2-oidc-sdk:jar + com.azure:azure-core:jar + com.azure:azure-identity:jar + com.azure:azure-core-http-netty:jar + com.azure:azure-json:jar + com.microsoft.azure:azure-keyvault-core:jar + com.azure:azure-security-keyvault-secrets:jar + com.azure:azure-storage-blob:jar + com.azure:azure-storage-common:jar + com.azure:azure-storage-internal-avro:jar + com.azure:azure-xml:jar + com.nimbusds:nimbus-jose-jwt:jar + io.confluent::jar + com.google.code.gson:gson:jar + org.apache.commons:commons-collections4:jar + org.apache.commons:commons-lang3:jar + commons-collections:commons-collections:jar + com.fasterxml.woodstox:woodstox-core:jar + com.ibm.icu:icu4j:jar + com.fasterxml.jackson.core:jackson-annotations:jar + software.amazon.awssdk:*:jar + software.amazon.eventstream:eventstream:jar + javax.annotation:javax.annotation-api:jar + javax.inject:javax.inject:jar + org.jctools:jctools-core:jar + com.nimbusds:lang-tag:jar + io.dropwizard.metrics:*:jar + com.eclipsesource.minimal-json:minimal-json:jar + org.slf4j:slf4j-api:jar + + lib/core + + + \ No newline at end of file diff --git a/plugins/engines/beam/src/assembly/assembly.xml b/plugins/engines/beam/src/assembly/assembly.xml index c012216d5cb..cf9fe298760 100644 --- a/plugins/engines/beam/src/assembly/assembly.xml +++ b/plugins/engines/beam/src/assembly/assembly.xml @@ -18,7 +18,8 @@ - hop-engines-beam + + plugin zip @@ -50,265 +51,5 @@ plugins/engines/beam - - runtime - - org.apache.hop:hop-engines-beam:jar - org.apache.hadoop:*:jar - org.apache.hadoop.thirdparty:*:jar - org.yaml:snakeyaml:jar - com.google.protobuf:protobuf-java:jar - com.google.protobuf:protobuf-java-util:jar - org.jetbrains:annotations:jar - com.google.auto.value:auto-value-annotations:jar - org.apache.beam:beam-vendor-guava-32_1_2-jre:jar - com.github.luben:zstd-jni:jar - com.google.auth:google-auth-library-oauth2-http:jar - com.google.oauth-client:google-oauth-client:jar - com.google.api-client:google-api-client:jar - com.google.http-client:google-http-client:jar - com.google.http-client:google-http-client-apache-v2:jar - com.google.http-client:google-http-client-appengine:jar - google-http-client-gson:jar - com.google.http-client:google-http-client-jackson2:jar - com.google.android:annotations:jar - org.codehaus.mojo:animal-sniffer-annotations:jar - com.google.api:api-common:jar - com.google.auto.value:auto-value-annotations:jar - com.google.guava::jar - org.jetbrains.kotlin::jar - io.netty::jar - org.codehaus.mojo:animal-sniffer-annotations:jar - io.projectreactor.netty::jar - io.grpc:grpc-netty-shaded:jar - io.grpc:grpc-xds:jar - org.apache.kafka::jar - org.xerial.snappy:snappy-java:jar - org.eclipse.jetty::jar - org.eclipse.jetty.compression::jar - com.google.cloud:google-cloud-storage:jar - io.grpc::jar - com.google.cloud:google-cloud-core-grpc:jar - com.google.api.grpc:grpc-google-cloud-storage-v2:jar - com.google.api:gax-grpc:jar - com.google.api.grpc::jar - org.checkerframework:checker-qual:jar - io.confluent:common-utils:jar - commons-cli:commons-cli:jar - commons-codec:commons-codec:jar - commons-logging:commons-logging:jar - org.apache.commons:commons-text:jar - com.google.cloud.opentelemetry:detector-resources-support:jar - com.google.errorprone:error_prone_annotations:jar - com.google.cloud.opentelemetry:exporter-metrics:jar - com.google.api:gax:jar - com.google.api:gax-httpjson:jar - com.google.apis:google-api-services-storage:jar - com.google.auth:google-auth-library-credentials:jar - com.google.auth:google-auth-library-oauth2-http:jar - com.google.cloud:google-cloud-core:jar - com.google.cloud:google-cloud-core-http:jar - com.google.cloud:google-cloud-monitoring:jar - com.google.http-client:google-http-client-gson:jar - org.apache.httpcomponents:httpclient:jar - org.apache.httpcomponents:httpcore:jar - com.google.j2objc:j2objc-annotations:jar - com.fasterxml.jackson.core::jar - com.fasterxml.jackson.dataformat::jar - com.fasterxml.jackson.datatype::jar - com.fasterxml.jackson::jar - com.github.stephenc.jcip:jcip-annotations:jar - net.java.dev.jna::jar - com.google.code.findbugs:jsr305:jar - com.squareup.okhttp3:okhttp:jar - com.squareup.okio::jar - io.opentelemetry::jar - com.google.cloud.opentelemetry:shared-resourcemapping:jar - org.codehaus.woodstox:stax2-api:jar - org.threeten::jar - org.lz4:lz4-java:jar - io.opentelemetry.contrib::jar - io.opentelemetry.semconv::jar - io.perfmark:perfmark-api:jar - com.google.re2j:re2j:jar - org.reactivestreams:reactive-streams:jar - io.projectreactor:reactor-core:jar - org.bouncycastle::jar - com.microsoft.azure:msal4j:jar - com.microsoft.azure:msal4j-persistence-extension:jar - com.amazonaws:aws-java-sdk-core:jar - com.amazonaws:aws-java-sdk-kms:jar - com.amazonaws:aws-java-sdk-s3:jar - com.nimbusds:oauth2-oidc-sdk:jar - com.azure:azure-core:jar - com.azure:azure-identity:jar - com.azure:azure-core-http-netty:jar - com.azure:azure-json:jar - com.microsoft.azure:azure-keyvault-core:jar - com.azure:azure-security-keyvault-secrets:jar - com.azure:azure-storage-blob:jar - com.azure:azure-storage-common:jar - com.azure:azure-storage-internal-avro:jar - com.azure:azure-xml:jar - com.nimbusds:nimbus-jose-jwt:jar - io.confluent::jar - com.google.code.gson:gson:jar - org.apache.commons:commons-collections4:jar - org.jspecify:jspecify:jar - org.apache.commons:commons-lang3:jar - commons-collections:commons-collections:jar - com.fasterxml.woodstox:woodstox-core:jar - com.ibm.icu:icu4j:jar - com.fasterxml.jackson.core:jackson-annotations:jar - software.amazon.awssdk:*:jar - software.amazon.eventstream:eventstream:jar - javax.annotation:javax.annotation-api:jar - javax.inject:javax.inject:jar - org.jctools:jctools-core:jar - com.nimbusds:lang-tag:jar - io.dropwizard.metrics:*:jar - com.eclipsesource.minimal-json:minimal-json:jar - org.slf4j:slf4j-api:jar - - org.apache.spark:spark-core_2.12:jar - org.apache.spark:spark-streaming_2.12:jar - org.apache.spark:spark-launcher_2.12:jar - org.apache.spark:spark-kvstore_2.12:jar - org.apache.spark:spark-network-common_2.12:jar - org.apache.spark:spark-network-shuffle_2.12:jar - org.apache.spark:spark-unsafe_2.12:jar - org.apache.spark:spark-tags_2.12:jar - - lib/beam - - - - runtime - - org.apache.spark:spark-core_2.12:jar - org.apache.spark:spark-streaming_2.12:jar - org.apache.spark:spark-launcher_2.12:jar - org.apache.spark:spark-kvstore_2.12:jar - org.apache.spark:spark-network-common_2.12:jar - org.apache.spark:spark-network-shuffle_2.12:jar - org.apache.spark:spark-unsafe_2.12:jar - org.apache.spark:spark-tags_2.12:jar - - lib/spark-client - - - runtime - - org.apache.hadoop:*:jar - org.apache.hadoop.thirdparty:*:jar - org.yaml:snakeyaml:jar - org.jetbrains:annotations:jar - com.google.auto.value:auto-value-annotations:jar - org.apache.beam:beam-vendor-guava-32_1_2-jre:jar - com.github.luben:zstd-jni:jar - com.google.auth:google-auth-library-oauth2-http:jar - com.google.oauth-client:google-oauth-client:jar - com.google.api-client:google-api-client:jar - com.google.http-client:google-http-client:jar - com.google.http-client:google-http-client-apache-v2:jar - com.google.http-client:google-http-client-appengine:jar - google-http-client-gson:jar - com.google.http-client:google-http-client-jackson2:jar - com.google.android:annotations:jar - org.codehaus.mojo:animal-sniffer-annotations:jar - com.google.api:api-common:jar - com.google.auto.value:auto-value-annotations:jar - org.jetbrains.kotlin::jar - io.netty::jar - io.projectreactor.netty::jar - io.projectreactor:reactor-core:jar - io.grpc:grpc-netty-shaded:jar - org.apache.kafka::jar - com.google.cloud:google-cloud-storage:jar - io.grpc::jar - com.google.cloud:google-cloud-core-grpc:jar - com.google.api.grpc:grpc-google-cloud-storage-v2:jar - com.google.api:gax-grpc:jar - com.google.api:gax:jar - com.google.api.grpc::jar - org.checkerframework:checker-qual:jar - io.confluent:common-utils:jar - commons-cli:commons-cli:jar - commons-codec:commons-codec:jar - commons-logging:commons-logging:jar - org.apache.commons:commons-text:jar - com.google.cloud.opentelemetry:detector-resources-support:jar - com.google.errorprone:error_prone_annotations:jar - com.google.cloud.opentelemetry:exporter-metrics:jar - com.google.api:gax-httpjson:jar - com.google.apis:google-api-services-storage:jar - com.google.auth:google-auth-library-credentials:jar - com.google.auth:google-auth-library-oauth2-http:jar - com.google.cloud:google-cloud-core:jar - com.google.cloud:google-cloud-core-http:jar - com.google.cloud:google-cloud-monitoring:jar - com.google.http-client:google-http-client-gson:jar - org.apache.httpcomponents:httpclient:jar - org.apache.httpcomponents:httpcore:jar - com.google.j2objc:j2objc-annotations:jar - com.fasterxml.jackson.core::jar - com.fasterxml.jackson.dataformat::jar - com.fasterxml.jackson.datatype::jar - com.fasterxml.jackson::jar - com.github.stephenc.jcip:jcip-annotations:jar - net.java.dev.jna::jar - com.google.code.findbugs:jsr305:jar - com.squareup.okhttp3:okhttp:jar - com.squareup.okio::jar - io.opentelemetry::jar - io.opentelemetry.contrib::jar - io.opentelemetry.semconv::jar - com.google.cloud.opentelemetry:shared-resourcemapping:jar - org.codehaus.woodstox:stax2-api:jar - org.threeten::jar - org.lz4:lz4-java:jar - io.perfmark:perfmark-api:jar - com.google.re2j:re2j:jar - org.reactivestreams:reactive-streams:jar - org.bouncycastle::jar - com.microsoft.azure:msal4j:jar - com.microsoft.azure:msal4j-persistence-extension:jar - com.amazonaws:aws-java-sdk-core:jar - com.amazonaws:aws-java-sdk-kms:jar - com.amazonaws:aws-java-sdk-s3:jar - com.nimbusds:oauth2-oidc-sdk:jar - com.azure:azure-core:jar - com.azure:azure-identity:jar - com.azure:azure-core-http-netty:jar - com.azure:azure-json:jar - com.microsoft.azure:azure-keyvault-core:jar - com.azure:azure-security-keyvault-secrets:jar - com.azure:azure-storage-blob:jar - com.azure:azure-storage-common:jar - com.azure:azure-storage-internal-avro:jar - com.azure:azure-xml:jar - com.nimbusds:nimbus-jose-jwt:jar - io.confluent::jar - com.google.code.gson:gson:jar - org.apache.commons:commons-collections4:jar - org.apache.commons:commons-lang3:jar - commons-collections:commons-collections:jar - com.fasterxml.woodstox:woodstox-core:jar - com.ibm.icu:icu4j:jar - com.fasterxml.jackson.core:jackson-annotations:jar - software.amazon.awssdk:*:jar - software.amazon.eventstream:eventstream:jar - javax.annotation:javax.annotation-api:jar - javax.inject:javax.inject:jar - org.jctools:jctools-core:jar - com.nimbusds:lang-tag:jar - io.dropwizard.metrics:*:jar - com.eclipsesource.minimal-json:minimal-json:jar - org.slf4j:slf4j-api:jar - - lib/core - - \ No newline at end of file + diff --git a/plugins/misc/marketplace/README.md b/plugins/misc/marketplace/README.md new file mode 100644 index 00000000000..8a1fbadd3fe --- /dev/null +++ b/plugins/misc/marketplace/README.md @@ -0,0 +1,66 @@ + + +# Hop Marketplace plugin + +Bundled core plugin that installs optional Hop plugins from a Maven repository +(Maven Central, ASF Nexus, or a local Artifactory). + +## CLI + +From the Hop install directory (`HOP_HOME`): + +```bash +./hop marketplace install hop-tech-parquet +./hop marketplace install hop-engines-spark:2.19.0 +./hop marketplace install hop-engines-beam +./hop marketplace list +./hop marketplace uninstall hop-tech-parquet +``` + +Coordinates: + +- `artifactId` (uses config `defaultVersion` / Hop version) +- `artifactId:version` +- `groupId:artifactId:version` + +After install or uninstall, **restart Hop** so the plugin registry reloads. + +## Config (`hop-config.json`) + +```json +{ + "marketplace": { + "enabled": true, + "groupId": "org.apache.hop", + "defaultVersion": "2.19.0-SNAPSHOT", + "repositories": [ + { "id": "central", "url": "https://repo1.maven.org/maven2/" } + ] + } +} +``` + +For local testing see `docker/marketplace-artifactory/README.md`. + +## Beam note + +`hop-engines-beam` marketplace package is the **plugin** (`plugins/engines/beam`) only. +`lib/beam` remains part of the default Hop distribution and is never removed by +marketplace uninstall. diff --git a/plugins/misc/marketplace/pom.xml b/plugins/misc/marketplace/pom.xml new file mode 100644 index 00000000000..2b09cc2b5a4 --- /dev/null +++ b/plugins/misc/marketplace/pom.xml @@ -0,0 +1,35 @@ + + + + 4.0.0 + + + org.apache.hop + hop-plugins-misc + 2.19.0-SNAPSHOT + + + hop-misc-marketplace + jar + Hop Plugins Miscellaneous Marketplace + + + + + diff --git a/plugins/misc/marketplace/src/assembly/assembly.xml b/plugins/misc/marketplace/src/assembly/assembly.xml new file mode 100644 index 00000000000..db9d323ad9f --- /dev/null +++ b/plugins/misc/marketplace/src/assembly/assembly.xml @@ -0,0 +1,39 @@ + + + + + hop-misc-marketplace + + zip + + . + + + ${project.basedir}/src/main/resources/version.xml + ${hop.plugin.libdir} + true + + + + + ${maven.multiModuleProjectDirectory}/assemblies/shared/hop-plugin-libs.xml + + diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java new file mode 100644 index 00000000000..002c3669e06 --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java @@ -0,0 +1,202 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.command; + +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.StringUtils; +import org.apache.hop.core.HopVersionProvider; +import org.apache.hop.core.exception.HopException; +import org.apache.hop.core.logging.ILogChannel; +import org.apache.hop.core.logging.LogChannel; +import org.apache.hop.core.variables.IVariables; +import org.apache.hop.hop.plugin.HopCommand; +import org.apache.hop.hop.plugin.IHopCommand; +import org.apache.hop.marketplace.config.MarketplaceConfig; +import org.apache.hop.marketplace.install.HopHome; +import org.apache.hop.marketplace.install.InstallReceipt; +import org.apache.hop.marketplace.install.PluginInstaller; +import org.apache.hop.marketplace.install.PluginUninstaller; +import org.apache.hop.marketplace.resolve.MavenCoordinates; +import org.apache.hop.metadata.api.IHasHopMetadataProvider; +import org.apache.hop.metadata.serializer.multi.MultiMetadataProvider; +import picocli.CommandLine; +import picocli.CommandLine.Command; +import picocli.CommandLine.Parameters; + +@Getter +@Setter +@Command( + name = "marketplace", + mixinStandardHelpOptions = true, + description = "Install and manage optional Hop plugins from a Maven repository", + subcommands = { + MarketplaceCommand.InstallCommand.class, + MarketplaceCommand.UninstallCommand.class, + MarketplaceCommand.ListCommand.class + }) +@HopCommand(id = "marketplace", description = "Hop plugin marketplace") +public class MarketplaceCommand implements Runnable, IHopCommand, IHasHopMetadataProvider { + + private ILogChannel log; + private CommandLine cmd; + private IVariables variables; + private MultiMetadataProvider metadataProvider; + + @Override + public void initialize( + CommandLine cmd, IVariables variables, MultiMetadataProvider metadataProvider) + throws HopException { + this.cmd = cmd; + this.variables = variables; + this.metadataProvider = metadataProvider; + this.log = new LogChannel("Marketplace"); + // Wire nested subcommands with shared context + for (CommandLine sub : cmd.getSubcommands().values()) { + Object userObject = sub.getCommand(); + if (userObject instanceof MarketplaceSubCommand nested) { + nested.init(log, variables); + } + } + } + + @Override + public void run() { + cmd.usage(System.out); + } + + static String resolveDefaultVersion(MarketplaceConfig config) { + if (StringUtils.isNotBlank(config.getDefaultVersion())) { + return config.getDefaultVersion(); + } + String[] versions = new HopVersionProvider().getVersion(); + if (versions != null && versions.length > 0 && StringUtils.isNotBlank(versions[0])) { + return versions[0]; + } + // Development builds often have null Implementation-Version + return System.getProperty("hop.version", "2.19.0-SNAPSHOT"); + } + + abstract static class MarketplaceSubCommand implements Runnable { + protected ILogChannel log; + protected IVariables variables; + + void init(ILogChannel log, IVariables variables) { + this.log = log; + this.variables = variables; + } + } + + @Command(name = "install", description = "Download and install a plugin zip by Maven coordinates") + static class InstallCommand extends MarketplaceSubCommand { + @Parameters( + index = "0", + paramLabel = "COORDINATE", + description = + "artifactId, artifactId:version, or groupId:artifactId:version (e.g. hop-tech-parquet)") + private String coordinate; + + @Override + public void run() { + try { + MarketplaceConfig config = MarketplaceConfig.load(); + if (!config.isEnabled()) { + throw new HopException("Marketplace is disabled in hop-config.json"); + } + Path hopHome = HopHome.resolve(); + // Activate any previously staged plugins first + new PluginInstaller(log, hopHome, config).activateAllPending(); + + MavenCoordinates gav = + MavenCoordinates.parse(coordinate, config.getGroupId(), resolveDefaultVersion(config)); + new PluginInstaller(log, hopHome, config).install(gav, true); + System.out.println( + "Plugin " + gav.gav() + " installed under " + hopHome + ". Restart Hop to load it."); + } catch (Exception e) { + System.err.println("ERROR: " + e.getMessage()); + if (log != null) { + log.logError("Marketplace install failed", e); + } + throw new CommandLine.ExecutionException( + new CommandLine(this), e.getMessage() == null ? "install failed" : e.getMessage(), e); + } + } + } + + @Command( + name = "uninstall", + description = "Remove a plugin previously installed via the marketplace") + static class UninstallCommand extends MarketplaceSubCommand { + @Parameters(index = "0", paramLabel = "ARTIFACT_ID", description = "e.g. hop-tech-parquet") + private String artifactId; + + @Override + public void run() { + try { + Path hopHome = HopHome.resolve(); + new PluginUninstaller(log, hopHome).uninstall(artifactId); + System.out.println("Uninstalled " + artifactId + ". Restart Hop."); + } catch (Exception e) { + System.err.println("ERROR: " + e.getMessage()); + throw new CommandLine.ExecutionException( + new CommandLine(this), e.getMessage() == null ? "uninstall failed" : e.getMessage(), e); + } + } + } + + @Command(name = "list", description = "List marketplace-installed plugins (receipts)") + static class ListCommand extends MarketplaceSubCommand { + @Override + public void run() { + try { + Path hopHome = HopHome.resolve(); + Path receipts = hopHome.resolve(PluginInstaller.RECEIPTS_DIR); + if (!Files.isDirectory(receipts)) { + System.out.println("No marketplace-installed plugins."); + return; + } + try (DirectoryStream stream = Files.newDirectoryStream(receipts, "*.json")) { + boolean any = false; + for (Path file : stream) { + any = true; + InstallReceipt receipt = + org.apache.hop.core.json.HopJson.newMapper() + .readValue(file.toFile(), InstallReceipt.class); + System.out.printf( + "%s %s:%s:%s%s%n", + receipt.getArtifactId(), + receipt.getGroupId(), + receipt.getArtifactId(), + receipt.getVersion(), + receipt.isPendingActivation() ? " (pending activation)" : ""); + } + if (!any) { + System.out.println("No marketplace-installed plugins."); + } + } + } catch (Exception e) { + System.err.println("ERROR: " + e.getMessage()); + throw new CommandLine.ExecutionException( + new CommandLine(this), e.getMessage() == null ? "list failed" : e.getMessage(), e); + } + } + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java new file mode 100644 index 00000000000..c8b57f29ac0 --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.config; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import org.apache.hop.core.config.HopConfig; +import org.apache.hop.core.json.HopJson; +import org.apache.hop.core.logging.ILogChannel; +import org.apache.hop.core.logging.LogChannel; + +// Map used when serializing to hop-config.json + +/** + * Marketplace settings stored under the {@code marketplace} key in hop-config.json (or defaults). + */ +@Getter +@Setter +public class MarketplaceConfig { + public static final String CONFIG_KEY = "marketplace"; + public static final String DEFAULT_GROUP_ID = "org.apache.hop"; + public static final String DEFAULT_REPO_URL = "https://repo1.maven.org/maven2/"; + + private boolean enabled = true; + private String groupId = DEFAULT_GROUP_ID; + private String defaultVersion; + private String searchApiUrl = "https://search.maven.org/solrsearch/select"; + private int cacheTtlHours = 24; + private List repositories = new ArrayList<>(); + + public MarketplaceConfig() { + repositories.add(new MarketplaceRepository("central", DEFAULT_REPO_URL)); + } + + public static MarketplaceConfig load() { + ILogChannel log = new LogChannel("Marketplace"); + try { + Object raw = HopConfig.readOption(CONFIG_KEY); + if (raw == null) { + return new MarketplaceConfig(); + } + return HopJson.newMapper().convertValue(raw, MarketplaceConfig.class); + } catch (Exception e) { + log.logError("Unable to load marketplace config, using defaults", e); + return new MarketplaceConfig(); + } + } + + @SuppressWarnings("unchecked") + public void save() { + Map asMap = HopJson.newMapper().convertValue(this, Map.class); + HopConfig.getInstance().saveOption(CONFIG_KEY, asMap); + } + + /** First repository base URL, or Maven Central. Always ends with {@code /}. */ + public String primaryRepositoryUrl() { + if (repositories == null || repositories.isEmpty()) { + return DEFAULT_REPO_URL; + } + String url = repositories.get(0).getUrl(); + if (url == null || url.isBlank()) { + return DEFAULT_REPO_URL; + } + return url.endsWith("/") ? url : url + "/"; + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java new file mode 100644 index 00000000000..043b21ffb37 --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.config; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class MarketplaceRepository { + private String id = "central"; + private String url = "https://repo1.maven.org/maven2/"; + + public MarketplaceRepository() { + // Jackson + } + + public MarketplaceRepository(String id, String url) { + this.id = id; + this.url = url; + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/HopHome.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/HopHome.java new file mode 100644 index 00000000000..12312f2780a --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/HopHome.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.install; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.apache.commons.lang3.StringUtils; +import org.apache.hop.core.exception.HopException; + +/** Resolves the Hop installation directory (the folder that contains {@code plugins/}). */ +public final class HopHome { + + public static final String ENV_HOP_HOME = "HOP_HOME"; + public static final String PROP_HOP_HOME = "hop.home"; + + private HopHome() {} + + public static Path resolve() throws HopException { + String fromEnv = System.getenv(ENV_HOP_HOME); + if (StringUtils.isNotBlank(fromEnv)) { + return validate(Paths.get(fromEnv)); + } + String fromProp = System.getProperty(PROP_HOP_HOME); + if (StringUtils.isNotBlank(fromProp)) { + return validate(Paths.get(fromProp)); + } + Path cwd = Paths.get(System.getProperty("user.dir")); + if (Files.isDirectory(cwd.resolve("plugins"))) { + return cwd.toAbsolutePath().normalize(); + } + // hop-gui often runs with cwd = hop home already; otherwise walk up one level + Path parent = cwd.getParent(); + if (parent != null && Files.isDirectory(parent.resolve("plugins"))) { + return parent.toAbsolutePath().normalize(); + } + throw new HopException( + "Cannot determine Hop installation directory. Set HOP_HOME or run from the Hop install root" + + " (the directory that contains plugins/)."); + } + + private static Path validate(Path path) throws HopException { + Path abs = path.toAbsolutePath().normalize(); + if (!Files.isDirectory(abs)) { + throw new HopException("Hop home is not a directory: " + abs); + } + return abs; + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/InstallReceipt.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/InstallReceipt.java new file mode 100644 index 00000000000..84fe6d9adc0 --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/InstallReceipt.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.install; + +import java.util.ArrayList; +import java.util.List; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class InstallReceipt { + private String groupId; + private String artifactId; + private String version; + private String installedAt; + private List paths = new ArrayList<>(); + private boolean pendingActivation; + + public InstallReceipt() { + // Jackson + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java new file mode 100644 index 00000000000..d06fd8bbe9c --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java @@ -0,0 +1,264 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.install; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; +import java.nio.file.attribute.BasicFileAttributes; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import org.apache.hop.core.exception.HopException; +import org.apache.hop.core.json.HopJson; +import org.apache.hop.core.logging.ILogChannel; +import org.apache.hop.marketplace.config.MarketplaceConfig; +import org.apache.hop.marketplace.resolve.MavenCoordinates; +import org.apache.hop.marketplace.resolve.MavenRepositoryClient; + +/** + * Downloads a plugin zip, stages it under {@code plugins/.staging/}, writes a receipt, and + * activates into the live plugins tree. Uses stage-then-activate (restart-friendly) rather than + * hot-reload. + */ +public class PluginInstaller { + + public static final String STAGING_DIR = "plugins/.staging"; + public static final String RECEIPTS_DIR = "plugins/.marketplace"; + + private final ILogChannel log; + private final Path hopHome; + private final MarketplaceConfig config; + private final MavenRepositoryClient client; + + public PluginInstaller(ILogChannel log, Path hopHome, MarketplaceConfig config) { + this.log = log; + this.hopHome = hopHome; + this.config = config; + this.client = new MavenRepositoryClient(log); + } + + PluginInstaller( + ILogChannel log, Path hopHome, MarketplaceConfig config, MavenRepositoryClient client) { + this.log = log; + this.hopHome = hopHome; + this.config = config; + this.client = client; + } + + /** + * Download, stage, and activate a plugin. Returns the receipt after activation. + * + * @param activateImmediately if true, move staged files into place now (CLI default). GUI may + * stage and ask for restart later; for CLI we activate immediately then ask the user to + * restart so classloaders pick up the new jars. + */ + public InstallReceipt install(MavenCoordinates coordinates, boolean activateImmediately) + throws HopException { + Path downloadDir = hopHome.resolve(STAGING_DIR).resolve(".download"); + Path zipFile = + downloadDir.resolve(coordinates.artifactId() + "-" + coordinates.version() + ".zip"); + try { + client.downloadZip(config.primaryRepositoryUrl(), coordinates, zipFile); + Path stageRoot = hopHome.resolve(STAGING_DIR).resolve(coordinates.artifactId()); + deleteRecursive(stageRoot); + Files.createDirectories(stageRoot); + List relativePaths = unzipAllowedEntries(zipFile, stageRoot); + + InstallReceipt receipt = new InstallReceipt(); + receipt.setGroupId(coordinates.groupId()); + receipt.setArtifactId(coordinates.artifactId()); + receipt.setVersion(coordinates.version()); + receipt.setInstalledAt(Instant.now().toString()); + receipt.setPaths(relativePaths); + receipt.setPendingActivation(!activateImmediately); + writeReceipt(receipt); + + if (activateImmediately) { + activateStaged(coordinates.artifactId(), relativePaths); + receipt.setPendingActivation(false); + writeReceipt(receipt); + deleteRecursive(stageRoot); + } + + Files.deleteIfExists(zipFile); + log.logBasic( + "Installed " + + coordinates.gav() + + (activateImmediately + ? ". Restart Hop to load the plugin." + : ". Staged for activation on next restart.")); + return receipt; + } catch (IOException e) { + throw new HopException("Failed to install plugin " + coordinates.gav(), e); + } + } + + /** Activate all staged plugins (startup hook). */ + public void activateAllPending() throws HopException { + Path staging = hopHome.resolve(STAGING_DIR); + if (!Files.isDirectory(staging)) { + return; + } + try { + try (var stream = Files.list(staging)) { + for (Path staged : stream.filter(Files::isDirectory).toList()) { + if (staged.getFileName().toString().startsWith(".")) { + continue; + } + List paths = collectRelativePaths(staged); + activateStaged(staged.getFileName().toString(), paths); + deleteRecursive(staged); + log.logBasic("Activated staged plugin: " + staged.getFileName()); + } + } + } catch (IOException e) { + throw new HopException("Failed to activate staged plugins", e); + } + } + + private void activateStaged(String artifactId, List relativePaths) throws HopException { + Path stageRoot = hopHome.resolve(STAGING_DIR).resolve(artifactId); + try { + for (String relative : relativePaths) { + // Never overwrite core beam libraries from a marketplace zip + if (isProtectedPath(relative)) { + log.logBasic("Skipping protected path from marketplace package: " + relative); + continue; + } + Path from = stageRoot.resolve(relative); + Path to = hopHome.resolve(relative); + if (Files.isDirectory(from)) { + Files.createDirectories(to); + } else if (Files.isRegularFile(from)) { + Files.createDirectories(to.getParent()); + Files.copy(from, to, StandardCopyOption.REPLACE_EXISTING); + } + } + } catch (IOException e) { + throw new HopException("Failed to activate staged plugin " + artifactId, e); + } + } + + static boolean isProtectedPath(String relative) { + String normalized = relative.replace('\\', '/'); + return normalized.equals("lib/beam") + || normalized.startsWith("lib/beam/") + || normalized.equals("lib/core") + || normalized.startsWith("lib/core/"); + } + + private List unzipAllowedEntries(Path zipFile, Path stageRoot) + throws IOException, HopException { + List paths = new ArrayList<>(); + try (ZipFile zip = new ZipFile(zipFile.toFile())) { + Enumeration entries = zip.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + String name = entry.getName(); + if (name == null || name.isBlank()) { + continue; + } + // Normalize and reject path traversal + Path resolved = stageRoot.resolve(name).normalize(); + if (!resolved.startsWith(stageRoot)) { + throw new HopException("Zip entry escapes target directory: " + name); + } + if (entry.isDirectory()) { + Files.createDirectories(resolved); + } else { + Files.createDirectories(resolved.getParent()); + try (InputStream in = zip.getInputStream(entry)) { + Files.copy(in, resolved, StandardCopyOption.REPLACE_EXISTING); + } + } + String relative = stageRoot.relativize(resolved).toString().replace('\\', '/'); + if (!relative.isBlank()) { + paths.add(relative); + } + } + } + return paths; + } + + private void writeReceipt(InstallReceipt receipt) throws HopException { + try { + Path dir = hopHome.resolve(RECEIPTS_DIR); + Files.createDirectories(dir); + Path file = dir.resolve(receipt.getArtifactId() + ".json"); + HopJson.newMapper().writerWithDefaultPrettyPrinter().writeValue(file.toFile(), receipt); + } catch (IOException e) { + throw new HopException("Unable to write install receipt for " + receipt.getArtifactId(), e); + } + } + + static InstallReceipt readReceipt(Path hopHome, String artifactId) throws HopException { + Path file = hopHome.resolve(RECEIPTS_DIR).resolve(artifactId + ".json"); + if (!Files.isRegularFile(file)) { + return null; + } + try { + return HopJson.newMapper().readValue(file.toFile(), InstallReceipt.class); + } catch (IOException e) { + throw new HopException("Unable to read install receipt for " + artifactId, e); + } + } + + private static List collectRelativePaths(Path stageRoot) throws IOException { + List paths = new ArrayList<>(); + Files.walkFileTree( + stageRoot, + new SimpleFileVisitor<>() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { + paths.add(stageRoot.relativize(file).toString().replace('\\', '/')); + return FileVisitResult.CONTINUE; + } + }); + return paths; + } + + static void deleteRecursive(Path root) throws IOException { + if (!Files.exists(root)) { + return; + } + Files.walkFileTree( + root, + new SimpleFileVisitor<>() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginUninstaller.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginUninstaller.java new file mode 100644 index 00000000000..4b44776da38 --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginUninstaller.java @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.install; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Set; +import org.apache.hop.core.exception.HopException; +import org.apache.hop.core.logging.ILogChannel; + +/** Removes a marketplace-installed plugin using its receipt. Never touches core-protected paths. */ +public class PluginUninstaller { + + private final ILogChannel log; + private final Path hopHome; + + public PluginUninstaller(ILogChannel log, Path hopHome) { + this.log = log; + this.hopHome = hopHome; + } + + public void uninstall(String artifactId) throws HopException { + InstallReceipt receipt = PluginInstaller.readReceipt(hopHome, artifactId); + if (receipt == null) { + throw new HopException( + "No marketplace install receipt for '" + + artifactId + + "'. Only plugins installed via the marketplace can be uninstalled this way."); + } + + // Delete files deepest-first; skip protected paths (e.g. lib/beam) + Set dirs = new HashSet<>(); + for (String relative : receipt.getPaths()) { + if (PluginInstaller.isProtectedPath(relative)) { + log.logBasic("Leaving protected path in place: " + relative); + continue; + } + Path path = hopHome.resolve(relative); + try { + if (Files.isRegularFile(path)) { + Files.deleteIfExists(path); + Path parent = path.getParent(); + if (parent != null) { + dirs.add(parent); + } + } else if (Files.isDirectory(path)) { + dirs.add(path); + } + } catch (IOException e) { + throw new HopException("Failed to remove " + path, e); + } + } + + // Remove empty plugin directories under plugins/ + dirs.stream() + .sorted(Comparator.comparingInt(p -> -p.getNameCount())) + .forEach( + dir -> { + try { + if (Files.isDirectory(dir) && isEmpty(dir) && isUnderPlugins(dir)) { + Files.deleteIfExists(dir); + } + } catch (IOException e) { + log.logError("Could not remove directory " + dir, e); + } + }); + + Path receiptFile = hopHome.resolve(PluginInstaller.RECEIPTS_DIR).resolve(artifactId + ".json"); + try { + Files.deleteIfExists(receiptFile); + } catch (IOException e) { + throw new HopException("Failed to remove receipt for " + artifactId, e); + } + log.logBasic( + "Uninstalled " + + artifactId + + ". Restart Hop so the plugin registry drops the removed classes."); + } + + private boolean isUnderPlugins(Path dir) { + Path plugins = hopHome.resolve("plugins").toAbsolutePath().normalize(); + return dir.toAbsolutePath().normalize().startsWith(plugins); + } + + private static boolean isEmpty(Path dir) throws IOException { + try (var stream = Files.list(dir)) { + return stream.findAny().isEmpty(); + } + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenCoordinates.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenCoordinates.java new file mode 100644 index 00000000000..6b663b1051b --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenCoordinates.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.resolve; + +import java.util.Objects; +import org.apache.hop.core.exception.HopException; + +/** Simple GAV for Hop plugin zips. */ +public record MavenCoordinates(String groupId, String artifactId, String version) { + + public MavenCoordinates { + Objects.requireNonNull(groupId, "groupId"); + Objects.requireNonNull(artifactId, "artifactId"); + Objects.requireNonNull(version, "version"); + } + + /** + * Parse {@code artifactId}, {@code artifactId:version}, or {@code groupId:artifactId:version}. + */ + public static MavenCoordinates parse(String spec, String defaultGroupId, String defaultVersion) + throws HopException { + if (spec == null || spec.isBlank()) { + throw new HopException("Plugin coordinate is empty"); + } + String[] parts = spec.trim().split(":"); + return switch (parts.length) { + case 1 -> new MavenCoordinates(defaultGroupId, parts[0], requireVersion(defaultVersion)); + case 2 -> new MavenCoordinates(defaultGroupId, parts[0], parts[1]); + case 3 -> new MavenCoordinates(parts[0], parts[1], parts[2]); + default -> + throw new HopException( + "Invalid coordinate '" + + spec + + "'. Use artifactId, artifactId:version, or groupId:artifactId:version"); + }; + } + + private static String requireVersion(String defaultVersion) throws HopException { + if (defaultVersion == null || defaultVersion.isBlank()) { + throw new HopException( + "No version specified and no default Hop version available. Use artifactId:version"); + } + return defaultVersion; + } + + /** Maven repository relative path to the zip artifact (no leading slash). */ + public String zipRepositoryPath() { + String groupPath = groupId.replace('.', '/'); + String fileName = artifactId + "-" + version + ".zip"; + return groupPath + "/" + artifactId + "/" + version + "/" + fileName; + } + + public String gav() { + return groupId + ":" + artifactId + ":" + version; + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java new file mode 100644 index 00000000000..f293ad86b8f --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.resolve; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.time.Duration; +import org.apache.hop.core.exception.HopException; +import org.apache.hop.core.logging.ILogChannel; + +/** Downloads Maven layout artifacts over HTTP(S). */ +public class MavenRepositoryClient { + + private final HttpClient httpClient; + private final ILogChannel log; + + public MavenRepositoryClient(ILogChannel log) { + this.log = log; + this.httpClient = + HttpClient.newBuilder() + .connectTimeout(Duration.ofSeconds(30)) + .followRedirects(HttpClient.Redirect.NORMAL) + .build(); + } + + public MavenRepositoryClient(ILogChannel log, HttpClient httpClient) { + this.log = log; + this.httpClient = httpClient; + } + + public Path downloadZip(String repositoryBaseUrl, MavenCoordinates coordinates, Path targetFile) + throws HopException { + String base = repositoryBaseUrl.endsWith("/") ? repositoryBaseUrl : repositoryBaseUrl + "/"; + String url = base + coordinates.zipRepositoryPath(); + log.logBasic("Downloading " + coordinates.gav() + " from " + url); + try { + Files.createDirectories(targetFile.getParent()); + HttpRequest request = + HttpRequest.newBuilder(URI.create(url)).timeout(Duration.ofMinutes(30)).GET().build(); + HttpResponse response = + httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream()); + if (response.statusCode() != 200) { + throw new HopException( + "HTTP " + response.statusCode() + " downloading plugin zip from " + url); + } + try (InputStream in = response.body()) { + Files.copy(in, targetFile, StandardCopyOption.REPLACE_EXISTING); + } + log.logBasic("Downloaded " + targetFile + " (" + Files.size(targetFile) + " bytes)"); + return targetFile; + } catch (IOException | InterruptedException e) { + if (e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } + throw new HopException("Failed to download plugin zip from " + url, e); + } + } +} diff --git a/plugins/misc/marketplace/src/main/resources/version.xml b/plugins/misc/marketplace/src/main/resources/version.xml new file mode 100644 index 00000000000..36ab20e22eb --- /dev/null +++ b/plugins/misc/marketplace/src/main/resources/version.xml @@ -0,0 +1,20 @@ + + + +${project.version} diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/PluginInstallerTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/PluginInstallerTest.java new file mode 100644 index 00000000000..c83bb632dcc --- /dev/null +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/PluginInstallerTest.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.install; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.sun.net.httpserver.HttpServer; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; +import org.apache.hop.core.logging.HopLogStore; +import org.apache.hop.core.logging.LogChannel; +import org.apache.hop.marketplace.config.MarketplaceConfig; +import org.apache.hop.marketplace.config.MarketplaceRepository; +import org.apache.hop.marketplace.resolve.MavenCoordinates; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +class PluginInstallerTest { + + @TempDir Path tempDir; + + @BeforeAll + static void initLogging() { + HopLogStore.init(); + } + + @Test + void protectedPaths() { + assertTrue(PluginInstaller.isProtectedPath("lib/beam/foo.jar")); + assertTrue(PluginInstaller.isProtectedPath("lib/core/bar.jar")); + assertFalse(PluginInstaller.isProtectedPath("plugins/engines/beam/hop.jar")); + assertFalse(PluginInstaller.isProtectedPath("plugins/tech/parquet/lib/x.jar")); + } + + @Test + void installAndUninstallFromLocalHttpRepo() throws Exception { + byte[] zipBytes = buildPluginZip(); + HttpServer server = HttpServer.create(new InetSocketAddress(0), 0); + String path = "/org/apache/hop/hop-test-plugin/1.0.0/hop-test-plugin-1.0.0.zip"; + server.createContext( + path, + exchange -> { + exchange.getResponseHeaders().add("Content-Type", "application/zip"); + exchange.sendResponseHeaders(200, zipBytes.length); + exchange.getResponseBody().write(zipBytes); + exchange.close(); + }); + server.start(); + try { + int port = server.getAddress().getPort(); + Path hopHome = tempDir.resolve("hop"); + Files.createDirectories(hopHome.resolve("plugins")); + + MarketplaceConfig config = new MarketplaceConfig(); + config.getRepositories().clear(); + config + .getRepositories() + .add(new MarketplaceRepository("local", "http://127.0.0.1:" + port + "/")); + + LogChannel log = new LogChannel("test"); + PluginInstaller installer = new PluginInstaller(log, hopHome, config); + MavenCoordinates coords = new MavenCoordinates("org.apache.hop", "hop-test-plugin", "1.0.0"); + installer.install(coords, true); + + Path pluginJar = hopHome.resolve("plugins/tech/test/plugin.jar"); + assertTrue(Files.isRegularFile(pluginJar)); + assertTrue( + Files.isRegularFile( + hopHome.resolve(PluginInstaller.RECEIPTS_DIR).resolve("hop-test-plugin.json"))); + // protected path from zip must not be written + assertFalse(Files.exists(hopHome.resolve("lib/beam/evil.jar"))); + + new PluginUninstaller(log, hopHome).uninstall("hop-test-plugin"); + assertFalse(Files.exists(pluginJar)); + assertFalse( + Files.exists( + hopHome.resolve(PluginInstaller.RECEIPTS_DIR).resolve("hop-test-plugin.json"))); + } finally { + server.stop(0); + } + } + + private static byte[] buildPluginZip() throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try (ZipOutputStream zos = new ZipOutputStream(bos)) { + zos.putNextEntry(new ZipEntry("plugins/tech/test/plugin.jar")); + zos.write("fake-jar".getBytes(StandardCharsets.UTF_8)); + zos.closeEntry(); + zos.putNextEntry(new ZipEntry("plugins/tech/test/version.xml")); + zos.write("1.0.0".getBytes(StandardCharsets.UTF_8)); + zos.closeEntry(); + // Should be ignored on activate + zos.putNextEntry(new ZipEntry("lib/beam/evil.jar")); + zos.write("nope".getBytes(StandardCharsets.UTF_8)); + zos.closeEntry(); + } + return bos.toByteArray(); + } +} diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/resolve/MavenCoordinatesTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/resolve/MavenCoordinatesTest.java new file mode 100644 index 00000000000..9918a0a8b36 --- /dev/null +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/resolve/MavenCoordinatesTest.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.resolve; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.apache.hop.core.exception.HopException; +import org.junit.jupiter.api.Test; + +class MavenCoordinatesTest { + + @Test + void parseArtifactOnly() throws Exception { + MavenCoordinates c = MavenCoordinates.parse("hop-tech-parquet", "org.apache.hop", "2.19.0"); + assertEquals("org.apache.hop", c.groupId()); + assertEquals("hop-tech-parquet", c.artifactId()); + assertEquals("2.19.0", c.version()); + } + + @Test + void parseArtifactVersion() throws Exception { + MavenCoordinates c = + MavenCoordinates.parse("hop-engines-spark:2.19.0-SNAPSHOT", "org.apache.hop", "x"); + assertEquals("hop-engines-spark", c.artifactId()); + assertEquals("2.19.0-SNAPSHOT", c.version()); + } + + @Test + void parseFullGav() throws Exception { + MavenCoordinates c = MavenCoordinates.parse("org.example:foo:1.0", "ignored", "ignored"); + assertEquals("org.example", c.groupId()); + assertEquals("foo", c.artifactId()); + assertEquals("1.0", c.version()); + } + + @Test + void zipPath() { + MavenCoordinates c = new MavenCoordinates("org.apache.hop", "hop-tech-parquet", "2.19.0"); + assertEquals( + "org/apache/hop/hop-tech-parquet/2.19.0/hop-tech-parquet-2.19.0.zip", + c.zipRepositoryPath()); + } + + @Test + void missingVersionFails() { + HopException ex = + assertThrows( + HopException.class, () -> MavenCoordinates.parse("hop-tech-parquet", "g", null)); + assertTrue(ex.getMessage().toLowerCase().contains("version")); + } +} diff --git a/plugins/misc/pom.xml b/plugins/misc/pom.xml index 8c6e6053286..8af8f52b7ae 100644 --- a/plugins/misc/pom.xml +++ b/plugins/misc/pom.xml @@ -35,6 +35,7 @@ git import mail + marketplace passwords projects py4j diff --git a/tools/check-assembly-size.sh b/tools/check-assembly-size.sh new file mode 100755 index 00000000000..b6072a4e9ba --- /dev/null +++ b/tools/check-assembly-size.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Fail if published mega-artifacts exceed the ASF Artifactory package limit. +set -euo pipefail + +# 850 MiB ASF limit; use a safer default threshold of 800 MiB +MAX_BYTES=${MAX_ASSEMBLY_BYTES:-838860800} +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +FAILED=0 + +check() { + local label="$1" + local file="$2" + if [[ ! -f "$file" ]]; then + echo "SKIP (missing): $label — $file" + return 0 + fi + local size + size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file") + local mb + mb=$(awk -v s="$size" 'BEGIN { printf "%.1f", s/1024/1024 }') + if (( size > MAX_BYTES )); then + echo "FAIL: $label is ${mb} MB ($(printf '%s' "$size") bytes) > limit $(awk -v s="$MAX_BYTES" 'BEGIN { printf "%.0f", s/1024/1024 }') MB" + FAILED=1 + else + echo "OK: $label is ${mb} MB" + fi +} + +shopt -s nullglob +for f in "$ROOT"/assemblies/client/target/hop-client-*.zip; do + check "hop-client" "$f" +done +for f in "$ROOT"/assemblies/plugins/target/hop-assemblies-plugins-*.zip; do + # plugins aggregate should also stay under the limit + check "hop-assemblies-plugins" "$f" +done + +if (( FAILED )); then + echo "Assembly size check failed (limit ${MAX_BYTES} bytes)." + exit 1 +fi +echo "Assembly size check passed." From c13d65f7541d70cd3974d5125fc8534dd8c85061 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Sun, 19 Jul 2026 21:25:44 +0200 Subject: [PATCH 02/28] issue #7547: marketplace GUI and Wave 1 plugins for IT/Docker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Tools → Marketplace dialog for install/uninstall of optional plugins, a Wave 1 catalog, and install-wave1-plugins.sh wired into Jenkins and run-tests-docker so integration tests still get spark, beam, cassandra, and other marketplace-only plugins. --- Jenkinsfile | 2 + .../integration-tests/unit-tests.Dockerfile | 4 + integration-tests/scripts/run-tests-docker.sh | 10 + plugins/misc/marketplace/README.md | 17 + .../catalog/OptionalPluginCatalog.java | 126 ++++++++ .../catalog/OptionalPluginInfo.java | 44 +++ .../command/MarketplaceCommand.java | 2 +- .../marketplace/gui/MarketplaceDialog.java | 301 ++++++++++++++++++ .../marketplace/gui/MarketplaceGuiPlugin.java | 61 ++++ .../marketplace/install/PluginInstaller.java | 2 +- .../gui/messages/messages_en_US.properties | 45 +++ tools/install-wave1-plugins.sh | 61 ++++ 12 files changed, 673 insertions(+), 2 deletions(-) create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginInfo.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceGuiPlugin.java create mode 100644 plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties create mode 100755 tools/install-wave1-plugins.sh diff --git a/Jenkinsfile b/Jenkinsfile index b551226d30d..406bc894975 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -128,6 +128,8 @@ pipeline { } steps{ sh "unzip ./assemblies/client/target/hop-client-*.zip -d ./assemblies/client/target/" + // Optional Wave 1 plugins are marketplace-only; install into the extracted client for IT/Docker + sh "./tools/install-wave1-plugins.sh ./assemblies/client/target/hop" sh "unzip ./assemblies/web/target/hop.war -d ./assemblies/web/target/webapp" } } diff --git a/docker/integration-tests/unit-tests.Dockerfile b/docker/integration-tests/unit-tests.Dockerfile index c10cccd66b3..90e58676f12 100644 --- a/docker/integration-tests/unit-tests.Dockerfile +++ b/docker/integration-tests/unit-tests.Dockerfile @@ -74,6 +74,10 @@ RUN apt-get update \ COPY --chown=${JENKINS_USER}:${JENKINS_GROUP} ./assemblies/client/target/hop ${DEPLOYMENT_PATH}/hop +# Wave 1 optional plugins (marketplace) — expect host to have run tools/install-wave1-plugins.sh +# into assemblies/client/target/hop before this build (run-tests-docker.sh and Jenkins do this). +# If a plugin is still missing at runtime, corresponding ITs will fail clearly. + # Copy gcp key COPY --chown=${JENKINS_USER}:${JENKINS_GROUP} ${GCP_KEY_FILE} /tmp/google-key-apache-hop-it.json diff --git a/integration-tests/scripts/run-tests-docker.sh b/integration-tests/scripts/run-tests-docker.sh index 1d56361d104..dbcafc7536d 100755 --- a/integration-tests/scripts/run-tests-docker.sh +++ b/integration-tests/scripts/run-tests-docker.sh @@ -198,6 +198,16 @@ else echo "Skipping client unzip (CLIENT_UNZIP=${CLIENT_UNZIP}, using existing ${HOP_DIR})" fi +# Optional plugins (Wave 1) are not in hop-client.zip; install from reactor zips for ITs. +if [ -x "${REPO_ROOT}/tools/install-wave1-plugins.sh" ]; then + echo "Installing Wave 1 marketplace plugins into ${HOP_DIR} for integration tests" + "${REPO_ROOT}/tools/install-wave1-plugins.sh" "${HOP_DIR}" || { + echo "WARNING: install-wave1-plugins.sh reported errors; some ITs may fail if plugins are missing" + } +else + echo "WARNING: tools/install-wave1-plugins.sh not found; optional plugins not installed into ${HOP_DIR}" +fi + # Versioned Spark client packs are not in the client zip. Re-materialise after unzip so # HOP_SPARK_CLIENT_VERSION=… finds lib/spark-clients// (includes spark-streaming, etc.). # Also copy the selected pack into lib/spark-client/ so the default driver classpath always diff --git a/plugins/misc/marketplace/README.md b/plugins/misc/marketplace/README.md index 8a1fbadd3fe..8f1d551ec5b 100644 --- a/plugins/misc/marketplace/README.md +++ b/plugins/misc/marketplace/README.md @@ -59,8 +59,25 @@ After install or uninstall, **restart Hop** so the plugin registry reloads. For local testing see `docker/marketplace-artifactory/README.md`. +## GUI + +Hop GUI → **Tools → Marketplace…** lists Wave 1 optional plugins, installs from the +configured Maven repository, and uninstalls marketplace-managed installs. Restart +Hop after install/uninstall. + ## Beam note `hop-engines-beam` marketplace package is the **plugin** (`plugins/engines/beam`) only. `lib/beam` remains part of the default Hop distribution and is never removed by marketplace uninstall. + +## Integration tests / full local install + +Optional plugins are **not** in `hop-client.zip`. For ITs (or a full local install): + +```bash +unzip assemblies/client/target/hop-client-*.zip -d assemblies/client/target/ +./tools/install-wave1-plugins.sh assemblies/client/target/hop +``` + +`integration-tests/scripts/run-tests-docker.sh` and Jenkins run this automatically. diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java new file mode 100644 index 00000000000..18c18ab905b --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java @@ -0,0 +1,126 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.catalog; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Built-in catalog of Wave 1 optional plugins until remote Maven search is available in the GUI. + */ +public final class OptionalPluginCatalog { + + private static final List WAVE1 = new ArrayList<>(); + + static { + WAVE1.add( + new OptionalPluginInfo( + "hop-engines-spark", + "Native Spark engine", + "Engines", + "Run pipelines on Apache Spark (local or cluster).", + "plugins/engines/spark")); + WAVE1.add( + new OptionalPluginInfo( + "hop-engines-beam", + "Apache Beam engine", + "Engines", + "Beam pipeline engine and transforms (plugin only; lib/beam stays in the core install).", + "plugins/engines/beam")); + WAVE1.add( + new OptionalPluginInfo( + "hop-transform-script", + "Script transform", + "Transforms", + "Scripting transform with embedded language runtimes.", + "plugins/transforms/script")); + WAVE1.add( + new OptionalPluginInfo( + "hop-tech-cassandra", + "Cassandra", + "Technology", + "Apache Cassandra input/output and related tech.", + "plugins/tech/cassandra")); + WAVE1.add( + new OptionalPluginInfo( + "hop-transform-tika", + "Apache Tika", + "Transforms", + "Extract text and metadata from documents via Apache Tika.", + "plugins/transforms/tika")); + WAVE1.add( + new OptionalPluginInfo( + "hop-transform-drools", + "Drools", + "Transforms", + "Business rules with Drools.", + "plugins/transforms/drools")); + WAVE1.add( + new OptionalPluginInfo( + "hop-tech-parquet", + "Parquet", + "Technology", + "Parquet file format support.", + "plugins/tech/parquet")); + WAVE1.add( + new OptionalPluginInfo( + "hop-transform-stanfordnlp", + "Stanford NLP", + "Transforms", + "Natural language processing with Stanford NLP.", + "plugins/transforms/stanfordnlp")); + WAVE1.add( + new OptionalPluginInfo( + "hop-tech-arrow", + "Apache Arrow", + "Technology", + "Apache Arrow integration.", + "plugins/tech/arrow")); + WAVE1.add( + new OptionalPluginInfo( + "hop-tech-dropbox", + "Dropbox", + "Technology", + "Dropbox VFS and related support.", + "plugins/tech/dropbox")); + WAVE1.add( + new OptionalPluginInfo( + "hop-transform-edi2xml", + "EDI to XML", + "Transforms", + "Convert EDI messages to XML.", + "plugins/transforms/edi2xml")); + } + + private OptionalPluginCatalog() {} + + public static List listWave1() { + return Collections.unmodifiableList(WAVE1); + } + + public static boolean isInstalledOnDisk(Path hopHome, OptionalPluginInfo info) { + if (info.getInstallPath() == null) { + return false; + } + Path path = hopHome.resolve(info.getInstallPath()); + return Files.isDirectory(path); + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginInfo.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginInfo.java new file mode 100644 index 00000000000..866844c5edc --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginInfo.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.catalog; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class OptionalPluginInfo { + private String artifactId; + private String name; + private String category; + private String description; + private String installPath; + + public OptionalPluginInfo() { + // Jackson / default + } + + public OptionalPluginInfo( + String artifactId, String name, String category, String description, String installPath) { + this.artifactId = artifactId; + this.name = name; + this.category = category; + this.description = description; + this.installPath = installPath; + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java index 002c3669e06..c48f9e68e3e 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java @@ -83,7 +83,7 @@ public void run() { cmd.usage(System.out); } - static String resolveDefaultVersion(MarketplaceConfig config) { + public static String resolveDefaultVersion(MarketplaceConfig config) { if (StringUtils.isNotBlank(config.getDefaultVersion())) { return config.getDefaultVersion(); } diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java new file mode 100644 index 00000000000..f832011976c --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java @@ -0,0 +1,301 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.gui; + +import java.nio.file.Path; +import java.util.List; +import org.apache.hop.core.Const; +import org.apache.hop.core.logging.ILogChannel; +import org.apache.hop.core.logging.LogChannel; +import org.apache.hop.i18n.BaseMessages; +import org.apache.hop.marketplace.catalog.OptionalPluginCatalog; +import org.apache.hop.marketplace.catalog.OptionalPluginInfo; +import org.apache.hop.marketplace.command.MarketplaceCommand; +import org.apache.hop.marketplace.config.MarketplaceConfig; +import org.apache.hop.marketplace.install.HopHome; +import org.apache.hop.marketplace.install.InstallReceipt; +import org.apache.hop.marketplace.install.PluginInstaller; +import org.apache.hop.marketplace.install.PluginUninstaller; +import org.apache.hop.marketplace.resolve.MavenCoordinates; +import org.apache.hop.ui.core.PropsUi; +import org.apache.hop.ui.core.dialog.ErrorDialog; +import org.apache.hop.ui.core.dialog.MessageBox; +import org.apache.hop.ui.core.gui.GuiResource; +import org.apache.hop.ui.core.gui.WindowProperty; +import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Dialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; + +/** Tools → Marketplace dialog: list optional plugins and install/uninstall from a Maven repo. */ +public class MarketplaceDialog extends Dialog { + + private static final Class PKG = MarketplaceGuiPlugin.class; + + private final PropsUi props; + private final ILogChannel log = new LogChannel("Marketplace"); + + private Shell shell; + private Table wTable; + private Text wRepo; + private Label wStatus; + private Path hopHome; + private MarketplaceConfig config; + + public MarketplaceDialog(Shell parent) { + super(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX); + this.props = PropsUi.getInstance(); + } + + public void open() { + Shell parent = getParent(); + shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX); + props.setLook(shell); + shell.setImage(GuiResource.getInstance().getImageHopUi()); + shell.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Shell.Title")); + + FormLayout formLayout = new FormLayout(); + formLayout.marginWidth = Const.FORM_MARGIN; + formLayout.marginHeight = Const.FORM_MARGIN; + shell.setLayout(formLayout); + + try { + hopHome = HopHome.resolve(); + config = MarketplaceConfig.load(); + } catch (Exception e) { + new ErrorDialog( + parent, + BaseMessages.getString(PKG, "MarketplaceDialog.Error.Header"), + BaseMessages.getString(PKG, "MarketplaceDialog.Error.ResolveHome"), + e); + return; + } + + // Repository URL + Label wlRepo = new Label(shell, SWT.RIGHT); + props.setLook(wlRepo); + wlRepo.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Repository.Label")); + FormData fdlRepo = new FormData(); + fdlRepo.left = new FormAttachment(0, 0); + fdlRepo.top = new FormAttachment(0, 0); + wlRepo.setLayoutData(fdlRepo); + + wRepo = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + props.setLook(wRepo); + wRepo.setText(config.primaryRepositoryUrl()); + wRepo.setEditable(false); + FormData fdRepo = new FormData(); + fdRepo.left = new FormAttachment(wlRepo, Const.MARGIN); + fdRepo.top = new FormAttachment(wlRepo, 0, SWT.CENTER); + fdRepo.right = new FormAttachment(100, 0); + wRepo.setLayoutData(fdRepo); + + // Buttons (bottom) + Button wClose = new Button(shell, SWT.PUSH); + wClose.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.Close")); + wClose.addListener(SWT.Selection, e -> close()); + + Button wUninstall = new Button(shell, SWT.PUSH); + wUninstall.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.Uninstall")); + wUninstall.addListener(SWT.Selection, e -> uninstallSelected()); + + Button wInstall = new Button(shell, SWT.PUSH); + wInstall.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.Install")); + wInstall.addListener(SWT.Selection, e -> installSelected()); + + Button wRefresh = new Button(shell, SWT.PUSH); + wRefresh.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.Refresh")); + wRefresh.addListener(SWT.Selection, e -> refreshTable()); + + BaseTransformDialog.positionBottomButtons( + shell, new Button[] {wInstall, wUninstall, wRefresh, wClose}, Const.MARGIN, null); + + // Status + wStatus = new Label(shell, SWT.LEFT); + props.setLook(wStatus); + wStatus.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Status.RestartHint")); + FormData fdStatus = new FormData(); + fdStatus.left = new FormAttachment(0, 0); + fdStatus.right = new FormAttachment(100, 0); + fdStatus.bottom = new FormAttachment(wClose, -Const.MARGIN * 2); + wStatus.setLayoutData(fdStatus); + + // Table + wTable = new Table(shell, SWT.BORDER | SWT.FULL_SELECTION | SWT.SINGLE | SWT.V_SCROLL); + props.setLook(wTable); + wTable.setHeaderVisible(true); + wTable.setLinesVisible(true); + + TableColumn colName = new TableColumn(wTable, SWT.LEFT); + colName.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Column.Name")); + colName.setWidth(180); + TableColumn colArtifact = new TableColumn(wTable, SWT.LEFT); + colArtifact.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Column.Artifact")); + colArtifact.setWidth(200); + TableColumn colCategory = new TableColumn(wTable, SWT.LEFT); + colCategory.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Column.Category")); + colCategory.setWidth(100); + TableColumn colStatus = new TableColumn(wTable, SWT.LEFT); + colStatus.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Column.Status")); + colStatus.setWidth(100); + TableColumn colDesc = new TableColumn(wTable, SWT.LEFT); + colDesc.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Column.Description")); + colDesc.setWidth(320); + + FormData fdTable = new FormData(); + fdTable.left = new FormAttachment(0, 0); + fdTable.top = new FormAttachment(wRepo, Const.MARGIN * 2); + fdTable.right = new FormAttachment(100, 0); + fdTable.bottom = new FormAttachment(wStatus, -Const.MARGIN); + wTable.setLayoutData(fdTable); + + refreshTable(); + + BaseTransformDialog.setSize(shell); + shell.open(); + Display display = parent.getDisplay(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + } + + private void refreshTable() { + wTable.removeAll(); + List plugins = OptionalPluginCatalog.listWave1(); + for (OptionalPluginInfo info : plugins) { + TableItem item = new TableItem(wTable, SWT.NONE); + item.setText(0, Const.NVL(info.getName(), "")); + item.setText(1, Const.NVL(info.getArtifactId(), "")); + item.setText(2, Const.NVL(info.getCategory(), "")); + boolean onDisk = OptionalPluginCatalog.isInstalledOnDisk(hopHome, info); + InstallReceipt receipt = null; + try { + receipt = PluginInstaller.readReceipt(hopHome, info.getArtifactId()); + } catch (Exception e) { + log.logError("Unable to read receipt for " + info.getArtifactId(), e); + } + String status; + if (onDisk && receipt != null) { + status = + BaseMessages.getString(PKG, "MarketplaceDialog.Status.Installed") + + " (" + + receipt.getVersion() + + ")"; + } else if (onDisk) { + status = BaseMessages.getString(PKG, "MarketplaceDialog.Status.Present"); + } else { + status = BaseMessages.getString(PKG, "MarketplaceDialog.Status.NotInstalled"); + } + item.setText(3, status); + item.setText(4, Const.NVL(info.getDescription(), "")); + item.setData(info); + } + } + + private OptionalPluginInfo selected() { + TableItem[] items = wTable.getSelection(); + if (items == null || items.length == 0) { + return null; + } + return (OptionalPluginInfo) items[0].getData(); + } + + private void installSelected() { + OptionalPluginInfo info = selected(); + if (info == null) { + return; + } + try { + // Re-read repo URL in case config changed + config = MarketplaceConfig.load(); + String version = MarketplaceCommand.resolveDefaultVersion(config); + MavenCoordinates coords = + new MavenCoordinates(config.getGroupId(), info.getArtifactId(), version); + wStatus.setText( + BaseMessages.getString(PKG, "MarketplaceDialog.Status.Installing", coords.gav())); + shell.update(); + new PluginInstaller(log, hopHome, config).install(coords, true); + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION); + box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Install.Done.Header")); + box.setMessage( + BaseMessages.getString(PKG, "MarketplaceDialog.Install.Done.Message", coords.gav())); + box.open(); + refreshTable(); + wStatus.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Status.RestartHint")); + } catch (Exception e) { + new ErrorDialog( + shell, + BaseMessages.getString(PKG, "MarketplaceDialog.Error.Header"), + BaseMessages.getString(PKG, "MarketplaceDialog.Install.Error", info.getArtifactId()), + e); + } + } + + private void uninstallSelected() { + OptionalPluginInfo info = selected(); + if (info == null) { + return; + } + try { + InstallReceipt receipt = PluginInstaller.readReceipt(hopHome, info.getArtifactId()); + if (receipt == null) { + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_WARNING); + box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Uninstall.NoReceipt.Header")); + box.setMessage( + BaseMessages.getString( + PKG, "MarketplaceDialog.Uninstall.NoReceipt.Message", info.getArtifactId())); + box.open(); + return; + } + MessageBox confirm = new MessageBox(shell, SWT.YES | SWT.NO | SWT.ICON_QUESTION); + confirm.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Uninstall.Confirm.Header")); + confirm.setMessage( + BaseMessages.getString( + PKG, "MarketplaceDialog.Uninstall.Confirm.Message", info.getArtifactId())); + if (confirm.open() != SWT.YES) { + return; + } + new PluginUninstaller(log, hopHome).uninstall(info.getArtifactId()); + refreshTable(); + wStatus.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Status.RestartHint")); + } catch (Exception e) { + new ErrorDialog( + shell, + BaseMessages.getString(PKG, "MarketplaceDialog.Error.Header"), + BaseMessages.getString(PKG, "MarketplaceDialog.Uninstall.Error", info.getArtifactId()), + e); + } + } + + private void close() { + props.setScreen(new WindowProperty(shell)); + shell.dispose(); + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceGuiPlugin.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceGuiPlugin.java new file mode 100644 index 00000000000..0a272035153 --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceGuiPlugin.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.gui; + +import org.apache.hop.core.gui.plugin.GuiPlugin; +import org.apache.hop.core.gui.plugin.menu.GuiMenuElement; +import org.apache.hop.ui.core.dialog.ErrorDialog; +import org.apache.hop.ui.hopgui.HopGui; + +/** GUI entry points for the Hop plugin marketplace. */ +@GuiPlugin +public class MarketplaceGuiPlugin { + + public static final Class PKG = MarketplaceGuiPlugin.class; + + public static final String ID_MAIN_MENU_TOOLS_MARKETPLACE = "40200-menu-tools-marketplace"; + + private static MarketplaceGuiPlugin instance; + + public MarketplaceGuiPlugin() { + // Instantiated by the GUI plugin system + } + + public static MarketplaceGuiPlugin getInstance() { + if (instance == null) { + instance = new MarketplaceGuiPlugin(); + } + return instance; + } + + @GuiMenuElement( + root = HopGui.ID_MAIN_MENU, + id = ID_MAIN_MENU_TOOLS_MARKETPLACE, + label = "i18n::MarketplaceGuiPlugin.Menu.Marketplace.Text", + parentId = HopGui.ID_MAIN_MENU_TOOLS_PARENT_ID, + image = "ui/images/plugin.svg", + separator = true) + public void menuToolsMarketplace() { + HopGui hopGui = HopGui.getInstance(); + try { + new MarketplaceDialog(hopGui.getShell()).open(); + } catch (Exception e) { + new ErrorDialog(hopGui.getShell(), "Marketplace", "Unable to open the marketplace dialog", e); + } + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java index d06fd8bbe9c..5d434b0a53d 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java @@ -214,7 +214,7 @@ private void writeReceipt(InstallReceipt receipt) throws HopException { } } - static InstallReceipt readReceipt(Path hopHome, String artifactId) throws HopException { + public static InstallReceipt readReceipt(Path hopHome, String artifactId) throws HopException { Path file = hopHome.resolve(RECEIPTS_DIR).resolve(artifactId + ".json"); if (!Files.isRegularFile(file)) { return null; diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties new file mode 100644 index 00000000000..23200e7372d --- /dev/null +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties @@ -0,0 +1,45 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +MarketplaceGuiPlugin.Menu.Marketplace.Text=Marketplace... + +MarketplaceDialog.Shell.Title=Plugin Marketplace +MarketplaceDialog.Repository.Label=Repository +MarketplaceDialog.Column.Name=Name +MarketplaceDialog.Column.Artifact=Artifact +MarketplaceDialog.Column.Category=Category +MarketplaceDialog.Column.Status=Status +MarketplaceDialog.Column.Description=Description +MarketplaceDialog.Button.Install=Install +MarketplaceDialog.Button.Uninstall=Uninstall +MarketplaceDialog.Button.Refresh=Refresh +MarketplaceDialog.Button.Close=Close +MarketplaceDialog.Status.Installed=Installed +MarketplaceDialog.Status.Present=Present on disk +MarketplaceDialog.Status.NotInstalled=Not installed +MarketplaceDialog.Status.RestartHint=Restart Hop after install or uninstall so plugins are reloaded. +MarketplaceDialog.Status.Installing=Installing {0}... +MarketplaceDialog.Error.Header=Marketplace error +MarketplaceDialog.Error.ResolveHome=Could not determine the Hop installation directory (set HOP_HOME or start Hop from the install root). +MarketplaceDialog.Install.Done.Header=Plugin installed +MarketplaceDialog.Install.Done.Message=Installed {0}.\n\nPlease restart Hop to load the plugin. +MarketplaceDialog.Install.Error=Failed to install {0} +MarketplaceDialog.Uninstall.Confirm.Header=Uninstall plugin +MarketplaceDialog.Uninstall.Confirm.Message=Remove marketplace-installed plugin {0}? +MarketplaceDialog.Uninstall.NoReceipt.Header=Cannot uninstall +MarketplaceDialog.Uninstall.NoReceipt.Message=No marketplace install receipt for {0}. Only plugins installed via the marketplace can be uninstalled here. +MarketplaceDialog.Uninstall.Error=Failed to uninstall {0} diff --git a/tools/install-wave1-plugins.sh b/tools/install-wave1-plugins.sh new file mode 100755 index 00000000000..ad65957acfe --- /dev/null +++ b/tools/install-wave1-plugins.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unpack Wave 1 marketplace plugin zips into a Hop install (e.g. for IT images). +# Usage: +# ./tools/install-wave1-plugins.sh [HOP_HOME] +# Default HOP_HOME: assemblies/client/target/hop +# +# Requires plugin modules to have been packaged (*.zip under plugins/**/target/). +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +HOP_HOME="${1:-${ROOT}/assemblies/client/target/hop}" +VERSION="${HOP_VERSION:-2.19.0-SNAPSHOT}" + +if [[ ! -d "${HOP_HOME}" ]]; then + echo "Hop home not found: ${HOP_HOME}" >&2 + echo "Unzip hop-client first, or pass an existing install path." >&2 + exit 1 +fi + +# artifactId|relative path to zip under repo root +PLUGINS=( + "hop-engines-spark|plugins/engines/spark/target/hop-engines-spark-${VERSION}.zip" + "hop-engines-beam|plugins/engines/beam/target/hop-engines-beam-${VERSION}.zip" + "hop-transform-script|plugins/transforms/script/target/hop-transform-script-${VERSION}.zip" + "hop-tech-cassandra|plugins/tech/cassandra/target/hop-tech-cassandra-${VERSION}.zip" + "hop-transform-tika|plugins/transforms/tika/target/hop-transform-tika-${VERSION}.zip" + "hop-transform-drools|plugins/transforms/drools/target/hop-transform-drools-${VERSION}.zip" + "hop-tech-parquet|plugins/tech/parquet/target/hop-tech-parquet-${VERSION}.zip" + "hop-transform-stanfordnlp|plugins/transforms/stanfordnlp/target/hop-transform-stanfordnlp-${VERSION}.zip" + "hop-tech-arrow|plugins/tech/arrow/target/hop-tech-arrow-${VERSION}.zip" + "hop-tech-dropbox|plugins/tech/dropbox/target/hop-tech-dropbox-${VERSION}.zip" + "hop-transform-edi2xml|plugins/transforms/edi2xml/target/hop-transform-edi2xml-${VERSION}.zip" +) + +installed=0 +skipped=0 +for entry in "${PLUGINS[@]}"; do + id="${entry%%|*}" + rel="${entry#*|}" + zip="${ROOT}/${rel}" + if [[ ! -f "${zip}" ]]; then + echo "SKIP (not built): ${id} — ${rel}" + skipped=$((skipped + 1)) + continue + fi + echo "Installing ${id} from ${rel}" + unzip -o -q "${zip}" -d "${HOP_HOME}" + installed=$((installed + 1)) +done + +echo "Wave 1 plugins: installed=${installed} skipped=${skipped} into ${HOP_HOME}" +# Note: beam plugin zip does not include lib/beam (already in core client). From 202061fa653569ee7767c2ec85f31c7356714cd0 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Sun, 19 Jul 2026 21:41:27 +0200 Subject: [PATCH 03/28] issue #7547: hop-env.yaml apply/validate and hop-run drift check Add declarative environment files for marketplace plugins and JDBC dependencies: apply (--prune), validate, sample hop-env.yaml, and an optional HopRunStart enforcement when enforceOnRun is set. --- plugins/misc/marketplace/README.md | 29 ++ plugins/misc/marketplace/pom.xml | 18 +- .../marketplace/src/assembly/assembly.xml | 7 + .../command/MarketplaceCommand.java | 135 +++++++- .../marketplace/env/EnvironmentApplier.java | 324 ++++++++++++++++++ .../hop/marketplace/env/EnvironmentDrift.java | 55 +++ .../marketplace/env/HopEnvironmentLoader.java | 64 ++++ .../marketplace/env/HopEnvironmentSpec.java | 79 +++++ .../HopRunEnvironmentCheckExtensionPoint.java | 98 ++++++ .../src/main/samples/hop-env.example.yaml | 34 ++ .../env/EnvironmentApplierTest.java | 120 +++++++ .../env/HopEnvironmentLoaderTest.java | 88 +++++ 12 files changed, 1049 insertions(+), 2 deletions(-) create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/EnvironmentApplier.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/EnvironmentDrift.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentLoader.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentSpec.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/xp/HopRunEnvironmentCheckExtensionPoint.java create mode 100644 plugins/misc/marketplace/src/main/samples/hop-env.example.yaml create mode 100644 plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/env/EnvironmentApplierTest.java create mode 100644 plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/env/HopEnvironmentLoaderTest.java diff --git a/plugins/misc/marketplace/README.md b/plugins/misc/marketplace/README.md index 8f1d551ec5b..c83dd3869d5 100644 --- a/plugins/misc/marketplace/README.md +++ b/plugins/misc/marketplace/README.md @@ -32,6 +32,11 @@ From the Hop install directory (`HOP_HOME`): ./hop marketplace install hop-engines-beam ./hop marketplace list ./hop marketplace uninstall hop-tech-parquet + +# Declarative environment (CI/CD / Docker) +./hop marketplace apply -f hop-env.yaml +./hop marketplace apply -f hop-env.yaml --prune +./hop marketplace validate -f hop-env.yaml ``` Coordinates: @@ -42,6 +47,30 @@ Coordinates: After install or uninstall, **restart Hop** so the plugin registry reloads. +### hop-env.yaml + +See `config/projects/samples/marketplace/hop-env.example.yaml` (after install) or +`plugins/misc/marketplace/src/main/samples/hop-env.example.yaml` in source. + +```yaml +version: "1.0" +hopVersion: "2.19.0" +enforceOnRun: false # set true to hard-fail hop-run on drift +repositories: + - id: central + url: "https://repo1.maven.org/maven2/" +plugins: + - artifactId: hop-tech-parquet + version: "2.19.0" +dependencies: + - groupId: org.postgresql + artifactId: postgresql + version: "42.7.3" +``` + +`hop-run` checks the env file only when `enforceOnRun: true` or `-Dhop.env.enforce=true`. +Discovery order: `-f` / `HOP_ENV_FILE` / `PROJECT_HOME/hop-env.yaml` / `$HOP_HOME/hop-env.yaml`. + ## Config (`hop-config.json`) ```json diff --git a/plugins/misc/marketplace/pom.xml b/plugins/misc/marketplace/pom.xml index 2b09cc2b5a4..ac66abb4cba 100644 --- a/plugins/misc/marketplace/pom.xml +++ b/plugins/misc/marketplace/pom.xml @@ -29,7 +29,23 @@ jar Hop Plugins Miscellaneous Marketplace + + + + org.apache.hop + hop-libs + ${project.version} + pom + import + + + + - + + + org.yaml + snakeyaml + diff --git a/plugins/misc/marketplace/src/assembly/assembly.xml b/plugins/misc/marketplace/src/assembly/assembly.xml index db9d323ad9f..cc7f1ab7cc9 100644 --- a/plugins/misc/marketplace/src/assembly/assembly.xml +++ b/plugins/misc/marketplace/src/assembly/assembly.xml @@ -33,6 +33,13 @@ + + + ${project.basedir}/src/main/samples + config/projects/samples/marketplace/ + + + ${maven.multiModuleProjectDirectory}/assemblies/shared/hop-plugin-libs.xml diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java index c48f9e68e3e..72dbd8d3110 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java @@ -31,6 +31,10 @@ import org.apache.hop.hop.plugin.HopCommand; import org.apache.hop.hop.plugin.IHopCommand; import org.apache.hop.marketplace.config.MarketplaceConfig; +import org.apache.hop.marketplace.env.EnvironmentApplier; +import org.apache.hop.marketplace.env.EnvironmentDrift; +import org.apache.hop.marketplace.env.HopEnvironmentLoader; +import org.apache.hop.marketplace.env.HopEnvironmentSpec; import org.apache.hop.marketplace.install.HopHome; import org.apache.hop.marketplace.install.InstallReceipt; import org.apache.hop.marketplace.install.PluginInstaller; @@ -40,6 +44,7 @@ import org.apache.hop.metadata.serializer.multi.MultiMetadataProvider; import picocli.CommandLine; import picocli.CommandLine.Command; +import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; @Getter @@ -51,7 +56,9 @@ subcommands = { MarketplaceCommand.InstallCommand.class, MarketplaceCommand.UninstallCommand.class, - MarketplaceCommand.ListCommand.class + MarketplaceCommand.ListCommand.class, + MarketplaceCommand.ApplyCommand.class, + MarketplaceCommand.ValidateCommand.class }) @HopCommand(id = "marketplace", description = "Hop plugin marketplace") public class MarketplaceCommand implements Runnable, IHopCommand, IHasHopMetadataProvider { @@ -199,4 +206,130 @@ public void run() { } } } + + @Command( + name = "apply", + description = + "Install plugins and dependencies declared in hop-env.yaml (or .json). Optional --prune" + + " removes marketplace plugins not listed in the file.") + static class ApplyCommand extends MarketplaceSubCommand { + @Option( + names = {"-f", "--file"}, + required = true, + description = "Path to hop-env.yaml or hop-env.json") + private String file; + + @Option( + names = {"--prune"}, + description = + "Uninstall marketplace-installed plugins that are not listed in the environment file") + private boolean prune; + + @Override + public void run() { + try { + MarketplaceConfig config = MarketplaceConfig.load(); + if (!config.isEnabled()) { + throw new HopException("Marketplace is disabled in hop-config.json"); + } + Path hopHome = HopHome.resolve(); + Path envPath = Path.of(file).toAbsolutePath().normalize(); + HopEnvironmentSpec env = HopEnvironmentLoader.load(envPath); + new EnvironmentApplier(log, hopHome, config).apply(env, prune); + System.out.println( + "Environment applied from " + + envPath + + ". Restart Hop (or re-run) so new plugins are loaded."); + } catch (Exception e) { + System.err.println("ERROR: " + e.getMessage()); + if (log != null) { + log.logError("Marketplace apply failed", e); + } + throw new CommandLine.ExecutionException( + new CommandLine(this), e.getMessage() == null ? "apply failed" : e.getMessage(), e); + } + } + } + + @Command( + name = "validate", + description = + "Check the local install against hop-env.yaml without installing. Exit code 1 on drift.") + static class ValidateCommand extends MarketplaceSubCommand { + @Option( + names = {"-f", "--file"}, + description = + "Path to hop-env.yaml or hop-env.json (default: discover hop-env.* under project/Hop" + + " home)") + private String file; + + @Option( + names = {"--strict"}, + description = "Also fail if extra marketplace plugins are installed beyond the env file") + private boolean strict; + + @Override + public void run() { + try { + Path hopHome = HopHome.resolve(); + Path envPath = EnvironmentApplier.resolveEnvironmentFile(hopHome, file); + if (envPath == null) { + throw new HopException( + "No environment file found. Pass -f hop-env.yaml or set HOP_ENV_FILE."); + } + HopEnvironmentSpec env = HopEnvironmentLoader.load(envPath); + EnvironmentDrift drift = + new EnvironmentApplier(log, hopHome, MarketplaceConfig.load()).validate(env); + boolean hard = + !drift.getMissingPlugins().isEmpty() + || !drift.getVersionMismatches().isEmpty() + || !drift.getMissingDependencies().isEmpty() + || (strict && !drift.getExtraMarketplacePlugins().isEmpty()); + // populate extras only when strict (validate() currently does not; add here) + if (strict) { + addExtraPlugins(hopHome, env, drift); + hard = hard || !drift.getExtraMarketplacePlugins().isEmpty(); + } + if (!hard) { + System.out.println("OK: environment matches " + envPath); + return; + } + System.err.println("Environment drift against " + envPath + ":"); + System.err.print(drift.formatReport()); + System.err.println("Run: hop marketplace apply -f " + envPath); + throw new CommandLine.ExecutionException(new CommandLine(this), "environment drift"); + } catch (CommandLine.ExecutionException e) { + throw e; + } catch (Exception e) { + System.err.println("ERROR: " + e.getMessage()); + throw new CommandLine.ExecutionException( + new CommandLine(this), e.getMessage() == null ? "validate failed" : e.getMessage(), e); + } + } + + private static void addExtraPlugins( + Path hopHome, HopEnvironmentSpec env, EnvironmentDrift drift) throws Exception { + java.util.Set desired = new java.util.HashSet<>(); + if (env.getPlugins() != null) { + for (HopEnvironmentSpec.PluginRef ref : env.getPlugins()) { + if (ref.getArtifactId() != null) { + desired.add(ref.getArtifactId()); + } + } + } + Path receipts = hopHome.resolve(PluginInstaller.RECEIPTS_DIR); + if (!Files.isDirectory(receipts)) { + return; + } + try (DirectoryStream stream = Files.newDirectoryStream(receipts, "*.json")) { + for (Path f : stream) { + String name = f.getFileName().toString(); + String id = name.substring(0, name.length() - ".json".length()); + if (!desired.contains(id)) { + drift.getExtraMarketplacePlugins().add(id); + } + } + } + } + } } diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/EnvironmentApplier.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/EnvironmentApplier.java new file mode 100644 index 00000000000..4573fc2565c --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/EnvironmentApplier.java @@ -0,0 +1,324 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.env; + +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.apache.commons.lang3.StringUtils; +import org.apache.hop.core.exception.HopException; +import org.apache.hop.core.logging.ILogChannel; +import org.apache.hop.marketplace.catalog.OptionalPluginCatalog; +import org.apache.hop.marketplace.catalog.OptionalPluginInfo; +import org.apache.hop.marketplace.command.MarketplaceCommand; +import org.apache.hop.marketplace.config.MarketplaceConfig; +import org.apache.hop.marketplace.config.MarketplaceRepository; +import org.apache.hop.marketplace.install.InstallReceipt; +import org.apache.hop.marketplace.install.PluginInstaller; +import org.apache.hop.marketplace.install.PluginUninstaller; +import org.apache.hop.marketplace.resolve.MavenCoordinates; + +/** Applies or validates a {@link HopEnvironmentSpec} against a Hop installation. */ +public class EnvironmentApplier { + + private final ILogChannel log; + private final Path hopHome; + private final MarketplaceConfig baseConfig; + + public EnvironmentApplier(ILogChannel log, Path hopHome, MarketplaceConfig baseConfig) { + this.log = log; + this.hopHome = hopHome; + this.baseConfig = baseConfig; + } + + public EnvironmentDrift validate(HopEnvironmentSpec env) throws HopException { + EnvironmentDrift drift = new EnvironmentDrift(); + String defaultVersion = resolveEnvVersion(env); + + for (HopEnvironmentSpec.PluginRef ref : nullSafe(env.getPlugins())) { + if (StringUtils.isBlank(ref.getArtifactId())) { + continue; + } + String groupId = + StringUtils.isNotBlank(ref.getGroupId()) ? ref.getGroupId() : baseConfig.getGroupId(); + String version = StringUtils.isNotBlank(ref.getVersion()) ? ref.getVersion() : defaultVersion; + InstallReceipt receipt = PluginInstaller.readReceipt(hopHome, ref.getArtifactId()); + boolean onDisk = isPluginOnDisk(ref.getArtifactId()); + if (!onDisk && receipt == null) { + drift.getMissingPlugins().add(groupId + ":" + ref.getArtifactId() + ":" + version); + continue; + } + if (receipt != null + && StringUtils.isNotBlank(version) + && !version.equals(receipt.getVersion())) { + drift + .getVersionMismatches() + .add(ref.getArtifactId() + " local=" + receipt.getVersion() + " required=" + version); + } + } + + for (HopEnvironmentSpec.DependencyRef dep : nullSafe(env.getDependencies())) { + if (StringUtils.isAnyBlank(dep.getGroupId(), dep.getArtifactId(), dep.getVersion())) { + continue; + } + String target = StringUtils.defaultIfBlank(dep.getTarget(), "lib/jdbc"); + Path jar = + hopHome.resolve(target).resolve(dep.getArtifactId() + "-" + dep.getVersion() + ".jar"); + if (!Files.isRegularFile(jar)) { + // also accept any jar starting with artifactId- + if (!anyJarPresent(hopHome.resolve(target), dep.getArtifactId())) { + drift + .getMissingDependencies() + .add(dep.getGroupId() + ":" + dep.getArtifactId() + ":" + dep.getVersion()); + } + } + } + + return drift; + } + + /** + * Install missing plugins/deps; optionally prune marketplace plugins not listed in the env file. + */ + public void apply(HopEnvironmentSpec env, boolean prune) throws HopException { + MarketplaceConfig config = configFromEnv(env); + String defaultVersion = resolveEnvVersion(env); + PluginInstaller installer = new PluginInstaller(log, hopHome, config); + installer.activateAllPending(); + + Set desiredArtifacts = new HashSet<>(); + for (HopEnvironmentSpec.PluginRef ref : nullSafe(env.getPlugins())) { + if (StringUtils.isBlank(ref.getArtifactId())) { + continue; + } + desiredArtifacts.add(ref.getArtifactId()); + String groupId = + StringUtils.isNotBlank(ref.getGroupId()) ? ref.getGroupId() : config.getGroupId(); + String version = StringUtils.isNotBlank(ref.getVersion()) ? ref.getVersion() : defaultVersion; + InstallReceipt receipt = PluginInstaller.readReceipt(hopHome, ref.getArtifactId()); + boolean onDisk = isPluginOnDisk(ref.getArtifactId()); + // Present on disk without a receipt (e.g. install-wave1-plugins.sh) counts as satisfied. + boolean versionMismatch = + receipt != null + && StringUtils.isNotBlank(version) + && !version.equals(receipt.getVersion()); + boolean needsInstall = (!onDisk && receipt == null) || versionMismatch; + if (needsInstall) { + MavenCoordinates coords = new MavenCoordinates(groupId, ref.getArtifactId(), version); + log.logBasic("Applying environment: installing " + coords.gav()); + installer.install(coords, true); + } else { + log.logBasic("Applying environment: " + ref.getArtifactId() + " already satisfied"); + } + } + + for (HopEnvironmentSpec.DependencyRef dep : nullSafe(env.getDependencies())) { + if (StringUtils.isAnyBlank(dep.getGroupId(), dep.getArtifactId(), dep.getVersion())) { + continue; + } + String target = StringUtils.defaultIfBlank(dep.getTarget(), "lib/jdbc"); + Path dir = hopHome.resolve(target); + Path jar = dir.resolve(dep.getArtifactId() + "-" + dep.getVersion() + ".jar"); + if (Files.isRegularFile(jar)) { + log.logBasic("Dependency already present: " + jar.getFileName()); + continue; + } + MavenCoordinates coords = + new MavenCoordinates(dep.getGroupId(), dep.getArtifactId(), dep.getVersion()); + String base = config.primaryRepositoryUrl(); + log.logBasic("Downloading dependency " + coords.gav() + " → " + target); + try { + Files.createDirectories(dir); + downloadJar(base, coords, jar); + } catch (IOException e) { + throw new HopException("Failed to install dependency " + coords.gav(), e); + } + } + + if (prune) { + pruneExtras(desiredArtifacts); + } + } + + private void downloadJar(String repoBase, MavenCoordinates coords, Path targetJar) + throws HopException, IOException { + String path = + coords.groupId().replace('.', '/') + + "/" + + coords.artifactId() + + "/" + + coords.version() + + "/" + + coords.artifactId() + + "-" + + coords.version() + + ".jar"; + String base = repoBase.endsWith("/") ? repoBase : repoBase + "/"; + java.net.http.HttpClient http = + java.net.http.HttpClient.newBuilder() + .followRedirects(java.net.http.HttpClient.Redirect.NORMAL) + .build(); + java.net.http.HttpRequest request = + java.net.http.HttpRequest.newBuilder(java.net.URI.create(base + path)) + .timeout(java.time.Duration.ofMinutes(10)) + .GET() + .build(); + try { + java.net.http.HttpResponse response = + http.send(request, java.net.http.HttpResponse.BodyHandlers.ofInputStream()); + if (response.statusCode() != 200) { + throw new HopException("HTTP " + response.statusCode() + " downloading " + base + path); + } + Files.createDirectories(targetJar.getParent()); + try (java.io.InputStream in = response.body()) { + Files.copy(in, targetJar, java.nio.file.StandardCopyOption.REPLACE_EXISTING); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new HopException("Interrupted downloading " + coords.gav(), e); + } + } + + private void pruneExtras(Set desiredArtifacts) throws HopException { + Path receiptsDir = hopHome.resolve(PluginInstaller.RECEIPTS_DIR); + if (!Files.isDirectory(receiptsDir)) { + return; + } + PluginUninstaller uninstaller = new PluginUninstaller(log, hopHome); + try (DirectoryStream stream = Files.newDirectoryStream(receiptsDir, "*.json")) { + for (Path file : stream) { + String name = file.getFileName().toString(); + String artifactId = name.substring(0, name.length() - ".json".length()); + if (!desiredArtifacts.contains(artifactId)) { + log.logBasic("Pruning marketplace plugin not in env file: " + artifactId); + uninstaller.uninstall(artifactId); + } + } + } catch (IOException e) { + throw new HopException("Failed to scan marketplace receipts for prune", e); + } + } + + private MarketplaceConfig configFromEnv(HopEnvironmentSpec env) { + MarketplaceConfig config = new MarketplaceConfig(); + config.setEnabled(baseConfig.isEnabled()); + config.setGroupId(baseConfig.getGroupId()); + config.setDefaultVersion( + StringUtils.isNotBlank(env.getHopVersion()) + ? env.getHopVersion() + : MarketplaceCommand.resolveDefaultVersion(baseConfig)); + config.getRepositories().clear(); + if (env.getRepositories() != null && !env.getRepositories().isEmpty()) { + for (HopEnvironmentSpec.RepositoryRef ref : env.getRepositories()) { + if (StringUtils.isNotBlank(ref.getUrl())) { + config + .getRepositories() + .add( + new MarketplaceRepository( + StringUtils.defaultIfBlank(ref.getId(), "env"), ref.getUrl())); + } + } + } + if (config.getRepositories().isEmpty()) { + config.getRepositories().addAll(baseConfig.getRepositories()); + } + if (config.getRepositories().isEmpty()) { + config + .getRepositories() + .add(new MarketplaceRepository("central", MarketplaceConfig.DEFAULT_REPO_URL)); + } + return config; + } + + private String resolveEnvVersion(HopEnvironmentSpec env) { + if (StringUtils.isNotBlank(env.getHopVersion())) { + return env.getHopVersion(); + } + return MarketplaceCommand.resolveDefaultVersion(baseConfig); + } + + private boolean isPluginOnDisk(String artifactId) { + for (OptionalPluginInfo info : OptionalPluginCatalog.listWave1()) { + if (artifactId.equals(info.getArtifactId())) { + return OptionalPluginCatalog.isInstalledOnDisk(hopHome, info); + } + } + // fallback: any receipt counts as installed for non-catalog plugins + try { + return PluginInstaller.readReceipt(hopHome, artifactId) != null; + } catch (HopException e) { + return false; + } + } + + private static boolean anyJarPresent(Path dir, String artifactId) throws HopException { + if (!Files.isDirectory(dir)) { + return false; + } + try (DirectoryStream stream = Files.newDirectoryStream(dir, artifactId + "-*.jar")) { + return stream.iterator().hasNext(); + } catch (IOException e) { + throw new HopException("Unable to list " + dir, e); + } + } + + private static List nullSafe(List list) { + return list == null ? List.of() : list; + } + + /** Locate hop-env.yaml/json relative to hop home / project / properties. */ + public static Path resolveEnvironmentFile(Path hopHome, String explicitPath) { + if (StringUtils.isNotBlank(explicitPath)) { + return Path.of(explicitPath).toAbsolutePath().normalize(); + } + String prop = System.getProperty("hop.env.file"); + if (StringUtils.isNotBlank(prop)) { + return Path.of(prop).toAbsolutePath().normalize(); + } + String env = System.getenv("HOP_ENV_FILE"); + if (StringUtils.isNotBlank(env)) { + return Path.of(env).toAbsolutePath().normalize(); + } + String projectHome = System.getProperty("PROJECT_HOME"); + if (StringUtils.isBlank(projectHome)) { + projectHome = System.getenv("PROJECT_HOME"); + } + if (StringUtils.isNotBlank(projectHome)) { + Path p = Path.of(projectHome); + for (String name : List.of("hop-env.yaml", "hop-env.yml", "hop-env.json")) { + Path candidate = p.resolve(name); + if (Files.isRegularFile(candidate)) { + return candidate; + } + } + } + if (hopHome != null) { + for (String name : List.of("hop-env.yaml", "hop-env.yml", "hop-env.json")) { + Path candidate = hopHome.resolve(name); + if (Files.isRegularFile(candidate)) { + return candidate; + } + } + } + return null; + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/EnvironmentDrift.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/EnvironmentDrift.java new file mode 100644 index 00000000000..ba5dc875d5c --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/EnvironmentDrift.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.env; + +import java.util.ArrayList; +import java.util.List; +import lombok.Getter; + +/** Result of comparing a hop-env file against the local install. */ +@Getter +public class EnvironmentDrift { + private final List missingPlugins = new ArrayList<>(); + private final List versionMismatches = new ArrayList<>(); + private final List extraMarketplacePlugins = new ArrayList<>(); + private final List missingDependencies = new ArrayList<>(); + + public boolean hasDrift() { + return !missingPlugins.isEmpty() + || !versionMismatches.isEmpty() + || !extraMarketplacePlugins.isEmpty() + || !missingDependencies.isEmpty(); + } + + public String formatReport() { + StringBuilder sb = new StringBuilder(); + for (String s : missingPlugins) { + sb.append(" MISSING plugin: ").append(s).append('\n'); + } + for (String s : versionMismatches) { + sb.append(" VERSION mismatch: ").append(s).append('\n'); + } + for (String s : extraMarketplacePlugins) { + sb.append(" EXTRA marketplace plugin (not in env file): ").append(s).append('\n'); + } + for (String s : missingDependencies) { + sb.append(" MISSING dependency jar: ").append(s).append('\n'); + } + return sb.toString(); + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentLoader.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentLoader.java new file mode 100644 index 00000000000..2228af6ca2f --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentLoader.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.env; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Locale; +import java.util.Map; +import org.apache.hop.core.exception.HopException; +import org.apache.hop.core.json.HopJson; +import org.yaml.snakeyaml.LoaderOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.SafeConstructor; + +/** Loads {@link HopEnvironmentSpec} from YAML or JSON. */ +public final class HopEnvironmentLoader { + + private HopEnvironmentLoader() {} + + public static HopEnvironmentSpec load(Path file) throws HopException { + if (file == null || !Files.isRegularFile(file)) { + throw new HopException("Environment file not found: " + file); + } + String name = file.getFileName().toString().toLowerCase(Locale.ROOT); + try (InputStream in = Files.newInputStream(file)) { + if (name.endsWith(".json")) { + return HopJson.newMapper().readValue(in, HopEnvironmentSpec.class); + } + // default: YAML (.yaml / .yml / anything else) + Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions())); + Object loaded = yaml.load(in); + if (loaded == null) { + return new HopEnvironmentSpec(); + } + if (!(loaded instanceof Map)) { + throw new HopException("Environment file root must be a YAML mapping: " + file); + } + return HopJson.newMapper().convertValue(loaded, HopEnvironmentSpec.class); + } catch (IOException e) { + throw new HopException("Unable to read environment file: " + file, e); + } catch (HopException e) { + throw e; + } catch (Exception e) { + throw new HopException("Unable to parse environment file: " + file, e); + } + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentSpec.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentSpec.java new file mode 100644 index 00000000000..c3a71f5d996 --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentSpec.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.env; + +import java.util.ArrayList; +import java.util.List; +import lombok.Getter; +import lombok.Setter; + +/** + * Declarative Hop environment file ({@code hop-env.yaml} / {@code hop-env.json}). + * + *
+ * version: "1.0"
+ * hopVersion: "2.19.0"
+ * enforceOnRun: false
+ * repositories:
+ *   - id: central
+ *     url: https://repo1.maven.org/maven2/
+ * plugins:
+ *   - artifactId: hop-tech-parquet
+ *     version: "2.19.0"
+ * dependencies:
+ *   - groupId: org.postgresql
+ *     artifactId: postgresql
+ *     version: "42.7.3"
+ * 
+ */ +@Getter +@Setter +public class HopEnvironmentSpec { + private String version = "1.0"; + private String hopVersion; + private boolean enforceOnRun; + private List repositories = new ArrayList<>(); + private List plugins = new ArrayList<>(); + private List dependencies = new ArrayList<>(); + + @Getter + @Setter + public static class RepositoryRef { + private String id; + private String url; + } + + @Getter + @Setter + public static class PluginRef { + private String groupId; + private String artifactId; + private String version; + } + + @Getter + @Setter + public static class DependencyRef { + private String groupId; + private String artifactId; + private String version; + + /** Target directory under Hop home; default {@code lib/jdbc}. */ + private String target = "lib/jdbc"; + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/xp/HopRunEnvironmentCheckExtensionPoint.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/xp/HopRunEnvironmentCheckExtensionPoint.java new file mode 100644 index 00000000000..7d9cb5c9fac --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/xp/HopRunEnvironmentCheckExtensionPoint.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.xp; + +import java.nio.file.Path; +import org.apache.commons.lang3.StringUtils; +import org.apache.hop.core.exception.HopException; +import org.apache.hop.core.extension.ExtensionPoint; +import org.apache.hop.core.extension.IExtensionPoint; +import org.apache.hop.core.logging.ILogChannel; +import org.apache.hop.core.variables.IVariables; +import org.apache.hop.marketplace.config.MarketplaceConfig; +import org.apache.hop.marketplace.env.EnvironmentApplier; +import org.apache.hop.marketplace.env.EnvironmentDrift; +import org.apache.hop.marketplace.env.HopEnvironmentLoader; +import org.apache.hop.marketplace.env.HopEnvironmentSpec; +import org.apache.hop.marketplace.install.HopHome; +import org.apache.hop.run.HopRunBase; + +/** + * Optional drift check at hop-run start when a hop-env file is present and enforcement is enabled + * ({@code enforceOnRun: true} in the file, or {@code -Dhop.env.enforce=true}). + */ +@ExtensionPoint( + id = "HopRunEnvironmentCheckExtensionPoint", + description = "Validate hop-env.yaml against the local plugin install before hop-run executes", + extensionPointId = "HopRunStart") +public class HopRunEnvironmentCheckExtensionPoint implements IExtensionPoint { + + @Override + public void callExtensionPoint(ILogChannel log, IVariables variables, HopRunBase hopRun) + throws HopException { + Path hopHome; + try { + hopHome = HopHome.resolve(); + } catch (HopException e) { + // hop-run from unusual cwd: skip silently + return; + } + + String explicit = variables != null ? variables.getVariable("HOP_ENV_FILE") : null; + if (StringUtils.isBlank(explicit)) { + explicit = System.getProperty("hop.env.file"); + } + Path envFile = EnvironmentApplier.resolveEnvironmentFile(hopHome, explicit); + if (envFile == null) { + return; + } + + HopEnvironmentSpec env = HopEnvironmentLoader.load(envFile); + boolean enforce = + env.isEnforceOnRun() + || "true".equalsIgnoreCase(System.getProperty("hop.env.enforce", "false")) + || "Y".equalsIgnoreCase(System.getProperty("hop.env.enforce", "N")); + if (!enforce) { + log.logDetailed( + "Found environment file " + + envFile + + " (enforceOnRun=false); skipping drift check. Use hop marketplace validate -f " + + envFile.getFileName()); + return; + } + + EnvironmentApplier applier = new EnvironmentApplier(log, hopHome, MarketplaceConfig.load()); + EnvironmentDrift drift = applier.validate(env); + // For enforceOnRun we care about missing plugins/deps and version mismatches, not extras + boolean hard = + !drift.getMissingPlugins().isEmpty() + || !drift.getVersionMismatches().isEmpty() + || !drift.getMissingDependencies().isEmpty(); + if (hard) { + throw new HopException( + "FATAL: Environment drift detected against " + + envFile + + ":\n" + + drift.formatReport() + + "Run 'hop marketplace apply -f " + + envFile + + "' to fix your environment."); + } + log.logBasic("Environment file " + envFile + " matches local install."); + } +} diff --git a/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml b/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml new file mode 100644 index 00000000000..a7ae8260034 --- /dev/null +++ b/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml @@ -0,0 +1,34 @@ +# Example declarative Hop environment (copy to hop-env.yaml in your project or install). +# Apply with: +# hop marketplace apply -f hop-env.yaml +# hop marketplace apply -f hop-env.yaml --prune +# Validate: +# hop marketplace validate -f hop-env.yaml +# Optional hop-run enforcement: set enforceOnRun: true (or -Dhop.env.enforce=true) + +version: "1.0" +hopVersion: "2.19.0-SNAPSHOT" +enforceOnRun: false + +# Defaults to Maven Central when omitted +repositories: + - id: central + url: "https://repo1.maven.org/maven2/" + # Local Artifactory for development: + # - id: local-artifactory + # url: "http://localhost:8082/artifactory/hop-plugins-local/" + +plugins: + - artifactId: hop-tech-parquet + version: "2.19.0-SNAPSHOT" + - artifactId: hop-engines-spark + version: "2.19.0-SNAPSHOT" + # Beam engine plugin only (lib/beam stays in the core client): + # - artifactId: hop-engines-beam + # version: "2.19.0-SNAPSHOT" + +# Optional JDBC (or other) jars into lib/jdbc +# dependencies: +# - groupId: org.postgresql +# artifactId: postgresql +# version: "42.7.3" diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/env/EnvironmentApplierTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/env/EnvironmentApplierTest.java new file mode 100644 index 00000000000..69296565d80 --- /dev/null +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/env/EnvironmentApplierTest.java @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.env; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.file.Files; +import java.nio.file.Path; +import org.apache.hop.core.json.HopJson; +import org.apache.hop.core.logging.HopLogStore; +import org.apache.hop.core.logging.LogChannel; +import org.apache.hop.marketplace.config.MarketplaceConfig; +import org.apache.hop.marketplace.install.InstallReceipt; +import org.apache.hop.marketplace.install.PluginInstaller; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +class EnvironmentApplierTest { + + @TempDir Path tempDir; + + @BeforeAll + static void initLogging() { + HopLogStore.init(); + } + + @Test + void validateDetectsMissingPlugin() throws Exception { + Path hopHome = tempDir.resolve("hop"); + Files.createDirectories(hopHome.resolve("plugins")); + + HopEnvironmentSpec env = new HopEnvironmentSpec(); + env.setHopVersion("2.19.0"); + HopEnvironmentSpec.PluginRef ref = new HopEnvironmentSpec.PluginRef(); + ref.setArtifactId("hop-tech-parquet"); + ref.setVersion("2.19.0"); + env.getPlugins().add(ref); + + EnvironmentDrift drift = + new EnvironmentApplier(new LogChannel("test"), hopHome, new MarketplaceConfig()) + .validate(env); + assertTrue(drift.hasDrift()); + assertEquals(1, drift.getMissingPlugins().size()); + } + + @Test + void validateOkWhenPluginOnDisk() throws Exception { + Path hopHome = tempDir.resolve("hop"); + Files.createDirectories(hopHome.resolve("plugins/tech/parquet")); + + HopEnvironmentSpec env = new HopEnvironmentSpec(); + HopEnvironmentSpec.PluginRef ref = new HopEnvironmentSpec.PluginRef(); + ref.setArtifactId("hop-tech-parquet"); + env.getPlugins().add(ref); + + EnvironmentDrift drift = + new EnvironmentApplier(new LogChannel("test"), hopHome, new MarketplaceConfig()) + .validate(env); + assertFalse(drift.hasDrift()); + } + + @Test + void validateVersionMismatchFromReceipt() throws Exception { + Path hopHome = tempDir.resolve("hop"); + Files.createDirectories(hopHome.resolve("plugins/tech/parquet")); + Files.createDirectories(hopHome.resolve(PluginInstaller.RECEIPTS_DIR)); + InstallReceipt receipt = new InstallReceipt(); + receipt.setGroupId("org.apache.hop"); + receipt.setArtifactId("hop-tech-parquet"); + receipt.setVersion("2.18.0"); + HopJson.newMapper() + .writeValue( + hopHome.resolve(PluginInstaller.RECEIPTS_DIR).resolve("hop-tech-parquet.json").toFile(), + receipt); + + HopEnvironmentSpec env = new HopEnvironmentSpec(); + HopEnvironmentSpec.PluginRef ref = new HopEnvironmentSpec.PluginRef(); + ref.setArtifactId("hop-tech-parquet"); + ref.setVersion("2.19.0"); + env.getPlugins().add(ref); + + EnvironmentDrift drift = + new EnvironmentApplier(new LogChannel("test"), hopHome, new MarketplaceConfig()) + .validate(env); + assertEquals(1, drift.getVersionMismatches().size()); + } + + @Test + void resolveEnvironmentFileDiscoversProjectFile() throws Exception { + Path project = tempDir.resolve("project"); + Files.createDirectories(project); + Path envFile = project.resolve("hop-env.yaml"); + Files.writeString(envFile, "version: \"1.0\"\n"); + System.setProperty("PROJECT_HOME", project.toString()); + try { + Path found = EnvironmentApplier.resolveEnvironmentFile(tempDir, null); + assertEquals(envFile.toAbsolutePath().normalize(), found); + } finally { + System.clearProperty("PROJECT_HOME"); + } + } +} diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/env/HopEnvironmentLoaderTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/env/HopEnvironmentLoaderTest.java new file mode 100644 index 00000000000..d5343e654cb --- /dev/null +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/env/HopEnvironmentLoaderTest.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.env; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +class HopEnvironmentLoaderTest { + + @TempDir Path tempDir; + + @Test + void loadYaml() throws Exception { + Path file = tempDir.resolve("hop-env.yaml"); + Files.writeString( + file, + """ + version: "1.0" + hopVersion: "2.19.0" + enforceOnRun: true + repositories: + - id: local + url: http://localhost:8082/artifactory/hop-plugins-local/ + plugins: + - artifactId: hop-tech-parquet + version: "2.19.0" + - artifactId: hop-engines-spark + dependencies: + - groupId: org.postgresql + artifactId: postgresql + version: "42.7.3" + """, + StandardCharsets.UTF_8); + + HopEnvironmentSpec env = HopEnvironmentLoader.load(file); + assertEquals("1.0", env.getVersion()); + assertEquals("2.19.0", env.getHopVersion()); + assertTrue(env.isEnforceOnRun()); + assertEquals(1, env.getRepositories().size()); + assertEquals("local", env.getRepositories().get(0).getId()); + assertEquals(2, env.getPlugins().size()); + assertEquals("hop-tech-parquet", env.getPlugins().get(0).getArtifactId()); + assertEquals(1, env.getDependencies().size()); + assertEquals("postgresql", env.getDependencies().get(0).getArtifactId()); + } + + @Test + void loadJson() throws Exception { + Path file = tempDir.resolve("hop-env.json"); + Files.writeString( + file, + """ + { + "version": "1.0", + "hopVersion": "2.19.0", + "enforceOnRun": false, + "plugins": [ { "artifactId": "hop-tech-arrow", "version": "2.19.0" } ] + } + """, + StandardCharsets.UTF_8); + HopEnvironmentSpec env = HopEnvironmentLoader.load(file); + assertFalse(env.isEnforceOnRun()); + assertEquals(1, env.getPlugins().size()); + assertEquals("hop-tech-arrow", env.getPlugins().get(0).getArtifactId()); + } +} From 64895790fce1daaf880e3c8d77b437014c58f51e Mon Sep 17 00:00:00 2001 From: mattcasters Date: Sun, 19 Jul 2026 21:49:06 +0200 Subject: [PATCH 04/28] issue #7547: provide Artifactory master key for local marketplace stack Generate and mount keys/master.key (openssl rand -hex 32, mode 600, owner 1030:1030) so JFrog Artifactory OSS no longer hangs at startup. --- docker/marketplace-artifactory/README.md | 23 ++++++++ .../docker-compose.yml | 14 ++++- .../marketplace-artifactory/generate-keys.sh | 58 +++++++++++++++++++ .../marketplace-artifactory/keys/.gitignore | 4 ++ 4 files changed, 98 insertions(+), 1 deletion(-) create mode 100755 docker/marketplace-artifactory/generate-keys.sh create mode 100644 docker/marketplace-artifactory/keys/.gitignore diff --git a/docker/marketplace-artifactory/README.md b/docker/marketplace-artifactory/README.md index a42f849d5bb..937dbd16827 100644 --- a/docker/marketplace-artifactory/README.md +++ b/docker/marketplace-artifactory/README.md @@ -21,9 +21,32 @@ under the License. Use this stack to exercise plugin install/uninstall **without** ASF Nexus permissions. +## Master key (required) + +JFrog Artifactory will **hang at startup** unless a master key is provided. Generate +it once on the host (hex string, mode `600`, owned by UID/GID `1030:1030` — the +Artifactory process user in the official image): + +```bash +./docker/marketplace-artifactory/generate-keys.sh +``` + +That writes `docker/marketplace-artifactory/keys/master.key` via +`openssl rand -hex 32`, sets permissions, and chowns to `1030:1030` (using Docker +if you lack host root). The key is gitignored. + +The compose file bind-mounts: + +```text +./keys/master.key → /var/opt/jfrog/artifactory/etc/security/master.key +``` + +and sets `JF_SHARED_SECURITY_MASTER_KEY_FILE` to that path. + ## Start ```bash +./docker/marketplace-artifactory/generate-keys.sh docker compose -f docker/marketplace-artifactory/docker-compose.yml up -d ``` diff --git a/docker/marketplace-artifactory/docker-compose.yml b/docker/marketplace-artifactory/docker-compose.yml index c9c2d89431f..98b78b899e4 100644 --- a/docker/marketplace-artifactory/docker-compose.yml +++ b/docker/marketplace-artifactory/docker-compose.yml @@ -8,23 +8,35 @@ # http://www.apache.org/licenses/LICENSE-2.0 # # Local Artifactory OSS for Hop marketplace plugin testing (no ASF Nexus credentials required). +# +# Prerequisites: +# ./docker/marketplace-artifactory/generate-keys.sh +# # creates keys/master.key (openssl rand -hex 32), mode 600, owner 1030:1030 +# # Usage: # docker compose -f docker/marketplace-artifactory/docker-compose.yml up -d -# # open http://localhost:8082 (default admin / password — set on first UI login) +# # open http://localhost:8082 (set admin password on first UI login) # ./docker/marketplace-artifactory/publish-wave1-plugins.sh # services: artifactory: image: releases-docker.jfrog.io/jfrog/artifactory-oss:7.104.14 container_name: hop-marketplace-artifactory + # Official image runs as artifactory (UID/GID 1030) + user: "1030:1030" ports: - "8082:8082" - "8081:8081" volumes: - hop-artifactory-data:/var/opt/jfrog/artifactory + # Master key is required at startup; without it Artifactory hangs. + # Host file is prepared by generate-keys.sh (600 / 1030:1030). + - ./keys/master.key:/var/opt/jfrog/artifactory/etc/security/master.key:ro environment: # Reduce memory for local dev EXTRA_JAVA_OPTIONS: -Xms512m -Xmx1g + # Point shared security at the mounted master key (Artifactory 7.x) + JF_SHARED_SECURITY_MASTER_KEY_FILE: /var/opt/jfrog/artifactory/etc/security/master.key healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8082/artifactory/api/system/ping"] interval: 30s diff --git a/docker/marketplace-artifactory/generate-keys.sh b/docker/marketplace-artifactory/generate-keys.sh new file mode 100755 index 00000000000..b7e032a17ce --- /dev/null +++ b/docker/marketplace-artifactory/generate-keys.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Generate the JFrog Artifactory master key required for a clean startup. +# Artifactory runs as UID/GID 1030:1030 inside the container; the key file +# must be owned by that user and mode 600 or the service hangs at boot. +# +# Usage: +# ./docker/marketplace-artifactory/generate-keys.sh +# +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +KEYS_DIR="${SCRIPT_DIR}/keys" +MASTER_KEY_FILE="${KEYS_DIR}/master.key" + +# Artifactory process user inside the official OSS image +ARTIFACTORY_UID=1030 +ARTIFACTORY_GID=1030 + +mkdir -p "${KEYS_DIR}" + +if [[ -f "${MASTER_KEY_FILE}" ]]; then + echo "Master key already exists: ${MASTER_KEY_FILE}" +else + echo "Generating Artifactory master key (openssl rand -hex 32)..." + openssl rand -hex 32 > "${MASTER_KEY_FILE}" + echo "Wrote ${MASTER_KEY_FILE}" +fi + +chmod 600 "${MASTER_KEY_FILE}" + +# Ownership must be 1030:1030 so the container process can read the key. +if chown "${ARTIFACTORY_UID}:${ARTIFACTORY_GID}" "${MASTER_KEY_FILE}" 2>/dev/null; then + echo "Set owner ${ARTIFACTORY_UID}:${ARTIFACTORY_GID} on master.key" +elif command -v docker >/dev/null 2>&1; then + # No root on host: fix ownership via a throwaway container + docker run --rm \ + -v "${KEYS_DIR}:/keys" \ + alpine:3.19 \ + chown "${ARTIFACTORY_UID}:${ARTIFACTORY_GID}" /keys/master.key + echo "Set owner ${ARTIFACTORY_UID}:${ARTIFACTORY_GID} on master.key (via docker)" +else + echo "WARNING: could not chown master.key to ${ARTIFACTORY_UID}:${ARTIFACTORY_GID}." >&2 + echo " Run: sudo chown ${ARTIFACTORY_UID}:${ARTIFACTORY_GID} ${MASTER_KEY_FILE}" >&2 + exit 1 +fi + +ls -la "${MASTER_KEY_FILE}" +echo "Done. Start Artifactory with:" +echo " docker compose -f docker/marketplace-artifactory/docker-compose.yml up -d" diff --git a/docker/marketplace-artifactory/keys/.gitignore b/docker/marketplace-artifactory/keys/.gitignore new file mode 100644 index 00000000000..71b87a0665e --- /dev/null +++ b/docker/marketplace-artifactory/keys/.gitignore @@ -0,0 +1,4 @@ +# Generated locally by generate-keys.sh — never commit secrets +master.key +* +!.gitignore From 88b6d2c848eb8fc5f23ccda1505c20e5516f685f Mon Sep 17 00:00:00 2001 From: mattcasters Date: Sun, 19 Jul 2026 21:52:37 +0200 Subject: [PATCH 05/28] issue #7547: add Artifactory join.key so local stack can start Single-node OSS still requires a join key; generate and mount both master.key and join.key (64-char hex, 600, 1030:1030) and point JF_SHARED_SECURITY_JOIN_KEY_FILE at the mount. --- docker/marketplace-artifactory/README.md | 33 ++++- .../docker-compose.yml | 14 +- .../marketplace-artifactory/generate-keys.sh | 139 ++++++++++++++---- 3 files changed, 144 insertions(+), 42 deletions(-) diff --git a/docker/marketplace-artifactory/README.md b/docker/marketplace-artifactory/README.md index 937dbd16827..fcc8a2e2ca1 100644 --- a/docker/marketplace-artifactory/README.md +++ b/docker/marketplace-artifactory/README.md @@ -21,27 +21,44 @@ under the License. Use this stack to exercise plugin install/uninstall **without** ASF Nexus permissions. -## Master key (required) +## Security keys (required) -JFrog Artifactory will **hang at startup** unless a master key is provided. Generate -it once on the host (hex string, mode `600`, owned by UID/GID `1030:1030` — the -Artifactory process user in the official image): +JFrog Artifactory microservices **hang at startup** unless both a **master key** and a +**join key** are provided (you will see `Cluster join: Join key is missing` otherwise). +Generate them once on the host (hex strings, mode `600`, owned by UID/GID `1030:1030` — +the Artifactory process user in the official image): ```bash ./docker/marketplace-artifactory/generate-keys.sh ``` -That writes `docker/marketplace-artifactory/keys/master.key` via -`openssl rand -hex 32`, sets permissions, and chowns to `1030:1030` (using Docker -if you lack host root). The key is gitignored. +That writes under `docker/marketplace-artifactory/keys/`: + +| File | Source | +|------|--------| +| `master.key` | `openssl rand -hex 32` | +| `join.key` | `openssl rand -hex 32` | + +Permissions are set to `600` and ownership to `1030:1030` (via Docker if you lack host root). +Keys are gitignored. The compose file bind-mounts: ```text ./keys/master.key → /var/opt/jfrog/artifactory/etc/security/master.key +./keys/join.key → /var/opt/jfrog/artifactory/etc/security/join.key ``` -and sets `JF_SHARED_SECURITY_MASTER_KEY_FILE` to that path. +and sets `JF_SHARED_SECURITY_MASTER_KEY_FILE` / `JF_SHARED_SECURITY_JOIN_KEY_FILE`. + +If you previously started the stack with only a master key, regenerate/refresh keys and +recreate the container: + +```bash +./docker/marketplace-artifactory/generate-keys.sh +docker compose -f docker/marketplace-artifactory/docker-compose.yml down +docker compose -f docker/marketplace-artifactory/docker-compose.yml up -d +``` ## Start diff --git a/docker/marketplace-artifactory/docker-compose.yml b/docker/marketplace-artifactory/docker-compose.yml index 98b78b899e4..abe778d9e7d 100644 --- a/docker/marketplace-artifactory/docker-compose.yml +++ b/docker/marketplace-artifactory/docker-compose.yml @@ -11,7 +11,8 @@ # # Prerequisites: # ./docker/marketplace-artifactory/generate-keys.sh -# # creates keys/master.key (openssl rand -hex 32), mode 600, owner 1030:1030 +# # creates keys/master.key and keys/join.key (openssl rand -hex 32), +# # mode 600, owner 1030:1030 # # Usage: # docker compose -f docker/marketplace-artifactory/docker-compose.yml up -d @@ -29,20 +30,23 @@ services: - "8081:8081" volumes: - hop-artifactory-data:/var/opt/jfrog/artifactory - # Master key is required at startup; without it Artifactory hangs. - # Host file is prepared by generate-keys.sh (600 / 1030:1030). + # Both keys are required at startup; without them microservices hang + # ("Cluster join: Join key is missing" / master key pending). + # Host files prepared by generate-keys.sh (600 / 1030:1030). - ./keys/master.key:/var/opt/jfrog/artifactory/etc/security/master.key:ro + - ./keys/join.key:/var/opt/jfrog/artifactory/etc/security/join.key:ro environment: # Reduce memory for local dev EXTRA_JAVA_OPTIONS: -Xms512m -Xmx1g - # Point shared security at the mounted master key (Artifactory 7.x) + # Artifactory 7.x shared security key locations JF_SHARED_SECURITY_MASTER_KEY_FILE: /var/opt/jfrog/artifactory/etc/security/master.key + JF_SHARED_SECURITY_JOIN_KEY_FILE: /var/opt/jfrog/artifactory/etc/security/join.key healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8082/artifactory/api/system/ping"] interval: 30s timeout: 10s retries: 20 - start_period: 120s + start_period: 180s volumes: hop-artifactory-data: diff --git a/docker/marketplace-artifactory/generate-keys.sh b/docker/marketplace-artifactory/generate-keys.sh index b7e032a17ce..52fcf3c7b97 100755 --- a/docker/marketplace-artifactory/generate-keys.sh +++ b/docker/marketplace-artifactory/generate-keys.sh @@ -8,9 +8,13 @@ # # http://www.apache.org/licenses/LICENSE-2.0 # -# Generate the JFrog Artifactory master key required for a clean startup. -# Artifactory runs as UID/GID 1030:1030 inside the container; the key file -# must be owned by that user and mode 600 or the service hangs at boot. +# Generate JFrog Artifactory security keys required for a clean startup: +# - master.key (shared master key) +# - join.key (cluster join key; required even for a single-node OSS stack) +# +# Both are openssl rand -hex 32 (64 hex chars, no trailing newline), mode 600, +# owned by UID/GID 1030:1030 (Artifactory process user in the official image). +# Without them, services hang ("Cluster join: Join key is missing"). # # Usage: # ./docker/marketplace-artifactory/generate-keys.sh @@ -19,40 +23,117 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" KEYS_DIR="${SCRIPT_DIR}/keys" -MASTER_KEY_FILE="${KEYS_DIR}/master.key" -# Artifactory process user inside the official OSS image ARTIFACTORY_UID=1030 ARTIFACTORY_GID=1030 +if ! command -v openssl >/dev/null 2>&1; then + echo "ERROR: openssl is required on the host to generate keys" >&2 + exit 1 +fi + mkdir -p "${KEYS_DIR}" -if [[ -f "${MASTER_KEY_FILE}" ]]; then - echo "Master key already exists: ${MASTER_KEY_FILE}" -else - echo "Generating Artifactory master key (openssl rand -hex 32)..." - openssl rand -hex 32 > "${MASTER_KEY_FILE}" - echo "Wrote ${MASTER_KEY_FILE}" -fi +# Write key material to a host temp file (64 hex chars, no newline) +make_key_material() { + local tmp + tmp="$(mktemp)" + openssl rand -hex 32 | tr -d '\n' > "${tmp}" + # Verify length (32 bytes → 64 hex chars) + local len + len="$(wc -c < "${tmp}" | tr -d ' ')" + if [[ "${len}" != "64" ]]; then + rm -f "${tmp}" + echo "ERROR: expected 64-char hex key, got length ${len}" >&2 + exit 1 + fi + echo "${tmp}" +} -chmod 600 "${MASTER_KEY_FILE}" - -# Ownership must be 1030:1030 so the container process can read the key. -if chown "${ARTIFACTORY_UID}:${ARTIFACTORY_GID}" "${MASTER_KEY_FILE}" 2>/dev/null; then - echo "Set owner ${ARTIFACTORY_UID}:${ARTIFACTORY_GID} on master.key" -elif command -v docker >/dev/null 2>&1; then - # No root on host: fix ownership via a throwaway container - docker run --rm \ - -v "${KEYS_DIR}:/keys" \ - alpine:3.19 \ - chown "${ARTIFACTORY_UID}:${ARTIFACTORY_GID}" /keys/master.key - echo "Set owner ${ARTIFACTORY_UID}:${ARTIFACTORY_GID} on master.key (via docker)" -else - echo "WARNING: could not chown master.key to ${ARTIFACTORY_UID}:${ARTIFACTORY_GID}." >&2 - echo " Run: sudo chown ${ARTIFACTORY_UID}:${ARTIFACTORY_GID} ${MASTER_KEY_FILE}" >&2 +# Install a key file as 1030:1030 mode 600. Works even when an old key is owned by 1030. +install_key() { + local name="$1" + local dest="${KEYS_DIR}/${name}" + local material + material="$(make_key_material)" + + if [[ -f "${dest}" ]]; then + # Readable empty/corrupt keys should be replaced + local existing_len=0 + if [[ -r "${dest}" ]]; then + existing_len="$(wc -c < "${dest}" | tr -d ' ')" + else + # Unreadable (owned by 1030): probe via docker + if command -v docker >/dev/null 2>&1; then + existing_len="$(docker run --rm -v "${KEYS_DIR}:/keys" alpine:3.19 \ + sh -c "wc -c < /keys/${name}" | tr -d ' ')" + fi + fi + if [[ "${existing_len}" == "64" ]]; then + rm -f "${material}" + echo "Key already exists and looks valid: ${dest} (${existing_len} bytes)" + return 0 + fi + echo "Replacing invalid/empty ${dest} (length ${existing_len})" + else + echo "Generating ${name}..." + fi + + # Try host write first + if cat "${material}" > "${dest}" 2>/dev/null \ + && chmod 600 "${dest}" 2>/dev/null \ + && chown "${ARTIFACTORY_UID}:${ARTIFACTORY_GID}" "${dest}" 2>/dev/null; then + rm -f "${material}" + echo "Wrote ${dest}" + return 0 + fi + + # Host cannot overwrite 1030-owned file: install via docker as root + if command -v docker >/dev/null 2>&1; then + docker run --rm \ + -v "${KEYS_DIR}:/keys" \ + -v "${material}:/tmp/key.material:ro" \ + alpine:3.19 \ + sh -c "cp /tmp/key.material /keys/${name} && chmod 600 /keys/${name} && chown ${ARTIFACTORY_UID}:${ARTIFACTORY_GID} /keys/${name}" + rm -f "${material}" + echo "Wrote ${dest} (via docker)" + return 0 + fi + + rm -f "${material}" + echo "ERROR: unable to write ${dest} (need docker or root for chown 1030:1030)" >&2 exit 1 +} + +fix_perms() { + local name="$1" + if chmod 600 "${KEYS_DIR}/${name}" 2>/dev/null \ + && chown "${ARTIFACTORY_UID}:${ARTIFACTORY_GID}" "${KEYS_DIR}/${name}" 2>/dev/null; then + return 0 + fi + if command -v docker >/dev/null 2>&1; then + docker run --rm -v "${KEYS_DIR}:/keys" alpine:3.19 \ + sh -c "chmod 600 /keys/${name} && chown ${ARTIFACTORY_UID}:${ARTIFACTORY_GID} /keys/${name}" + return 0 + fi + echo "WARNING: could not enforce 600 / ${ARTIFACTORY_UID}:${ARTIFACTORY_GID} on ${name}" >&2 + return 1 +} + +install_key "master.key" +install_key "join.key" +fix_perms "master.key" +fix_perms "join.key" + +echo "Key files:" +if command -v docker >/dev/null 2>&1; then + docker run --rm -v "${KEYS_DIR}:/keys" alpine:3.19 \ + sh -c 'ls -la /keys/master.key /keys/join.key && echo -n "lengths: " && wc -c /keys/master.key /keys/join.key' +else + ls -la "${KEYS_DIR}"/*.key + wc -c "${KEYS_DIR}"/*.key fi -ls -la "${MASTER_KEY_FILE}" -echo "Done. Start Artifactory with:" +echo "Done. Restart Artifactory with:" +echo " docker compose -f docker/marketplace-artifactory/docker-compose.yml down" echo " docker compose -f docker/marketplace-artifactory/docker-compose.yml up -d" From f44eb6cdc059909214af3047df32dc7d20938931 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Sun, 19 Jul 2026 22:00:09 +0200 Subject: [PATCH 06/28] issue #7547: run Artifactory OSS with PostgreSQL and env keys Modern Artifactory 7.x requires Postgres (no embedded DB). Add a postgres service, pass master/join keys via .env (not RO file mounts), fix master key size to AES-128 (hex-16), and add start.sh --reset. --- docker/marketplace-artifactory/.gitignore | 4 + docker/marketplace-artifactory/README.md | 91 +++++++----- .../docker-compose.yml | 61 +++++--- .../marketplace-artifactory/generate-keys.sh | 137 +++++------------- .../marketplace-artifactory/keys/.gitignore | 1 - docker/marketplace-artifactory/start.sh | 57 ++++++++ 6 files changed, 191 insertions(+), 160 deletions(-) create mode 100644 docker/marketplace-artifactory/.gitignore create mode 100755 docker/marketplace-artifactory/start.sh diff --git a/docker/marketplace-artifactory/.gitignore b/docker/marketplace-artifactory/.gitignore new file mode 100644 index 00000000000..f2168c16bb8 --- /dev/null +++ b/docker/marketplace-artifactory/.gitignore @@ -0,0 +1,4 @@ +# Generated by generate-keys.sh — never commit +.env +keys/master.key +keys/join.key diff --git a/docker/marketplace-artifactory/README.md b/docker/marketplace-artifactory/README.md index fcc8a2e2ca1..7e84e42d8c9 100644 --- a/docker/marketplace-artifactory/README.md +++ b/docker/marketplace-artifactory/README.md @@ -21,55 +21,62 @@ under the License. Use this stack to exercise plugin install/uninstall **without** ASF Nexus permissions. -## Security keys (required) +## Requirements -JFrog Artifactory microservices **hang at startup** unless both a **master key** and a -**join key** are provided (you will see `Cluster join: Join key is missing` otherwise). -Generate them once on the host (hex strings, mode `600`, owned by UID/GID `1030:1030` — -the Artifactory process user in the official image): +Recent **Artifactory OSS 7.x requires PostgreSQL** (the embedded database is gone). This +compose stack runs: + +| Service | Purpose | +|---------|---------| +| `postgres` | Required DB for Artifactory | +| `artifactory` | Maven repo for Hop plugin zips | + +Also requires Docker Compose and `openssl` on the host. + +## Security keys + +Artifactory needs a **master key** (AES-128) and a **join key**. Generate once: ```bash ./docker/marketplace-artifactory/generate-keys.sh ``` -That writes under `docker/marketplace-artifactory/keys/`: +| File | Size | How | +|------|------|-----| +| `keys/master.key` | 32 hex chars | `openssl rand -hex 16` | +| `keys/join.key` | 64 hex chars | `openssl rand -hex 32` | +| `.env` | compose env | master/join + Postgres password | -| File | Source | -|------|--------| -| `master.key` | `openssl rand -hex 32` | -| `join.key` | `openssl rand -hex 32` | +Keys and `.env` are gitignored. Keys are passed into the container as +**environment variables** (`JF_SHARED_SECURITY_MASTER_KEY` / +`JF_SHARED_SECURITY_JOIN_KEY`), not bind-mounted files — Artifactory tries to +rewrite key files and RO mounts break startup. -Permissions are set to `600` and ownership to `1030:1030` (via Docker if you lack host root). -Keys are gitignored. +## Start -The compose file bind-mounts: +```bash +# First time or after failed starts with an old volume layout: +./docker/marketplace-artifactory/start.sh --reset -```text -./keys/master.key → /var/opt/jfrog/artifactory/etc/security/master.key -./keys/join.key → /var/opt/jfrog/artifactory/etc/security/join.key +# Normal start: +./docker/marketplace-artifactory/start.sh ``` -and sets `JF_SHARED_SECURITY_MASTER_KEY_FILE` / `JF_SHARED_SECURITY_JOIN_KEY_FILE`. - -If you previously started the stack with only a master key, regenerate/refresh keys and -recreate the container: +First boot can take **2–4 minutes**. Watch logs: ```bash -./docker/marketplace-artifactory/generate-keys.sh -docker compose -f docker/marketplace-artifactory/docker-compose.yml down -docker compose -f docker/marketplace-artifactory/docker-compose.yml up -d +docker logs -f hop-marketplace-artifactory ``` -## Start +Healthy when: ```bash -./docker/marketplace-artifactory/generate-keys.sh -docker compose -f docker/marketplace-artifactory/docker-compose.yml up -d +curl -sf http://localhost:8082/artifactory/api/system/ping && echo OK ``` -Open http://localhost:8082 and complete first-time Artifactory setup (admin password). +Open http://localhost:8082 and complete first-time admin password setup. -Create a **local** Maven repository, for example: +### Create the Maven repository | Field | Value | |-------|--------| @@ -77,7 +84,7 @@ Create a **local** Maven repository, for example: | Repository Key | `hop-plugins-local` | | Repository Layout | maven-2-default | -Public URL base (typical OSS default): +Base URL: ```text http://localhost:8082/artifactory/hop-plugins-local/ @@ -94,12 +101,8 @@ export ARTIFACTORY_PASSWORD=… # from first-time setup ./docker/marketplace-artifactory/publish-wave1-plugins.sh ``` -The script deploys each Wave 1 `*.zip` with Maven layout under `org/apache/hop/…`. - ## Point Hop marketplace at local Artifactory -In `config/hop-config.json` (or via GUI later): - ```json { "marketplace": { @@ -116,16 +119,26 @@ In `config/hop-config.json` (or via GUI later): } ``` -Then from the Hop install directory: - ```bash export HOP_HOME=/path/to/hop ./hop marketplace install hop-tech-parquet -./hop marketplace install hop-engines-beam ./hop marketplace list ``` -Notes: +## Troubleshooting -- `hop-engines-beam` marketplace zip is the **plugin only**; `lib/beam` stays in the default client. -- Restart Hop after install/uninstall so the plugin registry reloads. +| Symptom | Fix | +|---------|-----| +| `Cannot start … database other than PostgreSQL` | Use this compose stack (includes Postgres). Wipe old volumes: `start.sh --reset` | +| `Join key is missing` | Run `generate-keys.sh`; ensure `.env` is passed to compose (`start.sh` does this) | +| `read-only file system` on join.key | Do not bind-mount key files; use env vars via `.env` | +| Stuck after earlier failed boots | `./start.sh --reset` to drop volumes | +| Low disk warning | Free space under Docker’s data root | + +## Stop + +```bash +docker compose -f docker/marketplace-artifactory/docker-compose.yml --env-file docker/marketplace-artifactory/.env down +# Wipe data: +docker compose -f docker/marketplace-artifactory/docker-compose.yml --env-file docker/marketplace-artifactory/.env down -v +``` diff --git a/docker/marketplace-artifactory/docker-compose.yml b/docker/marketplace-artifactory/docker-compose.yml index abe778d9e7d..694ba62a0ca 100644 --- a/docker/marketplace-artifactory/docker-compose.yml +++ b/docker/marketplace-artifactory/docker-compose.yml @@ -7,46 +7,65 @@ # # http://www.apache.org/licenses/LICENSE-2.0 # -# Local Artifactory OSS for Hop marketplace plugin testing (no ASF Nexus credentials required). +# Local Artifactory OSS + PostgreSQL for Hop marketplace testing. +# +# Recent Artifactory 7.x builds require PostgreSQL (embedded Derby is gone). # # Prerequisites: # ./docker/marketplace-artifactory/generate-keys.sh -# # creates keys/master.key and keys/join.key (openssl rand -hex 32), -# # mode 600, owner 1030:1030 +# Start: +# ./docker/marketplace-artifactory/start.sh # -# Usage: -# docker compose -f docker/marketplace-artifactory/docker-compose.yml up -d -# # open http://localhost:8082 (set admin password on first UI login) -# ./docker/marketplace-artifactory/publish-wave1-plugins.sh +# UI: http://localhost:8082 # services: + postgres: + image: postgres:15-alpine + container_name: hop-marketplace-postgres + environment: + POSTGRES_DB: artifactory + POSTGRES_USER: artifactory + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-hop_artifactory_dev} + volumes: + - hop-artifactory-postgres:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U artifactory -d artifactory"] + interval: 5s + timeout: 5s + retries: 20 + start_period: 10s + # Not published to host by default (Artifactory reaches it on the compose network) + artifactory: image: releases-docker.jfrog.io/jfrog/artifactory-oss:7.104.14 container_name: hop-marketplace-artifactory - # Official image runs as artifactory (UID/GID 1030) - user: "1030:1030" + depends_on: + postgres: + condition: service_healthy ports: - "8082:8082" - "8081:8081" volumes: - hop-artifactory-data:/var/opt/jfrog/artifactory - # Both keys are required at startup; without them microservices hang - # ("Cluster join: Join key is missing" / master key pending). - # Host files prepared by generate-keys.sh (600 / 1030:1030). - - ./keys/master.key:/var/opt/jfrog/artifactory/etc/security/master.key:ro - - ./keys/join.key:/var/opt/jfrog/artifactory/etc/security/join.key:ro environment: - # Reduce memory for local dev - EXTRA_JAVA_OPTIONS: -Xms512m -Xmx1g - # Artifactory 7.x shared security key locations - JF_SHARED_SECURITY_MASTER_KEY_FILE: /var/opt/jfrog/artifactory/etc/security/master.key - JF_SHARED_SECURITY_JOIN_KEY_FILE: /var/opt/jfrog/artifactory/etc/security/join.key + # Security keys as values (not bind-mounted files — Artifactory rewrites them) + JF_SHARED_SECURITY_MASTER_KEY: ${JF_SHARED_SECURITY_MASTER_KEY:?Run generate-keys.sh first} + JF_SHARED_SECURITY_JOIN_KEY: ${JF_SHARED_SECURITY_JOIN_KEY:?Run generate-keys.sh first} + # PostgreSQL (required by modern Artifactory OSS) + JF_SHARED_DATABASE_TYPE: postgresql + JF_SHARED_DATABASE_URL: jdbc:postgresql://postgres:5432/artifactory + JF_SHARED_DATABASE_USERNAME: artifactory + JF_SHARED_DATABASE_PASSWORD: ${POSTGRES_PASSWORD:-hop_artifactory_dev} + JF_SHARED_DATABASE_DRIVER: org.postgresql.Driver + # Heap: 1g is tight; raise if the host has RAM to spare + JF_SHARED_EXTRAJAVAOPTS: -Xms512m -Xmx2g healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8082/artifactory/api/system/ping"] interval: 30s timeout: 10s - retries: 20 - start_period: 180s + retries: 30 + start_period: 240s volumes: hop-artifactory-data: + hop-artifactory-postgres: diff --git a/docker/marketplace-artifactory/generate-keys.sh b/docker/marketplace-artifactory/generate-keys.sh index 52fcf3c7b97..d96f495ee12 100755 --- a/docker/marketplace-artifactory/generate-keys.sh +++ b/docker/marketplace-artifactory/generate-keys.sh @@ -8,13 +8,12 @@ # # http://www.apache.org/licenses/LICENSE-2.0 # -# Generate JFrog Artifactory security keys required for a clean startup: -# - master.key (shared master key) -# - join.key (cluster join key; required even for a single-node OSS stack) +# Generate JFrog Artifactory security keys for docker-compose: +# - master.key AES-128 → openssl rand -hex 16 (32 hex chars) +# - join.key cluster join → openssl rand -hex 32 (64 hex chars) # -# Both are openssl rand -hex 32 (64 hex chars, no trailing newline), mode 600, -# owned by UID/GID 1030:1030 (Artifactory process user in the official image). -# Without them, services hang ("Cluster join: Join key is missing"). +# Keys are written under keys/ and also mirrored into .env for compose +# (JF_SHARED_SECURITY_MASTER_KEY / JF_SHARED_SECURITY_JOIN_KEY). # # Usage: # ./docker/marketplace-artifactory/generate-keys.sh @@ -23,117 +22,57 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" KEYS_DIR="${SCRIPT_DIR}/keys" - -ARTIFACTORY_UID=1030 -ARTIFACTORY_GID=1030 +ENV_FILE="${SCRIPT_DIR}/.env" if ! command -v openssl >/dev/null 2>&1; then - echo "ERROR: openssl is required on the host to generate keys" >&2 + echo "ERROR: openssl is required on the host" >&2 exit 1 fi mkdir -p "${KEYS_DIR}" -# Write key material to a host temp file (64 hex chars, no newline) -make_key_material() { - local tmp - tmp="$(mktemp)" - openssl rand -hex 32 | tr -d '\n' > "${tmp}" - # Verify length (32 bytes → 64 hex chars) - local len - len="$(wc -c < "${tmp}" | tr -d ' ')" - if [[ "${len}" != "64" ]]; then - rm -f "${tmp}" - echo "ERROR: expected 64-char hex key, got length ${len}" >&2 - exit 1 - fi - echo "${tmp}" -} - -# Install a key file as 1030:1030 mode 600. Works even when an old key is owned by 1030. -install_key() { +# $1=filename $2=openssl hex byte count (16 → 32 chars, 32 → 64 chars) +ensure_key() { local name="$1" + local bytes="$2" + local expected_len=$((bytes * 2)) local dest="${KEYS_DIR}/${name}" - local material - material="$(make_key_material)" if [[ -f "${dest}" ]]; then - # Readable empty/corrupt keys should be replaced - local existing_len=0 - if [[ -r "${dest}" ]]; then - existing_len="$(wc -c < "${dest}" | tr -d ' ')" - else - # Unreadable (owned by 1030): probe via docker - if command -v docker >/dev/null 2>&1; then - existing_len="$(docker run --rm -v "${KEYS_DIR}:/keys" alpine:3.19 \ - sh -c "wc -c < /keys/${name}" | tr -d ' ')" - fi - fi - if [[ "${existing_len}" == "64" ]]; then - rm -f "${material}" - echo "Key already exists and looks valid: ${dest} (${existing_len} bytes)" + local len + len="$(wc -c < "${dest}" | tr -d ' ')" + if [[ "${len}" == "${expected_len}" ]]; then + echo "Key already exists: ${dest} (${len} bytes)" return 0 fi - echo "Replacing invalid/empty ${dest} (length ${existing_len})" + echo "Replacing invalid ${dest} (length ${len}, expected ${expected_len})" else - echo "Generating ${name}..." - fi - - # Try host write first - if cat "${material}" > "${dest}" 2>/dev/null \ - && chmod 600 "${dest}" 2>/dev/null \ - && chown "${ARTIFACTORY_UID}:${ARTIFACTORY_GID}" "${dest}" 2>/dev/null; then - rm -f "${material}" - echo "Wrote ${dest}" - return 0 + echo "Generating ${name} (openssl rand -hex ${bytes})..." fi - # Host cannot overwrite 1030-owned file: install via docker as root - if command -v docker >/dev/null 2>&1; then - docker run --rm \ - -v "${KEYS_DIR}:/keys" \ - -v "${material}:/tmp/key.material:ro" \ - alpine:3.19 \ - sh -c "cp /tmp/key.material /keys/${name} && chmod 600 /keys/${name} && chown ${ARTIFACTORY_UID}:${ARTIFACTORY_GID} /keys/${name}" - rm -f "${material}" - echo "Wrote ${dest} (via docker)" - return 0 - fi - - rm -f "${material}" - echo "ERROR: unable to write ${dest} (need docker or root for chown 1030:1030)" >&2 - exit 1 + # No trailing newline + openssl rand -hex "${bytes}" | tr -d '\n' > "${dest}" + chmod 600 "${dest}" 2>/dev/null || true + echo "Wrote ${dest}" } -fix_perms() { - local name="$1" - if chmod 600 "${KEYS_DIR}/${name}" 2>/dev/null \ - && chown "${ARTIFACTORY_UID}:${ARTIFACTORY_GID}" "${KEYS_DIR}/${name}" 2>/dev/null; then - return 0 - fi - if command -v docker >/dev/null 2>&1; then - docker run --rm -v "${KEYS_DIR}:/keys" alpine:3.19 \ - sh -c "chmod 600 /keys/${name} && chown ${ARTIFACTORY_UID}:${ARTIFACTORY_GID} /keys/${name}" - return 0 - fi - echo "WARNING: could not enforce 600 / ${ARTIFACTORY_UID}:${ARTIFACTORY_GID} on ${name}" >&2 - return 1 -} +ensure_key "master.key" 16 +ensure_key "join.key" 32 -install_key "master.key" -install_key "join.key" -fix_perms "master.key" -fix_perms "join.key" +MASTER_KEY="$(cat "${KEYS_DIR}/master.key")" +JOIN_KEY="$(cat "${KEYS_DIR}/join.key")" -echo "Key files:" -if command -v docker >/dev/null 2>&1; then - docker run --rm -v "${KEYS_DIR}:/keys" alpine:3.19 \ - sh -c 'ls -la /keys/master.key /keys/join.key && echo -n "lengths: " && wc -c /keys/master.key /keys/join.key' -else - ls -la "${KEYS_DIR}"/*.key - wc -c "${KEYS_DIR}"/*.key -fi +# Compose reads these as JF_SHARED_SECURITY_* (no file mounts — Artifactory +# tries to rewrite key files and RO bind-mounts fail). +cat > "${ENV_FILE}" <&2 + exit 1 +fi + +if [[ "${RESET}" == "true" ]]; then + echo "Resetting volumes (removes all Artifactory/Postgres data)..." + docker compose --env-file .env down -v +fi + +echo "Starting Artifactory + PostgreSQL..." +docker compose --env-file .env up -d + +echo +echo "Waiting for health (can take 2–4 minutes on first boot)..." +echo " Logs: docker logs -f hop-marketplace-artifactory" +echo " UI: http://localhost:8082" +echo +echo "Create a local Maven repo key 'hop-plugins-local', then:" +echo " export ARTIFACTORY_URL=http://localhost:8082/artifactory/hop-plugins-local" +echo " export ARTIFACTORY_USER=admin" +echo " export ARTIFACTORY_PASSWORD=… # set on first login" +echo " ./publish-wave1-plugins.sh" From 3c8a62151d4608edc3007b659553d4907009ccc5 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Sun, 19 Jul 2026 22:18:06 +0200 Subject: [PATCH 07/28] issue #7547: Basic auth for marketplace downloads (Artifactory 401) Send HTTP Basic credentials when installing plugins so private Maven repos work. Prefer HOP_MARKETPLACE_USERNAME/PASSWORD (or ARTIFACTORY_*) over storing secrets in hop-config.json. --- docker/marketplace-artifactory/README.md | 11 ++- plugins/misc/marketplace/README.md | 17 ++++- .../marketplace/config/MarketplaceConfig.java | 18 +++-- .../config/MarketplaceRepository.java | 68 ++++++++++++++++++ .../marketplace/env/EnvironmentApplier.java | 72 +++++++------------ .../marketplace/env/HopEnvironmentSpec.java | 5 ++ .../marketplace/install/PluginInstaller.java | 2 +- .../resolve/MavenRepositoryClient.java | 72 ++++++++++++++++--- .../install/PluginInstallerTest.java | 50 +++++++++++++ 9 files changed, 249 insertions(+), 66 deletions(-) diff --git a/docker/marketplace-artifactory/README.md b/docker/marketplace-artifactory/README.md index 7e84e42d8c9..f14a0639c91 100644 --- a/docker/marketplace-artifactory/README.md +++ b/docker/marketplace-artifactory/README.md @@ -112,19 +112,28 @@ export ARTIFACTORY_PASSWORD=… # from first-time setup "repositories": [ { "id": "local-artifactory", - "url": "http://localhost:8082/artifactory/hop-plugins-local/" + "url": "http://localhost:8082/artifactory/hop-plugins-local/", + "username": "admin" } ] } } ``` +Password via env (recommended — avoids storing secrets in hop-config.json): + ```bash export HOP_HOME=/path/to/hop +export HOP_MARKETPLACE_USERNAME=admin +export HOP_MARKETPLACE_PASSWORD='your-artifactory-password' +# aliases also work: ARTIFACTORY_USER / ARTIFACTORY_PASSWORD ./hop marketplace install hop-tech-parquet ./hop marketplace list ``` +**HTTP 401** means Artifactory rejected anonymous download — set the env vars (or put +`password` on the repository object) and retry. + ## Troubleshooting | Symptom | Fix | diff --git a/plugins/misc/marketplace/README.md b/plugins/misc/marketplace/README.md index c83dd3869d5..876bd22c6d4 100644 --- a/plugins/misc/marketplace/README.md +++ b/plugins/misc/marketplace/README.md @@ -80,13 +80,26 @@ Discovery order: `-f` / `HOP_ENV_FILE` / `PROJECT_HOME/hop-env.yaml` / `$HOP_HOM "groupId": "org.apache.hop", "defaultVersion": "2.19.0-SNAPSHOT", "repositories": [ - { "id": "central", "url": "https://repo1.maven.org/maven2/" } + { + "id": "local-artifactory", + "url": "http://localhost:8082/artifactory/hop-plugins-local/", + "username": "admin" + } ] } } ``` -For local testing see `docker/marketplace-artifactory/README.md`. +Password via environment (recommended — do not store secrets in hop-config.json): + +```bash +export HOP_MARKETPLACE_USERNAME=admin # or ARTIFACTORY_USER +export HOP_MARKETPLACE_PASSWORD='your-password' # or ARTIFACTORY_PASSWORD +``` + +**HTTP 401** means the repository requires auth: set the env vars (or `password` on the +repository object) and retry. For local Artifactory details see +`docker/marketplace-artifactory/README.md`. ## GUI diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java index c8b57f29ac0..18977187d30 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java @@ -72,13 +72,17 @@ public void save() { /** First repository base URL, or Maven Central. Always ends with {@code /}. */ public String primaryRepositoryUrl() { - if (repositories == null || repositories.isEmpty()) { - return DEFAULT_REPO_URL; - } - String url = repositories.get(0).getUrl(); - if (url == null || url.isBlank()) { - return DEFAULT_REPO_URL; + return primaryRepository().normalizedUrl(); + } + + /** First configured repository (with credentials), or Maven Central defaults. */ + public MarketplaceRepository primaryRepository() { + if (repositories != null && !repositories.isEmpty()) { + MarketplaceRepository first = repositories.get(0); + if (first != null && first.getUrl() != null && !first.getUrl().isBlank()) { + return first; + } } - return url.endsWith("/") ? url : url + "/"; + return new MarketplaceRepository("central", DEFAULT_REPO_URL); } } diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java index 043b21ffb37..37520b7e302 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java @@ -19,6 +19,7 @@ import lombok.Getter; import lombok.Setter; +import org.apache.commons.lang3.StringUtils; @Getter @Setter @@ -26,6 +27,15 @@ public class MarketplaceRepository { private String id = "central"; private String url = "https://repo1.maven.org/maven2/"; + /** Optional HTTP Basic auth username (e.g. Artifactory admin). */ + private String username; + + /** + * Optional HTTP Basic auth password. Prefer leaving this empty in hop-config.json and setting + * {@code HOP_MARKETPLACE_PASSWORD} or {@code ARTIFACTORY_PASSWORD} instead. + */ + private String password; + public MarketplaceRepository() { // Jackson } @@ -34,4 +44,62 @@ public MarketplaceRepository(String id, String url) { this.id = id; this.url = url; } + + public MarketplaceRepository(String id, String url, String username, String password) { + this.id = id; + this.url = url; + this.username = username; + this.password = password; + } + + /** Base URL always ending with {@code /}. */ + public String normalizedUrl() { + if (StringUtils.isBlank(url)) { + return MarketplaceConfig.DEFAULT_REPO_URL; + } + return url.endsWith("/") ? url : url + "/"; + } + + /** + * Effective credentials: config fields, then env {@code HOP_MARKETPLACE_*} / {@code + * ARTIFACTORY_*}. + */ + public String effectiveUsername() { + if (StringUtils.isNotBlank(username)) { + return username; + } + String fromEnv = + firstNonBlank( + System.getenv("HOP_MARKETPLACE_USERNAME"), + System.getenv("HOP_MARKETPLACE_USER"), + System.getenv("ARTIFACTORY_USER")); + return StringUtils.isNotBlank(fromEnv) ? fromEnv : null; + } + + public String effectivePassword() { + if (StringUtils.isNotBlank(password)) { + return password; + } + String fromEnv = + firstNonBlank( + System.getenv("HOP_MARKETPLACE_PASSWORD"), System.getenv("ARTIFACTORY_PASSWORD")); + return StringUtils.isNotBlank(fromEnv) ? fromEnv : null; + } + + public boolean hasCredentials() { + return StringUtils.isNotBlank(effectiveUsername()) + && StringUtils.isNotBlank(effectivePassword()); + } + + private static String firstNonBlank(String... values) { + if (values == null) { + return null; + } + for (String v : values) { + if (StringUtils.isNotBlank(v)) { + return v; + } + } + return null; + } } diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/EnvironmentApplier.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/EnvironmentApplier.java index 4573fc2565c..b9c11e3032a 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/EnvironmentApplier.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/EnvironmentApplier.java @@ -36,6 +36,7 @@ import org.apache.hop.marketplace.install.PluginInstaller; import org.apache.hop.marketplace.install.PluginUninstaller; import org.apache.hop.marketplace.resolve.MavenCoordinates; +import org.apache.hop.marketplace.resolve.MavenRepositoryClient; /** Applies or validates a {@link HopEnvironmentSpec} against a Hop installation. */ public class EnvironmentApplier { @@ -144,11 +145,22 @@ public void apply(HopEnvironmentSpec env, boolean prune) throws HopException { } MavenCoordinates coords = new MavenCoordinates(dep.getGroupId(), dep.getArtifactId(), dep.getVersion()); - String base = config.primaryRepositoryUrl(); + String relativePath = + coords.groupId().replace('.', '/') + + "/" + + coords.artifactId() + + "/" + + coords.version() + + "/" + + coords.artifactId() + + "-" + + coords.version() + + ".jar"; log.logBasic("Downloading dependency " + coords.gav() + " → " + target); try { Files.createDirectories(dir); - downloadJar(base, coords, jar); + new MavenRepositoryClient(log) + .downloadArtifact(config.primaryRepository(), relativePath, coords.gav(), jar); } catch (IOException e) { throw new HopException("Failed to install dependency " + coords.gav(), e); } @@ -159,45 +171,6 @@ public void apply(HopEnvironmentSpec env, boolean prune) throws HopException { } } - private void downloadJar(String repoBase, MavenCoordinates coords, Path targetJar) - throws HopException, IOException { - String path = - coords.groupId().replace('.', '/') - + "/" - + coords.artifactId() - + "/" - + coords.version() - + "/" - + coords.artifactId() - + "-" - + coords.version() - + ".jar"; - String base = repoBase.endsWith("/") ? repoBase : repoBase + "/"; - java.net.http.HttpClient http = - java.net.http.HttpClient.newBuilder() - .followRedirects(java.net.http.HttpClient.Redirect.NORMAL) - .build(); - java.net.http.HttpRequest request = - java.net.http.HttpRequest.newBuilder(java.net.URI.create(base + path)) - .timeout(java.time.Duration.ofMinutes(10)) - .GET() - .build(); - try { - java.net.http.HttpResponse response = - http.send(request, java.net.http.HttpResponse.BodyHandlers.ofInputStream()); - if (response.statusCode() != 200) { - throw new HopException("HTTP " + response.statusCode() + " downloading " + base + path); - } - Files.createDirectories(targetJar.getParent()); - try (java.io.InputStream in = response.body()) { - Files.copy(in, targetJar, java.nio.file.StandardCopyOption.REPLACE_EXISTING); - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new HopException("Interrupted downloading " + coords.gav(), e); - } - } - private void pruneExtras(Set desiredArtifacts) throws HopException { Path receiptsDir = hopHome.resolve(PluginInstaller.RECEIPTS_DIR); if (!Files.isDirectory(receiptsDir)) { @@ -227,14 +200,21 @@ private MarketplaceConfig configFromEnv(HopEnvironmentSpec env) { ? env.getHopVersion() : MarketplaceCommand.resolveDefaultVersion(baseConfig)); config.getRepositories().clear(); + MarketplaceRepository baseRepo = baseConfig.primaryRepository(); if (env.getRepositories() != null && !env.getRepositories().isEmpty()) { for (HopEnvironmentSpec.RepositoryRef ref : env.getRepositories()) { if (StringUtils.isNotBlank(ref.getUrl())) { - config - .getRepositories() - .add( - new MarketplaceRepository( - StringUtils.defaultIfBlank(ref.getId(), "env"), ref.getUrl())); + MarketplaceRepository repo = + new MarketplaceRepository( + StringUtils.defaultIfBlank(ref.getId(), "env"), + ref.getUrl(), + StringUtils.isNotBlank(ref.getUsername()) + ? ref.getUsername() + : baseRepo.getUsername(), + StringUtils.isNotBlank(ref.getPassword()) + ? ref.getPassword() + : baseRepo.getPassword()); + config.getRepositories().add(repo); } } } diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentSpec.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentSpec.java index c3a71f5d996..66d0e474529 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentSpec.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentSpec.java @@ -56,6 +56,11 @@ public class HopEnvironmentSpec { public static class RepositoryRef { private String id; private String url; + + /** Optional Basic auth username (prefer env HOP_MARKETPLACE_PASSWORD for secrets). */ + private String username; + + private String password; } @Getter diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java index 5d434b0a53d..30777b07182 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java @@ -81,7 +81,7 @@ public InstallReceipt install(MavenCoordinates coordinates, boolean activateImme Path zipFile = downloadDir.resolve(coordinates.artifactId() + "-" + coordinates.version() + ".zip"); try { - client.downloadZip(config.primaryRepositoryUrl(), coordinates, zipFile); + client.downloadZip(config.primaryRepository(), coordinates, zipFile); Path stageRoot = hopHome.resolve(STAGING_DIR).resolve(coordinates.artifactId()); deleteRecursive(stageRoot); Files.createDirectories(stageRoot); diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java index f293ad86b8f..96b9ad47b9f 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java @@ -23,14 +23,18 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.time.Duration; +import java.util.Base64; +import org.apache.commons.lang3.StringUtils; import org.apache.hop.core.exception.HopException; import org.apache.hop.core.logging.ILogChannel; +import org.apache.hop.marketplace.config.MarketplaceRepository; -/** Downloads Maven layout artifacts over HTTP(S). */ +/** Downloads Maven layout artifacts over HTTP(S), with optional Basic authentication. */ public class MavenRepositoryClient { private final HttpClient httpClient; @@ -50,20 +54,56 @@ public MavenRepositoryClient(ILogChannel log, HttpClient httpClient) { this.httpClient = httpClient; } - public Path downloadZip(String repositoryBaseUrl, MavenCoordinates coordinates, Path targetFile) + public Path downloadZip( + MarketplaceRepository repository, MavenCoordinates coordinates, Path targetFile) throws HopException { - String base = repositoryBaseUrl.endsWith("/") ? repositoryBaseUrl : repositoryBaseUrl + "/"; + String base = repository.normalizedUrl(); String url = base + coordinates.zipRepositoryPath(); - log.logBasic("Downloading " + coordinates.gav() + " from " + url); + return download(url, repository, coordinates.gav(), targetFile); + } + + /** + * @deprecated use {@link #downloadZip(MarketplaceRepository, MavenCoordinates, Path)} + */ + public Path downloadZip(String repositoryBaseUrl, MavenCoordinates coordinates, Path targetFile) + throws HopException { + MarketplaceRepository repo = new MarketplaceRepository("adhoc", repositoryBaseUrl); + return downloadZip(repo, coordinates, targetFile); + } + + public Path downloadArtifact( + MarketplaceRepository repository, String relativePath, String label, Path targetFile) + throws HopException { + String base = repository.normalizedUrl(); + String url = base + (relativePath.startsWith("/") ? relativePath.substring(1) : relativePath); + return download(url, repository, label, targetFile); + } + + private Path download(String url, MarketplaceRepository repository, String label, Path targetFile) + throws HopException { + log.logBasic("Downloading " + label + " from " + url); try { Files.createDirectories(targetFile.getParent()); - HttpRequest request = - HttpRequest.newBuilder(URI.create(url)).timeout(Duration.ofMinutes(30)).GET().build(); + HttpRequest.Builder builder = + HttpRequest.newBuilder(URI.create(url)).timeout(Duration.ofMinutes(30)).GET(); + applyBasicAuth(builder, repository); HttpResponse response = - httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream()); + httpClient.send(builder.build(), HttpResponse.BodyHandlers.ofInputStream()); + if (response.statusCode() == 401 || response.statusCode() == 403) { + throw new HopException( + "HTTP " + + response.statusCode() + + " downloading " + + label + + " from " + + url + + ". Set repository username/password in hop-config.json marketplace.repositories," + + " or export HOP_MARKETPLACE_USERNAME / HOP_MARKETPLACE_PASSWORD" + + " (or ARTIFACTORY_USER / ARTIFACTORY_PASSWORD)."); + } if (response.statusCode() != 200) { throw new HopException( - "HTTP " + response.statusCode() + " downloading plugin zip from " + url); + "HTTP " + response.statusCode() + " downloading " + label + " from " + url); } try (InputStream in = response.body()) { Files.copy(in, targetFile, StandardCopyOption.REPLACE_EXISTING); @@ -74,7 +114,21 @@ public Path downloadZip(String repositoryBaseUrl, MavenCoordinates coordinates, if (e instanceof InterruptedException) { Thread.currentThread().interrupt(); } - throw new HopException("Failed to download plugin zip from " + url, e); + throw new HopException("Failed to download " + label + " from " + url, e); + } + } + + static void applyBasicAuth(HttpRequest.Builder builder, MarketplaceRepository repository) { + if (repository == null || !repository.hasCredentials()) { + return; + } + String user = repository.effectiveUsername(); + String pass = repository.effectivePassword(); + if (StringUtils.isAnyBlank(user, pass)) { + return; } + String token = + Base64.getEncoder().encodeToString((user + ":" + pass).getBytes(StandardCharsets.UTF_8)); + builder.header("Authorization", "Basic " + token); } } diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/PluginInstallerTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/PluginInstallerTest.java index c83bb632dcc..b7aa07f02f8 100644 --- a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/PluginInstallerTest.java +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/PluginInstallerTest.java @@ -103,6 +103,56 @@ void installAndUninstallFromLocalHttpRepo() throws Exception { } } + @Test + void installWithBasicAuth() throws Exception { + byte[] zipBytes = buildPluginZip(); + HttpServer server = HttpServer.create(new InetSocketAddress(0), 0); + String path = "/org/apache/hop/hop-test-plugin/1.0.0/hop-test-plugin-1.0.0.zip"; + server.createContext( + path, + exchange -> { + String auth = exchange.getRequestHeaders().getFirst("Authorization"); + if (auth == null || !auth.startsWith("Basic ")) { + exchange.sendResponseHeaders(401, -1); + exchange.close(); + return; + } + String decoded = + new String( + java.util.Base64.getDecoder().decode(auth.substring("Basic ".length())), + StandardCharsets.UTF_8); + if (!"admin:s3cret".equals(decoded)) { + exchange.sendResponseHeaders(401, -1); + exchange.close(); + return; + } + exchange.getResponseHeaders().add("Content-Type", "application/zip"); + exchange.sendResponseHeaders(200, zipBytes.length); + exchange.getResponseBody().write(zipBytes); + exchange.close(); + }); + server.start(); + try { + int port = server.getAddress().getPort(); + Path hopHome = tempDir.resolve("hop-auth"); + Files.createDirectories(hopHome.resolve("plugins")); + + MarketplaceConfig config = new MarketplaceConfig(); + config.getRepositories().clear(); + config + .getRepositories() + .add( + new MarketplaceRepository( + "local", "http://127.0.0.1:" + port + "/", "admin", "s3cret")); + + new PluginInstaller(new LogChannel("test"), hopHome, config) + .install(new MavenCoordinates("org.apache.hop", "hop-test-plugin", "1.0.0"), true); + assertTrue(Files.isRegularFile(hopHome.resolve("plugins/tech/test/plugin.jar"))); + } finally { + server.stop(0); + } + } + private static byte[] buildPluginZip() throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try (ZipOutputStream zos = new ZipOutputStream(bos)) { From 40d19e0303f5c85303011eb814bb97d615213748 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Sun, 19 Jul 2026 22:24:27 +0200 Subject: [PATCH 08/28] issue #7547: configure Artifactory anonymous read for marketplace installs Add configure-anonymous-read.sh and document the intended security model: admin only for publish; anonymous read-only on hop-plugins-local for Hop downloads (no admin credentials in hop-config). --- docker/marketplace-artifactory/README.md | 166 +++++++++------ .../configure-anonymous-read.sh | 197 ++++++++++++++++++ plugins/misc/marketplace/README.md | 14 +- 3 files changed, 311 insertions(+), 66 deletions(-) create mode 100755 docker/marketplace-artifactory/configure-anonymous-read.sh diff --git a/docker/marketplace-artifactory/README.md b/docker/marketplace-artifactory/README.md index f14a0639c91..08a6f6e9823 100644 --- a/docker/marketplace-artifactory/README.md +++ b/docker/marketplace-artifactory/README.md @@ -21,87 +21,99 @@ under the License. Use this stack to exercise plugin install/uninstall **without** ASF Nexus permissions. -## Requirements +## Security model (recommended) -Recent **Artifactory OSS 7.x requires PostgreSQL** (the embedded database is gone). This -compose stack runs: +| Action | Who | +|--------|-----| +| **Download / install plugins** (Hop marketplace) | **Anonymous** (read-only on `hop-plugins-local`) | +| **Publish plugin zips** (`publish-wave1-plugins.sh`) | **Admin** (or a deploy user) | +| UI administration | Admin only | -| Service | Purpose | -|---------|---------| -| `postgres` | Required DB for Artifactory | -| `artifactory` | Maven repo for Hop plugin zips | +Nobody should put admin credentials into `hop-config.json` or day-to-day Hop usage. +Admin is only for publishing and one-time setup. -Also requires Docker Compose and `openssl` on the host. - -## Security keys - -Artifactory needs a **master key** (AES-128) and a **join key**. Generate once: - -```bash -./docker/marketplace-artifactory/generate-keys.sh -``` - -| File | Size | How | -|------|------|-----| -| `keys/master.key` | 32 hex chars | `openssl rand -hex 16` | -| `keys/join.key` | 64 hex chars | `openssl rand -hex 32` | -| `.env` | compose env | master/join + Postgres password | - -Keys and `.env` are gitignored. Keys are passed into the container as -**environment variables** (`JF_SHARED_SECURITY_MASTER_KEY` / -`JF_SHARED_SECURITY_JOIN_KEY`), not bind-mounted files — Artifactory tries to -rewrite key files and RO mounts break startup. +Recent Artifactory versions also **require PostgreSQL** (embedded DB is gone). This compose +stack runs Postgres + Artifactory OSS. ## Start ```bash -# First time or after failed starts with an old volume layout: +# First time or after a broken volume layout: ./docker/marketplace-artifactory/start.sh --reset -# Normal start: +# Later: ./docker/marketplace-artifactory/start.sh ``` -First boot can take **2–4 minutes**. Watch logs: +Wait until healthy: ```bash -docker logs -f hop-marketplace-artifactory +curl -sf http://localhost:8082/artifactory/api/system/ping && echo OK ``` -Healthy when: +Open http://localhost:8082 and set the **admin** password on first login. + +## Configure anonymous read (after admin password) ```bash -curl -sf http://localhost:8082/artifactory/api/system/ping && echo OK +export ARTIFACTORY_PASSWORD='your-admin-password' +./docker/marketplace-artifactory/configure-anonymous-read.sh ``` -Open http://localhost:8082 and complete first-time admin password setup. +That script: + +1. Creates local Maven repo **`hop-plugins-local`** (if missing) +2. Turns on **Allow Anonymous Access** +3. Adds permission **`hop-plugins-anonymous-read`**: user `anonymous` → **read only** + on `hop-plugins-local` (no deploy/delete/manage) -### Create the Maven repository +### UI equivalent (if the script cannot update security config) -| Field | Value | -|-------|--------| -| Package type | Maven | -| Repository Key | `hop-plugins-local` | -| Repository Layout | maven-2-default | +1. **Administration → User Management → Settings** + - Enable **Allow Anonymous Access** +2. **Administration → Repositories → Add Repositories → Local Repository** + - Package type: Maven + - Repository Key: `hop-plugins-local` + - Layout: `maven-2-default` +3. **Administration → User Management → Permissions → New Permission** + - Name: e.g. `hop-plugins-anonymous-read` + - **Repositories:** `hop-plugins-local` only + - **Users:** `anonymous` + - **Actions:** **Read** only (do **not** tick Deploy / Delete / Manage / Annotate) -Base URL: +Repo URL: ```text http://localhost:8082/artifactory/hop-plugins-local/ ``` -## Publish Wave 1 plugin zips +## Publish Wave 1 plugin zips (authenticated) -Build Hop plugins first, then: +Build plugin modules, then deploy with admin (or a dedicated deploy user): ```bash export ARTIFACTORY_URL=http://localhost:8082/artifactory/hop-plugins-local export ARTIFACTORY_USER=admin -export ARTIFACTORY_PASSWORD=… # from first-time setup +export ARTIFACTORY_PASSWORD='your-admin-password' +# Maven needs a matching in ~/.m2/settings.xml (id = hop-plugins-local) ./docker/marketplace-artifactory/publish-wave1-plugins.sh ``` -## Point Hop marketplace at local Artifactory +`~/.m2/settings.xml` snippet: + +```xml + + + hop-plugins-local + admin + your-admin-password + + +``` + +## Install from Hop (anonymous — no password) + +`hop-config.json` (no username/password required once anonymous read is configured): ```json { @@ -112,42 +124,70 @@ export ARTIFACTORY_PASSWORD=… # from first-time setup "repositories": [ { "id": "local-artifactory", - "url": "http://localhost:8082/artifactory/hop-plugins-local/", - "username": "admin" + "url": "http://localhost:8082/artifactory/hop-plugins-local/" } ] } } ``` -Password via env (recommended — avoids storing secrets in hop-config.json): - ```bash export HOP_HOME=/path/to/hop -export HOP_MARKETPLACE_USERNAME=admin -export HOP_MARKETPLACE_PASSWORD='your-artifactory-password' -# aliases also work: ARTIFACTORY_USER / ARTIFACTORY_PASSWORD +# Do NOT export admin password for install ./hop marketplace install hop-tech-parquet -./hop marketplace list ``` -**HTTP 401** means Artifactory rejected anonymous download — set the env vars (or put -`password` on the repository object) and retry. +Quick anonymous check: + +```bash +# Expect 200 (or 404 if that path is empty), not 401 +curl -sI "http://localhost:8082/artifactory/hop-plugins-local/org/apache/hop/" | head -1 +``` + +If you still get **401**, anonymous access or the read permission is not applied — re-run +`configure-anonymous-read.sh` or the UI steps above. + +### Optional: authenticated downloads + +Corporate Artifactory that cannot allow anonymous can still use: + +```bash +export HOP_MARKETPLACE_USERNAME=deploy-reader +export HOP_MARKETPLACE_PASSWORD='…' +``` + +Prefer a **read-only deploy user**, not admin. + +## Security keys (compose bootstrap) + +```bash +./docker/marketplace-artifactory/generate-keys.sh +``` + +| File | Size | How | +|------|------|-----| +| `keys/master.key` | 32 hex chars | `openssl rand -hex 16` | +| `keys/join.key` | 64 hex chars | `openssl rand -hex 32` | +| `.env` | compose env | master/join + Postgres password | + +Gitignored. Passed as env vars into the container (not RO file mounts). ## Troubleshooting | Symptom | Fix | |---------|-----| -| `Cannot start … database other than PostgreSQL` | Use this compose stack (includes Postgres). Wipe old volumes: `start.sh --reset` | -| `Join key is missing` | Run `generate-keys.sh`; ensure `.env` is passed to compose (`start.sh` does this) | -| `read-only file system` on join.key | Do not bind-mount key files; use env vars via `.env` | -| Stuck after earlier failed boots | `./start.sh --reset` to drop volumes | -| Low disk warning | Free space under Docker’s data root | +| `HTTP 401` on `hop marketplace install` | Enable anonymous + read permission (`configure-anonymous-read.sh`) | +| `Cannot start … PostgreSQL` | Use this compose stack; `./start.sh --reset` | +| Join key / startup hang | `generate-keys.sh` + `start.sh --reset` | +| Publish 401 | Admin `settings.xml` / `ARTIFACTORY_PASSWORD` for deploy only | ## Stop ```bash -docker compose -f docker/marketplace-artifactory/docker-compose.yml --env-file docker/marketplace-artifactory/.env down -# Wipe data: -docker compose -f docker/marketplace-artifactory/docker-compose.yml --env-file docker/marketplace-artifactory/.env down -v +docker compose -f docker/marketplace-artifactory/docker-compose.yml \ + --env-file docker/marketplace-artifactory/.env down + +# Wipe all data: +docker compose -f docker/marketplace-artifactory/docker-compose.yml \ + --env-file docker/marketplace-artifactory/.env down -v ``` diff --git a/docker/marketplace-artifactory/configure-anonymous-read.sh b/docker/marketplace-artifactory/configure-anonymous-read.sh new file mode 100755 index 00000000000..832c0ac0973 --- /dev/null +++ b/docker/marketplace-artifactory/configure-anonymous-read.sh @@ -0,0 +1,197 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Configure local Artifactory so Hop marketplace can download plugins without +# admin credentials: +# 1. Ensure local Maven repo hop-plugins-local exists +# 2. Enable global "Allow Anonymous Access" +# 3. Grant anonymous *read only* on hop-plugins-local (not deploy/delete) +# +# Deploy/publish still requires admin (or another user with write). +# +# Usage: +# export ARTIFACTORY_PASSWORD='…' # admin password from first login +# ./docker/marketplace-artifactory/configure-anonymous-read.sh +# +set -euo pipefail + +BASE_URL="${ARTIFACTORY_URL_BASE:-http://localhost:8082}" +USER="${ARTIFACTORY_USER:-admin}" +PASS="${ARTIFACTORY_PASSWORD:-}" +REPO_KEY="${ARTIFACTORY_REPO_KEY:-hop-plugins-local}" +PERM_NAME="${ARTIFACTORY_ANON_PERM:-hop-plugins-anonymous-read}" + +if [[ -z "${PASS}" ]]; then + echo "Set ARTIFACTORY_PASSWORD to the Artifactory admin password." >&2 + exit 1 +fi + +AUTH=(-u "${USER}:${PASS}") +API="${BASE_URL}/artifactory/api" + +echo "==> Checking Artifactory at ${BASE_URL}" +if ! curl -sf "${BASE_URL}/artifactory/api/system/ping" >/dev/null; then + echo "ERROR: Artifactory not reachable (ping failed)." >&2 + exit 1 +fi + +# --- 1) Local Maven repository ------------------------------------------------ +echo "==> Ensuring local Maven repository '${REPO_KEY}'" +REPO_CODE=$(curl -s -o /tmp/hop-af-repo.json -w '%{http_code}' "${AUTH[@]}" \ + "${API}/repositories/${REPO_KEY}" || true) +if [[ "${REPO_CODE}" == "200" ]]; then + echo " Repository already exists" +else + HTTP=$(curl -s -o /tmp/hop-af-create-repo.json -w '%{http_code}' "${AUTH[@]}" \ + -X PUT "${API}/repositories/${REPO_KEY}" \ + -H 'Content-Type: application/json' \ + -d "{ + \"key\": \"${REPO_KEY}\", + \"rclass\": \"local\", + \"packageType\": \"maven\", + \"repoLayoutRef\": \"maven-2-default\", + \"description\": \"Hop marketplace plugin zips (local / IT)\" + }") + if [[ "${HTTP}" != "200" && "${HTTP}" != "201" ]]; then + echo "ERROR: create repository failed (HTTP ${HTTP}):" >&2 + cat /tmp/hop-af-create-repo.json >&2 || true + exit 1 + fi + echo " Created ${REPO_KEY}" +fi + +# --- 2) Enable anonymous access (global) -------------------------------------- +# Artifactory security configuration (classic REST). We GET, patch anonAccessEnabled, PUT back. +echo "==> Enabling global anonymous access" +if curl -sf "${AUTH[@]}" "${API}/security/configuration" -o /tmp/hop-af-sec.json; then + # configuration is XML for some versions, JSON for others — handle both lightly + if head -c 1 /tmp/hop-af-sec.json | grep -q '<'; then + # XML: set true + if grep -q '' /tmp/hop-af-sec.json; then + sed -i 's#[^<]*#true#' /tmp/hop-af-sec.json + else + # insert before closing security tag if present + sed -i 's## true\n#' /tmp/hop-af-sec.json + fi + HTTP=$(curl -s -o /tmp/hop-af-sec-put.json -w '%{http_code}' "${AUTH[@]}" \ + -X POST "${API}/security/configuration" \ + -H 'Content-Type: application/xml' \ + --data-binary @/tmp/hop-af-sec.json) + else + # JSON (Access / newer): set anonAccessEnabled + if command -v python3 >/dev/null 2>&1; then + python3 - <<'PY' +import json +from pathlib import Path +p = Path("/tmp/hop-af-sec.json") +data = json.loads(p.read_text()) +# common shapes +if isinstance(data, dict): + data["anonAccessEnabled"] = True + if "security" in data and isinstance(data["security"], dict): + data["security"]["anonAccessEnabled"] = True +p.write_text(json.dumps(data)) +PY + fi + HTTP=$(curl -s -o /tmp/hop-af-sec-put.json -w '%{http_code}' "${AUTH[@]}" \ + -X POST "${API}/security/configuration" \ + -H 'Content-Type: application/json' \ + --data-binary @/tmp/hop-af-sec.json) + fi + if [[ "${HTTP}" == "200" || "${HTTP}" == "201" || "${HTTP}" == "204" ]]; then + echo " Anonymous access enabled (API)" + else + echo " WARNING: could not set anonymous via API (HTTP ${HTTP})." + echo " Do this in the UI: Administration → User Management → Settings → Allow Anonymous Access" + cat /tmp/hop-af-sec-put.json 2>/dev/null || true + fi +else + echo " WARNING: GET /security/configuration failed." + echo " Enable in UI: Administration → User Management → Settings → Allow Anonymous Access" +fi + +# --- 3) Permission: anonymous READ only on hop-plugins-local -------------------- +# Artifactory 7.x removed anonymous from the default "Anything" target — grant explicitly. +echo "==> Creating permission '${PERM_NAME}' (anonymous → read on ${REPO_KEY} only)" +HTTP=$(curl -s -o /tmp/hop-af-perm.json -w '%{http_code}' "${AUTH[@]}" \ + -X PUT "${API}/v2/security/permissions/${PERM_NAME}" \ + -H 'Content-Type: application/json' \ + -d "{ + \"name\": \"${PERM_NAME}\", + \"repo\": { + \"include-patterns\": [\"**\"], + \"exclude-patterns\": [], + \"repositories\": [\"${REPO_KEY}\"], + \"actions\": { + \"users\": { + \"anonymous\": [\"read\"] + } + } + } + }") + +if [[ "${HTTP}" != "200" && "${HTTP}" != "201" ]]; then + # Fallback: classic permissions API + HTTP2=$(curl -s -o /tmp/hop-af-perm2.json -w '%{http_code}' "${AUTH[@]}" \ + -X PUT "${API}/security/permissions/${PERM_NAME}" \ + -H 'Content-Type: application/json' \ + -d "{ + \"name\": \"${PERM_NAME}\", + \"repositories\": [\"${REPO_KEY}\"], + \"principals\": { + \"users\": { + \"anonymous\": [\"r\"] + } + } + }") + if [[ "${HTTP2}" != "200" && "${HTTP2}" != "201" ]]; then + echo "ERROR: could not create permission (v2 HTTP ${HTTP}, classic HTTP ${HTTP2}):" >&2 + cat /tmp/hop-af-perm.json >&2 || true + cat /tmp/hop-af-perm2.json >&2 || true + echo >&2 + echo "UI fallback:" >&2 + echo " 1) Administration → User Management → Settings → Allow Anonymous Access = ON" >&2 + echo " 2) Administration → User Management → Permissions → New Permission" >&2 + echo " Repositories: ${REPO_KEY}" >&2 + echo " Users: anonymous → Read only (no Deploy/Delete/Manage)" >&2 + exit 1 + fi + echo " Permission created (classic API)" +else + echo " Permission created (v2 API)" +fi + +# --- 4) Smoke test anonymous download path ------------------------------------ +echo "==> Smoke test: anonymous GET on repo root (expect 200 or 404 empty, not 401)" +ANON_CODE=$(curl -s -o /dev/null -w '%{http_code}' \ + "${BASE_URL}/artifactory/${REPO_KEY}/" || true) +case "${ANON_CODE}" in + 200|404) + echo " OK (HTTP ${ANON_CODE}) — anonymous can reach the repository" + ;; + 401|403) + echo " STILL DENIED (HTTP ${ANON_CODE}). Check UI anonymous + permission steps above." >&2 + exit 1 + ;; + *) + echo " Unexpected HTTP ${ANON_CODE} (repo may be empty; try install after publish)" + ;; +esac + +echo +echo "Done. Deploy still needs admin; downloads do not:" +echo " # publish (authenticated)" +echo " export ARTIFACTORY_PASSWORD=…" +echo " ./docker/marketplace-artifactory/publish-wave1-plugins.sh" +echo +echo " # install (no credentials)" +echo " # hop-config marketplace.repositories[0].url =" +echo " # ${BASE_URL}/artifactory/${REPO_KEY}/" +echo " ./hop marketplace install hop-tech-parquet" diff --git a/plugins/misc/marketplace/README.md b/plugins/misc/marketplace/README.md index 876bd22c6d4..1e7064580ea 100644 --- a/plugins/misc/marketplace/README.md +++ b/plugins/misc/marketplace/README.md @@ -97,9 +97,17 @@ export HOP_MARKETPLACE_USERNAME=admin # or ARTIFACTORY_USER export HOP_MARKETPLACE_PASSWORD='your-password' # or ARTIFACTORY_PASSWORD ``` -**HTTP 401** means the repository requires auth: set the env vars (or `password` on the -repository object) and retry. For local Artifactory details see -`docker/marketplace-artifactory/README.md`. +**HTTP 401** means the repository requires auth. For local Artifactory, prefer +**anonymous read** on `hop-plugins-local` (no credentials in Hop): + +```bash +export ARTIFACTORY_PASSWORD='admin-password' +./docker/marketplace-artifactory/configure-anonymous-read.sh +``` + +Then install without password. Corporate repos that cannot allow anonymous can still use +`HOP_MARKETPLACE_USERNAME` / `HOP_MARKETPLACE_PASSWORD` (prefer a read-only user, not admin). +See `docker/marketplace-artifactory/README.md`. ## GUI From cbc5441551940d5d4f6345e54dffddb7dbb4357e Mon Sep 17 00:00:00 2001 From: mattcasters Date: Sun, 19 Jul 2026 22:26:59 +0200 Subject: [PATCH 09/28] issue #7547: Artifactory OSS anonymous setup via UI (no Pro REST) Repository create REST is Pro-only on Artifactory OSS. Rewrite configure-anonymous-read.sh to document UI steps and verify anonymous read instead of calling Pro APIs. --- .../configure-anonymous-read.sh | 256 +++++++----------- 1 file changed, 101 insertions(+), 155 deletions(-) diff --git a/docker/marketplace-artifactory/configure-anonymous-read.sh b/docker/marketplace-artifactory/configure-anonymous-read.sh index 832c0ac0973..9c5eccfc123 100755 --- a/docker/marketplace-artifactory/configure-anonymous-read.sh +++ b/docker/marketplace-artifactory/configure-anonymous-read.sh @@ -8,16 +8,18 @@ # # http://www.apache.org/licenses/LICENSE-2.0 # -# Configure local Artifactory so Hop marketplace can download plugins without -# admin credentials: -# 1. Ensure local Maven repo hop-plugins-local exists -# 2. Enable global "Allow Anonymous Access" -# 3. Grant anonymous *read only* on hop-plugins-local (not deploy/delete) +# Configure *Artifactory OSS* so Hop can download plugins without admin credentials. # -# Deploy/publish still requires admin (or another user with write). +# IMPORTANT: Artifactory OSS does NOT allow creating repositories (or many admin +# security resources) via REST — those APIs return HTTP 400 "Artifactory Pro only". +# Repository + anonymous + read permission are done in the UI; this script prints +# the exact clicks and verifies anonymous access afterward. # # Usage: -# export ARTIFACTORY_PASSWORD='…' # admin password from first login +# # 1) Create hop-plugins-local in the UI (see printed steps) +# # 2) Enable anonymous + read permission (see printed steps) +# # 3) Optional verify: +# export ARTIFACTORY_PASSWORD='…' # ./docker/marketplace-artifactory/configure-anonymous-read.sh # set -euo pipefail @@ -26,172 +28,116 @@ BASE_URL="${ARTIFACTORY_URL_BASE:-http://localhost:8082}" USER="${ARTIFACTORY_USER:-admin}" PASS="${ARTIFACTORY_PASSWORD:-}" REPO_KEY="${ARTIFACTORY_REPO_KEY:-hop-plugins-local}" -PERM_NAME="${ARTIFACTORY_ANON_PERM:-hop-plugins-anonymous-read}" + +REPO_URL="${BASE_URL}/artifactory/${REPO_KEY}/" + +echo "============================================================" +echo " Artifactory OSS — anonymous read for Hop marketplace" +echo "============================================================" +echo +echo "Artifactory OSS license: repository create/manage REST APIs are Pro-only." +echo "Do the following once in the UI at ${BASE_URL}/" +echo + +cat <&2 - exit 1 + echo "Set ARTIFACTORY_PASSWORD and re-run this script to verify anonymous access:" + echo " export ARTIFACTORY_PASSWORD='…'" + echo " $0" + exit 0 fi AUTH=(-u "${USER}:${PASS}") -API="${BASE_URL}/artifactory/api" -echo "==> Checking Artifactory at ${BASE_URL}" +echo "==> Checking Artifactory" if ! curl -sf "${BASE_URL}/artifactory/api/system/ping" >/dev/null; then - echo "ERROR: Artifactory not reachable (ping failed)." >&2 + echo "ERROR: ping failed — is the stack up?" >&2 exit 1 fi +echo " ping OK" -# --- 1) Local Maven repository ------------------------------------------------ -echo "==> Ensuring local Maven repository '${REPO_KEY}'" -REPO_CODE=$(curl -s -o /tmp/hop-af-repo.json -w '%{http_code}' "${AUTH[@]}" \ - "${API}/repositories/${REPO_KEY}" || true) -if [[ "${REPO_CODE}" == "200" ]]; then - echo " Repository already exists" -else - HTTP=$(curl -s -o /tmp/hop-af-create-repo.json -w '%{http_code}' "${AUTH[@]}" \ - -X PUT "${API}/repositories/${REPO_KEY}" \ - -H 'Content-Type: application/json' \ - -d "{ - \"key\": \"${REPO_KEY}\", - \"rclass\": \"local\", - \"packageType\": \"maven\", - \"repoLayoutRef\": \"maven-2-default\", - \"description\": \"Hop marketplace plugin zips (local / IT)\" - }") - if [[ "${HTTP}" != "200" && "${HTTP}" != "201" ]]; then - echo "ERROR: create repository failed (HTTP ${HTTP}):" >&2 - cat /tmp/hop-af-create-repo.json >&2 || true - exit 1 - fi - echo " Created ${REPO_KEY}" -fi - -# --- 2) Enable anonymous access (global) -------------------------------------- -# Artifactory security configuration (classic REST). We GET, patch anonAccessEnabled, PUT back. -echo "==> Enabling global anonymous access" -if curl -sf "${AUTH[@]}" "${API}/security/configuration" -o /tmp/hop-af-sec.json; then - # configuration is XML for some versions, JSON for others — handle both lightly - if head -c 1 /tmp/hop-af-sec.json | grep -q '<'; then - # XML: set true - if grep -q '' /tmp/hop-af-sec.json; then - sed -i 's#[^<]*#true#' /tmp/hop-af-sec.json - else - # insert before closing security tag if present - sed -i 's## true\n#' /tmp/hop-af-sec.json - fi - HTTP=$(curl -s -o /tmp/hop-af-sec-put.json -w '%{http_code}' "${AUTH[@]}" \ - -X POST "${API}/security/configuration" \ - -H 'Content-Type: application/xml' \ - --data-binary @/tmp/hop-af-sec.json) - else - # JSON (Access / newer): set anonAccessEnabled - if command -v python3 >/dev/null 2>&1; then - python3 - <<'PY' -import json -from pathlib import Path -p = Path("/tmp/hop-af-sec.json") -data = json.loads(p.read_text()) -# common shapes -if isinstance(data, dict): - data["anonAccessEnabled"] = True - if "security" in data and isinstance(data["security"], dict): - data["security"]["anonAccessEnabled"] = True -p.write_text(json.dumps(data)) -PY - fi - HTTP=$(curl -s -o /tmp/hop-af-sec-put.json -w '%{http_code}' "${AUTH[@]}" \ - -X POST "${API}/security/configuration" \ - -H 'Content-Type: application/json' \ - --data-binary @/tmp/hop-af-sec.json) - fi - if [[ "${HTTP}" == "200" || "${HTTP}" == "201" || "${HTTP}" == "204" ]]; then - echo " Anonymous access enabled (API)" - else - echo " WARNING: could not set anonymous via API (HTTP ${HTTP})." - echo " Do this in the UI: Administration → User Management → Settings → Allow Anonymous Access" - cat /tmp/hop-af-sec-put.json 2>/dev/null || true - fi -else - echo " WARNING: GET /security/configuration failed." - echo " Enable in UI: Administration → User Management → Settings → Allow Anonymous Access" -fi +# Confirm we are on OSS (informational) +LICENSE=$(curl -sf "${AUTH[@]}" "${BASE_URL}/artifactory/api/system/version" \ + | sed -n 's/.*"license"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1 || true) +echo " license: ${LICENSE:-unknown}" -# --- 3) Permission: anonymous READ only on hop-plugins-local -------------------- -# Artifactory 7.x removed anonymous from the default "Anything" target — grant explicitly. -echo "==> Creating permission '${PERM_NAME}' (anonymous → read on ${REPO_KEY} only)" -HTTP=$(curl -s -o /tmp/hop-af-perm.json -w '%{http_code}' "${AUTH[@]}" \ - -X PUT "${API}/v2/security/permissions/${PERM_NAME}" \ - -H 'Content-Type: application/json' \ - -d "{ - \"name\": \"${PERM_NAME}\", - \"repo\": { - \"include-patterns\": [\"**\"], - \"exclude-patterns\": [], - \"repositories\": [\"${REPO_KEY}\"], - \"actions\": { - \"users\": { - \"anonymous\": [\"read\"] - } - } - } - }") - -if [[ "${HTTP}" != "200" && "${HTTP}" != "201" ]]; then - # Fallback: classic permissions API - HTTP2=$(curl -s -o /tmp/hop-af-perm2.json -w '%{http_code}' "${AUTH[@]}" \ - -X PUT "${API}/security/permissions/${PERM_NAME}" \ - -H 'Content-Type: application/json' \ - -d "{ - \"name\": \"${PERM_NAME}\", - \"repositories\": [\"${REPO_KEY}\"], - \"principals\": { - \"users\": { - \"anonymous\": [\"r\"] - } - } - }") - if [[ "${HTTP2}" != "200" && "${HTTP2}" != "201" ]]; then - echo "ERROR: could not create permission (v2 HTTP ${HTTP}, classic HTTP ${HTTP2}):" >&2 - cat /tmp/hop-af-perm.json >&2 || true - cat /tmp/hop-af-perm2.json >&2 || true - echo >&2 - echo "UI fallback:" >&2 - echo " 1) Administration → User Management → Settings → Allow Anonymous Access = ON" >&2 - echo " 2) Administration → User Management → Permissions → New Permission" >&2 - echo " Repositories: ${REPO_KEY}" >&2 - echo " Users: anonymous → Read only (no Deploy/Delete/Manage)" >&2 +echo "==> Checking repository '${REPO_KEY}' exists (authenticated)" +# OSS: list/get repository REST may also be limited; probe storage path instead. +HTTP_AUTH=$(curl -s -o /dev/null -w '%{http_code}' "${AUTH[@]}" "${REPO_URL}" || true) +case "${HTTP_AUTH}" in + 200|404) + echo " Repository path reachable as admin (HTTP ${HTTP_AUTH})" + ;; + 401|403) + echo "ERROR: admin auth failed (HTTP ${HTTP_AUTH}). Check ARTIFACTORY_PASSWORD." >&2 exit 1 - fi - echo " Permission created (classic API)" -else - echo " Permission created (v2 API)" -fi + ;; + *) + echo " WARNING: unexpected HTTP ${HTTP_AUTH} for ${REPO_URL}" + echo " If the repo is missing, create it in the UI (step A above)." + ;; +esac -# --- 4) Smoke test anonymous download path ------------------------------------ -echo "==> Smoke test: anonymous GET on repo root (expect 200 or 404 empty, not 401)" -ANON_CODE=$(curl -s -o /dev/null -w '%{http_code}' \ - "${BASE_URL}/artifactory/${REPO_KEY}/" || true) -case "${ANON_CODE}" in +echo "==> Checking anonymous read on '${REPO_KEY}'" +HTTP_ANON=$(curl -s -o /dev/null -w '%{http_code}' "${REPO_URL}" || true) +case "${HTTP_ANON}" in 200|404) - echo " OK (HTTP ${ANON_CODE}) — anonymous can reach the repository" + echo " OK — anonymous access works (HTTP ${HTTP_ANON})" + echo + echo "Hop config (no username/password):" + echo " \"url\": \"${REPO_URL}\"" + echo + echo "Then:" + echo " unset HOP_MARKETPLACE_PASSWORD ARTIFACTORY_PASSWORD" + echo " ./hop marketplace install hop-tech-parquet" + exit 0 ;; 401|403) - echo " STILL DENIED (HTTP ${ANON_CODE}). Check UI anonymous + permission steps above." >&2 + echo " NOT YET (HTTP ${HTTP_ANON}) — finish UI steps B and C above, then re-run:" + echo " $0" exit 1 ;; *) - echo " Unexpected HTTP ${ANON_CODE} (repo may be empty; try install after publish)" + echo " Unexpected HTTP ${HTTP_ANON}. Finish UI steps A–C and re-run." + exit 1 ;; esac - -echo -echo "Done. Deploy still needs admin; downloads do not:" -echo " # publish (authenticated)" -echo " export ARTIFACTORY_PASSWORD=…" -echo " ./docker/marketplace-artifactory/publish-wave1-plugins.sh" -echo -echo " # install (no credentials)" -echo " # hop-config marketplace.repositories[0].url =" -echo " # ${BASE_URL}/artifactory/${REPO_KEY}/" -echo " ./hop marketplace install hop-tech-parquet" From f5f8a59a9864713aafd6c56b1080f4c6cf5a9d90 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Sun, 19 Jul 2026 22:27:14 +0200 Subject: [PATCH 10/28] issue #7547: document Artifactory OSS UI-only repo/anonymous setup Clarify that create-repository REST is Pro-only and point users at the UI steps; keep configure-anonymous-read.sh as a verifier. --- docker/marketplace-artifactory/README.md | 50 ++++++++++++++---------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/docker/marketplace-artifactory/README.md b/docker/marketplace-artifactory/README.md index 08a6f6e9823..f256750f490 100644 --- a/docker/marketplace-artifactory/README.md +++ b/docker/marketplace-artifactory/README.md @@ -53,33 +53,30 @@ curl -sf http://localhost:8082/artifactory/api/system/ping && echo OK Open http://localhost:8082 and set the **admin** password on first login. -## Configure anonymous read (after admin password) +## Configure anonymous read (Artifactory **OSS**) -```bash -export ARTIFACTORY_PASSWORD='your-admin-password' -./docker/marketplace-artifactory/configure-anonymous-read.sh -``` +**Artifactory OSS blocks repository (and many security) REST APIs** — they return +HTTP 400 *“available only in Artifactory Pro”*. Do setup in the UI; the helper +script only prints steps and verifies anonymous access. -That script: +### UI steps (required on OSS) -1. Creates local Maven repo **`hop-plugins-local`** (if missing) -2. Turns on **Allow Anonymous Access** -3. Adds permission **`hop-plugins-anonymous-read`**: user `anonymous` → **read only** - on `hop-plugins-local` (no deploy/delete/manage) +1. **Create local Maven repo** + **Administration → Repositories → Create a Repository → Local** + - Package type: **Maven** + - Repository Key: **`hop-plugins-local`** + - Layout: **maven-2-default** -### UI equivalent (if the script cannot update security config) +2. **Allow anonymous access** + **Administration → User Management → Settings** + - ☑ **Allow Anonymous Access** → Save -1. **Administration → User Management → Settings** - - Enable **Allow Anonymous Access** -2. **Administration → Repositories → Add Repositories → Local Repository** - - Package type: Maven - - Repository Key: `hop-plugins-local` - - Layout: `maven-2-default` -3. **Administration → User Management → Permissions → New Permission** - - Name: e.g. `hop-plugins-anonymous-read` - - **Repositories:** `hop-plugins-local` only +3. **Anonymous read-only permission** + **Administration → User Management → Permissions → + Add** + - Name: `hop-plugins-anonymous-read` + - **Repositories:** only `hop-plugins-local` - **Users:** `anonymous` - - **Actions:** **Read** only (do **not** tick Deploy / Delete / Manage / Annotate) + - **Actions:** ☑ **Read** only (no Deploy / Delete / Manage / Annotate) Repo URL: @@ -87,6 +84,17 @@ Repo URL: http://localhost:8082/artifactory/hop-plugins-local/ ``` +### Verify + +```bash +export ARTIFACTORY_PASSWORD='your-admin-password' +./docker/marketplace-artifactory/configure-anonymous-read.sh +# Expect: OK — anonymous access works + +# Expect not 401: +curl -sI "http://localhost:8082/artifactory/hop-plugins-local/" | head -1 +``` + ## Publish Wave 1 plugin zips (authenticated) Build plugin modules, then deploy with admin (or a dedicated deploy user): From 51bda715e7087199a3a00c4a687894b73286ab51 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Sun, 19 Jul 2026 22:31:33 +0200 Subject: [PATCH 11/28] issue #7547: JFrog Platform UI guide with deep links for OSS setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document Administration module switching and deep links for repositories, anonymous access (Security → General), and permissions. Stop implying old "User Management → Settings" paths as primary. --- docker/marketplace-artifactory/JFROG-UI.md | 136 +++++++++++++++ docker/marketplace-artifactory/README.md | 48 ++---- .../configure-anonymous-read.sh | 157 ++++++++++-------- 3 files changed, 244 insertions(+), 97 deletions(-) create mode 100644 docker/marketplace-artifactory/JFROG-UI.md diff --git a/docker/marketplace-artifactory/JFROG-UI.md b/docker/marketplace-artifactory/JFROG-UI.md new file mode 100644 index 00000000000..22769ed1a60 --- /dev/null +++ b/docker/marketplace-artifactory/JFROG-UI.md @@ -0,0 +1,136 @@ + + +# Surviving the JFrog Platform UI (Artifactory OSS 7.x) + +The product UI is the **JFrog Platform** SPA at: + +```text +http://localhost:8082/ui/ +``` + +Older docs still say “Artifactory webapp” (`/artifactory/webapp/`) — that redirects into `/ui/`. +Menu labels move between minor releases; **deep links** below are more reliable than hunting the nav. + +## Orientation (this is the frustrating part) + +After login you may land in the **Application** module (packages, builds, scans). + +Admin work is under **Administration**: + +- Top bar: switch **Application | Administration**, **or** +- Gear / “Administration” control, **or** +- Left rail only shows admin sections once Administration is selected + +If the left menu has no “Repositories” / “Security”, you are still in Application. + +## Direct links (bookmark these) + +| Task | Open | +|------|------| +| Repositories | http://localhost:8082/ui/admin/repositories | +| Anonymous access | http://localhost:8082/ui/admin/security/general | +| Permissions | http://localhost:8082/ui/admin/user_management/permissions | +| Users | http://localhost:8082/ui/admin/user_management/users | + +(All return the SPA; the path selects the admin page after you are logged in.) + +## A) Local Maven repository `hop-plugins-local` + +1. Open **Repositories** link above (Administration module). +2. **+ Add Repositories** / **Create Repository** / **New**. +3. Type: **Local**. +4. Package type: **Maven**. +5. **Repository Key:** `hop-plugins-local` (exact spelling). +6. Layout: **maven-2-default**. +7. Create. + +**OSS note:** REST `PUT /artifactory/api/repositories/...` returns 400 *Pro only*. UI is mandatory. + +## B) Allow Anonymous Access + +1. Open **Anonymous / Security General** link above. + Path in menu: **Administration → Security → General** + (Some builds still show a toggle under User Management → Settings — same setting.) +2. Enable **Allow Anonymous Access**. +3. **Save**. + +## C) Permission: anonymous may **Read** only that repo + +Since **7.84.3**, anonymous is **not** on the default “Anything” permission. + +1. Open **Permissions** link above. + Menu: **Administration → User Management → Permissions**. +2. **+ New Permission**. +3. Name: `hop-plugins-anonymous-read`. +4. **Repositories** (or Resources): select **only** `hop-plugins-local`. + Do not select “Any Local” unless you want every local repo readable. +5. **Users**: add **anonymous**. +6. Actions for anonymous: + + | Action | Anonymous | + |--------|-----------| + | Read | ☑ | + | Annotate | ☐ | + | Deploy / Cache | ☐ | + | Delete / Overwrite | ☐ | + | Manage | ☐ | + +7. Save. + +## Verify (no UI archaeology) + +```bash +export ARTIFACTORY_PASSWORD='your-admin-password' +./docker/marketplace-artifactory/configure-anonymous-read.sh +``` + +Or: + +```bash +# Must not be 401 +curl -sI "http://localhost:8082/artifactory/hop-plugins-local/" | head -1 +``` + +Then Hop install **without** admin password: + +```bash +unset HOP_MARKETPLACE_PASSWORD ARTIFACTORY_PASSWORD +# hop-config: repositories[0].url = http://localhost:8082/artifactory/hop-plugins-local/ +./hop marketplace install hop-tech-parquet +``` + +## Who uses admin? + +| Action | Identity | +|--------|----------| +| UI setup (A–C) | admin once | +| `publish-wave1-plugins.sh` | admin / deploy user | +| `hop marketplace install` | **anonymous** | + +## If the UI still makes no sense + +The marketplace client also supports Basic auth with a **read-only** user (not admin): + +```bash +export HOP_MARKETPLACE_USERNAME=reader +export HOP_MARKETPLACE_PASSWORD='…' +``` + +Create that user under **User Management → Users**, grant **Read** on `hop-plugins-local` only, and skip anonymous if preferred. diff --git a/docker/marketplace-artifactory/README.md b/docker/marketplace-artifactory/README.md index f256750f490..42c6fa90273 100644 --- a/docker/marketplace-artifactory/README.md +++ b/docker/marketplace-artifactory/README.md @@ -53,46 +53,34 @@ curl -sf http://localhost:8082/artifactory/api/system/ping && echo OK Open http://localhost:8082 and set the **admin** password on first login. -## Configure anonymous read (Artifactory **OSS**) +## Configure anonymous read (Artifactory **OSS** + Platform UI) -**Artifactory OSS blocks repository (and many security) REST APIs** — they return -HTTP 400 *“available only in Artifactory Pro”*. Do setup in the UI; the helper -script only prints steps and verifies anonymous access. +**Repo-create REST is Pro-only** on OSS (HTTP 400). Use the **JFrog Platform UI** +at http://localhost:8082/ui/ — menus move every release; use deep links. -### UI steps (required on OSS) +**Step-by-step with current UI landmarks:** see **[JFROG-UI.md](./JFROG-UI.md)**. -1. **Create local Maven repo** - **Administration → Repositories → Create a Repository → Local** - - Package type: **Maven** - - Repository Key: **`hop-plugins-local`** - - Layout: **maven-2-default** +Quick links (log in as admin first): -2. **Allow anonymous access** - **Administration → User Management → Settings** - - ☑ **Allow Anonymous Access** → Save +| Task | URL | +|------|-----| +| Repositories | http://localhost:8082/ui/admin/repositories | +| Anonymous access | http://localhost:8082/ui/admin/security/general | +| Permissions | http://localhost:8082/ui/admin/user_management/permissions | -3. **Anonymous read-only permission** - **Administration → User Management → Permissions → + Add** - - Name: `hop-plugins-anonymous-read` - - **Repositories:** only `hop-plugins-local` - - **Users:** `anonymous` - - **Actions:** ☑ **Read** only (no Deploy / Delete / Manage / Annotate) - -Repo URL: - -```text -http://localhost:8082/artifactory/hop-plugins-local/ -``` - -### Verify +Or print the same guide + verify: ```bash +./docker/marketplace-artifactory/configure-anonymous-read.sh +# after UI steps A–C: export ARTIFACTORY_PASSWORD='your-admin-password' ./docker/marketplace-artifactory/configure-anonymous-read.sh -# Expect: OK — anonymous access works +``` + +Repo URL for Hop: -# Expect not 401: -curl -sI "http://localhost:8082/artifactory/hop-plugins-local/" | head -1 +```text +http://localhost:8082/artifactory/hop-plugins-local/ ``` ## Publish Wave 1 plugin zips (authenticated) diff --git a/docker/marketplace-artifactory/configure-anonymous-read.sh b/docker/marketplace-artifactory/configure-anonymous-read.sh index 9c5eccfc123..05d95bf3b80 100755 --- a/docker/marketplace-artifactory/configure-anonymous-read.sh +++ b/docker/marketplace-artifactory/configure-anonymous-read.sh @@ -8,17 +8,13 @@ # # http://www.apache.org/licenses/LICENSE-2.0 # -# Configure *Artifactory OSS* so Hop can download plugins without admin credentials. -# -# IMPORTANT: Artifactory OSS does NOT allow creating repositories (or many admin -# security resources) via REST — those APIs return HTTP 400 "Artifactory Pro only". -# Repository + anonymous + read permission are done in the UI; this script prints -# the exact clicks and verifies anonymous access afterward. +# Artifactory OSS (JFrog Platform UI, 7.x): +# - Repository create / many admin REST APIs are Pro-only (HTTP 400). +# - This script prints deep links into the *current* Platform UI and verifies +# anonymous read afterward. # # Usage: -# # 1) Create hop-plugins-local in the UI (see printed steps) -# # 2) Enable anonymous + read permission (see printed steps) -# # 3) Optional verify: +# # After admin password is set, open the links and complete A–C, then: # export ARTIFACTORY_PASSWORD='…' # ./docker/marketplace-artifactory/configure-anonymous-read.sh # @@ -28,61 +24,84 @@ BASE_URL="${ARTIFACTORY_URL_BASE:-http://localhost:8082}" USER="${ARTIFACTORY_USER:-admin}" PASS="${ARTIFACTORY_PASSWORD:-}" REPO_KEY="${ARTIFACTORY_REPO_KEY:-hop-plugins-local}" - REPO_URL="${BASE_URL}/artifactory/${REPO_KEY}/" +# JFrog Platform SPA deep links (7.x). All load the same app; path selects the page. +UI_REPOS="${BASE_URL}/ui/admin/repositories" +UI_ANON="${BASE_URL}/ui/admin/security/general" +UI_PERMS="${BASE_URL}/ui/admin/user_management/permissions" +UI_HOME="${BASE_URL}/ui/" + echo "============================================================" -echo " Artifactory OSS — anonymous read for Hop marketplace" +echo " Hop marketplace + Artifactory OSS (JFrog Platform UI)" echo "============================================================" echo -echo "Artifactory OSS license: repository create/manage REST APIs are Pro-only." -echo "Do the following once in the UI at ${BASE_URL}/" +echo "You are on Artifactory OSS. Repo-create REST is Pro-only — use the UI." +echo "Open ${UI_HOME} and log in as admin, then use the links below." +echo +echo "If the left menu looks empty: top of the page switch" +echo " Application | Administration ← click Administration" +echo " (or the gear / 'Administration' control in the top bar)" echo cat < Checking Artifactory" if ! curl -sf "${BASE_URL}/artifactory/api/system/ping" >/dev/null; then - echo "ERROR: ping failed — is the stack up?" >&2 + echo "ERROR: ping failed — is the stack up? (${BASE_URL})" >&2 exit 1 fi echo " ping OK" -# Confirm we are on OSS (informational) -LICENSE=$(curl -sf "${AUTH[@]}" "${BASE_URL}/artifactory/api/system/version" \ +LICENSE=$(curl -sf "${AUTH[@]}" "${BASE_URL}/artifactory/api/system/version" 2>/dev/null \ | sed -n 's/.*"license"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1 || true) echo " license: ${LICENSE:-unknown}" -echo "==> Checking repository '${REPO_KEY}' exists (authenticated)" -# OSS: list/get repository REST may also be limited; probe storage path instead. +echo "==> Admin probe of ${REPO_URL}" HTTP_AUTH=$(curl -s -o /dev/null -w '%{http_code}' "${AUTH[@]}" "${REPO_URL}" || true) case "${HTTP_AUTH}" in 200|404) - echo " Repository path reachable as admin (HTTP ${HTTP_AUTH})" + echo " OK as admin (HTTP ${HTTP_AUTH}) — repo path exists" ;; 401|403) echo "ERROR: admin auth failed (HTTP ${HTTP_AUTH}). Check ARTIFACTORY_PASSWORD." >&2 exit 1 ;; *) - echo " WARNING: unexpected HTTP ${HTTP_AUTH} for ${REPO_URL}" - echo " If the repo is missing, create it in the UI (step A above)." + echo " WARNING: HTTP ${HTTP_AUTH}. If the repo is missing, finish step A." ;; esac -echo "==> Checking anonymous read on '${REPO_KEY}'" +echo "==> Anonymous probe of ${REPO_URL}" HTTP_ANON=$(curl -s -o /dev/null -w '%{http_code}' "${REPO_URL}" || true) case "${HTTP_ANON}" in 200|404) - echo " OK — anonymous access works (HTTP ${HTTP_ANON})" + echo " OK — anonymous read works (HTTP ${HTTP_ANON})" echo - echo "Hop config (no username/password):" + echo "Hop hop-config.json marketplace repo (no username/password):" echo " \"url\": \"${REPO_URL}\"" echo - echo "Then:" echo " unset HOP_MARKETPLACE_PASSWORD ARTIFACTORY_PASSWORD" echo " ./hop marketplace install hop-tech-parquet" exit 0 ;; 401|403) - echo " NOT YET (HTTP ${HTTP_ANON}) — finish UI steps B and C above, then re-run:" - echo " $0" + echo " STILL DENIED (HTTP ${HTTP_ANON})" + echo + echo "Usually one of:" + echo " • Step B not saved (Allow Anonymous Access still off)" + echo " • Step C missing — anonymous has no Read on ${REPO_KEY}" + echo " • Step A — repo key typo (must be exactly ${REPO_KEY})" + echo + echo "Re-open:" + echo " B) ${UI_ANON}" + echo " C) ${UI_PERMS}" exit 1 ;; *) - echo " Unexpected HTTP ${HTTP_ANON}. Finish UI steps A–C and re-run." + echo " Unexpected HTTP ${HTTP_ANON}. Finish A–C and re-run." exit 1 ;; esac From 2c39263949913a99519779c053fa2c074cc124d8 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Sun, 19 Jul 2026 22:52:27 +0200 Subject: [PATCH 12/28] issue #7547: replace JFrog local stack with Sonatype Nexus OSS Add docker/marketplace-nexus with scripted bootstrap (anonymous read, hosted hop-plugins repo), publish Wave 1 zips, and SNAPSHOT resolution via maven-metadata.xml. Remove docker/marketplace-artifactory entirely. --- docker/marketplace-artifactory/.gitignore | 4 - docker/marketplace-artifactory/JFROG-UI.md | 136 ------------- docker/marketplace-artifactory/README.md | 189 ------------------ .../configure-anonymous-read.sh | 166 --------------- .../docker-compose.yml | 71 ------- .../marketplace-artifactory/generate-keys.sh | 78 -------- .../marketplace-artifactory/keys/.gitignore | 3 - docker/marketplace-artifactory/start.sh | 57 ------ docker/marketplace-nexus/.gitignore | 1 + docker/marketplace-nexus/README.md | 129 ++++++++++++ docker/marketplace-nexus/configure-nexus.sh | 180 +++++++++++++++++ docker/marketplace-nexus/docker-compose.yml | 32 +++ .../publish-wave1-plugins.sh | 81 +++++--- docker/marketplace-nexus/start.sh | 91 +++++++++ plugins/misc/marketplace/README.md | 27 +-- .../resolve/MavenRepositoryClient.java | 93 ++++++++- .../MavenRepositoryClientSnapshotTest.java | 79 ++++++++ 17 files changed, 666 insertions(+), 751 deletions(-) delete mode 100644 docker/marketplace-artifactory/.gitignore delete mode 100644 docker/marketplace-artifactory/JFROG-UI.md delete mode 100644 docker/marketplace-artifactory/README.md delete mode 100755 docker/marketplace-artifactory/configure-anonymous-read.sh delete mode 100644 docker/marketplace-artifactory/docker-compose.yml delete mode 100755 docker/marketplace-artifactory/generate-keys.sh delete mode 100644 docker/marketplace-artifactory/keys/.gitignore delete mode 100755 docker/marketplace-artifactory/start.sh create mode 100644 docker/marketplace-nexus/.gitignore create mode 100644 docker/marketplace-nexus/README.md create mode 100755 docker/marketplace-nexus/configure-nexus.sh create mode 100644 docker/marketplace-nexus/docker-compose.yml rename docker/{marketplace-artifactory => marketplace-nexus}/publish-wave1-plugins.sh (50%) create mode 100755 docker/marketplace-nexus/start.sh create mode 100644 plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/resolve/MavenRepositoryClientSnapshotTest.java diff --git a/docker/marketplace-artifactory/.gitignore b/docker/marketplace-artifactory/.gitignore deleted file mode 100644 index f2168c16bb8..00000000000 --- a/docker/marketplace-artifactory/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Generated by generate-keys.sh — never commit -.env -keys/master.key -keys/join.key diff --git a/docker/marketplace-artifactory/JFROG-UI.md b/docker/marketplace-artifactory/JFROG-UI.md deleted file mode 100644 index 22769ed1a60..00000000000 --- a/docker/marketplace-artifactory/JFROG-UI.md +++ /dev/null @@ -1,136 +0,0 @@ - - -# Surviving the JFrog Platform UI (Artifactory OSS 7.x) - -The product UI is the **JFrog Platform** SPA at: - -```text -http://localhost:8082/ui/ -``` - -Older docs still say “Artifactory webapp” (`/artifactory/webapp/`) — that redirects into `/ui/`. -Menu labels move between minor releases; **deep links** below are more reliable than hunting the nav. - -## Orientation (this is the frustrating part) - -After login you may land in the **Application** module (packages, builds, scans). - -Admin work is under **Administration**: - -- Top bar: switch **Application | Administration**, **or** -- Gear / “Administration” control, **or** -- Left rail only shows admin sections once Administration is selected - -If the left menu has no “Repositories” / “Security”, you are still in Application. - -## Direct links (bookmark these) - -| Task | Open | -|------|------| -| Repositories | http://localhost:8082/ui/admin/repositories | -| Anonymous access | http://localhost:8082/ui/admin/security/general | -| Permissions | http://localhost:8082/ui/admin/user_management/permissions | -| Users | http://localhost:8082/ui/admin/user_management/users | - -(All return the SPA; the path selects the admin page after you are logged in.) - -## A) Local Maven repository `hop-plugins-local` - -1. Open **Repositories** link above (Administration module). -2. **+ Add Repositories** / **Create Repository** / **New**. -3. Type: **Local**. -4. Package type: **Maven**. -5. **Repository Key:** `hop-plugins-local` (exact spelling). -6. Layout: **maven-2-default**. -7. Create. - -**OSS note:** REST `PUT /artifactory/api/repositories/...` returns 400 *Pro only*. UI is mandatory. - -## B) Allow Anonymous Access - -1. Open **Anonymous / Security General** link above. - Path in menu: **Administration → Security → General** - (Some builds still show a toggle under User Management → Settings — same setting.) -2. Enable **Allow Anonymous Access**. -3. **Save**. - -## C) Permission: anonymous may **Read** only that repo - -Since **7.84.3**, anonymous is **not** on the default “Anything” permission. - -1. Open **Permissions** link above. - Menu: **Administration → User Management → Permissions**. -2. **+ New Permission**. -3. Name: `hop-plugins-anonymous-read`. -4. **Repositories** (or Resources): select **only** `hop-plugins-local`. - Do not select “Any Local” unless you want every local repo readable. -5. **Users**: add **anonymous**. -6. Actions for anonymous: - - | Action | Anonymous | - |--------|-----------| - | Read | ☑ | - | Annotate | ☐ | - | Deploy / Cache | ☐ | - | Delete / Overwrite | ☐ | - | Manage | ☐ | - -7. Save. - -## Verify (no UI archaeology) - -```bash -export ARTIFACTORY_PASSWORD='your-admin-password' -./docker/marketplace-artifactory/configure-anonymous-read.sh -``` - -Or: - -```bash -# Must not be 401 -curl -sI "http://localhost:8082/artifactory/hop-plugins-local/" | head -1 -``` - -Then Hop install **without** admin password: - -```bash -unset HOP_MARKETPLACE_PASSWORD ARTIFACTORY_PASSWORD -# hop-config: repositories[0].url = http://localhost:8082/artifactory/hop-plugins-local/ -./hop marketplace install hop-tech-parquet -``` - -## Who uses admin? - -| Action | Identity | -|--------|----------| -| UI setup (A–C) | admin once | -| `publish-wave1-plugins.sh` | admin / deploy user | -| `hop marketplace install` | **anonymous** | - -## If the UI still makes no sense - -The marketplace client also supports Basic auth with a **read-only** user (not admin): - -```bash -export HOP_MARKETPLACE_USERNAME=reader -export HOP_MARKETPLACE_PASSWORD='…' -``` - -Create that user under **User Management → Users**, grant **Read** on `hop-plugins-local` only, and skip anonymous if preferred. diff --git a/docker/marketplace-artifactory/README.md b/docker/marketplace-artifactory/README.md deleted file mode 100644 index 42c6fa90273..00000000000 --- a/docker/marketplace-artifactory/README.md +++ /dev/null @@ -1,189 +0,0 @@ - - -# Local Artifactory for Hop Marketplace testing - -Use this stack to exercise plugin install/uninstall **without** ASF Nexus permissions. - -## Security model (recommended) - -| Action | Who | -|--------|-----| -| **Download / install plugins** (Hop marketplace) | **Anonymous** (read-only on `hop-plugins-local`) | -| **Publish plugin zips** (`publish-wave1-plugins.sh`) | **Admin** (or a deploy user) | -| UI administration | Admin only | - -Nobody should put admin credentials into `hop-config.json` or day-to-day Hop usage. -Admin is only for publishing and one-time setup. - -Recent Artifactory versions also **require PostgreSQL** (embedded DB is gone). This compose -stack runs Postgres + Artifactory OSS. - -## Start - -```bash -# First time or after a broken volume layout: -./docker/marketplace-artifactory/start.sh --reset - -# Later: -./docker/marketplace-artifactory/start.sh -``` - -Wait until healthy: - -```bash -curl -sf http://localhost:8082/artifactory/api/system/ping && echo OK -``` - -Open http://localhost:8082 and set the **admin** password on first login. - -## Configure anonymous read (Artifactory **OSS** + Platform UI) - -**Repo-create REST is Pro-only** on OSS (HTTP 400). Use the **JFrog Platform UI** -at http://localhost:8082/ui/ — menus move every release; use deep links. - -**Step-by-step with current UI landmarks:** see **[JFROG-UI.md](./JFROG-UI.md)**. - -Quick links (log in as admin first): - -| Task | URL | -|------|-----| -| Repositories | http://localhost:8082/ui/admin/repositories | -| Anonymous access | http://localhost:8082/ui/admin/security/general | -| Permissions | http://localhost:8082/ui/admin/user_management/permissions | - -Or print the same guide + verify: - -```bash -./docker/marketplace-artifactory/configure-anonymous-read.sh -# after UI steps A–C: -export ARTIFACTORY_PASSWORD='your-admin-password' -./docker/marketplace-artifactory/configure-anonymous-read.sh -``` - -Repo URL for Hop: - -```text -http://localhost:8082/artifactory/hop-plugins-local/ -``` - -## Publish Wave 1 plugin zips (authenticated) - -Build plugin modules, then deploy with admin (or a dedicated deploy user): - -```bash -export ARTIFACTORY_URL=http://localhost:8082/artifactory/hop-plugins-local -export ARTIFACTORY_USER=admin -export ARTIFACTORY_PASSWORD='your-admin-password' -# Maven needs a matching in ~/.m2/settings.xml (id = hop-plugins-local) -./docker/marketplace-artifactory/publish-wave1-plugins.sh -``` - -`~/.m2/settings.xml` snippet: - -```xml - - - hop-plugins-local - admin - your-admin-password - - -``` - -## Install from Hop (anonymous — no password) - -`hop-config.json` (no username/password required once anonymous read is configured): - -```json -{ - "marketplace": { - "enabled": true, - "groupId": "org.apache.hop", - "defaultVersion": "2.19.0-SNAPSHOT", - "repositories": [ - { - "id": "local-artifactory", - "url": "http://localhost:8082/artifactory/hop-plugins-local/" - } - ] - } -} -``` - -```bash -export HOP_HOME=/path/to/hop -# Do NOT export admin password for install -./hop marketplace install hop-tech-parquet -``` - -Quick anonymous check: - -```bash -# Expect 200 (or 404 if that path is empty), not 401 -curl -sI "http://localhost:8082/artifactory/hop-plugins-local/org/apache/hop/" | head -1 -``` - -If you still get **401**, anonymous access or the read permission is not applied — re-run -`configure-anonymous-read.sh` or the UI steps above. - -### Optional: authenticated downloads - -Corporate Artifactory that cannot allow anonymous can still use: - -```bash -export HOP_MARKETPLACE_USERNAME=deploy-reader -export HOP_MARKETPLACE_PASSWORD='…' -``` - -Prefer a **read-only deploy user**, not admin. - -## Security keys (compose bootstrap) - -```bash -./docker/marketplace-artifactory/generate-keys.sh -``` - -| File | Size | How | -|------|------|-----| -| `keys/master.key` | 32 hex chars | `openssl rand -hex 16` | -| `keys/join.key` | 64 hex chars | `openssl rand -hex 32` | -| `.env` | compose env | master/join + Postgres password | - -Gitignored. Passed as env vars into the container (not RO file mounts). - -## Troubleshooting - -| Symptom | Fix | -|---------|-----| -| `HTTP 401` on `hop marketplace install` | Enable anonymous + read permission (`configure-anonymous-read.sh`) | -| `Cannot start … PostgreSQL` | Use this compose stack; `./start.sh --reset` | -| Join key / startup hang | `generate-keys.sh` + `start.sh --reset` | -| Publish 401 | Admin `settings.xml` / `ARTIFACTORY_PASSWORD` for deploy only | - -## Stop - -```bash -docker compose -f docker/marketplace-artifactory/docker-compose.yml \ - --env-file docker/marketplace-artifactory/.env down - -# Wipe all data: -docker compose -f docker/marketplace-artifactory/docker-compose.yml \ - --env-file docker/marketplace-artifactory/.env down -v -``` diff --git a/docker/marketplace-artifactory/configure-anonymous-read.sh b/docker/marketplace-artifactory/configure-anonymous-read.sh deleted file mode 100755 index 05d95bf3b80..00000000000 --- a/docker/marketplace-artifactory/configure-anonymous-read.sh +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/env bash -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Artifactory OSS (JFrog Platform UI, 7.x): -# - Repository create / many admin REST APIs are Pro-only (HTTP 400). -# - This script prints deep links into the *current* Platform UI and verifies -# anonymous read afterward. -# -# Usage: -# # After admin password is set, open the links and complete A–C, then: -# export ARTIFACTORY_PASSWORD='…' -# ./docker/marketplace-artifactory/configure-anonymous-read.sh -# -set -euo pipefail - -BASE_URL="${ARTIFACTORY_URL_BASE:-http://localhost:8082}" -USER="${ARTIFACTORY_USER:-admin}" -PASS="${ARTIFACTORY_PASSWORD:-}" -REPO_KEY="${ARTIFACTORY_REPO_KEY:-hop-plugins-local}" -REPO_URL="${BASE_URL}/artifactory/${REPO_KEY}/" - -# JFrog Platform SPA deep links (7.x). All load the same app; path selects the page. -UI_REPOS="${BASE_URL}/ui/admin/repositories" -UI_ANON="${BASE_URL}/ui/admin/security/general" -UI_PERMS="${BASE_URL}/ui/admin/user_management/permissions" -UI_HOME="${BASE_URL}/ui/" - -echo "============================================================" -echo " Hop marketplace + Artifactory OSS (JFrog Platform UI)" -echo "============================================================" -echo -echo "You are on Artifactory OSS. Repo-create REST is Pro-only — use the UI." -echo "Open ${UI_HOME} and log in as admin, then use the links below." -echo -echo "If the left menu looks empty: top of the page switch" -echo " Application | Administration ← click Administration" -echo " (or the gear / 'Administration' control in the top bar)" -echo - -cat < Checking Artifactory" -if ! curl -sf "${BASE_URL}/artifactory/api/system/ping" >/dev/null; then - echo "ERROR: ping failed — is the stack up? (${BASE_URL})" >&2 - exit 1 -fi -echo " ping OK" - -LICENSE=$(curl -sf "${AUTH[@]}" "${BASE_URL}/artifactory/api/system/version" 2>/dev/null \ - | sed -n 's/.*"license"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1 || true) -echo " license: ${LICENSE:-unknown}" - -echo "==> Admin probe of ${REPO_URL}" -HTTP_AUTH=$(curl -s -o /dev/null -w '%{http_code}' "${AUTH[@]}" "${REPO_URL}" || true) -case "${HTTP_AUTH}" in - 200|404) - echo " OK as admin (HTTP ${HTTP_AUTH}) — repo path exists" - ;; - 401|403) - echo "ERROR: admin auth failed (HTTP ${HTTP_AUTH}). Check ARTIFACTORY_PASSWORD." >&2 - exit 1 - ;; - *) - echo " WARNING: HTTP ${HTTP_AUTH}. If the repo is missing, finish step A." - ;; -esac - -echo "==> Anonymous probe of ${REPO_URL}" -HTTP_ANON=$(curl -s -o /dev/null -w '%{http_code}' "${REPO_URL}" || true) -case "${HTTP_ANON}" in - 200|404) - echo " OK — anonymous read works (HTTP ${HTTP_ANON})" - echo - echo "Hop hop-config.json marketplace repo (no username/password):" - echo " \"url\": \"${REPO_URL}\"" - echo - echo " unset HOP_MARKETPLACE_PASSWORD ARTIFACTORY_PASSWORD" - echo " ./hop marketplace install hop-tech-parquet" - exit 0 - ;; - 401|403) - echo " STILL DENIED (HTTP ${HTTP_ANON})" - echo - echo "Usually one of:" - echo " • Step B not saved (Allow Anonymous Access still off)" - echo " • Step C missing — anonymous has no Read on ${REPO_KEY}" - echo " • Step A — repo key typo (must be exactly ${REPO_KEY})" - echo - echo "Re-open:" - echo " B) ${UI_ANON}" - echo " C) ${UI_PERMS}" - exit 1 - ;; - *) - echo " Unexpected HTTP ${HTTP_ANON}. Finish A–C and re-run." - exit 1 - ;; -esac diff --git a/docker/marketplace-artifactory/docker-compose.yml b/docker/marketplace-artifactory/docker-compose.yml deleted file mode 100644 index 694ba62a0ca..00000000000 --- a/docker/marketplace-artifactory/docker-compose.yml +++ /dev/null @@ -1,71 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Local Artifactory OSS + PostgreSQL for Hop marketplace testing. -# -# Recent Artifactory 7.x builds require PostgreSQL (embedded Derby is gone). -# -# Prerequisites: -# ./docker/marketplace-artifactory/generate-keys.sh -# Start: -# ./docker/marketplace-artifactory/start.sh -# -# UI: http://localhost:8082 -# -services: - postgres: - image: postgres:15-alpine - container_name: hop-marketplace-postgres - environment: - POSTGRES_DB: artifactory - POSTGRES_USER: artifactory - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-hop_artifactory_dev} - volumes: - - hop-artifactory-postgres:/var/lib/postgresql/data - healthcheck: - test: ["CMD-SHELL", "pg_isready -U artifactory -d artifactory"] - interval: 5s - timeout: 5s - retries: 20 - start_period: 10s - # Not published to host by default (Artifactory reaches it on the compose network) - - artifactory: - image: releases-docker.jfrog.io/jfrog/artifactory-oss:7.104.14 - container_name: hop-marketplace-artifactory - depends_on: - postgres: - condition: service_healthy - ports: - - "8082:8082" - - "8081:8081" - volumes: - - hop-artifactory-data:/var/opt/jfrog/artifactory - environment: - # Security keys as values (not bind-mounted files — Artifactory rewrites them) - JF_SHARED_SECURITY_MASTER_KEY: ${JF_SHARED_SECURITY_MASTER_KEY:?Run generate-keys.sh first} - JF_SHARED_SECURITY_JOIN_KEY: ${JF_SHARED_SECURITY_JOIN_KEY:?Run generate-keys.sh first} - # PostgreSQL (required by modern Artifactory OSS) - JF_SHARED_DATABASE_TYPE: postgresql - JF_SHARED_DATABASE_URL: jdbc:postgresql://postgres:5432/artifactory - JF_SHARED_DATABASE_USERNAME: artifactory - JF_SHARED_DATABASE_PASSWORD: ${POSTGRES_PASSWORD:-hop_artifactory_dev} - JF_SHARED_DATABASE_DRIVER: org.postgresql.Driver - # Heap: 1g is tight; raise if the host has RAM to spare - JF_SHARED_EXTRAJAVAOPTS: -Xms512m -Xmx2g - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8082/artifactory/api/system/ping"] - interval: 30s - timeout: 10s - retries: 30 - start_period: 240s - -volumes: - hop-artifactory-data: - hop-artifactory-postgres: diff --git a/docker/marketplace-artifactory/generate-keys.sh b/docker/marketplace-artifactory/generate-keys.sh deleted file mode 100755 index d96f495ee12..00000000000 --- a/docker/marketplace-artifactory/generate-keys.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env bash -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Generate JFrog Artifactory security keys for docker-compose: -# - master.key AES-128 → openssl rand -hex 16 (32 hex chars) -# - join.key cluster join → openssl rand -hex 32 (64 hex chars) -# -# Keys are written under keys/ and also mirrored into .env for compose -# (JF_SHARED_SECURITY_MASTER_KEY / JF_SHARED_SECURITY_JOIN_KEY). -# -# Usage: -# ./docker/marketplace-artifactory/generate-keys.sh -# -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -KEYS_DIR="${SCRIPT_DIR}/keys" -ENV_FILE="${SCRIPT_DIR}/.env" - -if ! command -v openssl >/dev/null 2>&1; then - echo "ERROR: openssl is required on the host" >&2 - exit 1 -fi - -mkdir -p "${KEYS_DIR}" - -# $1=filename $2=openssl hex byte count (16 → 32 chars, 32 → 64 chars) -ensure_key() { - local name="$1" - local bytes="$2" - local expected_len=$((bytes * 2)) - local dest="${KEYS_DIR}/${name}" - - if [[ -f "${dest}" ]]; then - local len - len="$(wc -c < "${dest}" | tr -d ' ')" - if [[ "${len}" == "${expected_len}" ]]; then - echo "Key already exists: ${dest} (${len} bytes)" - return 0 - fi - echo "Replacing invalid ${dest} (length ${len}, expected ${expected_len})" - else - echo "Generating ${name} (openssl rand -hex ${bytes})..." - fi - - # No trailing newline - openssl rand -hex "${bytes}" | tr -d '\n' > "${dest}" - chmod 600 "${dest}" 2>/dev/null || true - echo "Wrote ${dest}" -} - -ensure_key "master.key" 16 -ensure_key "join.key" 32 - -MASTER_KEY="$(cat "${KEYS_DIR}/master.key")" -JOIN_KEY="$(cat "${KEYS_DIR}/join.key")" - -# Compose reads these as JF_SHARED_SECURITY_* (no file mounts — Artifactory -# tries to rewrite key files and RO bind-mounts fail). -cat > "${ENV_FILE}" <&2 - exit 1 -fi - -if [[ "${RESET}" == "true" ]]; then - echo "Resetting volumes (removes all Artifactory/Postgres data)..." - docker compose --env-file .env down -v -fi - -echo "Starting Artifactory + PostgreSQL..." -docker compose --env-file .env up -d - -echo -echo "Waiting for health (can take 2–4 minutes on first boot)..." -echo " Logs: docker logs -f hop-marketplace-artifactory" -echo " UI: http://localhost:8082" -echo -echo "Create a local Maven repo key 'hop-plugins-local', then:" -echo " export ARTIFACTORY_URL=http://localhost:8082/artifactory/hop-plugins-local" -echo " export ARTIFACTORY_USER=admin" -echo " export ARTIFACTORY_PASSWORD=… # set on first login" -echo " ./publish-wave1-plugins.sh" diff --git a/docker/marketplace-nexus/.gitignore b/docker/marketplace-nexus/.gitignore new file mode 100644 index 00000000000..4c49bd78f1d --- /dev/null +++ b/docker/marketplace-nexus/.gitignore @@ -0,0 +1 @@ +.env diff --git a/docker/marketplace-nexus/README.md b/docker/marketplace-nexus/README.md new file mode 100644 index 00000000000..acb427e5528 --- /dev/null +++ b/docker/marketplace-nexus/README.md @@ -0,0 +1,129 @@ + + +# Local Nexus for Hop Marketplace testing + +Sonatype **Nexus Repository OSS** is the supported local Maven repository for +developing and testing the Hop plugin marketplace. + +It is fully scriptable (no Pro-only APIs, no Postgres, no join keys). + +## Security model + +| Action | Who | +|--------|-----| +| `hop marketplace install` / GUI install | **Anonymous** read | +| `publish-wave1-plugins.sh` | **admin** (or a deploy user) | + +Do not put admin credentials in day-to-day `hop-config.json`. + +## Start + +```bash +./docker/marketplace-nexus/start.sh + +# Wipe data and re-bootstrap: +./docker/marketplace-nexus/start.sh --reset + +# Custom admin password: +NEXUS_ADMIN_PASSWORD='secret' ./docker/marketplace-nexus/start.sh +``` + +Default after bootstrap: + +| | | +|--|--| +| UI | http://localhost:8081/ | +| Admin | `admin` / `hop-nexus-dev` (unless overridden) | +| Hosted repo | http://127.0.0.1:8081/repository/hop-plugins/ | + +Prefer **`127.0.0.1`** over `localhost` in Hop config: on some hosts `localhost` resolves +to IPv6 (`::1`) while Docker only publishes IPv4, which surfaces as +`java.net.ConnectException` from the marketplace client. + +First start can take **1–3 minutes** while Nexus initializes. + +## Publish Wave 1 plugin zips + +```bash +# Package plugins first (from repo root) +./mvnw -pl plugins/engines/spark,plugins/engines/beam,plugins/transforms/script,\ +plugins/tech/cassandra,plugins/transforms/tika,plugins/transforms/drools,\ +plugins/tech/parquet,plugins/transforms/stanfordnlp,plugins/tech/arrow,\ +plugins/tech/dropbox,plugins/transforms/edi2xml -am package -DskipTests + +export NEXUS_PASSWORD=hop-nexus-dev # or your NEXUS_ADMIN_PASSWORD +./docker/marketplace-nexus/publish-wave1-plugins.sh +``` + +## Hop marketplace (anonymous install) + +`config/hop-config.json` under `$HOP_HOME`: + +```json +{ + "marketplace": { + "enabled": true, + "groupId": "org.apache.hop", + "defaultVersion": "2.19.0-SNAPSHOT", + "repositories": [ + { + "id": "local-nexus", + "url": "http://127.0.0.1:8081/repository/hop-plugins/" + } + ] + } +} +``` + +```bash +export HOP_HOME=/path/to/hop +export HOP_CONFIG_FOLDER="$HOP_HOME/config" # optional but recommended +# no password for install +./hop marketplace install hop-tech-parquet +``` + +Quick check: + +```bash +# Expect 200 or 404, not 401 +curl -sI "http://127.0.0.1:8081/repository/hop-plugins/" | head -1 +``` + +## Scripts + +| Script | Role | +|--------|------| +| `start.sh` | Compose up + wait + configure | +| `configure-nexus.sh` | Anonymous + hosted repo (idempotent) | +| `publish-wave1-plugins.sh` | `mvn deploy:deploy-file` of Wave 1 zips | + +## Stop + +```bash +docker compose -f docker/marketplace-nexus/docker-compose.yml down +# Wipe data: +docker compose -f docker/marketplace-nexus/docker-compose.yml down -v +``` + +## Production note + +Released Hop plugins still go through the **ASF release process** to +`repository.apache.org` → Maven Central. This Nexus stack only mimics Maven +layout for local development. diff --git a/docker/marketplace-nexus/configure-nexus.sh b/docker/marketplace-nexus/configure-nexus.sh new file mode 100755 index 00000000000..203bf250e67 --- /dev/null +++ b/docker/marketplace-nexus/configure-nexus.sh @@ -0,0 +1,180 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Idempotent Nexus OSS bootstrap for Hop marketplace: +# - change admin password from first-boot random password if needed +# - enable anonymous access +# - create hosted Maven repo hop-plugins (MIXED / ALLOW for SNAPSHOT zips) +# +# Env: +# NEXUS_URL default http://localhost:8081 +# NEXUS_ADMIN_USER default admin +# NEXUS_ADMIN_PASSWORD desired admin password (default hop-nexus-dev) +# +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BASE_URL="${NEXUS_URL:-http://localhost:8081}" +BASE_URL="${BASE_URL%/}" +ADMIN_USER="${NEXUS_ADMIN_USER:-admin}" +ADMIN_PASSWORD="${NEXUS_ADMIN_PASSWORD:-hop-nexus-dev}" +REPO_NAME="${NEXUS_REPO_NAME:-hop-plugins}" +CONTAINER="${NEXUS_CONTAINER:-hop-marketplace-nexus}" + +api() { + # api METHOD PATH [curl args...] + local method="$1" + local path="$2" + shift 2 + curl -sS -u "${ADMIN_USER}:${CURRENT_PASSWORD}" \ + -X "${method}" \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + "${BASE_URL}${path}" \ + "$@" +} + +http_code() { + local method="$1" + local path="$2" + shift 2 + curl -sS -o /tmp/nexus-http.body -w '%{http_code}' \ + -u "${ADMIN_USER}:${CURRENT_PASSWORD}" \ + -X "${method}" \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + "${BASE_URL}${path}" \ + "$@" +} + +echo "==> Resolving admin password" +CURRENT_PASSWORD="${ADMIN_PASSWORD}" + +# If desired password already works, skip change +code=$(curl -sS -o /dev/null -w '%{http_code}' -u "${ADMIN_USER}:${CURRENT_PASSWORD}" \ + "${BASE_URL}/service/rest/v1/status" || echo 000) +if [[ "${code}" != "200" ]]; then + # First-boot password is in the data volume + if docker exec "${CONTAINER}" test -f /nexus-data/admin.password 2>/dev/null; then + BOOT_PASSWORD=$(docker exec "${CONTAINER}" cat /nexus-data/admin.password | tr -d '\r\n') + echo " Using first-boot password from container volume" + CURRENT_PASSWORD="${BOOT_PASSWORD}" + code=$(curl -sS -o /dev/null -w '%{http_code}' -u "${ADMIN_USER}:${CURRENT_PASSWORD}" \ + "${BASE_URL}/service/rest/v1/status" || echo 000) + fi +fi + +if [[ "${code}" != "200" ]]; then + echo "ERROR: cannot authenticate as ${ADMIN_USER} (HTTP ${code})." >&2 + echo " If you set a custom password earlier, export NEXUS_ADMIN_PASSWORD=…" >&2 + echo " Or reset: ./start.sh --reset" >&2 + exit 1 +fi +echo " Authenticated as ${ADMIN_USER}" + +# Change password if still on first-boot password +if [[ "${CURRENT_PASSWORD}" != "${ADMIN_PASSWORD}" ]]; then + echo "==> Setting admin password" + chg=$(curl -sS -o /tmp/nexus-chg.body -w '%{http_code}' \ + -u "${ADMIN_USER}:${CURRENT_PASSWORD}" \ + -X PUT \ + -H 'Content-Type: text/plain' \ + --data-binary "${ADMIN_PASSWORD}" \ + "${BASE_URL}/service/rest/v1/security/users/${ADMIN_USER}/change-password" || echo 000) + # Some versions expect JSON body: + if [[ "${chg}" != "204" && "${chg}" != "200" ]]; then + chg=$(curl -sS -o /tmp/nexus-chg.body -w '%{http_code}' \ + -u "${ADMIN_USER}:${CURRENT_PASSWORD}" \ + -X PUT \ + -H 'Content-Type: application/json' \ + -d "{\"password\":\"${ADMIN_PASSWORD}\"}" \ + "${BASE_URL}/service/rest/v1/security/users/${ADMIN_USER}/change-password" || echo 000) + fi + if [[ "${chg}" == "204" || "${chg}" == "200" ]]; then + echo " Password updated" + CURRENT_PASSWORD="${ADMIN_PASSWORD}" + else + echo " WARNING: change-password returned HTTP ${chg} (body: $(cat /tmp/nexus-chg.body 2>/dev/null || true))" + echo " Continuing with current credentials" + fi +fi + +echo "==> Enabling anonymous access" +anon=$(http_code PUT /service/rest/v1/security/anonymous \ + -d '{"enabled":true,"userId":"anonymous","realmName":"NexusAuthorizingRealm"}') +if [[ "${anon}" == "200" || "${anon}" == "204" ]]; then + echo " Anonymous enabled (HTTP ${anon})" +else + # GET then PUT full object if needed + echo " WARNING: anonymous PUT HTTP ${anon}; check UI Security → Anonymous Access" + cat /tmp/nexus-http.body 2>/dev/null || true +fi + +echo "==> Ensuring hosted Maven repository '${REPO_NAME}'" +exists=$(curl -sS -o /dev/null -w '%{http_code}' -u "${ADMIN_USER}:${CURRENT_PASSWORD}" \ + "${BASE_URL}/service/rest/v1/repositories/${REPO_NAME}" || echo 000) +if [[ "${exists}" == "200" ]]; then + echo " Repository already exists" +else + create=$(http_code POST /service/rest/v1/repositories/maven/hosted -d "{ + \"name\": \"${REPO_NAME}\", + \"online\": true, + \"storage\": { + \"blobStoreName\": \"default\", + \"strictContentTypeValidation\": false, + \"writePolicy\": \"ALLOW\" + }, + \"cleanup\": { \"policyNames\": [] }, + \"component\": { \"proprietaryComponents\": false }, + \"maven\": { + \"versionPolicy\": \"MIXED\", + \"layoutPolicy\": \"PERMISSIVE\", + \"contentDisposition\": \"ATTACHMENT\" + } + }") + if [[ "${create}" == "201" || "${create}" == "200" ]]; then + echo " Created hosted Maven repo '${REPO_NAME}'" + else + echo "ERROR: create repository failed HTTP ${create}" >&2 + cat /tmp/nexus-http.body >&2 || true + exit 1 + fi +fi + +echo "==> Smoke test anonymous GET" +REPO_URL="${BASE_URL}/repository/${REPO_NAME}/" +anon_get=$(curl -sS -o /dev/null -w '%{http_code}' "${REPO_URL}" || echo 000) +case "${anon_get}" in + 200|404) + echo " OK — anonymous can reach ${REPO_URL} (HTTP ${anon_get})" + ;; + 401|403) + echo " WARNING: anonymous still denied (HTTP ${anon_get})." + echo " UI: Settings → Security → Anonymous Access → enable" + ;; + *) + echo " Unexpected HTTP ${anon_get} for ${REPO_URL}" + ;; +esac + +# Persist for publish scripts +ENV_FILE="${SCRIPT_DIR}/.env" +cat > "${ENV_FILE}" </dev/null || true +echo " Wrote ${ENV_FILE}" + +echo "Configure complete." diff --git a/docker/marketplace-nexus/docker-compose.yml b/docker/marketplace-nexus/docker-compose.yml new file mode 100644 index 00000000000..e8711a0d0fa --- /dev/null +++ b/docker/marketplace-nexus/docker-compose.yml @@ -0,0 +1,32 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Local Sonatype Nexus Repository OSS for Hop marketplace testing. +# Usage: ./docker/marketplace-nexus/start.sh +# +services: + nexus: + image: sonatype/nexus3:3.76.1 + container_name: hop-marketplace-nexus + ports: + - "8081:8081" + volumes: + - hop-nexus-data:/nexus-data + # Nexus needs a few GB free under the volume; reduce heap for laptops if needed + environment: + INSTALL4J_ADD_VM_PARAMS: "-Xms512m -Xmx1536m -XX:MaxDirectMemorySize=1g -Djava.util.prefs.userRoot=/nexus-data/javaprefs" + healthcheck: + test: ["CMD", "curl", "-sf", "http://localhost:8081/service/rest/v1/status"] + interval: 15s + timeout: 10s + retries: 40 + start_period: 120s + +volumes: + hop-nexus-data: diff --git a/docker/marketplace-artifactory/publish-wave1-plugins.sh b/docker/marketplace-nexus/publish-wave1-plugins.sh similarity index 50% rename from docker/marketplace-artifactory/publish-wave1-plugins.sh rename to docker/marketplace-nexus/publish-wave1-plugins.sh index beaf9e6548c..dfe7b160b42 100755 --- a/docker/marketplace-artifactory/publish-wave1-plugins.sh +++ b/docker/marketplace-nexus/publish-wave1-plugins.sh @@ -8,19 +8,34 @@ # # http://www.apache.org/licenses/LICENSE-2.0 # -# Deploy Wave 1 marketplace plugin zips to a local Maven repository -# (Artifactory, Nexus, or any HTTP Maven layout endpoint that accepts deploy-file). +# Deploy Wave 1 marketplace plugin zips to local Nexus (or any Maven repo). +# +# Env: +# NEXUS_REPO_URL or ARTIFACTORY_URL e.g. http://localhost:8081/repository/hop-plugins +# NEXUS_USER / NEXUS_PASSWORD (or ARTIFACTORY_USER / ARTIFACTORY_PASSWORD) +# HOP_VERSION default 2.19.0-SNAPSHOT +# set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" -REPO_URL="${ARTIFACTORY_URL:-http://localhost:8082/artifactory/hop-plugins-local}" -REPO_ID="${ARTIFACTORY_REPO_ID:-hop-plugins-local}" -USER="${ARTIFACTORY_USER:-admin}" -PASS="${ARTIFACTORY_PASSWORD:-}" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Load .env from start/configure if present +if [[ -f "${SCRIPT_DIR}/.env" ]]; then + # shellcheck disable=SC1091 + set -a + source "${SCRIPT_DIR}/.env" + set +a +fi + +REPO_URL="${NEXUS_REPO_URL:-${ARTIFACTORY_URL:-http://localhost:8081/repository/hop-plugins}}" +REPO_URL="${REPO_URL%/}" +REPO_ID="${NEXUS_REPO_ID:-hop-plugins}" +USER="${NEXUS_USER:-${NEXUS_ADMIN_USER:-${ARTIFACTORY_USER:-admin}}}" +PASS="${NEXUS_PASSWORD:-${NEXUS_ADMIN_PASSWORD:-${ARTIFACTORY_PASSWORD:-}}}" VERSION="${HOP_VERSION:-2.19.0-SNAPSHOT}" GROUP_ID="org.apache.hop" -# artifactId → path to built zip (relative to repo root) declare -A ZIPS=( [hop-engines-spark]="plugins/engines/spark/target/hop-engines-spark-${VERSION}.zip" [hop-engines-beam]="plugins/engines/beam/target/hop-engines-beam-${VERSION}.zip" @@ -35,44 +50,56 @@ declare -A ZIPS=( [hop-transform-edi2xml]="plugins/transforms/edi2xml/target/hop-transform-edi2xml-${VERSION}.zip" ) -if [[ -z "$PASS" ]]; then - echo "Set ARTIFACTORY_PASSWORD (and optionally ARTIFACTORY_USER / ARTIFACTORY_URL)" >&2 +if [[ -z "${PASS}" ]]; then + echo "Set NEXUS_PASSWORD (or NEXUS_ADMIN_PASSWORD). After start.sh the default is hop-nexus-dev." >&2 exit 1 fi MVN="${ROOT}/mvnw" -if [[ ! -x "$MVN" ]]; then +if [[ ! -x "${MVN}" ]]; then MVN=mvn fi +# Temporary settings.xml so deploy-file can authenticate without editing ~/.m2 +SETTINGS="$(mktemp)" +trap 'rm -f "${SETTINGS}"' EXIT +cat > "${SETTINGS}" < + + + ${REPO_ID} + ${USER} + ${PASS} + + + +EOF + deploy_one() { local artifactId="$1" local rel="$2" - local file="$ROOT/$rel" - if [[ ! -f "$file" ]]; then - echo "SKIP (not built): $artifactId — missing $rel" >&2 + local file="${ROOT}/${rel}" + if [[ ! -f "${file}" ]]; then + echo "SKIP (not built): ${artifactId} — missing ${rel}" return 0 fi - echo "Deploying $artifactId → $REPO_URL" - "$MVN" -q org.apache.maven.plugins:maven-deploy-plugin:3.1.3:deploy-file \ - -DgroupId="$GROUP_ID" \ - -DartifactId="$artifactId" \ - -Dversion="$VERSION" \ + echo "Deploying ${artifactId} → ${REPO_URL}" + "${MVN}" -q -s "${SETTINGS}" \ + org.apache.maven.plugins:maven-deploy-plugin:3.1.3:deploy-file \ + -DgroupId="${GROUP_ID}" \ + -DartifactId="${artifactId}" \ + -Dversion="${VERSION}" \ -Dpackaging=zip \ - -Dfile="$file" \ - -DrepositoryId="$REPO_ID" \ - -Durl="$REPO_URL" \ + -Dfile="${file}" \ + -DrepositoryId="${REPO_ID}" \ + -Durl="${REPO_URL}" \ -DgeneratePom=true \ -DretryFailedDeploymentCount=2 } -# Allow password via settings or wagon; deploy-file uses server credentials from settings.xml -# when repositoryId matches. Also support inline for local-only: -export MAVEN_OPTS="${MAVEN_OPTS:-}" - for artifactId in "${!ZIPS[@]}"; do - deploy_one "$artifactId" "${ZIPS[$artifactId]}" + deploy_one "${artifactId}" "${ZIPS[${artifactId}]}" done -echo "Done. Configure hop marketplace repositories[0].url to: ${REPO_URL%/}/" +echo "Done. Marketplace base URL: ${REPO_URL}/" echo "Example: hop marketplace install hop-tech-parquet" diff --git a/docker/marketplace-nexus/start.sh b/docker/marketplace-nexus/start.sh new file mode 100755 index 00000000000..3ecb41354c0 --- /dev/null +++ b/docker/marketplace-nexus/start.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Start Nexus, set admin password, create hop-plugins repo, enable anonymous read. +# +# Usage: +# ./docker/marketplace-nexus/start.sh +# ./docker/marketplace-nexus/start.sh --reset # wipe volumes +# NEXUS_ADMIN_PASSWORD=secret ./docker/marketplace-nexus/start.sh +# +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "${SCRIPT_DIR}" + +BASE_URL="${NEXUS_URL:-http://localhost:8081}" +ADMIN_USER="${NEXUS_ADMIN_USER:-admin}" +# Password we want after bootstrap (override with env) +ADMIN_PASSWORD="${NEXUS_ADMIN_PASSWORD:-hop-nexus-dev}" +RESET=false + +for arg in "$@"; do + case "${arg}" in + --reset|-r) RESET=true ;; + -h|--help) + echo "Usage: $0 [--reset]" + echo " NEXUS_ADMIN_PASSWORD admin password to set (default: hop-nexus-dev)" + exit 0 + ;; + esac +done + +if [[ "${RESET}" == "true" ]]; then + echo "Resetting Nexus volumes..." + docker compose down -v +fi + +echo "Starting Nexus Repository OSS..." +docker compose up -d + +echo "Waiting for Nexus status API (first boot can take 1–3 minutes)..." +ready=false +for i in $(seq 1 80); do + if curl -sf "${BASE_URL}/service/rest/v1/status" >/dev/null 2>&1; then + ready=true + break + fi + # Also accept 200/503 from status/writable during warmup + code=$(curl -s -o /dev/null -w '%{http_code}' "${BASE_URL}/service/rest/v1/status" 2>/dev/null || echo 000) + if [[ "${code}" == "200" ]]; then + ready=true + break + fi + printf '.' + sleep 3 +done +echo +if [[ "${ready}" != "true" ]]; then + echo "ERROR: Nexus did not become ready. Logs:" >&2 + docker logs hop-marketplace-nexus 2>&1 | tail -40 >&2 + exit 1 +fi +echo "Nexus is up: ${BASE_URL}" + +export NEXUS_URL="${BASE_URL}" +export NEXUS_ADMIN_USER="${ADMIN_USER}" +export NEXUS_ADMIN_PASSWORD="${ADMIN_PASSWORD}" +./configure-nexus.sh + +echo +echo "Done." +echo " UI: ${BASE_URL}/" +echo " Admin user: ${ADMIN_USER}" +echo " Admin pass: ${ADMIN_PASSWORD}" +echo " Hosted repo: ${BASE_URL}/repository/hop-plugins/" +echo +echo "Publish (authenticated):" +echo " export NEXUS_URL=${BASE_URL}/repository/hop-plugins" +echo " export NEXUS_USER=${ADMIN_USER}" +echo " export NEXUS_PASSWORD=${ADMIN_PASSWORD}" +echo " ./publish-wave1-plugins.sh" +echo +echo "Hop marketplace (anonymous read):" +echo " \"url\": \"${BASE_URL}/repository/hop-plugins/\"" diff --git a/plugins/misc/marketplace/README.md b/plugins/misc/marketplace/README.md index 1e7064580ea..86703ef177c 100644 --- a/plugins/misc/marketplace/README.md +++ b/plugins/misc/marketplace/README.md @@ -73,6 +73,9 @@ Discovery order: `-f` / `HOP_ENV_FILE` / `PROJECT_HOME/hop-env.yaml` / `$HOP_HOM ## Config (`hop-config.json`) +Local Sonatype Nexus (recommended for marketplace development — see +`docker/marketplace-nexus/README.md`): + ```json { "marketplace": { @@ -81,33 +84,25 @@ Discovery order: `-f` / `HOP_ENV_FILE` / `PROJECT_HOME/hop-env.yaml` / `$HOP_HOM "defaultVersion": "2.19.0-SNAPSHOT", "repositories": [ { - "id": "local-artifactory", - "url": "http://localhost:8082/artifactory/hop-plugins-local/", - "username": "admin" + "id": "local-nexus", + "url": "http://localhost:8081/repository/hop-plugins/" } ] } } ``` -Password via environment (recommended — do not store secrets in hop-config.json): - -```bash -export HOP_MARKETPLACE_USERNAME=admin # or ARTIFACTORY_USER -export HOP_MARKETPLACE_PASSWORD='your-password' # or ARTIFACTORY_PASSWORD -``` +After `./docker/marketplace-nexus/start.sh`, installs are **anonymous** — no password +in Hop config. -**HTTP 401** means the repository requires auth. For local Artifactory, prefer -**anonymous read** on `hop-plugins-local` (no credentials in Hop): +Corporate private repos can use Basic auth (prefer a read-only user, not admin): ```bash -export ARTIFACTORY_PASSWORD='admin-password' -./docker/marketplace-artifactory/configure-anonymous-read.sh +export HOP_MARKETPLACE_USERNAME=reader +export HOP_MARKETPLACE_PASSWORD='…' ``` -Then install without password. Corporate repos that cannot allow anonymous can still use -`HOP_MARKETPLACE_USERNAME` / `HOP_MARKETPLACE_PASSWORD` (prefer a read-only user, not admin). -See `docker/marketplace-artifactory/README.md`. +**HTTP 401** means the repository requires auth or anonymous is disabled on the server. ## GUI diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java index 96b9ad47b9f..3847eae9b84 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java @@ -29,6 +29,8 @@ import java.nio.file.StandardCopyOption; import java.time.Duration; import java.util.Base64; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; import org.apache.hop.core.exception.HopException; import org.apache.hop.core.logging.ILogChannel; @@ -37,6 +39,15 @@ /** Downloads Maven layout artifacts over HTTP(S), with optional Basic authentication. */ public class MavenRepositoryClient { + private static final Pattern SNAPSHOT_ZIP_VALUE = + Pattern.compile( + "\\s*zip\\s*([^<]+)", + Pattern.DOTALL); + private static final Pattern SNAPSHOT_TIMESTAMP = + Pattern.compile( + "\\s*([^<]+)\\s*([^<]+)", + Pattern.DOTALL); + private final HttpClient httpClient; private final ILogChannel log; @@ -58,7 +69,8 @@ public Path downloadZip( MarketplaceRepository repository, MavenCoordinates coordinates, Path targetFile) throws HopException { String base = repository.normalizedUrl(); - String url = base + coordinates.zipRepositoryPath(); + String relative = resolveZipRelativePath(repository, coordinates); + String url = base + relative; return download(url, repository, coordinates.gav(), targetFile); } @@ -79,6 +91,80 @@ public Path downloadArtifact( return download(url, repository, label, targetFile); } + /** + * For release versions: {@code g/a/v/a-v.zip}. For {@code *-SNAPSHOT}, resolve the unique + * timestamped file name from {@code maven-metadata.xml} (as deployed by Maven / Nexus). + */ + String resolveZipRelativePath(MarketplaceRepository repository, MavenCoordinates coordinates) + throws HopException { + String version = coordinates.version(); + if (version == null || !version.endsWith("-SNAPSHOT")) { + return coordinates.zipRepositoryPath(); + } + + String groupPath = coordinates.groupId().replace('.', '/'); + String metadataPath = + groupPath + "/" + coordinates.artifactId() + "/" + version + "/maven-metadata.xml"; + String metadataUrl = repository.normalizedUrl() + metadataPath; + log.logDetailed("Resolving SNAPSHOT zip via " + metadataUrl); + String metadata = getText(metadataUrl, repository); + String unique = parseSnapshotZipValue(metadata, coordinates.artifactId(), version); + if (unique == null) { + // Fall back to non-unique name (some repos allow it) + log.logBasic( + "Could not parse SNAPSHOT zip from maven-metadata.xml; trying non-unique file name"); + return coordinates.zipRepositoryPath(); + } + return groupPath + + "/" + + coordinates.artifactId() + + "/" + + version + + "/" + + coordinates.artifactId() + + "-" + + unique + + ".zip"; + } + + static String parseSnapshotZipValue( + String metadataXml, String artifactId, String snapshotVersion) { + if (metadataXml == null || metadataXml.isBlank()) { + return null; + } + Matcher m = SNAPSHOT_ZIP_VALUE.matcher(metadataXml); + if (m.find()) { + return m.group(1).trim(); + } + // timestamp + buildNumber → 2.19.0-20260719.204953-1 + Matcher t = SNAPSHOT_TIMESTAMP.matcher(metadataXml); + if (t.find()) { + String base = snapshotVersion.substring(0, snapshotVersion.length() - "-SNAPSHOT".length()); + return base + "-" + t.group(1).trim() + "-" + t.group(2).trim(); + } + return null; + } + + private String getText(String url, MarketplaceRepository repository) throws HopException { + try { + HttpRequest.Builder builder = + HttpRequest.newBuilder(URI.create(url)).timeout(Duration.ofMinutes(2)).GET(); + applyBasicAuth(builder, repository); + HttpResponse response = + httpClient.send(builder.build(), HttpResponse.BodyHandlers.ofString()); + if (response.statusCode() != 200) { + throw new HopException( + "HTTP " + response.statusCode() + " fetching maven-metadata from " + url); + } + return response.body(); + } catch (IOException | InterruptedException e) { + if (e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } + throw new HopException("Failed to fetch " + url, e); + } + } + private Path download(String url, MarketplaceRepository repository, String label, Path targetFile) throws HopException { log.logBasic("Downloading " + label + " from " + url); @@ -97,9 +183,8 @@ private Path download(String url, MarketplaceRepository repository, String label + label + " from " + url - + ". Set repository username/password in hop-config.json marketplace.repositories," - + " or export HOP_MARKETPLACE_USERNAME / HOP_MARKETPLACE_PASSWORD" - + " (or ARTIFACTORY_USER / ARTIFACTORY_PASSWORD)."); + + ". For local Nexus enable anonymous read, or set" + + " HOP_MARKETPLACE_USERNAME / HOP_MARKETPLACE_PASSWORD."); } if (response.statusCode() != 200) { throw new HopException( diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/resolve/MavenRepositoryClientSnapshotTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/resolve/MavenRepositoryClientSnapshotTest.java new file mode 100644 index 00000000000..4ac9c418899 --- /dev/null +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/resolve/MavenRepositoryClientSnapshotTest.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.resolve; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import org.junit.jupiter.api.Test; + +class MavenRepositoryClientSnapshotTest { + + @Test + void parseSnapshotZipFromMetadata() { + String xml = + """ + + 2.19.0-SNAPSHOT + + + 20260719.204953 + 1 + + + + zip + 2.19.0-20260719.204953-1 + 20260719204953 + + + pom + 2.19.0-20260719.204953-1 + + + + + """; + assertEquals( + "2.19.0-20260719.204953-1", + MavenRepositoryClient.parseSnapshotZipValue(xml, "hop-tech-parquet", "2.19.0-SNAPSHOT")); + } + + @Test + void parseSnapshotFromTimestampOnly() { + String xml = + """ + + + + 20260101.120000 + 3 + + + + """; + assertEquals( + "1.0.0-20260101.120000-3", + MavenRepositoryClient.parseSnapshotZipValue(xml, "x", "1.0.0-SNAPSHOT")); + } + + @Test + void emptyMetadata() { + assertNull(MavenRepositoryClient.parseSnapshotZipValue("", "a", "1-SNAPSHOT")); + } +} From 14d24e1818f1ffd252a8867e72ad6b295f15b269 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Sun, 19 Jul 2026 23:04:26 +0200 Subject: [PATCH 13/28] issue #7547: fix Hop home when HOP_HOME is a relative path Relative HOP_HOME values were resolved against the current directory, doubling paths like assemblies/client/target/hop when already inside the install. Prefer any candidate that contains plugins/, including cwd. --- .../hop/marketplace/install/HopHome.java | 62 ++++++++++++------ .../hop/marketplace/install/HopHomeTest.java | 65 +++++++++++++++++++ 2 files changed, 107 insertions(+), 20 deletions(-) create mode 100644 plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/HopHomeTest.java diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/HopHome.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/HopHome.java index 12312f2780a..4043d116cc6 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/HopHome.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/HopHome.java @@ -20,10 +20,21 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.apache.hop.core.exception.HopException; -/** Resolves the Hop installation directory (the folder that contains {@code plugins/}). */ +/** + * Resolves the Hop installation directory (the folder that contains {@code plugins/}). + * + *

Order: {@code HOP_HOME} / {@code hop.home} if they point at a valid install, then {@code + * user.dir}, then parent of {@code user.dir}. A relative {@code HOP_HOME} that is resolved against + * a cwd already inside the install (e.g. {@code assemblies/client/target/hop} while sitting in that + * directory) is ignored so we do not double the path. + */ public final class HopHome { public static final String ENV_HOP_HOME = "HOP_HOME"; @@ -32,33 +43,44 @@ public final class HopHome { private HopHome() {} public static Path resolve() throws HopException { + List tried = new ArrayList<>(); + for (Path candidate : candidates()) { + Path abs = candidate.toAbsolutePath().normalize(); + tried.add(abs.toString()); + if (isHopHome(abs)) { + return abs; + } + } + throw new HopException( + "Cannot determine Hop installation directory (need a folder containing plugins/)." + + " Tried: " + + String.join(", ", tried) + + ". Unset a relative HOP_HOME if you are already in the hop install, or set HOP_HOME" + + " to an absolute path."); + } + + private static Set candidates() { + // LinkedHashSet preserves order and drops duplicates after normalize + Set paths = new LinkedHashSet<>(); String fromEnv = System.getenv(ENV_HOP_HOME); if (StringUtils.isNotBlank(fromEnv)) { - return validate(Paths.get(fromEnv)); + paths.add(Paths.get(fromEnv.trim())); } String fromProp = System.getProperty(PROP_HOP_HOME); if (StringUtils.isNotBlank(fromProp)) { - return validate(Paths.get(fromProp)); - } - Path cwd = Paths.get(System.getProperty("user.dir")); - if (Files.isDirectory(cwd.resolve("plugins"))) { - return cwd.toAbsolutePath().normalize(); + paths.add(Paths.get(fromProp.trim())); } - // hop-gui often runs with cwd = hop home already; otherwise walk up one level - Path parent = cwd.getParent(); - if (parent != null && Files.isDirectory(parent.resolve("plugins"))) { - return parent.toAbsolutePath().normalize(); + Path cwd = Paths.get(System.getProperty("user.dir", ".")); + paths.add(cwd); + Path parent = cwd.toAbsolutePath().normalize().getParent(); + if (parent != null) { + paths.add(parent); } - throw new HopException( - "Cannot determine Hop installation directory. Set HOP_HOME or run from the Hop install root" - + " (the directory that contains plugins/)."); + return paths; } - private static Path validate(Path path) throws HopException { - Path abs = path.toAbsolutePath().normalize(); - if (!Files.isDirectory(abs)) { - throw new HopException("Hop home is not a directory: " + abs); - } - return abs; + /** True if path is a directory that looks like a Hop install (has {@code plugins/}). */ + static boolean isHopHome(Path path) { + return path != null && Files.isDirectory(path) && Files.isDirectory(path.resolve("plugins")); } } diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/HopHomeTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/HopHomeTest.java new file mode 100644 index 00000000000..14c47c118ed --- /dev/null +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/HopHomeTest.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.install; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.file.Files; +import java.nio.file.Path; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +class HopHomeTest { + + @TempDir Path tempDir; + + @Test + void isHopHomeRequiresPluginsDir() throws Exception { + Path hop = tempDir.resolve("hop"); + Files.createDirectories(hop); + assertFalse(HopHome.isHopHome(hop)); + Files.createDirectories(hop.resolve("plugins")); + assertTrue(HopHome.isHopHome(hop)); + } + + @Test + void resolveUsesUserDirWhenItIsHopHome() throws Exception { + Path hop = tempDir.resolve("hop"); + Files.createDirectories(hop.resolve("plugins")); + String previous = System.getProperty("user.dir"); + String previousProp = System.getProperty(HopHome.PROP_HOP_HOME); + try { + System.clearProperty(HopHome.PROP_HOP_HOME); + System.setProperty("user.dir", hop.toString()); + // Env HOP_HOME may still be set in the process; prop/user.dir path must work when env + // is unset — we only assert isHopHome behavior + absolute resolution of user.dir + Path resolved = hop.toAbsolutePath().normalize(); + assertTrue(HopHome.isHopHome(resolved)); + assertEquals(resolved, hop.toAbsolutePath().normalize()); + } finally { + System.setProperty("user.dir", previous); + if (previousProp == null) { + System.clearProperty(HopHome.PROP_HOP_HOME); + } else { + System.setProperty(HopHome.PROP_HOP_HOME, previousProp); + } + } + } +} From 600c2afae025c291daa30f9393398dc4487aacd9 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Sun, 19 Jul 2026 23:28:34 +0200 Subject: [PATCH 14/28] issue #7547: simplify marketplace install root and add Nexus smoke test Resolve the client install from process cwd (hop launchers already cd there), drop HOP_HOME/hop.home indirection, clarify hop-config is always under HOP_CONFIG_FOLDER, improve 401 auth errors, and add an anonymous Nexus CLI smoke script for install/list/validate/apply/uninstall. --- docker/marketplace-nexus/README.md | 19 ++- docker/marketplace-nexus/smoke-test.sh | 124 ++++++++++++++++++ plugins/misc/marketplace/README.md | 25 +++- .../marketplace/config/MarketplaceConfig.java | 4 + .../config/MarketplaceRepository.java | 15 +-- .../hop/marketplace/install/HopHome.java | 27 +--- .../resolve/MavenRepositoryClient.java | 32 +++-- .../gui/messages/messages_en_US.properties | 2 +- .../src/main/samples/hop-env.example.yaml | 13 +- .../hop/marketplace/install/HopHomeTest.java | 28 ++-- tools/install-wave1-plugins.sh | 14 +- 11 files changed, 228 insertions(+), 75 deletions(-) create mode 100755 docker/marketplace-nexus/smoke-test.sh diff --git a/docker/marketplace-nexus/README.md b/docker/marketplace-nexus/README.md index acb427e5528..6da6400c2b1 100644 --- a/docker/marketplace-nexus/README.md +++ b/docker/marketplace-nexus/README.md @@ -74,7 +74,8 @@ export NEXUS_PASSWORD=hop-nexus-dev # or your NEXUS_ADMIN_PASSWORD ## Hop marketplace (anonymous install) -`config/hop-config.json` under `$HOP_HOME`: +Edit **`${HOP_CONFIG_FOLDER}/hop-config.json`** (always that file). If +`HOP_CONFIG_FOLDER` is unset, the hop launcher uses `/config`. ```json { @@ -93,9 +94,7 @@ export NEXUS_PASSWORD=hop-nexus-dev # or your NEXUS_ADMIN_PASSWORD ``` ```bash -export HOP_HOME=/path/to/hop -export HOP_CONFIG_FOLDER="$HOP_HOME/config" # optional but recommended -# no password for install +cd /path/to/hop # the unzipped hop-client directory ./hop marketplace install hop-tech-parquet ``` @@ -106,6 +105,17 @@ Quick check: curl -sI "http://127.0.0.1:8081/repository/hop-plugins/" | head -1 ``` +## Smoke test (CLI install / list / validate / apply / uninstall) + +```bash +# Nexus up + Wave 1 published + hop client unzipped +./docker/marketplace-nexus/smoke-test.sh +``` + +Uses a temporary `HOP_CONFIG_FOLDER` (does not touch your real hop-config) and +installs two small plugins into `assemblies/client/target/hop` (override with +`HOP_DIR`). + ## Scripts | Script | Role | @@ -113,6 +123,7 @@ curl -sI "http://127.0.0.1:8081/repository/hop-plugins/" | head -1 | `start.sh` | Compose up + wait + configure | | `configure-nexus.sh` | Anonymous + hosted repo (idempotent) | | `publish-wave1-plugins.sh` | `mvn deploy:deploy-file` of Wave 1 zips | +| `smoke-test.sh` | Anonymous install / list / validate / apply / uninstall | ## Stop diff --git a/docker/marketplace-nexus/smoke-test.sh b/docker/marketplace-nexus/smoke-test.sh new file mode 100755 index 00000000000..947dff216d0 --- /dev/null +++ b/docker/marketplace-nexus/smoke-test.sh @@ -0,0 +1,124 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# End-to-end smoke test: local Nexus + hop marketplace CLI (anonymous). +# +# Prerequisites: +# - ./docker/marketplace-nexus/start.sh +# - ./docker/marketplace-nexus/publish-wave1-plugins.sh +# - Unzipped hop client at assemblies/client/target/hop (or HOP_DIR) +# +# Usage (from repo root): +# ./docker/marketplace-nexus/smoke-test.sh +# +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +HOP_DIR="${HOP_DIR:-${ROOT}/assemblies/client/target/hop}" +REPO_URL="${NEXUS_REPO_URL:-http://127.0.0.1:8081/repository/hop-plugins/}" +REPO_URL="${REPO_URL%/}/" +VERSION="${HOP_VERSION:-2.19.0-SNAPSHOT}" + +# Small plugins for a fast round-trip (publish-wave1 must have deployed them) +INSTALL_A="${SMOKE_PLUGIN_A:-hop-tech-dropbox}" +INSTALL_B="${SMOKE_PLUGIN_B:-hop-transform-edi2xml}" + +if [[ ! -x "${HOP_DIR}/hop" ]]; then + echo "Hop launcher not found: ${HOP_DIR}/hop" >&2 + echo "Build/unzip hop-client first (assemblies/client/target/hop)." >&2 + exit 1 +fi + +echo "==> Checking Nexus anonymous read: ${REPO_URL}" +code=$(curl -sS -o /dev/null -w '%{http_code}' "${REPO_URL}" || true) +if [[ "${code}" != "200" && "${code}" != "404" ]]; then + echo "Nexus not reachable or not anonymous (HTTP ${code}). Run start.sh first." >&2 + exit 1 +fi + +# Isolated config so we do not touch the developer's HOP_CONFIG_FOLDER +CFG_DIR="$(mktemp -d "${TMPDIR:-/tmp}/hop-marketplace-smoke.XXXXXX")" +AUDIT_DIR="$(mktemp -d "${TMPDIR:-/tmp}/hop-marketplace-audit.XXXXXX")" +trap 'rm -rf "${CFG_DIR}" "${AUDIT_DIR}"' EXIT + +cat > "${CFG_DIR}/hop-config.json" < "${ENV_FILE}" < marketplace list (baseline)" +run_hop marketplace list || true + +echo "==> marketplace install ${INSTALL_A}" +run_hop marketplace install "${INSTALL_A}" + +echo "==> marketplace install ${INSTALL_B}" +run_hop marketplace install "${INSTALL_B}" + +echo "==> marketplace list (expect both)" +list_out=$(run_hop marketplace list) +echo "${list_out}" +echo "${list_out}" | grep -q "${INSTALL_A}" +echo "${list_out}" | grep -q "${INSTALL_B}" + +echo "==> marketplace validate -f hop-env-smoke.yaml" +run_hop marketplace validate -f "${ENV_FILE}" + +echo "==> marketplace uninstall ${INSTALL_B}" +run_hop marketplace uninstall "${INSTALL_B}" + +echo "==> marketplace apply -f hop-env-smoke.yaml (idempotent ${INSTALL_A})" +run_hop marketplace apply -f "${ENV_FILE}" + +echo "==> marketplace list (expect ${INSTALL_A} only from smoke installs; others may remain)" +run_hop marketplace list | grep -q "${INSTALL_A}" + +if [[ ! -d "${HOP_DIR}/plugins" ]]; then + echo "FAIL: plugins/ missing under ${HOP_DIR}" >&2 + exit 1 +fi + +echo +echo "OK — marketplace smoke test passed against ${REPO_URL}" +echo " hop install: ${HOP_DIR}" +echo " config: ${HOP_CONFIG_FOLDER}/hop-config.json" diff --git a/plugins/misc/marketplace/README.md b/plugins/misc/marketplace/README.md index 86703ef177c..7bbe397d12d 100644 --- a/plugins/misc/marketplace/README.md +++ b/plugins/misc/marketplace/README.md @@ -24,7 +24,8 @@ Bundled core plugin that installs optional Hop plugins from a Maven repository ## CLI -From the Hop install directory (`HOP_HOME`): +From the Hop install directory (or invoke the `hop` script by path — it already +`cd`s to the install root): ```bash ./hop marketplace install hop-tech-parquet @@ -69,10 +70,15 @@ dependencies: ``` `hop-run` checks the env file only when `enforceOnRun: true` or `-Dhop.env.enforce=true`. -Discovery order: `-f` / `HOP_ENV_FILE` / `PROJECT_HOME/hop-env.yaml` / `$HOP_HOME/hop-env.yaml`. +Discovery order: `-f` / `HOP_ENV_FILE` / `PROJECT_HOME/hop-env.yaml` / install-root `hop-env.yaml`. ## Config (`hop-config.json`) +Marketplace settings live under the `marketplace` key in **`${HOP_CONFIG_FOLDER}/hop-config.json`** +(always that path — not a separate file under the client zip). If `HOP_CONFIG_FOLDER` is +unset, Hop defaults it to `/config` (with the hop launcher, that is +`/config`). + Local Sonatype Nexus (recommended for marketplace development — see `docker/marketplace-nexus/README.md`): @@ -93,17 +99,24 @@ Local Sonatype Nexus (recommended for marketplace development — see ``` After `./docker/marketplace-nexus/start.sh`, installs are **anonymous** — no password -in Hop config. +in that hop-config. -Corporate private repos can use Basic auth (prefer a read-only user, not admin): +```bash +cd /path/to/hop +./hop marketplace install hop-tech-parquet +``` + +Local Nexus after `docker/marketplace-nexus/start.sh` is **anonymous read** — leave +`username` / `password` out of config and do **not** set `HOP_MARKETPLACE_*` (wrong +Basic auth causes HTTP 401 even though anonymous would succeed). + +Corporate private repos can use Basic auth (prefer a read-only user): ```bash export HOP_MARKETPLACE_USERNAME=reader export HOP_MARKETPLACE_PASSWORD='…' ``` -**HTTP 401** means the repository requires auth or anonymous is disabled on the server. - ## GUI Hop GUI → **Tools → Marketplace…** lists Wave 1 optional plugins, installs from the diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java index 18977187d30..af810046a74 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java @@ -31,6 +31,10 @@ /** * Marketplace settings stored under the {@code marketplace} key in hop-config.json (or defaults). + * + *

Hop always loads that file from {@code ${HOP_CONFIG_FOLDER}/hop-config.json}. When {@code + * HOP_CONFIG_FOLDER} is unset, it defaults to {@code /config} (with the hop launcher, the + * client install's {@code config/} directory). */ @Getter @Setter diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java index 37520b7e302..68beb29e55a 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java @@ -32,7 +32,7 @@ public class MarketplaceRepository { /** * Optional HTTP Basic auth password. Prefer leaving this empty in hop-config.json and setting - * {@code HOP_MARKETPLACE_PASSWORD} or {@code ARTIFACTORY_PASSWORD} instead. + * {@code HOP_MARKETPLACE_PASSWORD} instead. Do not send credentials for anonymous local Nexus. */ private String password; @@ -61,8 +61,9 @@ public String normalizedUrl() { } /** - * Effective credentials: config fields, then env {@code HOP_MARKETPLACE_*} / {@code - * ARTIFACTORY_*}. + * Effective credentials: repository config fields, then {@code HOP_MARKETPLACE_USERNAME} / {@code + * HOP_MARKETPLACE_PASSWORD}. No credentials means anonymous HTTP (correct for local Nexus after + * {@code docker/marketplace-nexus/start.sh}). */ public String effectiveUsername() { if (StringUtils.isNotBlank(username)) { @@ -70,9 +71,7 @@ public String effectiveUsername() { } String fromEnv = firstNonBlank( - System.getenv("HOP_MARKETPLACE_USERNAME"), - System.getenv("HOP_MARKETPLACE_USER"), - System.getenv("ARTIFACTORY_USER")); + System.getenv("HOP_MARKETPLACE_USERNAME"), System.getenv("HOP_MARKETPLACE_USER")); return StringUtils.isNotBlank(fromEnv) ? fromEnv : null; } @@ -80,9 +79,7 @@ public String effectivePassword() { if (StringUtils.isNotBlank(password)) { return password; } - String fromEnv = - firstNonBlank( - System.getenv("HOP_MARKETPLACE_PASSWORD"), System.getenv("ARTIFACTORY_PASSWORD")); + String fromEnv = System.getenv("HOP_MARKETPLACE_PASSWORD"); return StringUtils.isNotBlank(fromEnv) ? fromEnv : null; } diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/HopHome.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/HopHome.java index 4043d116cc6..9cb5591f8fa 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/HopHome.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/HopHome.java @@ -24,22 +24,17 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; -import org.apache.commons.lang3.StringUtils; import org.apache.hop.core.exception.HopException; /** - * Resolves the Hop installation directory (the folder that contains {@code plugins/}). + * Resolves the Hop client install directory (folder containing {@code plugins/}). * - *

Order: {@code HOP_HOME} / {@code hop.home} if they point at a valid install, then {@code - * user.dir}, then parent of {@code user.dir}. A relative {@code HOP_HOME} that is resolved against - * a cwd already inside the install (e.g. {@code assemblies/client/target/hop} while sitting in that - * directory) is ignored so we do not double the path. + *

Hop launchers {@code cd} to the install root before starting the JVM, so the process working + * directory is the install. Marketplace unpacks plugins into that tree only — the same + * {@code plugins/} folder Hop already scans. */ public final class HopHome { - public static final String ENV_HOP_HOME = "HOP_HOME"; - public static final String PROP_HOP_HOME = "hop.home"; - private HopHome() {} public static Path resolve() throws HopException { @@ -53,23 +48,13 @@ public static Path resolve() throws HopException { } throw new HopException( "Cannot determine Hop installation directory (need a folder containing plugins/)." + + " Run the hop launcher from the client install (./hop …)." + " Tried: " - + String.join(", ", tried) - + ". Unset a relative HOP_HOME if you are already in the hop install, or set HOP_HOME" - + " to an absolute path."); + + String.join(", ", tried)); } private static Set candidates() { - // LinkedHashSet preserves order and drops duplicates after normalize Set paths = new LinkedHashSet<>(); - String fromEnv = System.getenv(ENV_HOP_HOME); - if (StringUtils.isNotBlank(fromEnv)) { - paths.add(Paths.get(fromEnv.trim())); - } - String fromProp = System.getProperty(PROP_HOP_HOME); - if (StringUtils.isNotBlank(fromProp)) { - paths.add(Paths.get(fromProp.trim())); - } Path cwd = Paths.get(System.getProperty("user.dir", ".")); paths.add(cwd); Path parent = cwd.toAbsolutePath().normalize().getParent(); diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java index 3847eae9b84..b7a12c644b9 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java @@ -152,6 +152,9 @@ private String getText(String url, MarketplaceRepository repository) throws HopE applyBasicAuth(builder, repository); HttpResponse response = httpClient.send(builder.build(), HttpResponse.BodyHandlers.ofString()); + if (response.statusCode() == 401 || response.statusCode() == 403) { + throw new HopException(authFailureMessage(response.statusCode(), url, repository)); + } if (response.statusCode() != 200) { throw new HopException( "HTTP " + response.statusCode() + " fetching maven-metadata from " + url); @@ -176,15 +179,7 @@ private Path download(String url, MarketplaceRepository repository, String label HttpResponse response = httpClient.send(builder.build(), HttpResponse.BodyHandlers.ofInputStream()); if (response.statusCode() == 401 || response.statusCode() == 403) { - throw new HopException( - "HTTP " - + response.statusCode() - + " downloading " - + label - + " from " - + url - + ". For local Nexus enable anonymous read, or set" - + " HOP_MARKETPLACE_USERNAME / HOP_MARKETPLACE_PASSWORD."); + throw new HopException(authFailureMessage(response.statusCode(), url, repository)); } if (response.statusCode() != 200) { throw new HopException( @@ -216,4 +211,23 @@ static void applyBasicAuth(HttpRequest.Builder builder, MarketplaceRepository re Base64.getEncoder().encodeToString((user + ":" + pass).getBytes(StandardCharsets.UTF_8)); builder.header("Authorization", "Basic " + token); } + + private static String authFailureMessage( + int status, String url, MarketplaceRepository repository) { + StringBuilder sb = new StringBuilder(); + sb.append("HTTP ").append(status).append(" from ").append(url).append(". "); + if (repository != null && repository.hasCredentials()) { + sb.append("Basic auth was sent as user '") + .append(repository.effectiveUsername()) + .append("'. Wrong credentials make Nexus reject the request even when anonymous read") + .append(" would work. Clear username/password in hop-config marketplace.repositories") + .append(" and unset HOP_MARKETPLACE_USERNAME / HOP_MARKETPLACE_PASSWORD, or fix the") + .append(" password."); + } else { + sb.append("No credentials were sent (anonymous). Enable anonymous read on the repository") + .append(" (docker/marketplace-nexus/start.sh does this), or set") + .append(" HOP_MARKETPLACE_USERNAME / HOP_MARKETPLACE_PASSWORD for a private repo."); + } + return sb.toString(); + } } diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties index 23200e7372d..17a12af4816 100644 --- a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties @@ -34,7 +34,7 @@ MarketplaceDialog.Status.NotInstalled=Not installed MarketplaceDialog.Status.RestartHint=Restart Hop after install or uninstall so plugins are reloaded. MarketplaceDialog.Status.Installing=Installing {0}... MarketplaceDialog.Error.Header=Marketplace error -MarketplaceDialog.Error.ResolveHome=Could not determine the Hop installation directory (set HOP_HOME or start Hop from the install root). +MarketplaceDialog.Error.ResolveHome=Could not determine the Hop installation directory. Start Hop from the install root using the hop launcher. MarketplaceDialog.Install.Done.Header=Plugin installed MarketplaceDialog.Install.Done.Message=Installed {0}.\n\nPlease restart Hop to load the plugin. MarketplaceDialog.Install.Error=Failed to install {0} diff --git a/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml b/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml index a7ae8260034..a60950fe97e 100644 --- a/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml +++ b/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml @@ -10,13 +10,14 @@ version: "1.0" hopVersion: "2.19.0-SNAPSHOT" enforceOnRun: false -# Defaults to Maven Central when omitted +# Defaults to Maven Central when omitted. +# Local Sonatype Nexus (docker/marketplace-nexus/start.sh): repositories: - - id: central - url: "https://repo1.maven.org/maven2/" - # Local Artifactory for development: - # - id: local-artifactory - # url: "http://localhost:8082/artifactory/hop-plugins-local/" + - id: local-nexus + url: "http://127.0.0.1:8081/repository/hop-plugins/" + # Production / CI: + # - id: central + # url: "https://repo1.maven.org/maven2/" plugins: - artifactId: hop-tech-parquet diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/HopHomeTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/HopHomeTest.java index 14c47c118ed..fae4b4a1840 100644 --- a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/HopHomeTest.java +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/HopHomeTest.java @@ -44,22 +44,26 @@ void resolveUsesUserDirWhenItIsHopHome() throws Exception { Path hop = tempDir.resolve("hop"); Files.createDirectories(hop.resolve("plugins")); String previous = System.getProperty("user.dir"); - String previousProp = System.getProperty(HopHome.PROP_HOP_HOME); try { - System.clearProperty(HopHome.PROP_HOP_HOME); System.setProperty("user.dir", hop.toString()); - // Env HOP_HOME may still be set in the process; prop/user.dir path must work when env - // is unset — we only assert isHopHome behavior + absolute resolution of user.dir - Path resolved = hop.toAbsolutePath().normalize(); - assertTrue(HopHome.isHopHome(resolved)); - assertEquals(resolved, hop.toAbsolutePath().normalize()); + assertEquals(hop.toAbsolutePath().normalize(), HopHome.resolve()); + } finally { + System.setProperty("user.dir", previous); + } + } + + @Test + void resolveFallsBackToParentOfUserDir() throws Exception { + Path hop = tempDir.resolve("hop"); + Files.createDirectories(hop.resolve("plugins")); + Path nested = hop.resolve("subdir"); + Files.createDirectories(nested); + String previous = System.getProperty("user.dir"); + try { + System.setProperty("user.dir", nested.toString()); + assertEquals(hop.toAbsolutePath().normalize(), HopHome.resolve()); } finally { System.setProperty("user.dir", previous); - if (previousProp == null) { - System.clearProperty(HopHome.PROP_HOP_HOME); - } else { - System.setProperty(HopHome.PROP_HOP_HOME, previousProp); - } } } } diff --git a/tools/install-wave1-plugins.sh b/tools/install-wave1-plugins.sh index ad65957acfe..da48395e955 100755 --- a/tools/install-wave1-plugins.sh +++ b/tools/install-wave1-plugins.sh @@ -10,18 +10,18 @@ # # Unpack Wave 1 marketplace plugin zips into a Hop install (e.g. for IT images). # Usage: -# ./tools/install-wave1-plugins.sh [HOP_HOME] -# Default HOP_HOME: assemblies/client/target/hop +# ./tools/install-wave1-plugins.sh [HOP_INSTALL_DIR] +# Default install dir: assemblies/client/target/hop # # Requires plugin modules to have been packaged (*.zip under plugins/**/target/). set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -HOP_HOME="${1:-${ROOT}/assemblies/client/target/hop}" +INSTALL_DIR="${1:-${ROOT}/assemblies/client/target/hop}" VERSION="${HOP_VERSION:-2.19.0-SNAPSHOT}" -if [[ ! -d "${HOP_HOME}" ]]; then - echo "Hop home not found: ${HOP_HOME}" >&2 +if [[ ! -d "${INSTALL_DIR}" ]]; then + echo "Hop install not found: ${INSTALL_DIR}" >&2 echo "Unzip hop-client first, or pass an existing install path." >&2 exit 1 fi @@ -53,9 +53,9 @@ for entry in "${PLUGINS[@]}"; do continue fi echo "Installing ${id} from ${rel}" - unzip -o -q "${zip}" -d "${HOP_HOME}" + unzip -o -q "${zip}" -d "${INSTALL_DIR}" installed=$((installed + 1)) done -echo "Wave 1 plugins: installed=${installed} skipped=${skipped} into ${HOP_HOME}" +echo "Wave 1 plugins: installed=${installed} skipped=${skipped} into ${INSTALL_DIR}" # Note: beam plugin zip does not include lib/beam (already in core client). From fce59539f3993c4ee3a6b85e147851a2ee49e028 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Mon, 20 Jul 2026 00:00:53 +0200 Subject: [PATCH 15/28] issue #7547: ASF primary repos, marketplace repo CLI/GUI, install fallback Pre-configure repository.apache.org as primary with Maven Central fallback, add hop marketplace repo commands and Manage Repositories dialog, try enabled repos in order on install, and report disabled IT projects as skipped instead of a false docker environment failure. --- docker/marketplace-nexus/README.md | 26 +- integration-tests/scripts/run-tests-docker.sh | 146 +++--- plugins/misc/marketplace/README.md | 82 +-- .../command/MarketplaceCommand.java | 254 +++++++++- .../marketplace/config/MarketplaceConfig.java | 225 ++++++++- .../config/MarketplaceRepository.java | 42 +- .../marketplace/env/EnvironmentApplier.java | 9 +- .../gui/ManageRepositoriesDialog.java | 472 ++++++++++++++++++ .../marketplace/gui/MarketplaceDialog.java | 71 ++- .../marketplace/install/InstallReceipt.java | 7 + .../marketplace/install/PluginInstaller.java | 54 +- .../resolve/MavenRepositoryClient.java | 44 ++ .../gui/messages/messages_en_US.properties | 39 +- .../src/main/samples/hop-env.example.yaml | 15 +- .../config/MarketplaceConfigTest.java | 103 ++++ .../install/PluginInstallerTest.java | 63 ++- 16 files changed, 1488 insertions(+), 164 deletions(-) create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/ManageRepositoriesDialog.java create mode 100644 plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/config/MarketplaceConfigTest.java diff --git a/docker/marketplace-nexus/README.md b/docker/marketplace-nexus/README.md index 6da6400c2b1..4f61d9dcc2a 100644 --- a/docker/marketplace-nexus/README.md +++ b/docker/marketplace-nexus/README.md @@ -74,28 +74,18 @@ export NEXUS_PASSWORD=hop-nexus-dev # or your NEXUS_ADMIN_PASSWORD ## Hop marketplace (anonymous install) -Edit **`${HOP_CONFIG_FOLDER}/hop-config.json`** (always that file). If -`HOP_CONFIG_FOLDER` is unset, the hop launcher uses `/config`. - -```json -{ - "marketplace": { - "enabled": true, - "groupId": "org.apache.hop", - "defaultVersion": "2.19.0-SNAPSHOT", - "repositories": [ - { - "id": "local-nexus", - "url": "http://127.0.0.1:8081/repository/hop-plugins/" - } - ] - } -} -``` +Config is always **`${HOP_CONFIG_FOLDER}/hop-config.json`**. Defaults are ASF +primary + Maven Central; add local Nexus and make it primary for dev: ```bash cd /path/to/hop # the unzipped hop-client directory +./hop marketplace repo add --id local-nexus \ + --url http://127.0.0.1:8081/repository/hop-plugins/ --primary +./hop marketplace repo list ./hop marketplace install hop-tech-parquet +# restore production defaults later: +./hop marketplace repo set-primary asf +# or: ./hop marketplace repo reset-defaults ``` Quick check: diff --git a/integration-tests/scripts/run-tests-docker.sh b/integration-tests/scripts/run-tests-docker.sh index dbcafc7536d..45cb5720363 100755 --- a/integration-tests/scripts/run-tests-docker.sh +++ b/integration-tests/scripts/run-tests-docker.sh @@ -257,74 +257,108 @@ docker compose -f ${DOCKER_FILES_DIR}/integration-tests-base.yaml build --build- # project that actually references the fat jar is about to run. BEAM_IMAGE_BUILT="false" +write_surefire_skipped() { + local name="$1" + local reason="$2" + local report="${CURRENT_DIR}/../surefire-reports/surefile_${name}.xml" + mkdir -p "${CURRENT_DIR}/../surefire-reports" + cat >"${report}" < + + + +EOF +} + +write_surefire_env_failure() { + local name="$1" + local detail="$2" + local report="${CURRENT_DIR}/../surefire-reports/surefile_${name}.xml" + mkdir -p "${CURRENT_DIR}/../surefire-reports" + cat >"${report}" < + +${detail} + +EOF +} + # Loop over project folders for d in "${CURRENT_DIR}"/../${PROJECT_NAME}/; do + if [[ "$d" == *"scripts/" ]] || [[ "$d" == *"surefire-reports/" ]] || [[ "$d" == *"hopweb/" ]]; then + continue + fi - if [[ "$d" != *"scripts/" ]] && [[ "$d" != *"surefire-reports/" ]] && [[ "$d" != *"hopweb/" ]]; then - # If there is a file called disabled.txt the project is disabled - if [ ! -f "$d/disabled.txt" ]; then - - PROJECT_NAME=$(basename $d) - - echo "Project name: ${PROJECT_NAME}" - echo "project path: $d" - echo "docker compose path: ${DOCKER_FILES_DIR}" - - # If this project references the Hop fat jar (Beam runners), make sure hop-beam-image exists. - # Built once per run, and only when such a project is actually enabled. - if [ "${BEAM_IMAGE_BUILT}" != "true" ] && grep -rqs "hop-fatjar.jar" "$d" 2>/dev/null; then - echo "Project ${PROJECT_NAME} needs the Hop fat jar; building hop-beam-image (once)." - if [ -n "${HOP_SPARK_CLIENT_VERSION}" ]; then - echo "Spark client pack for fat jar: ${HOP_SPARK_CLIENT_VERSION}" - fi - HOP_SPARK_CLIENT_VERSION="${HOP_SPARK_CLIENT_VERSION}" \ - docker compose -f ${DOCKER_FILES_DIR}/integration-tests-beam-base.yaml build \ - --build-arg HOP_SPARK_CLIENT_VERSION="${HOP_SPARK_CLIENT_VERSION}" - EXECUTED_COMPOSE_FILES=("${EXECUTED_COMPOSE_FILES[@]}" "${DOCKER_FILES_DIR}/integration-tests-beam-base.yaml") - BEAM_IMAGE_BUILT="true" - fi + # Normalize project name from the folder we are iterating + PROJECT_NAME=$(basename "${d}") - # Check if specific compose exists + # If there is a file called disabled.txt the project is disabled — do not pretend Docker failed + if [ -f "$d/disabled.txt" ]; then + echo "Project ${PROJECT_NAME} is disabled (disabled.txt present); skipping." + if [ "${SUREFIRE_REPORT}" = "true" ]; then + write_surefire_skipped "${PROJECT_NAME}" "Project disabled via disabled.txt" + fi + continue + fi - if [ -n "${TEST_FILTER}" ]; then - echo "TEST_FILTER: ${TEST_FILTER}" - fi + echo "Project name: ${PROJECT_NAME}" + echo "project path: $d" + echo "docker compose path: ${DOCKER_FILES_DIR}" - if [ -f "${DOCKER_FILES_DIR}/integration-tests-${PROJECT_NAME}.yaml" ]; then - echo "Project compose exists." - EXECUTED_COMPOSE_FILES=("${EXECUTED_COMPOSE_FILES[@]}" "${DOCKER_FILES_DIR}/integration-tests-${PROJECT_NAME}.yaml") - # Rebuild project images so SPARK_VERSION (and similar) build args take effect. - # hop_server also must rebuild: its hop-server service image (apache/hop:Development - # from docker/Dockerfile) otherwise stays cached and can miss client-side assembly - # plugins needed by remote-export ITs (main-0008/0009/0010). - if [ "${PROJECT_NAME}" = "spark" ]; then - echo "Spark IT cluster version: ${SPARK_VERSION} (hadoop ${HADOOP_VERSION})" - PROJECT_NAME=${PROJECT_NAME} TEST_FILTER=${TEST_FILTER} SKIP_GOOGLE_SHEETS=${SKIP_GOOGLE_SHEETS} SPARK_VERSION=${SPARK_VERSION} HADOOP_VERSION=${HADOOP_VERSION} SPARK_BASE_URL=${SPARK_BASE_URL} \ - docker compose -f ${DOCKER_FILES_DIR}/integration-tests-${PROJECT_NAME}.yaml up --build --abort-on-container-exit - elif [ "${PROJECT_NAME}" = "hop_server" ]; then - echo "Rebuilding hop_server images so remote Hop Server matches current assemblies" - PROJECT_NAME=${PROJECT_NAME} TEST_FILTER=${TEST_FILTER} SKIP_GOOGLE_SHEETS=${SKIP_GOOGLE_SHEETS} \ - docker compose -f ${DOCKER_FILES_DIR}/integration-tests-${PROJECT_NAME}.yaml up --build --abort-on-container-exit - else - PROJECT_NAME=${PROJECT_NAME} TEST_FILTER=${TEST_FILTER} SKIP_GOOGLE_SHEETS=${SKIP_GOOGLE_SHEETS} \ - docker compose -f ${DOCKER_FILES_DIR}/integration-tests-${PROJECT_NAME}.yaml up --abort-on-container-exit - fi - else - echo "Project compose does not exists." - PROJECT_NAME=${PROJECT_NAME} TEST_FILTER=${TEST_FILTER} SKIP_GOOGLE_SHEETS=${SKIP_GOOGLE_SHEETS} \ - docker compose -f ${DOCKER_FILES_DIR}/integration-tests-base.yaml up --abort-on-container-exit - fi + # If this project references the Hop fat jar (Beam runners), make sure hop-beam-image exists. + # Built once per run, and only when such a project is actually enabled. + if [ "${BEAM_IMAGE_BUILT}" != "true" ] && grep -rqs "hop-fatjar.jar" "$d" 2>/dev/null; then + echo "Project ${PROJECT_NAME} needs the Hop fat jar; building hop-beam-image (once)." + if [ -n "${HOP_SPARK_CLIENT_VERSION}" ]; then + echo "Spark client pack for fat jar: ${HOP_SPARK_CLIENT_VERSION}" fi + HOP_SPARK_CLIENT_VERSION="${HOP_SPARK_CLIENT_VERSION}" \ + docker compose -f ${DOCKER_FILES_DIR}/integration-tests-beam-base.yaml build \ + --build-arg HOP_SPARK_CLIENT_VERSION="${HOP_SPARK_CLIENT_VERSION}" + EXECUTED_COMPOSE_FILES=("${EXECUTED_COMPOSE_FILES[@]}" "${DOCKER_FILES_DIR}/integration-tests-beam-base.yaml") + BEAM_IMAGE_BUILT="true" + fi + + if [ -n "${TEST_FILTER}" ]; then + echo "TEST_FILTER: ${TEST_FILTER}" + fi + + COMPOSE_EXIT=0 + if [ -f "${DOCKER_FILES_DIR}/integration-tests-${PROJECT_NAME}.yaml" ]; then + echo "Project compose exists." + EXECUTED_COMPOSE_FILES=("${EXECUTED_COMPOSE_FILES[@]}" "${DOCKER_FILES_DIR}/integration-tests-${PROJECT_NAME}.yaml") + # Rebuild project images so SPARK_VERSION (and similar) build args take effect. + # hop_server also must rebuild: its hop-server service image (apache/hop:Development + # from docker/Dockerfile) otherwise stays cached and can miss client-side assembly + # plugins needed by remote-export ITs (main-0008/0009/0010). + if [ "${PROJECT_NAME}" = "spark" ]; then + echo "Spark IT cluster version: ${SPARK_VERSION} (hadoop ${HADOOP_VERSION})" + PROJECT_NAME=${PROJECT_NAME} TEST_FILTER=${TEST_FILTER} SKIP_GOOGLE_SHEETS=${SKIP_GOOGLE_SHEETS} SPARK_VERSION=${SPARK_VERSION} HADOOP_VERSION=${HADOOP_VERSION} SPARK_BASE_URL=${SPARK_BASE_URL} \ + docker compose -f ${DOCKER_FILES_DIR}/integration-tests-${PROJECT_NAME}.yaml up --build --abort-on-container-exit \ + || COMPOSE_EXIT=$? + elif [ "${PROJECT_NAME}" = "hop_server" ]; then + echo "Rebuilding hop_server images so remote Hop Server matches current assemblies" + PROJECT_NAME=${PROJECT_NAME} TEST_FILTER=${TEST_FILTER} SKIP_GOOGLE_SHEETS=${SKIP_GOOGLE_SHEETS} \ + docker compose -f ${DOCKER_FILES_DIR}/integration-tests-${PROJECT_NAME}.yaml up --build --abort-on-container-exit \ + || COMPOSE_EXIT=$? + else + PROJECT_NAME=${PROJECT_NAME} TEST_FILTER=${TEST_FILTER} SKIP_GOOGLE_SHEETS=${SKIP_GOOGLE_SHEETS} \ + docker compose -f ${DOCKER_FILES_DIR}/integration-tests-${PROJECT_NAME}.yaml up --abort-on-container-exit \ + || COMPOSE_EXIT=$? + fi + else + echo "Project compose does not exists." + PROJECT_NAME=${PROJECT_NAME} TEST_FILTER=${TEST_FILTER} SKIP_GOOGLE_SHEETS=${SKIP_GOOGLE_SHEETS} \ + docker compose -f ${DOCKER_FILES_DIR}/integration-tests-base.yaml up --abort-on-container-exit \ + || COMPOSE_EXIT=$? fi - # Create final report + # Create final report only when the project was actually run and no report was produced if [ "${SUREFIRE_REPORT}" = "true" ]; then if [ ! -f "${CURRENT_DIR}/../surefire-reports/surefile_${PROJECT_NAME}.xml" ]; then - echo "" >"${CURRENT_DIR}"/../surefire-reports/surefile_${PROJECT_NAME}.xml - echo "" >>"${CURRENT_DIR}"/../surefire-reports/surefile_${PROJECT_NAME}.xml - echo "" >>"${CURRENT_DIR}"/../surefire-reports/surefile_${PROJECT_NAME}.xml - echo "" >>"${CURRENT_DIR}"/../surefire-reports/surefile_${PROJECT_NAME}.xml + write_surefire_env_failure "${PROJECT_NAME}" \ + "Could not start docker environment for ${PROJECT_NAME} (compose exit ${COMPOSE_EXIT}). Check docker compose logs above." fi fi done diff --git a/plugins/misc/marketplace/README.md b/plugins/misc/marketplace/README.md index 7bbe397d12d..32a970e4c54 100644 --- a/plugins/misc/marketplace/README.md +++ b/plugins/misc/marketplace/README.md @@ -19,8 +19,9 @@ under the License. # Hop Marketplace plugin -Bundled core plugin that installs optional Hop plugins from a Maven repository -(Maven Central, ASF Nexus, or a local Artifactory). +Bundled core plugin that installs optional Hop plugins from Maven repositories. +**Default primary:** [Apache Repository](https://repository.apache.org/content/groups/public/) +(`repository.apache.org`), with **Maven Central** as fallback. ## CLI @@ -29,17 +30,30 @@ From the Hop install directory (or invoke the `hop` script by path — it alread ```bash ./hop marketplace install hop-tech-parquet -./hop marketplace install hop-engines-spark:2.19.0 +./hop marketplace install hop-engines-spark:2.19.0 --repo asf ./hop marketplace install hop-engines-beam ./hop marketplace list ./hop marketplace uninstall hop-tech-parquet +# Repositories (saved to ${HOP_CONFIG_FOLDER}/hop-config.json) +./hop marketplace repo list +./hop marketplace repo add --id local-nexus --url http://127.0.0.1:8081/repository/hop-plugins/ --primary +./hop marketplace repo set-primary asf +./hop marketplace repo enable central +./hop marketplace repo disable local-nexus +./hop marketplace repo remove local-nexus +./hop marketplace repo reset-defaults # ASF primary + Central + # Declarative environment (CI/CD / Docker) ./hop marketplace apply -f hop-env.yaml ./hop marketplace apply -f hop-env.yaml --prune ./hop marketplace validate -f hop-env.yaml ``` +Install tries the **primary** repository first, then other **enabled** repositories +in list order, until the zip is found (or all fail). Use `--repo ` to force a +single repository. + Coordinates: - `artifactId` (uses config `defaultVersion` / Hop version) @@ -58,6 +72,8 @@ version: "1.0" hopVersion: "2.19.0" enforceOnRun: false # set true to hard-fail hop-run on drift repositories: + - id: asf + url: "https://repository.apache.org/content/groups/public/" - id: central url: "https://repo1.maven.org/maven2/" plugins: @@ -75,12 +91,13 @@ Discovery order: `-f` / `HOP_ENV_FILE` / `PROJECT_HOME/hop-env.yaml` / install-r ## Config (`hop-config.json`) Marketplace settings live under the `marketplace` key in **`${HOP_CONFIG_FOLDER}/hop-config.json`** -(always that path — not a separate file under the client zip). If `HOP_CONFIG_FOLDER` is -unset, Hop defaults it to `/config` (with the hop launcher, that is -`/config`). +(always that path). If `HOP_CONFIG_FOLDER` is unset, Hop defaults it to +`/config` (with the hop launcher: `/config`). + +When the `marketplace` key is absent, defaults are: -Local Sonatype Nexus (recommended for marketplace development — see -`docker/marketplace-nexus/README.md`): +1. **asf** (primary) — `https://repository.apache.org/content/groups/public/` +2. **central** — `https://repo1.maven.org/maven2/` ```json { @@ -90,25 +107,34 @@ Local Sonatype Nexus (recommended for marketplace development — see "defaultVersion": "2.19.0-SNAPSHOT", "repositories": [ { - "id": "local-nexus", - "url": "http://localhost:8081/repository/hop-plugins/" + "id": "asf", + "name": "Apache Repository", + "url": "https://repository.apache.org/content/groups/public/", + "primary": true, + "enabled": true + }, + { + "id": "central", + "name": "Maven Central", + "url": "https://repo1.maven.org/maven2/", + "primary": false, + "enabled": true } ] } } ``` -After `./docker/marketplace-nexus/start.sh`, installs are **anonymous** — no password -in that hop-config. +Local Sonatype Nexus for development (see `docker/marketplace-nexus/README.md`): ```bash -cd /path/to/hop +./hop marketplace repo add --id local-nexus \ + --url http://127.0.0.1:8081/repository/hop-plugins/ --primary ./hop marketplace install hop-tech-parquet ``` -Local Nexus after `docker/marketplace-nexus/start.sh` is **anonymous read** — leave -`username` / `password` out of config and do **not** set `HOP_MARKETPLACE_*` (wrong -Basic auth causes HTTP 401 even though anonymous would succeed). +Anonymous local Nexus needs **no** username/password and **no** `HOP_MARKETPLACE_*` +env (wrong Basic auth causes HTTP 401 even when anonymous would work). Corporate private repos can use Basic auth (prefer a read-only user): @@ -119,23 +145,7 @@ export HOP_MARKETPLACE_PASSWORD='…' ## GUI -Hop GUI → **Tools → Marketplace…** lists Wave 1 optional plugins, installs from the -configured Maven repository, and uninstalls marketplace-managed installs. Restart -Hop after install/uninstall. - -## Beam note - -`hop-engines-beam` marketplace package is the **plugin** (`plugins/engines/beam`) only. -`lib/beam` remains part of the default Hop distribution and is never removed by -marketplace uninstall. - -## Integration tests / full local install - -Optional plugins are **not** in `hop-client.zip`. For ITs (or a full local install): - -```bash -unzip assemblies/client/target/hop-client-*.zip -d assemblies/client/target/ -./tools/install-wave1-plugins.sh assemblies/client/target/hop -``` - -`integration-tests/scripts/run-tests-docker.sh` and Jenkins run this automatically. +Hop GUI → **Tools → Marketplace…** lists Wave 1 optional plugins. Choose the +**primary repository**, or **Manage…** to add/edit/remove/reorder repositories +(same hop-config.json as the CLI). Install uses the primary first, then fallbacks. +Restart after install or uninstall. diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java index 72dbd8d3110..b7432655931 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java @@ -20,9 +20,11 @@ import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; +import java.util.stream.Collectors; import lombok.Getter; import lombok.Setter; import org.apache.commons.lang3.StringUtils; +import org.apache.hop.core.Const; import org.apache.hop.core.HopVersionProvider; import org.apache.hop.core.exception.HopException; import org.apache.hop.core.logging.ILogChannel; @@ -31,6 +33,7 @@ import org.apache.hop.hop.plugin.HopCommand; import org.apache.hop.hop.plugin.IHopCommand; import org.apache.hop.marketplace.config.MarketplaceConfig; +import org.apache.hop.marketplace.config.MarketplaceRepository; import org.apache.hop.marketplace.env.EnvironmentApplier; import org.apache.hop.marketplace.env.EnvironmentDrift; import org.apache.hop.marketplace.env.HopEnvironmentLoader; @@ -58,7 +61,8 @@ MarketplaceCommand.UninstallCommand.class, MarketplaceCommand.ListCommand.class, MarketplaceCommand.ApplyCommand.class, - MarketplaceCommand.ValidateCommand.class + MarketplaceCommand.ValidateCommand.class, + MarketplaceCommand.RepoCommand.class }) @HopCommand(id = "marketplace", description = "Hop plugin marketplace") public class MarketplaceCommand implements Runnable, IHopCommand, IHasHopMetadataProvider { @@ -76,12 +80,18 @@ public void initialize( this.variables = variables; this.metadataProvider = metadataProvider; this.log = new LogChannel("Marketplace"); - // Wire nested subcommands with shared context - for (CommandLine sub : cmd.getSubcommands().values()) { + // Wire nested subcommands (including marketplace repo *) with shared context + wireSubcommands(cmd, log, variables); + } + + private static void wireSubcommands( + CommandLine commandLine, ILogChannel log, IVariables variables) { + for (CommandLine sub : commandLine.getSubcommands().values()) { Object userObject = sub.getCommand(); if (userObject instanceof MarketplaceSubCommand nested) { nested.init(log, variables); } + wireSubcommands(sub, log, variables); } } @@ -121,6 +131,12 @@ static class InstallCommand extends MarketplaceSubCommand { "artifactId, artifactId:version, or groupId:artifactId:version (e.g. hop-tech-parquet)") private String coordinate; + @Option( + names = {"--repo"}, + description = + "Use only this repository id (skip fallback chain). Default: try primary then others.") + private String repoId; + @Override public void run() { try { @@ -134,9 +150,17 @@ public void run() { MavenCoordinates gav = MavenCoordinates.parse(coordinate, config.getGroupId(), resolveDefaultVersion(config)); - new PluginInstaller(log, hopHome, config).install(gav, true); + InstallReceipt receipt = + new PluginInstaller(log, hopHome, config).install(gav, true, repoId); System.out.println( - "Plugin " + gav.gav() + " installed under " + hopHome + ". Restart Hop to load it."); + "Plugin " + + gav.gav() + + " installed under " + + hopHome + + (receipt.getRepositoryId() != null + ? " from repo '" + receipt.getRepositoryId() + "'" + : "") + + ". Restart Hop to load it."); } catch (Exception e) { System.err.println("ERROR: " + e.getMessage()); if (log != null) { @@ -332,4 +356,224 @@ private static void addExtraPlugins( } } } + + @Command( + name = "repo", + description = "Manage marketplace Maven repositories in hop-config.json", + subcommands = { + MarketplaceCommand.RepoListCommand.class, + MarketplaceCommand.RepoAddCommand.class, + MarketplaceCommand.RepoRemoveCommand.class, + MarketplaceCommand.RepoSetPrimaryCommand.class, + MarketplaceCommand.RepoEnableCommand.class, + MarketplaceCommand.RepoDisableCommand.class, + MarketplaceCommand.RepoResetDefaultsCommand.class + }) + static class RepoCommand extends MarketplaceSubCommand { + @Override + public void run() { + // picocli shows usage when no subcommand + new CommandLine(this).usage(System.out); + } + } + + @Command(name = "list", description = "List configured marketplace repositories") + static class RepoListCommand extends MarketplaceSubCommand { + @Override + public void run() { + MarketplaceConfig config = MarketplaceConfig.load(); + System.out.printf("%-8s %-10s %-12s %-20s %s%n", "PRIMARY", "ENABLED", "ID", "NAME", "URL"); + for (MarketplaceRepository repo : config.getRepositories()) { + if (repo == null) { + continue; + } + System.out.printf( + "%-8s %-10s %-12s %-20s %s%n", + repo.isPrimary() ? "*" : "", + repo.isEnabled() ? "yes" : "no", + Const.NVL(repo.getId(), ""), + Const.NVL(repo.displayName(), ""), + repo.normalizedUrl()); + } + System.out.println(); + System.out.println( + "Install order: " + + config.orderedRepositories().stream() + .map(MarketplaceRepository::getId) + .collect(Collectors.joining(" → "))); + } + } + + @Command(name = "add", description = "Add a marketplace repository and save hop-config.json") + static class RepoAddCommand extends MarketplaceSubCommand { + @Option( + names = {"--id"}, + required = true, + description = "Stable repository id (e.g. local-nexus)") + private String id; + + @Option( + names = {"--url"}, + required = true, + description = "Maven base URL (…/repository/hop-plugins/)") + private String url; + + @Option( + names = {"--name"}, + description = "Display name") + private String name; + + @Option( + names = {"--primary"}, + description = "Make this the primary repository") + private boolean primary; + + @Option( + names = {"--username"}, + description = "Optional Basic auth username") + private String username; + + @Option( + names = {"--password"}, + description = "Optional Basic auth password (prefer env HOP_MARKETPLACE_PASSWORD)") + private String password; + + @Override + public void run() { + try { + MarketplaceConfig config = MarketplaceConfig.load(); + MarketplaceRepository repo = + new MarketplaceRepository(id, StringUtils.isNotBlank(name) ? name : id, url, primary); + repo.setUsername(username); + repo.setPassword(password); + config.addRepository(repo); + config.save(); + System.out.println( + "Added repository '" + + id + + "'" + + (primary ? " (primary)" : "") + + " → " + + repo.normalizedUrl()); + } catch (Exception e) { + System.err.println("ERROR: " + e.getMessage()); + throw new CommandLine.ExecutionException( + new CommandLine(this), e.getMessage() == null ? "repo add failed" : e.getMessage(), e); + } + } + } + + @Command(name = "remove", description = "Remove a marketplace repository by id") + static class RepoRemoveCommand extends MarketplaceSubCommand { + @Parameters(index = "0", paramLabel = "ID", description = "Repository id") + private String id; + + @Override + public void run() { + try { + MarketplaceConfig config = MarketplaceConfig.load(); + config.removeRepository(id); + config.save(); + System.out.println("Removed repository '" + id + "'"); + } catch (Exception e) { + System.err.println("ERROR: " + e.getMessage()); + throw new CommandLine.ExecutionException( + new CommandLine(this), + e.getMessage() == null ? "repo remove failed" : e.getMessage(), + e); + } + } + } + + @Command(name = "set-primary", description = "Set the primary marketplace repository") + static class RepoSetPrimaryCommand extends MarketplaceSubCommand { + @Parameters(index = "0", paramLabel = "ID", description = "Repository id") + private String id; + + @Override + public void run() { + try { + MarketplaceConfig config = MarketplaceConfig.load(); + config.setPrimary(id); + config.save(); + System.out.println("Primary marketplace repository is now '" + id + "'"); + } catch (Exception e) { + System.err.println("ERROR: " + e.getMessage()); + throw new CommandLine.ExecutionException( + new CommandLine(this), + e.getMessage() == null ? "repo set-primary failed" : e.getMessage(), + e); + } + } + } + + @Command(name = "enable", description = "Enable a repository in the fallback chain") + static class RepoEnableCommand extends MarketplaceSubCommand { + @Parameters(index = "0", paramLabel = "ID") + private String id; + + @Override + public void run() { + try { + MarketplaceConfig config = MarketplaceConfig.load(); + config.setEnabled(id, true); + config.save(); + System.out.println("Enabled repository '" + id + "'"); + } catch (Exception e) { + System.err.println("ERROR: " + e.getMessage()); + throw new CommandLine.ExecutionException( + new CommandLine(this), + e.getMessage() == null ? "repo enable failed" : e.getMessage(), + e); + } + } + } + + @Command(name = "disable", description = "Disable a repository (skip in fallback chain)") + static class RepoDisableCommand extends MarketplaceSubCommand { + @Parameters(index = "0", paramLabel = "ID") + private String id; + + @Override + public void run() { + try { + MarketplaceConfig config = MarketplaceConfig.load(); + config.setEnabled(id, false); + config.save(); + System.out.println("Disabled repository '" + id + "'"); + } catch (Exception e) { + System.err.println("ERROR: " + e.getMessage()); + throw new CommandLine.ExecutionException( + new CommandLine(this), + e.getMessage() == null ? "repo disable failed" : e.getMessage(), + e); + } + } + } + + @Command( + name = "reset-defaults", + description = "Reset repositories to ASF primary + Maven Central fallback") + static class RepoResetDefaultsCommand extends MarketplaceSubCommand { + @Override + public void run() { + try { + MarketplaceConfig config = MarketplaceConfig.load(); + config.resetToDefaults(); + config.save(); + System.out.println( + "Marketplace repositories reset to ASF primary + Maven Central fallback."); + for (MarketplaceRepository repo : config.getRepositories()) { + System.out.println( + (repo.isPrimary() ? "* " : " ") + repo.getId() + " " + repo.normalizedUrl()); + } + } catch (Exception e) { + System.err.println("ERROR: " + e.getMessage()); + throw new CommandLine.ExecutionException( + new CommandLine(this), + e.getMessage() == null ? "repo reset-defaults failed" : e.getMessage(), + e); + } + } + } } diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java index af810046a74..0c5381fd17b 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java @@ -20,15 +20,16 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import lombok.Getter; import lombok.Setter; +import org.apache.commons.lang3.StringUtils; import org.apache.hop.core.config.HopConfig; +import org.apache.hop.core.exception.HopException; import org.apache.hop.core.json.HopJson; import org.apache.hop.core.logging.ILogChannel; import org.apache.hop.core.logging.LogChannel; -// Map used when serializing to hop-config.json - /** * Marketplace settings stored under the {@code marketplace} key in hop-config.json (or defaults). * @@ -41,7 +42,20 @@ public class MarketplaceConfig { public static final String CONFIG_KEY = "marketplace"; public static final String DEFAULT_GROUP_ID = "org.apache.hop"; - public static final String DEFAULT_REPO_URL = "https://repo1.maven.org/maven2/"; + + public static final String DEFAULT_ASF_ID = "asf"; + public static final String DEFAULT_ASF_NAME = "Apache Repository"; + public static final String DEFAULT_ASF_URL = + "https://repository.apache.org/content/groups/public/"; + + public static final String DEFAULT_CENTRAL_ID = "central"; + public static final String DEFAULT_CENTRAL_NAME = "Maven Central"; + public static final String DEFAULT_CENTRAL_URL = "https://repo1.maven.org/maven2/"; + + /** + * @deprecated use {@link #DEFAULT_ASF_URL} + */ + @Deprecated public static final String DEFAULT_REPO_URL = DEFAULT_ASF_URL; private boolean enabled = true; private String groupId = DEFAULT_GROUP_ID; @@ -51,7 +65,17 @@ public class MarketplaceConfig { private List repositories = new ArrayList<>(); public MarketplaceConfig() { - repositories.add(new MarketplaceRepository("central", DEFAULT_REPO_URL)); + repositories.addAll(defaultRepositories()); + } + + /** ASF primary + Maven Central fallback (shipped defaults). */ + public static List defaultRepositories() { + List list = new ArrayList<>(); + list.add(new MarketplaceRepository(DEFAULT_ASF_ID, DEFAULT_ASF_NAME, DEFAULT_ASF_URL, true)); + list.add( + new MarketplaceRepository( + DEFAULT_CENTRAL_ID, DEFAULT_CENTRAL_NAME, DEFAULT_CENTRAL_URL, false)); + return list; } public static MarketplaceConfig load() { @@ -61,7 +85,12 @@ public static MarketplaceConfig load() { if (raw == null) { return new MarketplaceConfig(); } - return HopJson.newMapper().convertValue(raw, MarketplaceConfig.class); + MarketplaceConfig config = HopJson.newMapper().convertValue(raw, MarketplaceConfig.class); + if (config.getRepositories() == null || config.getRepositories().isEmpty()) { + config.setRepositories(defaultRepositories()); + } + config.ensureValidPrimary(); + return config; } catch (Exception e) { log.logError("Unable to load marketplace config, using defaults", e); return new MarketplaceConfig(); @@ -70,23 +99,195 @@ public static MarketplaceConfig load() { @SuppressWarnings("unchecked") public void save() { + ensureValidPrimary(); Map asMap = HopJson.newMapper().convertValue(this, Map.class); HopConfig.getInstance().saveOption(CONFIG_KEY, asMap); } - /** First repository base URL, or Maven Central. Always ends with {@code /}. */ + /** Replace repository list with shipped ASF + Central defaults. */ + public void resetToDefaults() { + repositories = defaultRepositories(); + } + + /** + * Ensure exactly one primary among enabled repos when possible. Keeps the first {@code + * primary=true} entry and clears the rest; if none, marks the first enabled repo. + */ + public void ensureValidPrimary() { + if (repositories == null) { + repositories = new ArrayList<>(); + } + MarketplaceRepository firstPrimary = null; + for (MarketplaceRepository repo : repositories) { + if (repo == null) { + continue; + } + if (repo.isPrimary()) { + if (firstPrimary == null) { + firstPrimary = repo; + } else { + repo.setPrimary(false); + } + } + } + if (firstPrimary == null) { + for (MarketplaceRepository repo : repositories) { + if (repo != null && repo.isEnabled()) { + repo.setPrimary(true); + break; + } + } + } + } + + /** First repository base URL, or ASF public. Always ends with {@code /}. */ public String primaryRepositoryUrl() { return primaryRepository().normalizedUrl(); } - /** First configured repository (with credentials), or Maven Central defaults. */ + /** + * Primary repository (preferred for display and tried first on install), or ASF built-in + * defaults. + */ public MarketplaceRepository primaryRepository() { - if (repositories != null && !repositories.isEmpty()) { - MarketplaceRepository first = repositories.get(0); - if (first != null && first.getUrl() != null && !first.getUrl().isBlank()) { - return first; + ensureValidPrimary(); + if (repositories != null) { + for (MarketplaceRepository repo : repositories) { + if (repo != null + && repo.isPrimary() + && repo.isEnabled() + && StringUtils.isNotBlank(repo.getUrl())) { + return repo; + } + } + for (MarketplaceRepository repo : repositories) { + if (repo != null && repo.isEnabled() && StringUtils.isNotBlank(repo.getUrl())) { + return repo; + } + } + } + return new MarketplaceRepository(DEFAULT_ASF_ID, DEFAULT_ASF_NAME, DEFAULT_ASF_URL, true); + } + + /** + * Enabled repositories in install order: primary first, then remaining list order. Used as the + * fallback chain. + */ + public List orderedRepositories() { + ensureValidPrimary(); + List ordered = new ArrayList<>(); + MarketplaceRepository primary = null; + if (repositories != null) { + for (MarketplaceRepository repo : repositories) { + if (repo != null + && repo.isPrimary() + && repo.isEnabled() + && StringUtils.isNotBlank(repo.getUrl())) { + primary = repo; + break; + } + } + } + if (primary != null) { + ordered.add(primary); + } + if (repositories != null) { + for (MarketplaceRepository repo : repositories) { + if (repo == null || !repo.isEnabled() || StringUtils.isBlank(repo.getUrl())) { + continue; + } + if (primary != null && Objects.equals(primary.getId(), repo.getId()) && primary == repo) { + continue; + } + if (primary != null && primary == repo) { + continue; + } + // skip duplicate of primary by id + if (primary != null + && StringUtils.isNotBlank(primary.getId()) + && primary.getId().equals(repo.getId())) { + continue; + } + ordered.add(repo); + } + } + if (ordered.isEmpty()) { + ordered.add( + new MarketplaceRepository(DEFAULT_ASF_ID, DEFAULT_ASF_NAME, DEFAULT_ASF_URL, true)); + } + return ordered; + } + + public MarketplaceRepository findRepository(String id) { + if (StringUtils.isBlank(id) || repositories == null) { + return null; + } + for (MarketplaceRepository repo : repositories) { + if (repo != null && id.equals(repo.getId())) { + return repo; + } + } + return null; + } + + public void addRepository(MarketplaceRepository repo) throws HopException { + if (repo == null || StringUtils.isBlank(repo.getId()) || StringUtils.isBlank(repo.getUrl())) { + throw new HopException("Repository requires id and url"); + } + if (findRepository(repo.getId()) != null) { + throw new HopException("Repository id already exists: " + repo.getId()); + } + if (repositories == null) { + repositories = new ArrayList<>(); + } + if (repo.isPrimary()) { + clearPrimaryFlags(); + } + repositories.add(repo); + ensureValidPrimary(); + } + + public void removeRepository(String id) throws HopException { + MarketplaceRepository existing = findRepository(id); + if (existing == null) { + throw new HopException("Unknown repository id: " + id); + } + repositories.remove(existing); + ensureValidPrimary(); + } + + public void setPrimary(String id) throws HopException { + MarketplaceRepository repo = findRepository(id); + if (repo == null) { + throw new HopException("Unknown repository id: " + id); + } + if (!repo.isEnabled()) { + throw new HopException("Cannot set disabled repository as primary: " + id); + } + clearPrimaryFlags(); + repo.setPrimary(true); + } + + public void setEnabled(String id, boolean enabled) throws HopException { + MarketplaceRepository repo = findRepository(id); + if (repo == null) { + throw new HopException("Unknown repository id: " + id); + } + repo.setEnabled(enabled); + if (!enabled && repo.isPrimary()) { + repo.setPrimary(false); + } + ensureValidPrimary(); + } + + private void clearPrimaryFlags() { + if (repositories == null) { + return; + } + for (MarketplaceRepository repo : repositories) { + if (repo != null) { + repo.setPrimary(false); } } - return new MarketplaceRepository("central", DEFAULT_REPO_URL); } } diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java index 68beb29e55a..fcd8bb8e791 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java @@ -24,15 +24,23 @@ @Getter @Setter public class MarketplaceRepository { - private String id = "central"; - private String url = "https://repo1.maven.org/maven2/"; + private String id = MarketplaceConfig.DEFAULT_ASF_ID; + private String name; + private String url = MarketplaceConfig.DEFAULT_ASF_URL; - /** Optional HTTP Basic auth username (e.g. Artifactory admin). */ + /** When true, this repository is tried first for installs. */ + private boolean primary; + + /** When false, skipped in the install fallback chain. */ + private boolean enabled = true; + + /** Optional HTTP Basic auth username. */ private String username; /** * Optional HTTP Basic auth password. Prefer leaving this empty in hop-config.json and setting - * {@code HOP_MARKETPLACE_PASSWORD} instead. Do not send credentials for anonymous local Nexus. + * {@code HOP_MARKETPLACE_PASSWORD} instead for private repos. Do not set for anonymous ASF / + * Central / local Nexus. */ private String password; @@ -43,27 +51,45 @@ public MarketplaceRepository() { public MarketplaceRepository(String id, String url) { this.id = id; this.url = url; + this.name = id; } - public MarketplaceRepository(String id, String url, String username, String password) { + public MarketplaceRepository(String id, String url, boolean primary) { + this(id, url); + this.primary = primary; + } + + public MarketplaceRepository(String id, String name, String url, boolean primary) { this.id = id; + this.name = name; this.url = url; + this.primary = primary; + } + + public MarketplaceRepository(String id, String url, String username, String password) { + this(id, url); this.username = username; this.password = password; } + public String displayName() { + if (StringUtils.isNotBlank(name)) { + return name; + } + return StringUtils.isNotBlank(id) ? id : normalizedUrl(); + } + /** Base URL always ending with {@code /}. */ public String normalizedUrl() { if (StringUtils.isBlank(url)) { - return MarketplaceConfig.DEFAULT_REPO_URL; + return MarketplaceConfig.DEFAULT_ASF_URL; } return url.endsWith("/") ? url : url + "/"; } /** * Effective credentials: repository config fields, then {@code HOP_MARKETPLACE_USERNAME} / {@code - * HOP_MARKETPLACE_PASSWORD}. No credentials means anonymous HTTP (correct for local Nexus after - * {@code docker/marketplace-nexus/start.sh}). + * HOP_MARKETPLACE_PASSWORD}. No credentials means anonymous HTTP. */ public String effectiveUsername() { if (StringUtils.isNotBlank(username)) { diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/EnvironmentApplier.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/EnvironmentApplier.java index b9c11e3032a..c48640e37a9 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/EnvironmentApplier.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/EnvironmentApplier.java @@ -202,6 +202,7 @@ private MarketplaceConfig configFromEnv(HopEnvironmentSpec env) { config.getRepositories().clear(); MarketplaceRepository baseRepo = baseConfig.primaryRepository(); if (env.getRepositories() != null && !env.getRepositories().isEmpty()) { + boolean first = true; for (HopEnvironmentSpec.RepositoryRef ref : env.getRepositories()) { if (StringUtils.isNotBlank(ref.getUrl())) { MarketplaceRepository repo = @@ -214,7 +215,10 @@ private MarketplaceConfig configFromEnv(HopEnvironmentSpec env) { StringUtils.isNotBlank(ref.getPassword()) ? ref.getPassword() : baseRepo.getPassword()); + repo.setPrimary(first); + repo.setEnabled(true); config.getRepositories().add(repo); + first = false; } } } @@ -222,10 +226,9 @@ private MarketplaceConfig configFromEnv(HopEnvironmentSpec env) { config.getRepositories().addAll(baseConfig.getRepositories()); } if (config.getRepositories().isEmpty()) { - config - .getRepositories() - .add(new MarketplaceRepository("central", MarketplaceConfig.DEFAULT_REPO_URL)); + config.getRepositories().addAll(MarketplaceConfig.defaultRepositories()); } + config.ensureValidPrimary(); return config; } diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/ManageRepositoriesDialog.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/ManageRepositoriesDialog.java new file mode 100644 index 00000000000..2dd7c330a67 --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/ManageRepositoriesDialog.java @@ -0,0 +1,472 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.gui; + +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.lang3.StringUtils; +import org.apache.hop.core.Const; +import org.apache.hop.i18n.BaseMessages; +import org.apache.hop.marketplace.config.MarketplaceConfig; +import org.apache.hop.marketplace.config.MarketplaceRepository; +import org.apache.hop.ui.core.PropsUi; +import org.apache.hop.ui.core.dialog.ErrorDialog; +import org.apache.hop.ui.core.dialog.MessageBox; +import org.apache.hop.ui.core.gui.GuiResource; +import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Dialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; + +/** Edit marketplace repository list (saved to hop-config.json). */ +public class ManageRepositoriesDialog extends Dialog { + + private static final Class PKG = MarketplaceGuiPlugin.class; + + private final PropsUi props; + private final MarketplaceConfig config; + private boolean saved; + + private Shell shell; + private Table wTable; + + public ManageRepositoriesDialog(Shell parent, MarketplaceConfig config) { + super(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX); + this.props = PropsUi.getInstance(); + this.config = config; + } + + /** + * @return true if the user saved changes + */ + public boolean open() { + Shell parent = getParent(); + shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX); + props.setLook(shell); + shell.setImage(GuiResource.getInstance().getImageHopUi()); + shell.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Shell.Title")); + + FormLayout formLayout = new FormLayout(); + formLayout.marginWidth = Const.FORM_MARGIN; + formLayout.marginHeight = Const.FORM_MARGIN; + shell.setLayout(formLayout); + + Label wlHelp = new Label(shell, SWT.LEFT | SWT.WRAP); + props.setLook(wlHelp); + wlHelp.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Help")); + FormData fdlHelp = new FormData(); + fdlHelp.left = new FormAttachment(0, 0); + fdlHelp.top = new FormAttachment(0, 0); + fdlHelp.right = new FormAttachment(100, 0); + wlHelp.setLayoutData(fdlHelp); + + Button wCancel = new Button(shell, SWT.PUSH); + wCancel.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Cancel")); + wCancel.addListener(SWT.Selection, e -> shell.dispose()); + + Button wSave = new Button(shell, SWT.PUSH); + wSave.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Save")); + wSave.addListener(SWT.Selection, e -> save()); + + Button wReset = new Button(shell, SWT.PUSH); + wReset.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.ResetDefaults")); + wReset.addListener(SWT.Selection, e -> resetDefaults()); + + Button wRemove = new Button(shell, SWT.PUSH); + wRemove.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Remove")); + wRemove.addListener(SWT.Selection, e -> removeSelected()); + + Button wEdit = new Button(shell, SWT.PUSH); + wEdit.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Edit")); + wEdit.addListener(SWT.Selection, e -> editSelected()); + + Button wAdd = new Button(shell, SWT.PUSH); + wAdd.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Add")); + wAdd.addListener(SWT.Selection, e -> addRepository()); + + Button wPrimary = new Button(shell, SWT.PUSH); + wPrimary.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.SetPrimary")); + wPrimary.addListener(SWT.Selection, e -> setPrimarySelected()); + + Button wUp = new Button(shell, SWT.PUSH); + wUp.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.MoveUp")); + wUp.addListener(SWT.Selection, e -> moveSelected(-1)); + + Button wDown = new Button(shell, SWT.PUSH); + wDown.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.MoveDown")); + wDown.addListener(SWT.Selection, e -> moveSelected(1)); + + BaseTransformDialog.positionBottomButtons( + shell, + new Button[] {wAdd, wEdit, wRemove, wPrimary, wUp, wDown, wReset, wSave, wCancel}, + Const.MARGIN, + null); + + wTable = new Table(shell, SWT.BORDER | SWT.FULL_SELECTION | SWT.SINGLE | SWT.V_SCROLL); + props.setLook(wTable); + wTable.setHeaderVisible(true); + wTable.setLinesVisible(true); + addColumn(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Primary"), 60); + addColumn(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Enabled"), 60); + addColumn(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Id"), 100); + addColumn(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Name"), 160); + addColumn(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Url"), 360); + addColumn(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Auth"), 50); + + FormData fdTable = new FormData(); + fdTable.left = new FormAttachment(0, 0); + fdTable.top = new FormAttachment(wlHelp, Const.MARGIN * 2); + fdTable.right = new FormAttachment(100, 0); + fdTable.bottom = new FormAttachment(wSave, -Const.MARGIN * 2); + wTable.setLayoutData(fdTable); + + refreshTable(); + + BaseTransformDialog.setSize(shell); + shell.open(); + Display display = parent.getDisplay(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + return saved; + } + + private void addColumn(String title, int width) { + TableColumn col = new TableColumn(wTable, SWT.LEFT); + col.setText(title); + col.setWidth(width); + } + + private void refreshTable() { + wTable.removeAll(); + if (config.getRepositories() == null) { + return; + } + for (MarketplaceRepository repo : config.getRepositories()) { + if (repo == null) { + continue; + } + TableItem item = new TableItem(wTable, SWT.NONE); + item.setText(0, repo.isPrimary() ? "*" : ""); + item.setText(1, repo.isEnabled() ? "Y" : "N"); + item.setText(2, Const.NVL(repo.getId(), "")); + item.setText(3, Const.NVL(repo.displayName(), "")); + item.setText(4, Const.NVL(repo.getUrl(), "")); + item.setText( + 5, repo.hasCredentials() || StringUtils.isNotBlank(repo.getUsername()) ? "Y" : ""); + item.setData(repo); + } + } + + private MarketplaceRepository selected() { + TableItem[] items = wTable.getSelection(); + if (items == null || items.length == 0) { + return null; + } + return (MarketplaceRepository) items[0].getData(); + } + + private void addRepository() { + MarketplaceRepository repo = new MarketplaceRepository(); + repo.setId(""); + repo.setName(""); + repo.setUrl(""); + repo.setEnabled(true); + if (editRepository(repo, true)) { + try { + config.addRepository(repo); + refreshTable(); + } catch (Exception e) { + new ErrorDialog( + shell, + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Error.Header"), + e.getMessage(), + e); + } + } + } + + private void editSelected() { + MarketplaceRepository repo = selected(); + if (repo == null) { + return; + } + if (editRepository(repo, false)) { + config.ensureValidPrimary(); + refreshTable(); + } + } + + private boolean editRepository(MarketplaceRepository repo, boolean isNew) { + Shell dialog = new Shell(shell, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE); + props.setLook(dialog); + dialog.setText( + BaseMessages.getString( + PKG, + isNew + ? "ManageRepositoriesDialog.Edit.Title.Add" + : "ManageRepositoriesDialog.Edit.Title.Edit")); + FormLayout layout = new FormLayout(); + layout.marginWidth = Const.FORM_MARGIN; + layout.marginHeight = Const.FORM_MARGIN; + dialog.setLayout(layout); + + int middle = 25; + int margin = Const.MARGIN; + + Label wlId = new Label(dialog, SWT.RIGHT); + props.setLook(wlId); + wlId.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Id")); + FormData fdlId = new FormData(); + fdlId.left = new FormAttachment(0, 0); + fdlId.top = new FormAttachment(0, margin); + fdlId.right = new FormAttachment(middle, -margin); + wlId.setLayoutData(fdlId); + Text wId = new Text(dialog, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + props.setLook(wId); + wId.setText(Const.NVL(repo.getId(), "")); + wId.setEditable(isNew); + FormData fdId = new FormData(); + fdId.left = new FormAttachment(middle, 0); + fdId.top = new FormAttachment(wlId, 0, SWT.CENTER); + fdId.right = new FormAttachment(100, 0); + wId.setLayoutData(fdId); + + Label wlName = new Label(dialog, SWT.RIGHT); + props.setLook(wlName); + wlName.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Name")); + FormData fdlName = new FormData(); + fdlName.left = new FormAttachment(0, 0); + fdlName.top = new FormAttachment(wId, margin); + fdlName.right = new FormAttachment(middle, -margin); + wlName.setLayoutData(fdlName); + Text wName = new Text(dialog, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + props.setLook(wName); + wName.setText(Const.NVL(repo.getName(), "")); + FormData fdName = new FormData(); + fdName.left = new FormAttachment(middle, 0); + fdName.top = new FormAttachment(wlName, 0, SWT.CENTER); + fdName.right = new FormAttachment(100, 0); + wName.setLayoutData(fdName); + + Label wlUrl = new Label(dialog, SWT.RIGHT); + props.setLook(wlUrl); + wlUrl.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Url")); + FormData fdlUrl = new FormData(); + fdlUrl.left = new FormAttachment(0, 0); + fdlUrl.top = new FormAttachment(wName, margin); + fdlUrl.right = new FormAttachment(middle, -margin); + wlUrl.setLayoutData(fdlUrl); + Text wUrl = new Text(dialog, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + props.setLook(wUrl); + wUrl.setText(Const.NVL(repo.getUrl(), "")); + FormData fdUrl = new FormData(); + fdUrl.left = new FormAttachment(middle, 0); + fdUrl.top = new FormAttachment(wlUrl, 0, SWT.CENTER); + fdUrl.right = new FormAttachment(100, 0); + wUrl.setLayoutData(fdUrl); + + Label wlUser = new Label(dialog, SWT.RIGHT); + props.setLook(wlUser); + wlUser.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Username")); + FormData fdlUser = new FormData(); + fdlUser.left = new FormAttachment(0, 0); + fdlUser.top = new FormAttachment(wUrl, margin); + fdlUser.right = new FormAttachment(middle, -margin); + wlUser.setLayoutData(fdlUser); + Text wUser = new Text(dialog, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + props.setLook(wUser); + wUser.setText(Const.NVL(repo.getUsername(), "")); + FormData fdUser = new FormData(); + fdUser.left = new FormAttachment(middle, 0); + fdUser.top = new FormAttachment(wlUser, 0, SWT.CENTER); + fdUser.right = new FormAttachment(100, 0); + wUser.setLayoutData(fdUser); + + Label wlPass = new Label(dialog, SWT.RIGHT); + props.setLook(wlPass); + wlPass.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Password")); + FormData fdlPass = new FormData(); + fdlPass.left = new FormAttachment(0, 0); + fdlPass.top = new FormAttachment(wUser, margin); + fdlPass.right = new FormAttachment(middle, -margin); + wlPass.setLayoutData(fdlPass); + Text wPass = new Text(dialog, SWT.SINGLE | SWT.LEFT | SWT.BORDER | SWT.PASSWORD); + props.setLook(wPass); + FormData fdPass = new FormData(); + fdPass.left = new FormAttachment(middle, 0); + fdPass.top = new FormAttachment(wlPass, 0, SWT.CENTER); + fdPass.right = new FormAttachment(100, 0); + wPass.setLayoutData(fdPass); + + Button wEnabled = new Button(dialog, SWT.CHECK); + props.setLook(wEnabled); + wEnabled.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Enabled")); + wEnabled.setSelection(repo.isEnabled()); + FormData fdEnabled = new FormData(); + fdEnabled.left = new FormAttachment(middle, 0); + fdEnabled.top = new FormAttachment(wPass, margin); + wEnabled.setLayoutData(fdEnabled); + + Button wPrimary = new Button(dialog, SWT.CHECK); + props.setLook(wPrimary); + wPrimary.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Primary")); + wPrimary.setSelection(repo.isPrimary()); + FormData fdPrimary = new FormData(); + fdPrimary.left = new FormAttachment(middle, 0); + fdPrimary.top = new FormAttachment(wEnabled, margin); + wPrimary.setLayoutData(fdPrimary); + + final boolean[] ok = {false}; + Button wOk = new Button(dialog, SWT.PUSH); + wOk.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Ok")); + wOk.addListener( + SWT.Selection, + e -> { + if (StringUtils.isBlank(wId.getText()) || StringUtils.isBlank(wUrl.getText())) { + MessageBox box = new MessageBox(dialog, SWT.OK | SWT.ICON_WARNING); + box.setMessage( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.IdUrlRequired")); + box.open(); + return; + } + repo.setId(wId.getText().trim()); + repo.setName(wName.getText().trim()); + repo.setUrl(wUrl.getText().trim()); + repo.setUsername(StringUtils.trimToNull(wUser.getText())); + if (StringUtils.isNotBlank(wPass.getText())) { + repo.setPassword(wPass.getText()); + } + repo.setEnabled(wEnabled.getSelection()); + repo.setPrimary(wPrimary.getSelection()); + ok[0] = true; + dialog.dispose(); + }); + Button wCancel = new Button(dialog, SWT.PUSH); + wCancel.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Cancel")); + wCancel.addListener(SWT.Selection, e -> dialog.dispose()); + BaseTransformDialog.positionBottomButtons( + dialog, new Button[] {wOk, wCancel}, margin, wPrimary); + + dialog.setSize(560, 360); + dialog.open(); + Display display = shell.getDisplay(); + while (!dialog.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + if (ok[0] && repo.isPrimary()) { + for (MarketplaceRepository other : config.getRepositories()) { + if (other != null && other != repo) { + other.setPrimary(false); + } + } + } + return ok[0]; + } + + private void removeSelected() { + MarketplaceRepository repo = selected(); + if (repo == null) { + return; + } + try { + config.removeRepository(repo.getId()); + refreshTable(); + } catch (Exception e) { + new ErrorDialog( + shell, + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Error.Header"), + e.getMessage(), + e); + } + } + + private void setPrimarySelected() { + MarketplaceRepository repo = selected(); + if (repo == null) { + return; + } + try { + config.setPrimary(repo.getId()); + refreshTable(); + } catch (Exception e) { + new ErrorDialog( + shell, + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Error.Header"), + e.getMessage(), + e); + } + } + + private void moveSelected(int delta) { + MarketplaceRepository repo = selected(); + if (repo == null || config.getRepositories() == null) { + return; + } + List list = config.getRepositories(); + int idx = list.indexOf(repo); + int target = idx + delta; + if (idx < 0 || target < 0 || target >= list.size()) { + return; + } + list.remove(idx); + list.add(target, repo); + refreshTable(); + wTable.setSelection(target); + } + + private void resetDefaults() { + MessageBox confirm = new MessageBox(shell, SWT.YES | SWT.NO | SWT.ICON_QUESTION); + confirm.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Reset.Header")); + confirm.setMessage(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Reset.Message")); + if (confirm.open() != SWT.YES) { + return; + } + config.setRepositories(new ArrayList<>(MarketplaceConfig.defaultRepositories())); + refreshTable(); + } + + private void save() { + try { + config.ensureValidPrimary(); + config.save(); + saved = true; + shell.dispose(); + } catch (Exception e) { + new ErrorDialog( + shell, + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Error.Header"), + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Error.Save"), + e); + } + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java index f832011976c..06b3b5ef7d0 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java @@ -27,6 +27,7 @@ import org.apache.hop.marketplace.catalog.OptionalPluginInfo; import org.apache.hop.marketplace.command.MarketplaceCommand; import org.apache.hop.marketplace.config.MarketplaceConfig; +import org.apache.hop.marketplace.config.MarketplaceRepository; import org.apache.hop.marketplace.install.HopHome; import org.apache.hop.marketplace.install.InstallReceipt; import org.apache.hop.marketplace.install.PluginInstaller; @@ -43,6 +44,7 @@ import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Dialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; @@ -50,7 +52,6 @@ import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; -import org.eclipse.swt.widgets.Text; /** Tools → Marketplace dialog: list optional plugins and install/uninstall from a Maven repo. */ public class MarketplaceDialog extends Dialog { @@ -62,7 +63,8 @@ public class MarketplaceDialog extends Dialog { private Shell shell; private Table wTable; - private Text wRepo; + private Combo wRepo; + private final java.util.List repoComboIds = new java.util.ArrayList<>(); private Label wStatus; private Path hopHome; private MarketplaceConfig config; @@ -96,7 +98,7 @@ public void open() { return; } - // Repository URL + // Primary repository (install still uses full fallback chain with this first) Label wlRepo = new Label(shell, SWT.RIGHT); props.setLook(wlRepo); wlRepo.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Repository.Label")); @@ -105,15 +107,23 @@ public void open() { fdlRepo.top = new FormAttachment(0, 0); wlRepo.setLayoutData(fdlRepo); - wRepo = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + Button wManageRepos = new Button(shell, SWT.PUSH); + wManageRepos.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.ManageRepos")); + wManageRepos.addListener(SWT.Selection, e -> manageRepositories()); + FormData fdManage = new FormData(); + fdManage.right = new FormAttachment(100, 0); + fdManage.top = new FormAttachment(0, 0); + wManageRepos.setLayoutData(fdManage); + + wRepo = new Combo(shell, SWT.READ_ONLY | SWT.BORDER); props.setLook(wRepo); - wRepo.setText(config.primaryRepositoryUrl()); - wRepo.setEditable(false); FormData fdRepo = new FormData(); fdRepo.left = new FormAttachment(wlRepo, Const.MARGIN); fdRepo.top = new FormAttachment(wlRepo, 0, SWT.CENTER); - fdRepo.right = new FormAttachment(100, 0); + fdRepo.right = new FormAttachment(wManageRepos, -Const.MARGIN); wRepo.setLayoutData(fdRepo); + wRepo.addListener(SWT.Selection, e -> onPrimaryRepoSelected()); + fillRepoCombo(); // Buttons (bottom) Button wClose = new Button(shell, SWT.PUSH); @@ -186,6 +196,53 @@ public void open() { } } + private void fillRepoCombo() { + wRepo.removeAll(); + repoComboIds.clear(); + MarketplaceRepository primary = config.primaryRepository(); + int select = 0; + int i = 0; + for (MarketplaceRepository repo : config.getRepositories()) { + if (repo == null || !repo.isEnabled()) { + continue; + } + wRepo.add(repo.displayName() + " — " + repo.normalizedUrl()); + repoComboIds.add(repo.getId()); + if (primary != null && primary.getId() != null && primary.getId().equals(repo.getId())) { + select = i; + } + i++; + } + if (i > 0) { + wRepo.select(select); + } + } + + private void onPrimaryRepoSelected() { + int idx = wRepo.getSelectionIndex(); + if (idx < 0 || idx >= repoComboIds.size()) { + return; + } + try { + config.setPrimary(repoComboIds.get(idx)); + config.save(); + } catch (Exception e) { + new ErrorDialog( + shell, + BaseMessages.getString(PKG, "MarketplaceDialog.Error.Header"), + BaseMessages.getString(PKG, "MarketplaceDialog.Repository.SetPrimary.Error"), + e); + } + } + + private void manageRepositories() { + ManageRepositoriesDialog dialog = new ManageRepositoriesDialog(shell, config); + if (dialog.open()) { + config = MarketplaceConfig.load(); + fillRepoCombo(); + } + } + private void refreshTable() { wTable.removeAll(); List plugins = OptionalPluginCatalog.listWave1(); diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/InstallReceipt.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/InstallReceipt.java index 84fe6d9adc0..12edeb60632 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/InstallReceipt.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/InstallReceipt.java @@ -29,6 +29,13 @@ public class InstallReceipt { private String artifactId; private String version; private String installedAt; + + /** Repository id that supplied the zip (if known). */ + private String repositoryId; + + /** Repository base URL used for the download. */ + private String repositoryUrl; + private List paths = new ArrayList<>(); private boolean pendingActivation; diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java index 30777b07182..432e4df5a6e 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java @@ -31,10 +31,12 @@ import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; +import org.apache.commons.lang3.StringUtils; import org.apache.hop.core.exception.HopException; import org.apache.hop.core.json.HopJson; import org.apache.hop.core.logging.ILogChannel; import org.apache.hop.marketplace.config.MarketplaceConfig; +import org.apache.hop.marketplace.config.MarketplaceRepository; import org.apache.hop.marketplace.resolve.MavenCoordinates; import org.apache.hop.marketplace.resolve.MavenRepositoryClient; @@ -77,11 +79,45 @@ public PluginInstaller(ILogChannel log, Path hopHome, MarketplaceConfig config) */ public InstallReceipt install(MavenCoordinates coordinates, boolean activateImmediately) throws HopException { + return install(coordinates, activateImmediately, null); + } + + /** + * @param forceRepoId when non-blank, only that repository is used (no fallback chain) + */ + public InstallReceipt install( + MavenCoordinates coordinates, boolean activateImmediately, String forceRepoId) + throws HopException { Path downloadDir = hopHome.resolve(STAGING_DIR).resolve(".download"); Path zipFile = downloadDir.resolve(coordinates.artifactId() + "-" + coordinates.version() + ".zip"); try { - client.downloadZip(config.primaryRepository(), coordinates, zipFile); + List repos = resolveRepositories(forceRepoId); + MarketplaceRepository used = null; + List errors = new ArrayList<>(); + for (MarketplaceRepository repo : repos) { + try { + client.downloadZip(repo, coordinates, zipFile); + used = repo; + break; + } catch (HopException e) { + errors.add( + repo.getId() + + " @ " + + repo.normalizedUrl() + + " → " + + (e.getMessage() == null ? e.getClass().getSimpleName() : e.getMessage())); + log.logBasic("Repository attempt failed: " + errors.get(errors.size() - 1)); + } + } + if (used == null) { + throw new HopException( + "Could not download " + + coordinates.gav() + + " from any configured repository:\n - " + + String.join("\n - ", errors)); + } + Path stageRoot = hopHome.resolve(STAGING_DIR).resolve(coordinates.artifactId()); deleteRecursive(stageRoot); Files.createDirectories(stageRoot); @@ -92,6 +128,8 @@ public InstallReceipt install(MavenCoordinates coordinates, boolean activateImme receipt.setArtifactId(coordinates.artifactId()); receipt.setVersion(coordinates.version()); receipt.setInstalledAt(Instant.now().toString()); + receipt.setRepositoryId(used.getId()); + receipt.setRepositoryUrl(used.normalizedUrl()); receipt.setPaths(relativePaths); receipt.setPendingActivation(!activateImmediately); writeReceipt(receipt); @@ -116,6 +154,20 @@ public InstallReceipt install(MavenCoordinates coordinates, boolean activateImme } } + private List resolveRepositories(String forceRepoId) throws HopException { + if (StringUtils.isNotBlank(forceRepoId)) { + MarketplaceRepository forced = config.findRepository(forceRepoId); + if (forced == null) { + throw new HopException("Unknown marketplace repository id: " + forceRepoId); + } + if (!forced.isEnabled()) { + throw new HopException("Marketplace repository is disabled: " + forceRepoId); + } + return List.of(forced); + } + return config.orderedRepositories(); + } + /** Activate all staged plugins (startup hook). */ public void activateAllPending() throws HopException { Path staging = hopHome.resolve(STAGING_DIR); diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java index b7a12c644b9..3b0ac2f4bac 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java @@ -28,7 +28,9 @@ import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.time.Duration; +import java.util.ArrayList; import java.util.Base64; +import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; @@ -74,6 +76,48 @@ public Path downloadZip( return download(url, repository, coordinates.gav(), targetFile); } + /** + * Try each repository in order until a zip is downloaded. Aggregates per-repo errors if all fail + * (fallback chain). + */ + public Path downloadZipWithFallback( + List repositories, MavenCoordinates coordinates, Path targetFile) + throws HopException { + if (repositories == null || repositories.isEmpty()) { + throw new HopException("No marketplace repositories configured"); + } + List errors = new ArrayList<>(); + for (MarketplaceRepository repository : repositories) { + if (repository == null || !repository.isEnabled()) { + continue; + } + try { + log.logBasic( + "Trying repository '" + + repository.displayName() + + "' (" + + repository.normalizedUrl() + + ") for " + + coordinates.gav()); + return downloadZip(repository, coordinates, targetFile); + } catch (HopException e) { + String msg = + repository.getId() + + " @ " + + repository.normalizedUrl() + + " → " + + (e.getMessage() == null ? e.getClass().getSimpleName() : e.getMessage()); + errors.add(msg); + log.logBasic("Repository attempt failed: " + msg); + } + } + throw new HopException( + "Could not download " + + coordinates.gav() + + " from any configured repository:\n - " + + String.join("\n - ", errors)); + } + /** * @deprecated use {@link #downloadZip(MarketplaceRepository, MavenCoordinates, Path)} */ diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties index 17a12af4816..d4161e31f20 100644 --- a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties @@ -18,7 +18,8 @@ MarketplaceGuiPlugin.Menu.Marketplace.Text=Marketplace... MarketplaceDialog.Shell.Title=Plugin Marketplace -MarketplaceDialog.Repository.Label=Repository +MarketplaceDialog.Repository.Label=Primary repository +MarketplaceDialog.Repository.SetPrimary.Error=Could not set primary repository MarketplaceDialog.Column.Name=Name MarketplaceDialog.Column.Artifact=Artifact MarketplaceDialog.Column.Category=Category @@ -28,10 +29,11 @@ MarketplaceDialog.Button.Install=Install MarketplaceDialog.Button.Uninstall=Uninstall MarketplaceDialog.Button.Refresh=Refresh MarketplaceDialog.Button.Close=Close +MarketplaceDialog.Button.ManageRepos=Manage… MarketplaceDialog.Status.Installed=Installed MarketplaceDialog.Status.Present=Present on disk MarketplaceDialog.Status.NotInstalled=Not installed -MarketplaceDialog.Status.RestartHint=Restart Hop after install or uninstall so plugins are reloaded. +MarketplaceDialog.Status.RestartHint=Restart Hop after install or uninstall so plugins are reloaded. Install tries the primary repository, then other enabled repositories. MarketplaceDialog.Status.Installing=Installing {0}... MarketplaceDialog.Error.Header=Marketplace error MarketplaceDialog.Error.ResolveHome=Could not determine the Hop installation directory. Start Hop from the install root using the hop launcher. @@ -43,3 +45,36 @@ MarketplaceDialog.Uninstall.Confirm.Message=Remove marketplace-installed plugin MarketplaceDialog.Uninstall.NoReceipt.Header=Cannot uninstall MarketplaceDialog.Uninstall.NoReceipt.Message=No marketplace install receipt for {0}. Only plugins installed via the marketplace can be uninstalled here. MarketplaceDialog.Uninstall.Error=Failed to uninstall {0} + +ManageRepositoriesDialog.Shell.Title=Marketplace repositories +ManageRepositoriesDialog.Help=Primary repository is tried first; other enabled repositories are fallbacks. Defaults: Apache Repository (repository.apache.org) then Maven Central. Settings are saved to hop-config.json under HOP_CONFIG_FOLDER. +ManageRepositoriesDialog.Column.Primary=Primary +ManageRepositoriesDialog.Column.Enabled=Enabled +ManageRepositoriesDialog.Column.Id=Id +ManageRepositoriesDialog.Column.Name=Name +ManageRepositoriesDialog.Column.Url=URL +ManageRepositoriesDialog.Column.Auth=Auth +ManageRepositoriesDialog.Button.Add=Add +ManageRepositoriesDialog.Button.Edit=Edit +ManageRepositoriesDialog.Button.Remove=Remove +ManageRepositoriesDialog.Button.SetPrimary=Set primary +ManageRepositoriesDialog.Button.MoveUp=Up +ManageRepositoriesDialog.Button.MoveDown=Down +ManageRepositoriesDialog.Button.ResetDefaults=Reset defaults +ManageRepositoriesDialog.Button.Save=Save +ManageRepositoriesDialog.Button.Cancel=Cancel +ManageRepositoriesDialog.Button.Ok=OK +ManageRepositoriesDialog.Error.Header=Repository error +ManageRepositoriesDialog.Error.Save=Could not save marketplace configuration +ManageRepositoriesDialog.Reset.Header=Reset repositories +ManageRepositoriesDialog.Reset.Message=Replace the repository list with Apache Repository (primary) and Maven Central? +ManageRepositoriesDialog.Edit.Title.Add=Add repository +ManageRepositoriesDialog.Edit.Title.Edit=Edit repository +ManageRepositoriesDialog.Edit.Id=Id +ManageRepositoriesDialog.Edit.Name=Name +ManageRepositoriesDialog.Edit.Url=URL +ManageRepositoriesDialog.Edit.Username=Username +ManageRepositoriesDialog.Edit.Password=Password +ManageRepositoriesDialog.Edit.Enabled=Enabled (use in fallback chain) +ManageRepositoriesDialog.Edit.Primary=Primary (tried first) +ManageRepositoriesDialog.Edit.IdUrlRequired=Id and URL are required. diff --git a/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml b/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml index a60950fe97e..1cd2558243b 100644 --- a/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml +++ b/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml @@ -10,14 +10,15 @@ version: "1.0" hopVersion: "2.19.0-SNAPSHOT" enforceOnRun: false -# Defaults to Maven Central when omitted. -# Local Sonatype Nexus (docker/marketplace-nexus/start.sh): +# First entry is primary; later entries are fallbacks. repositories: - - id: local-nexus - url: "http://127.0.0.1:8081/repository/hop-plugins/" - # Production / CI: - # - id: central - # url: "https://repo1.maven.org/maven2/" + - id: asf + url: "https://repository.apache.org/content/groups/public/" + - id: central + url: "https://repo1.maven.org/maven2/" + # Local Sonatype Nexus for development (docker/marketplace-nexus/start.sh): + # - id: local-nexus + # url: "http://127.0.0.1:8081/repository/hop-plugins/" plugins: - artifactId: hop-tech-parquet diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/config/MarketplaceConfigTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/config/MarketplaceConfigTest.java new file mode 100644 index 00000000000..045fe323c03 --- /dev/null +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/config/MarketplaceConfigTest.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.config; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import org.junit.jupiter.api.Test; + +class MarketplaceConfigTest { + + @Test + void defaultsAreAsfPrimaryThenCentral() { + MarketplaceConfig config = new MarketplaceConfig(); + assertEquals(2, config.getRepositories().size()); + MarketplaceRepository primary = config.primaryRepository(); + assertEquals(MarketplaceConfig.DEFAULT_ASF_ID, primary.getId()); + assertTrue(primary.isPrimary()); + assertTrue(primary.normalizedUrl().contains("repository.apache.org")); + + List ordered = config.orderedRepositories(); + assertEquals(2, ordered.size()); + assertEquals(MarketplaceConfig.DEFAULT_ASF_ID, ordered.get(0).getId()); + assertEquals(MarketplaceConfig.DEFAULT_CENTRAL_ID, ordered.get(1).getId()); + } + + @Test + void ensureValidPrimaryPicksFirstWhenNoneMarked() { + MarketplaceConfig config = new MarketplaceConfig(); + config.getRepositories().forEach(r -> r.setPrimary(false)); + config.ensureValidPrimary(); + assertTrue(config.getRepositories().get(0).isPrimary()); + assertFalse(config.getRepositories().get(1).isPrimary()); + } + + @Test + void setPrimaryClearsOthers() throws Exception { + MarketplaceConfig config = new MarketplaceConfig(); + config.setPrimary(MarketplaceConfig.DEFAULT_CENTRAL_ID); + assertTrue(config.findRepository(MarketplaceConfig.DEFAULT_CENTRAL_ID).isPrimary()); + assertFalse(config.findRepository(MarketplaceConfig.DEFAULT_ASF_ID).isPrimary()); + assertEquals(MarketplaceConfig.DEFAULT_CENTRAL_ID, config.orderedRepositories().get(0).getId()); + } + + @Test + void addAndRemoveRepository() throws Exception { + MarketplaceConfig config = new MarketplaceConfig(); + config.addRepository( + new MarketplaceRepository( + "local", "Local Nexus", "http://127.0.0.1:8081/repository/hop-plugins/", true)); + assertEquals(3, config.getRepositories().size()); + assertEquals("local", config.primaryRepository().getId()); + config.removeRepository("local"); + assertEquals(2, config.getRepositories().size()); + assertTrue(config.primaryRepository().isPrimary()); + } + + @Test + void duplicateIdRejected() { + MarketplaceConfig config = new MarketplaceConfig(); + assertThrows( + Exception.class, + () -> + config.addRepository( + new MarketplaceRepository(MarketplaceConfig.DEFAULT_ASF_ID, "https://example/"))); + } + + @Test + void resetToDefaults() throws Exception { + MarketplaceConfig config = new MarketplaceConfig(); + config.addRepository(new MarketplaceRepository("x", "http://example.com/repo/", false)); + config.resetToDefaults(); + assertEquals(2, config.getRepositories().size()); + assertEquals(MarketplaceConfig.DEFAULT_ASF_ID, config.primaryRepository().getId()); + } + + @Test + void disabledReposSkippedInOrder() throws Exception { + MarketplaceConfig config = new MarketplaceConfig(); + config.setEnabled(MarketplaceConfig.DEFAULT_CENTRAL_ID, false); + List ordered = config.orderedRepositories(); + assertEquals(1, ordered.size()); + assertEquals(MarketplaceConfig.DEFAULT_ASF_ID, ordered.get(0).getId()); + } +} diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/PluginInstallerTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/PluginInstallerTest.java index b7aa07f02f8..30cf2130767 100644 --- a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/PluginInstallerTest.java +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/PluginInstallerTest.java @@ -17,6 +17,7 @@ package org.apache.hop.marketplace.install; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -76,14 +77,15 @@ void installAndUninstallFromLocalHttpRepo() throws Exception { MarketplaceConfig config = new MarketplaceConfig(); config.getRepositories().clear(); - config - .getRepositories() - .add(new MarketplaceRepository("local", "http://127.0.0.1:" + port + "/")); + MarketplaceRepository local = + new MarketplaceRepository("local", "http://127.0.0.1:" + port + "/", true); + config.getRepositories().add(local); LogChannel log = new LogChannel("test"); PluginInstaller installer = new PluginInstaller(log, hopHome, config); MavenCoordinates coords = new MavenCoordinates("org.apache.hop", "hop-test-plugin", "1.0.0"); - installer.install(coords, true); + InstallReceipt receipt = installer.install(coords, true); + assertEquals("local", receipt.getRepositoryId()); Path pluginJar = hopHome.resolve("plugins/tech/test/plugin.jar"); assertTrue(Files.isRegularFile(pluginJar)); @@ -139,11 +141,10 @@ void installWithBasicAuth() throws Exception { MarketplaceConfig config = new MarketplaceConfig(); config.getRepositories().clear(); - config - .getRepositories() - .add( - new MarketplaceRepository( - "local", "http://127.0.0.1:" + port + "/", "admin", "s3cret")); + MarketplaceRepository local = + new MarketplaceRepository("local", "http://127.0.0.1:" + port + "/", "admin", "s3cret"); + local.setPrimary(true); + config.getRepositories().add(local); new PluginInstaller(new LogChannel("test"), hopHome, config) .install(new MavenCoordinates("org.apache.hop", "hop-test-plugin", "1.0.0"), true); @@ -153,6 +154,50 @@ void installWithBasicAuth() throws Exception { } } + @Test + void installFallsBackToSecondRepository() throws Exception { + byte[] zipBytes = buildPluginZip(); + HttpServer server = HttpServer.create(new InetSocketAddress(0), 0); + String path = "/org/apache/hop/hop-test-plugin/1.0.0/hop-test-plugin-1.0.0.zip"; + server.createContext( + "/missing/", + exchange -> { + exchange.sendResponseHeaders(404, -1); + exchange.close(); + }); + server.createContext( + path, + exchange -> { + exchange.getResponseHeaders().add("Content-Type", "application/zip"); + exchange.sendResponseHeaders(200, zipBytes.length); + exchange.getResponseBody().write(zipBytes); + exchange.close(); + }); + server.start(); + try { + int port = server.getAddress().getPort(); + Path hopHome = tempDir.resolve("hop-fallback"); + Files.createDirectories(hopHome.resolve("plugins")); + + MarketplaceConfig config = new MarketplaceConfig(); + config.getRepositories().clear(); + MarketplaceRepository missing = + new MarketplaceRepository("missing", "http://127.0.0.1:" + port + "/missing/", true); + MarketplaceRepository ok = + new MarketplaceRepository("ok", "http://127.0.0.1:" + port + "/", false); + config.getRepositories().add(missing); + config.getRepositories().add(ok); + + InstallReceipt receipt = + new PluginInstaller(new LogChannel("test"), hopHome, config) + .install(new MavenCoordinates("org.apache.hop", "hop-test-plugin", "1.0.0"), true); + assertEquals("ok", receipt.getRepositoryId()); + assertTrue(Files.isRegularFile(hopHome.resolve("plugins/tech/test/plugin.jar"))); + } finally { + server.stop(0); + } + } + private static byte[] buildPluginZip() throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try (ZipOutputStream zos = new ZipOutputStream(bos)) { From bef7c399ac1e7c5d212947ec29e504cfdc3acf89 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Mon, 20 Jul 2026 00:03:23 +0200 Subject: [PATCH 16/28] issue #7547: document marketplace, release plugin zips, and size gate Add user-manual marketplace page, release-manager notes for deploying optional plugin zips to ASF Nexus, and packaging/size guidance for the lean hop-client. --- .../apache-release/creating-a-release.adoc | 16 ++++ docs/hop-user-manual/modules/ROOT/nav.adoc | 1 + .../ROOT/pages/hop-tools/hop-marketplace.adoc | 84 +++++++++++++++++++ .../modules/ROOT/pages/hop-tools/index.adoc | 1 + plugins/misc/marketplace/README.md | 14 ++++ 5 files changed, 116 insertions(+) create mode 100644 docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc diff --git a/docs/hop-dev-manual/modules/ROOT/pages/apache-release/creating-a-release.adoc b/docs/hop-dev-manual/modules/ROOT/pages/apache-release/creating-a-release.adoc index df77bc52beb..0c1b350d492 100644 --- a/docs/hop-dev-manual/modules/ROOT/pages/apache-release/creating-a-release.adoc +++ b/docs/hop-dev-manual/modules/ROOT/pages/apache-release/creating-a-release.adoc @@ -55,6 +55,22 @@ Build the software using the apache release profile mvn clean install -Papache-release ---- +=== Optional marketplace plugins (Wave 1) + +Large plugins are *not* bundled in the hop-client zip. Each optional plugin module +still builds a standalone zip (Maven assembly with `appendAssemblyId=false`), so +`mvn deploy` / the apache-release process publishes both the jar and the zip under +the same GAV, for example: + +---- +https://repository.apache.org/content/groups/public/org/apache/hop/hop-tech-parquet//hop-tech-parquet-.zip +---- + +After staging a release, verify Wave 1 zips resolve from the ASF public group (and +later Maven Central). Local SNAPSHOT testing can use `docker/marketplace-nexus/` +instead. Keep the client under the ASF ~850 MB package limit by running +`tools/check-assembly-size.sh` before promoting artifacts. + we are going to use the `mvn release:prepare` command to prepare the release process full command: diff --git a/docs/hop-user-manual/modules/ROOT/nav.adoc b/docs/hop-user-manual/modules/ROOT/nav.adoc index 63fca1915d4..fd95217ce9e 100644 --- a/docs/hop-user-manual/modules/ROOT/nav.adoc +++ b/docs/hop-user-manual/modules/ROOT/nav.adoc @@ -508,6 +508,7 @@ under the License. ** xref:hop-server/async-web-service.adoc[Async Web Service] * xref:hop-rest/index.adoc[Hop REST Web Application] * xref:hop-tools/index.adoc[Hop Tools] +** xref:hop-tools/hop-marketplace.adoc[hop marketplace] ** xref:hop-tools/hop-conf/hop-conf.adoc[hop-conf] ** xref:hop-tools/hop-encrypt.adoc[hop-encrypt] ** xref:hop-tools/hop-gui.adoc[hop-gui] diff --git a/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc b/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc new file mode 100644 index 00000000000..30d470a349d --- /dev/null +++ b/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc @@ -0,0 +1,84 @@ +//// +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +//// +:description: Install optional Hop plugins from Apache Repository / Maven Central using the marketplace CLI or GUI. + += Hop Marketplace + +Some Hop plugins are optional: they are not bundled in the default client zip so the download stays under the ASF packaging size limit. The *marketplace* installs those plugins into the running Hop client’s `plugins/` tree from a Maven repository. + +== Defaults + +Without extra configuration, Hop uses: + +. *asf* (primary) — `https://repository.apache.org/content/groups/public/` +. *central* (fallback) — `https://repo1.maven.org/maven2/` + +Install tries the primary repository first, then other *enabled* repositories, until the plugin zip is found. + +Settings are stored under the `marketplace` key in `${HOP_CONFIG_FOLDER}/hop-config.json` (always that file). + +== CLI + +From the Hop install directory: + +[source,bash] +---- +./hop marketplace install hop-tech-parquet +./hop marketplace install hop-engines-spark:2.19.0 +./hop marketplace list +./hop marketplace uninstall hop-tech-parquet + +# Repositories +./hop marketplace repo list +./hop marketplace repo add --id corporate --url https://nexus.example.com/repository/hop/ --primary +./hop marketplace repo set-primary asf +./hop marketplace repo reset-defaults + +# Declarative environment (CI / Docker) +./hop marketplace apply -f hop-env.yaml +./hop marketplace validate -f hop-env.yaml +---- + +After install or uninstall, *restart Hop* so the plugin registry reloads. + +Coordinates: `artifactId`, `artifactId:version`, or `groupId:artifactId:version`. + +== GUI + +*Tools → Marketplace…* lists featured optional plugins, installs/uninstalls them, and opens *Manage…* to edit repositories (same config as the CLI). + +== hop-env.yaml + +For reproducible environments (Docker, CI): + +[source,yaml] +---- +version: "1.0" +hopVersion: "2.19.0" +repositories: + - id: asf + url: "https://repository.apache.org/content/groups/public/" +plugins: + - artifactId: hop-tech-parquet + version: "2.19.0" +---- + +See also the sample under `config/projects/samples` after the marketplace plugin is present, or the source sample in `plugins/misc/marketplace`. + +== Enterprise / air-gapped + +Point marketplace repositories at your internal Nexus or Artifactory mirror of `org.apache.hop` plugin zips. Prefer anonymous read where possible; for private repos set Basic auth on the repository entry or use `HOP_MARKETPLACE_USERNAME` / `HOP_MARKETPLACE_PASSWORD`. Wrong credentials can cause HTTP 401 even when anonymous access would work. diff --git a/docs/hop-user-manual/modules/ROOT/pages/hop-tools/index.adoc b/docs/hop-user-manual/modules/ROOT/pages/hop-tools/index.adoc index 58d917c38aa..8e49c6561d3 100644 --- a/docs/hop-user-manual/modules/ROOT/pages/hop-tools/index.adoc +++ b/docs/hop-user-manual/modules/ROOT/pages/hop-tools/index.adoc @@ -22,6 +22,7 @@ Even though Hop developers will spend the majority of their time in Hop Gui, Hop This page provides an overview of the tools that are available in the platform. * xref:hop-tools/hop.adoc[Hop] +* xref:hop-tools/hop-marketplace.adoc[Hop Marketplace] * xref:hop-tools/hop-conf/hop-conf.adoc[Hop Conf] * xref:hop-tools/hop-encrypt.adoc[Hop Encrypt] * xref:hop-tools/hop-gui.adoc[Hop Gui] diff --git a/plugins/misc/marketplace/README.md b/plugins/misc/marketplace/README.md index 32a970e4c54..eb41437cdaa 100644 --- a/plugins/misc/marketplace/README.md +++ b/plugins/misc/marketplace/README.md @@ -149,3 +149,17 @@ Hop GUI → **Tools → Marketplace…** lists Wave 1 optional plugins. Choose t **primary repository**, or **Manage…** to add/edit/remove/reorder repositories (same hop-config.json as the CLI). Install uses the primary first, then fallbacks. Restart after install or uninstall. + +## Packaging & size + +Optional plugin modules already produce installable zips via the reactor `assembly` +profile (`appendAssemblyId=false` → `artifactId-version.zip` next to the jar). A +normal Maven deploy publishes that zip so marketplace can download it from ASF / +Central. For local SNAPSHOTs use `docker/marketplace-nexus/publish-wave1-plugins.sh`. + +Lean client size (after Wave 1 optional split) is checked with: + +```bash +./tools/check-assembly-size.sh +# typically hop-client ~590 MB (limit 850 MB) +``` From 9f779b58e910c97cf28215cb0af0d23071e81812 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Mon, 20 Jul 2026 00:10:19 +0200 Subject: [PATCH 17/28] issue #7547: document hop marketplace apply/validate and hop-env.yaml Expand the user-manual marketplace page with apply and validate options, file discovery, hop-run enforcement, and a full hop-env.yaml field reference with examples. --- .../ROOT/pages/hop-tools/hop-marketplace.adoc | 214 +++++++++++++++++- 1 file changed, 206 insertions(+), 8 deletions(-) diff --git a/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc b/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc index 30d470a349d..eae93f07386 100644 --- a/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc +++ b/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc @@ -14,7 +14,7 @@ KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. //// -:description: Install optional Hop plugins from Apache Repository / Maven Central using the marketplace CLI or GUI. +:description: Install optional Hop plugins from Apache Repository / Maven Central using the marketplace CLI or GUI, and declare environments with hop-env.yaml. = Hop Marketplace @@ -31,7 +31,7 @@ Install tries the primary repository first, then other *enabled* repositories, u Settings are stored under the `marketplace` key in `${HOP_CONFIG_FOLDER}/hop-config.json` (always that file). -== CLI +== CLI overview From the Hop install directory: @@ -39,6 +39,7 @@ From the Hop install directory: ---- ./hop marketplace install hop-tech-parquet ./hop marketplace install hop-engines-spark:2.19.0 +./hop marketplace install hop-engines-spark:2.19.0 --repo asf ./hop marketplace list ./hop marketplace uninstall hop-tech-parquet @@ -50,35 +51,232 @@ From the Hop install directory: # Declarative environment (CI / Docker) ./hop marketplace apply -f hop-env.yaml +./hop marketplace apply -f hop-env.yaml --prune ./hop marketplace validate -f hop-env.yaml +./hop marketplace validate -f hop-env.yaml --strict ---- -After install or uninstall, *restart Hop* so the plugin registry reloads. +After install, apply, or uninstall, *restart Hop* so the plugin registry reloads. -Coordinates: `artifactId`, `artifactId:version`, or `groupId:artifactId:version`. +Coordinates for `install`: `artifactId`, `artifactId:version`, or `groupId:artifactId:version`. +Optional `--repo ` forces a single repository (skips the fallback chain). == GUI *Tools → Marketplace…* lists featured optional plugins, installs/uninstalls them, and opens *Manage…* to edit repositories (same config as the CLI). -== hop-env.yaml +== Declarative environments (`hop-env.yaml`) -For reproducible environments (Docker, CI): +For CI/CD, Docker, and reproducible servers you can declare the required plugins (and optional jars) in a file, commit it to Git, and apply it without using the GUI. + +Supported file names / formats: + +* `hop-env.yaml` / `hop-env.yml` (YAML) +* `hop-env.json` (JSON — same field names) + +=== `hop marketplace apply` + +Installs missing plugins and dependencies declared in the environment file. Already-satisfied plugins are skipped. + +[cols="1,3"] +|=== +| Option | Description + +| `-f`, `--file` *(required)* +| Path to `hop-env.yaml` or `hop-env.json`. + +| `--prune` +| After installing what the file requires, *uninstall* marketplace-managed plugins that have an install receipt but are *not* listed under `plugins`. Core/bundled plugins and plugins present on disk without a marketplace receipt are not removed by prune. +|=== + +Examples: + +[source,bash] +---- +# Install everything listed (idempotent) +./hop marketplace apply -f hop-env.yaml + +# Also remove marketplace plugins that are no longer in the file +./hop marketplace apply -f ./deploy/hop-env.yaml --prune +---- + +Behaviour notes: + +* Repositories listed in the file override hop-config for this apply (first entry is primary; later entries are fallbacks). If the file omits `repositories`, hop-config repositories are used. +* Plugin `version` defaults to `hopVersion` in the file, then the marketplace/hop version. +* Plugins already on disk without a marketplace receipt (for example installed offline with `tools/install-wave1-plugins.sh`) count as satisfied and are not re-downloaded. +* Dependencies are downloaded as jars into `target` (default `lib/jdbc`). + +Always restart Hop after a successful apply when new plugins were installed. + +=== `hop marketplace validate` + +Compares the local install to the environment file *without* downloading or installing anything. Useful in CI as a pre-flight check. + +[cols="1,3"] +|=== +| Option | Description + +| `-f`, `--file` +| Path to the environment file. If omitted, Hop discovers a file (see <>). + +| `--strict` +| Also fail when *extra* marketplace-installed plugins (receipts under `plugins/.marketplace/`) are present that are not listed in the file. Without `--strict`, extras are ignored. +|=== + +Exit codes: + +* *0* — environment matches (prints `OK: environment matches …`) +* *non-zero* — drift detected or error (prints a drift report and suggests `hop marketplace apply -f …`) + +What counts as drift (always hard-fail): + +* *Missing plugin* — not on disk and no install receipt +* *Version mismatch* — receipt version differs from the version required in the file +* *Missing dependency* — jar not found under the dependency `target` directory + +Examples: + +[source,bash] +---- +./hop marketplace validate -f hop-env.yaml +./hop marketplace validate -f hop-env.yaml --strict + +# Discover hop-env under PROJECT_HOME or the Hop install +export PROJECT_HOME=/path/to/my-project +./hop marketplace validate +---- + +=== hop-run enforcement + +When a hop-env file is found and enforcement is on, `hop-run` validates before execution and aborts on missing plugins/deps or version mismatches (same checks as validate without `--strict`). + +Enable enforcement either: + +* in the file: `enforceOnRun: true`, or +* with a system property: `-Dhop.env.enforce=true` (or `Y`) + +If a hop-env file is present but `enforceOnRun` is false and the property is unset, hop-run only logs that the file was found and skips the check. + +[[hop-env-discovery]] +=== How the environment file is discovered + +Used by `validate` (when `-f` is omitted) and by hop-run: + +. Explicit path: `-f` / `--file` (validate only), or variable / property `HOP_ENV_FILE` / `hop.env.file` +. Under `PROJECT_HOME` (system property or env): `hop-env.yaml`, then `.yml`, then `.json` +. Under the Hop install root: same file names + +=== `hop-env.yaml` format + +Full example: [source,yaml] ---- +# Schema version of this file format (optional; default "1.0") version: "1.0" + +# Default plugin version when a plugin entry omits "version" hopVersion: "2.19.0" + +# If true, hop-run fails when the install drifts from this file +enforceOnRun: false + +# Maven repositories for apply (optional). +# First entry is primary; later entries are fallbacks for that apply only. +# If omitted, hop-config marketplace.repositories are used. repositories: - id: asf url: "https://repository.apache.org/content/groups/public/" + - id: central + url: "https://repo1.maven.org/maven2/" + # Private mirror example: + # - id: corporate + # url: "https://nexus.example.com/repository/hop-plugins/" + # username: reader + # password: "…" # prefer env HOP_MARKETPLACE_PASSWORD for secrets + +# Required optional plugins (installed into plugins/) plugins: - artifactId: hop-tech-parquet + version: "2.19.0" # optional if hopVersion is set + - groupId: org.apache.hop # optional; default org.apache.hop + artifactId: hop-engines-spark version: "2.19.0" + # Beam engine plugin only (lib/beam stays in the core client): + # - artifactId: hop-engines-beam + # version: "2.19.0" + +# Optional non-plugin jars (e.g. JDBC drivers) +dependencies: + - groupId: org.postgresql + artifactId: postgresql + version: "42.7.3" + target: lib/jdbc # optional; default lib/jdbc +---- + +==== Top-level fields + +[cols="1,1,3"] +|=== +| Field | Required | Description + +| `version` +| No +| Format version of the hop-env file itself (default `1.0`). + +| `hopVersion` +| Recommended +| Default version for plugin entries that omit `version`. Also used when aligning plugins with a Hop release. + +| `enforceOnRun` +| No +| When `true`, hop-run validates this file before running and fails on missing plugins/deps or version mismatches. + +| `repositories` +| No +| List of Maven base URLs used when *applying* this file. Order: first = primary, rest = fallbacks. Each item: `id`, `url`, optional `username` / `password`. + +| `plugins` +| No +| List of optional Hop plugins to install. Each item: `artifactId` (required), optional `groupId` (default `org.apache.hop`), optional `version` (default `hopVersion` / Hop version). + +| `dependencies` +| No +| Extra jars (not Hop plugin zips). Each item: `groupId`, `artifactId`, `version` (all required), optional `target` directory under the Hop install (default `lib/jdbc`). Downloaded as `artifactId-version.jar`. +|=== + +==== Minimal examples + +*Only plugins, ASF defaults from hop-config:* + +[source,yaml] +---- +version: "1.0" +hopVersion: "2.19.0" +plugins: + - artifactId: hop-tech-parquet + - artifactId: hop-tech-cassandra +---- + +*CI gate (no install):* + +[source,bash] +---- +./hop marketplace validate -f hop-env.yaml --strict || exit 1 +---- + +*Docker / pipeline install then run:* + +[source,bash] +---- +./hop marketplace apply -f /files/hop-env.yaml +# restart container or new process so plugins load +./hop-run.sh -f /files/main.hwf ---- -See also the sample under `config/projects/samples` after the marketplace plugin is present, or the source sample in `plugins/misc/marketplace`. +A longer sample ships with the marketplace plugin sources (`plugins/misc/marketplace/src/main/samples/hop-env.example.yaml`) and may appear under samples after the plugin is installed. == Enterprise / air-gapped -Point marketplace repositories at your internal Nexus or Artifactory mirror of `org.apache.hop` plugin zips. Prefer anonymous read where possible; for private repos set Basic auth on the repository entry or use `HOP_MARKETPLACE_USERNAME` / `HOP_MARKETPLACE_PASSWORD`. Wrong credentials can cause HTTP 401 even when anonymous access would work. +Point marketplace repositories at your internal Nexus or Artifactory mirror of `org.apache.hop` plugin zips. Prefer anonymous read where possible; for private repos set Basic auth on the repository entry (in hop-config or in hop-env `repositories`) or use `HOP_MARKETPLACE_USERNAME` / `HOP_MARKETPLACE_PASSWORD`. Wrong credentials can cause HTTP 401 even when anonymous access would work. From 4b6fea266c58b513a3cf026cf53f4bfba6d161be Mon Sep 17 00:00:00 2001 From: mattcasters Date: Mon, 20 Jul 2026 00:20:40 +0200 Subject: [PATCH 18/28] issue #7547: ship full-client-env.yaml from optional-plugins registry Add optional-plugins.yaml as the source of truth for marketplace-optional plugins, generate full-client-env.yaml at build time, package it at the Hop install root (and samples), load the GUI catalog from the registry, and document one-command restore of the previous full plugin set. --- .../ROOT/pages/hop-tools/hop-marketplace.adoc | 23 ++++ plugins/misc/marketplace/README.md | 20 +++ plugins/misc/marketplace/pom.xml | 30 +++- .../marketplace/src/assembly/assembly.xml | 11 ++ .../catalog/OptionalPluginCatalog.java | 128 ++++++++++++++---- .../hop/marketplace/optional-plugins.yaml | 88 ++++++++++++ .../catalog/OptionalPluginCatalogTest.java | 47 +++++++ tools/generate-full-client-env.sh | 66 +++++++++ tools/install-wave1-plugins.sh | 3 + 9 files changed, 392 insertions(+), 24 deletions(-) create mode 100644 plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml create mode 100644 plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalogTest.java create mode 100755 tools/generate-full-client-env.sh diff --git a/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc b/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc index eae93f07386..36e16b6a405 100644 --- a/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc +++ b/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc @@ -20,6 +20,29 @@ under the License. Some Hop plugins are optional: they are not bundled in the default client zip so the download stays under the ASF packaging size limit. The *marketplace* installs those plugins into the running Hop client’s `plugins/` tree from a Maven repository. +== Restore the previous full plugin set + +The default hop-client zip is intentionally smaller: large plugins are optional. To install +*all* marketplace-optional plugins that used to ship in the fat client (for this Hop version), +use the generated environment file at the install root: + +[source,bash] +---- +cd /path/to/hop +./hop marketplace apply -f full-client-env.yaml +# then restart Hop +---- + +Notes: + +* Requires network access to Apache Repository / Maven Central (or a mirror configured in hop-config). +* For SNAPSHOT builds, point marketplace at a local Nexus that has the Wave 1 zips published. +* The download is large (hundreds of MB); that is expected. +* Do *not* pass `--prune` unless you also want other marketplace installs removed. +* `full-client-env.yaml` is generated at build time from `optional-plugins.yaml` (source of truth). When more plugins become optional, rebuild the client to refresh the file. + +A copy is also under `config/projects/samples/marketplace/full-client-env.yaml`. + == Defaults Without extra configuration, Hop uses: diff --git a/plugins/misc/marketplace/README.md b/plugins/misc/marketplace/README.md index eb41437cdaa..93e95ea19dc 100644 --- a/plugins/misc/marketplace/README.md +++ b/plugins/misc/marketplace/README.md @@ -48,6 +48,9 @@ From the Hop install directory (or invoke the `hop` script by path — it alread ./hop marketplace apply -f hop-env.yaml ./hop marketplace apply -f hop-env.yaml --prune ./hop marketplace validate -f hop-env.yaml + +# Restore all optional plugins that used to ship in the fat client +./hop marketplace apply -f full-client-env.yaml ``` Install tries the **primary** repository first, then other **enabled** repositories @@ -150,6 +153,23 @@ Hop GUI → **Tools → Marketplace…** lists Wave 1 optional plugins. Choose t (same hop-config.json as the CLI). Install uses the primary first, then fallbacks. Restart after install or uninstall. +## Optional plugin registry & full-client-env.yaml + +Source of truth for marketplace-optional plugins: + +`src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml` + +- GUI catalog loads this file at runtime. +- `tools/generate-full-client-env.sh` builds `full-client-env.yaml` (Maven `generate-resources`). +- The marketplace plugin zip places `full-client-env.yaml` at the **Hop install root** (and under samples). + +When moving another plugin out of the fat client: exclude it from assemblies, **add one entry** +to `optional-plugins.yaml`, rebuild. Then: + +```bash +./hop marketplace apply -f full-client-env.yaml +``` + ## Packaging & size Optional plugin modules already produce installable zips via the reactor `assembly` diff --git a/plugins/misc/marketplace/pom.xml b/plugins/misc/marketplace/pom.xml index ac66abb4cba..f9aaf689aab 100644 --- a/plugins/misc/marketplace/pom.xml +++ b/plugins/misc/marketplace/pom.xml @@ -42,10 +42,38 @@ - + org.yaml snakeyaml + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.5.0 + + + generate-full-client-env + + exec + + generate-resources + + bash + + ${maven.multiModuleProjectDirectory}/tools/generate-full-client-env.sh + ${project.version} + ${project.build.directory}/generated/full-client-env.yaml + + + + + + + diff --git a/plugins/misc/marketplace/src/assembly/assembly.xml b/plugins/misc/marketplace/src/assembly/assembly.xml index cc7f1ab7cc9..9937d0f2546 100644 --- a/plugins/misc/marketplace/src/assembly/assembly.xml +++ b/plugins/misc/marketplace/src/assembly/assembly.xml @@ -31,6 +31,17 @@ ${hop.plugin.libdir} true + + + ${project.build.directory}/generated/full-client-env.yaml + . + full-client-env.yaml + + + ${project.build.directory}/generated/full-client-env.yaml + config/projects/samples/marketplace/ + full-client-env.yaml + diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java index 18c18ab905b..d90a8a9b6d0 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java @@ -17,110 +17,192 @@ package org.apache.hop.marketplace.catalog; +import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import org.apache.commons.lang3.StringUtils; +import org.yaml.snakeyaml.Yaml; /** - * Built-in catalog of Wave 1 optional plugins until remote Maven search is available in the GUI. + * Catalog of marketplace-optional plugins loaded from {@code optional-plugins.yaml} on the + * classpath (source of truth for Wave 1+ optional plugins and full-client-env generation). */ public final class OptionalPluginCatalog { - private static final List WAVE1 = new ArrayList<>(); + public static final String REGISTRY_RESOURCE = + "/org/apache/hop/marketplace/optional-plugins.yaml"; - static { - WAVE1.add( + private static final List PLUGINS = loadRegistry(); + + private OptionalPluginCatalog() {} + + public static List listWave1() { + return listOptional(); + } + + /** All marketplace-optional plugins from the registry. */ + public static List listOptional() { + return PLUGINS; + } + + public static boolean isInstalledOnDisk(Path hopHome, OptionalPluginInfo info) { + if (info.getInstallPath() == null) { + return false; + } + Path path = hopHome.resolve(info.getInstallPath()); + return Files.isDirectory(path); + } + + @SuppressWarnings("unchecked") + private static List loadRegistry() { + try (InputStream in = OptionalPluginCatalog.class.getResourceAsStream(REGISTRY_RESOURCE)) { + if (in == null) { + return Collections.unmodifiableList(fallbackCatalog()); + } + Yaml yaml = new Yaml(); + Object loaded = yaml.load(in); + if (!(loaded instanceof Map)) { + return Collections.unmodifiableList(fallbackCatalog()); + } + Map root = (Map) loaded; + Object pluginsObj = root.get("plugins"); + if (!(pluginsObj instanceof List)) { + return Collections.unmodifiableList(fallbackCatalog()); + } + List result = new ArrayList<>(); + for (Object entry : (List) pluginsObj) { + if (!(entry instanceof Map)) { + continue; + } + Map m = (Map) entry; + String artifactId = stringVal(m.get("artifactId")); + if (StringUtils.isBlank(artifactId)) { + continue; + } + result.add( + new OptionalPluginInfo( + artifactId, + stringVal(m.get("name")), + stringVal(m.get("category")), + stringVal(m.get("description")), + stringVal(m.get("installPath")))); + } + if (result.isEmpty()) { + return Collections.unmodifiableList(fallbackCatalog()); + } + return Collections.unmodifiableList(result); + } catch (Exception e) { + return Collections.unmodifiableList(fallbackCatalog()); + } + } + + private static String stringVal(Object o) { + return o == null ? null : String.valueOf(o); + } + + /** Hard-coded fallback if the registry resource is missing (tests / broken packaging). */ + private static List fallbackCatalog() { + List wave1 = new ArrayList<>(); + wave1.add( new OptionalPluginInfo( "hop-engines-spark", "Native Spark engine", "Engines", "Run pipelines on Apache Spark (local or cluster).", "plugins/engines/spark")); - WAVE1.add( + wave1.add( new OptionalPluginInfo( "hop-engines-beam", "Apache Beam engine", "Engines", "Beam pipeline engine and transforms (plugin only; lib/beam stays in the core install).", "plugins/engines/beam")); - WAVE1.add( + wave1.add( new OptionalPluginInfo( "hop-transform-script", "Script transform", "Transforms", "Scripting transform with embedded language runtimes.", "plugins/transforms/script")); - WAVE1.add( + wave1.add( new OptionalPluginInfo( "hop-tech-cassandra", "Cassandra", "Technology", "Apache Cassandra input/output and related tech.", "plugins/tech/cassandra")); - WAVE1.add( + wave1.add( new OptionalPluginInfo( "hop-transform-tika", "Apache Tika", "Transforms", "Extract text and metadata from documents via Apache Tika.", "plugins/transforms/tika")); - WAVE1.add( + wave1.add( new OptionalPluginInfo( "hop-transform-drools", "Drools", "Transforms", "Business rules with Drools.", "plugins/transforms/drools")); - WAVE1.add( + wave1.add( new OptionalPluginInfo( "hop-tech-parquet", "Parquet", "Technology", "Parquet file format support.", "plugins/tech/parquet")); - WAVE1.add( + wave1.add( new OptionalPluginInfo( "hop-transform-stanfordnlp", "Stanford NLP", "Transforms", "Natural language processing with Stanford NLP.", "plugins/transforms/stanfordnlp")); - WAVE1.add( + wave1.add( new OptionalPluginInfo( "hop-tech-arrow", "Apache Arrow", "Technology", "Apache Arrow integration.", "plugins/tech/arrow")); - WAVE1.add( + wave1.add( new OptionalPluginInfo( "hop-tech-dropbox", "Dropbox", "Technology", "Dropbox VFS and related support.", "plugins/tech/dropbox")); - WAVE1.add( + wave1.add( new OptionalPluginInfo( "hop-transform-edi2xml", "EDI to XML", "Transforms", "Convert EDI messages to XML.", "plugins/transforms/edi2xml")); + return wave1; } - private OptionalPluginCatalog() {} - - public static List listWave1() { - return Collections.unmodifiableList(WAVE1); + /** Artifact ids only (for tests / tooling). */ + public static List artifactIds() { + List ids = new ArrayList<>(); + for (OptionalPluginInfo info : PLUGINS) { + ids.add(info.getArtifactId()); + } + return ids; } - public static boolean isInstalledOnDisk(Path hopHome, OptionalPluginInfo info) { - if (info.getInstallPath() == null) { - return false; + /** Expose registry as simple maps for tests. */ + public static Map installPathsByArtifactId() { + Map map = new LinkedHashMap<>(); + for (OptionalPluginInfo info : PLUGINS) { + map.put(info.getArtifactId(), info.getInstallPath()); } - Path path = hopHome.resolve(info.getInstallPath()); - return Files.isDirectory(path); + return map; } } diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml new file mode 100644 index 00000000000..fb53a97b91c --- /dev/null +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml @@ -0,0 +1,88 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Source of truth for marketplace-optional plugins (not bundled in hop-client). +# full-client-env.yaml is generated from this list; GUI catalog loads it at runtime. +# When moving a plugin out of the fat assembly, add an entry here only. + +schemaVersion: "1" +groupId: org.apache.hop +plugins: + - artifactId: hop-engines-spark + name: Native Spark engine + category: Engines + description: Run pipelines on Apache Spark (local or cluster). + installPath: plugins/engines/spark + modulePath: plugins/engines/spark + - artifactId: hop-engines-beam + name: Apache Beam engine + category: Engines + description: Beam pipeline engine and transforms (plugin only; lib/beam stays in the core install). + installPath: plugins/engines/beam + modulePath: plugins/engines/beam + - artifactId: hop-transform-script + name: Script transform + category: Transforms + description: Scripting transform with embedded language runtimes. + installPath: plugins/transforms/script + modulePath: plugins/transforms/script + - artifactId: hop-tech-cassandra + name: Cassandra + category: Technology + description: Apache Cassandra input/output and related tech. + installPath: plugins/tech/cassandra + modulePath: plugins/tech/cassandra + - artifactId: hop-transform-tika + name: Apache Tika + category: Transforms + description: Extract text and metadata from documents via Apache Tika. + installPath: plugins/transforms/tika + modulePath: plugins/transforms/tika + - artifactId: hop-transform-drools + name: Drools + category: Transforms + description: Business rules with Drools. + installPath: plugins/transforms/drools + modulePath: plugins/transforms/drools + - artifactId: hop-tech-parquet + name: Parquet + category: Technology + description: Parquet file format support. + installPath: plugins/tech/parquet + modulePath: plugins/tech/parquet + - artifactId: hop-transform-stanfordnlp + name: Stanford NLP + category: Transforms + description: Natural language processing with Stanford NLP. + installPath: plugins/transforms/stanfordnlp + modulePath: plugins/transforms/stanfordnlp + - artifactId: hop-tech-arrow + name: Apache Arrow + category: Technology + description: Apache Arrow integration. + installPath: plugins/tech/arrow + modulePath: plugins/tech/arrow + - artifactId: hop-tech-dropbox + name: Dropbox + category: Technology + description: Dropbox VFS and related support. + installPath: plugins/tech/dropbox + modulePath: plugins/tech/dropbox + - artifactId: hop-transform-edi2xml + name: EDI to XML + category: Transforms + description: Convert EDI messages to XML. + installPath: plugins/transforms/edi2xml + modulePath: plugins/transforms/edi2xml diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalogTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalogTest.java new file mode 100644 index 00000000000..f93f8c83af0 --- /dev/null +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalogTest.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.catalog; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import org.junit.jupiter.api.Test; + +class OptionalPluginCatalogTest { + + @Test + void registryLoadsWave1Plugins() { + List plugins = OptionalPluginCatalog.listOptional(); + assertFalse(plugins.isEmpty()); + List ids = OptionalPluginCatalog.artifactIds(); + assertTrue(ids.contains("hop-tech-parquet")); + assertTrue(ids.contains("hop-engines-spark")); + assertTrue(ids.contains("hop-engines-beam")); + assertTrue(ids.contains("hop-transform-edi2xml")); + } + + @Test + void eachPluginHasInstallPath() { + for (OptionalPluginInfo info : OptionalPluginCatalog.listOptional()) { + assertTrue( + info.getInstallPath() != null && info.getInstallPath().startsWith("plugins/"), + "installPath for " + info.getArtifactId()); + } + } +} diff --git a/tools/generate-full-client-env.sh b/tools/generate-full-client-env.sh new file mode 100755 index 00000000000..7190f3e73fa --- /dev/null +++ b/tools/generate-full-client-env.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Generate full-client-env.yaml from optional-plugins.yaml (marketplace registry). +# +# Usage: +# ./tools/generate-full-client-env.sh [HOP_VERSION] [OUTPUT_PATH] +# +# Defaults: +# HOP_VERSION from ${project.version} when set by Maven, else 2.19.0-SNAPSHOT +# OUTPUT_PATH plugins/misc/marketplace/target/generated/full-client-env.yaml +# +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +REGISTRY="${ROOT}/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml" +VERSION="${1:-${HOP_VERSION:-2.19.0-SNAPSHOT}}" +OUT="${2:-${ROOT}/plugins/misc/marketplace/target/generated/full-client-env.yaml}" + +if [[ ! -f "${REGISTRY}" ]]; then + echo "Registry not found: ${REGISTRY}" >&2 + exit 1 +fi + +mkdir -p "$(dirname "${OUT}")" + +# Extract artifactIds (lines like " - artifactId: hop-tech-parquet") +mapfile -t ARTIFACTS < <(sed -n 's/^[[:space:]]*- artifactId:[[:space:]]*\(.*\)$/\1/p' "${REGISTRY}") + +if [[ ${#ARTIFACTS[@]} -eq 0 ]]; then + echo "No plugins found in ${REGISTRY}" >&2 + exit 1 +fi + +{ + cat <"${OUT}" + +echo "Wrote ${OUT} (${#ARTIFACTS[@]} plugins, hopVersion=${VERSION})" diff --git a/tools/install-wave1-plugins.sh b/tools/install-wave1-plugins.sh index da48395e955..471230a2908 100755 --- a/tools/install-wave1-plugins.sh +++ b/tools/install-wave1-plugins.sh @@ -14,6 +14,9 @@ # Default install dir: assemblies/client/target/hop # # Requires plugin modules to have been packaged (*.zip under plugins/**/target/). +# Keep the plugin list in sync with: +# plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml +# (source of truth for full-client-env.yaml and the GUI catalog). set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" From 6faaa9da0fc53971b1bd4910d783683bee6fb386 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Mon, 20 Jul 2026 00:25:31 +0200 Subject: [PATCH 19/28] issue #7547: GUI Apply/Validate for hop-env environment files Add environment file path, Browse, Validate, and Apply to the Marketplace dialog (with Prune and Strict options matching the CLI), pre-fill full-client-env.yaml when present, and document the GUI flow. --- .../ROOT/pages/hop-tools/hop-marketplace.adoc | 11 + .../marketplace/gui/MarketplaceDialog.java | 247 +++++++++++++++++- .../gui/messages/messages_en_US.properties | 33 ++- 3 files changed, 289 insertions(+), 2 deletions(-) diff --git a/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc b/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc index 36e16b6a405..df4ca6870b0 100644 --- a/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc +++ b/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc @@ -88,6 +88,17 @@ Optional `--repo ` forces a single repository (skips the fallback chain). *Tools → Marketplace…* lists featured optional plugins, installs/uninstalls them, and opens *Manage…* to edit repositories (same config as the CLI). +=== Environment file (Apply / Validate) + +The dialog also exposes declarative environments (same as the CLI): + +* **Environment file** — path to `hop-env.yaml` / `.yml` / `.json`. If present, `full-client-env.yaml` at the install root is pre-filled. +* **Browse…** — choose a file. +* **Validate** — compare the local install to the file without downloading. Use **Strict validate** to also fail when extra marketplace plugins are installed. +* **Apply** — install missing plugins and dependencies. Optionally enable **Prune extras on apply** (same as `apply --prune`; confirm before running). + +After Apply, restart Hop so plugins load. + == Declarative environments (`hop-env.yaml`) For CI/CD, Docker, and reproducible servers you can declare the required plugins (and optional jars) in a file, commit it to Git, and apply it without using the GUI. diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java index 06b3b5ef7d0..a5e274f0d9d 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java @@ -17,8 +17,13 @@ package org.apache.hop.marketplace.gui; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; import java.nio.file.Path; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import org.apache.commons.lang3.StringUtils; import org.apache.hop.core.Const; import org.apache.hop.core.logging.ILogChannel; import org.apache.hop.core.logging.LogChannel; @@ -28,12 +33,17 @@ import org.apache.hop.marketplace.command.MarketplaceCommand; import org.apache.hop.marketplace.config.MarketplaceConfig; import org.apache.hop.marketplace.config.MarketplaceRepository; +import org.apache.hop.marketplace.env.EnvironmentApplier; +import org.apache.hop.marketplace.env.EnvironmentDrift; +import org.apache.hop.marketplace.env.HopEnvironmentLoader; +import org.apache.hop.marketplace.env.HopEnvironmentSpec; import org.apache.hop.marketplace.install.HopHome; import org.apache.hop.marketplace.install.InstallReceipt; import org.apache.hop.marketplace.install.PluginInstaller; import org.apache.hop.marketplace.install.PluginUninstaller; import org.apache.hop.marketplace.resolve.MavenCoordinates; import org.apache.hop.ui.core.PropsUi; +import org.apache.hop.ui.core.dialog.BaseDialog; import org.apache.hop.ui.core.dialog.ErrorDialog; import org.apache.hop.ui.core.dialog.MessageBox; import org.apache.hop.ui.core.gui.GuiResource; @@ -52,6 +62,7 @@ import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; /** Tools → Marketplace dialog: list optional plugins and install/uninstall from a Maven repo. */ public class MarketplaceDialog extends Dialog { @@ -65,6 +76,9 @@ public class MarketplaceDialog extends Dialog { private Table wTable; private Combo wRepo; private final java.util.List repoComboIds = new java.util.ArrayList<>(); + private Text wEnvFile; + private Button wPrune; + private Button wStrict; private Label wStatus; private Path hopHome; private MarketplaceConfig config; @@ -125,6 +139,70 @@ public void open() { wRepo.addListener(SWT.Selection, e -> onPrimaryRepoSelected()); fillRepoCombo(); + // Environment file (hop-env / full-client-env) — Validate / Apply + Label wlEnv = new Label(shell, SWT.RIGHT); + props.setLook(wlEnv); + wlEnv.setText(BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Label")); + FormData fdlEnv = new FormData(); + fdlEnv.left = new FormAttachment(0, 0); + fdlEnv.top = new FormAttachment(wRepo, Const.MARGIN * 2); + wlEnv.setLayoutData(fdlEnv); + + Button wApplyEnv = new Button(shell, SWT.PUSH); + wApplyEnv.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.ApplyEnv")); + wApplyEnv.setToolTipText( + BaseMessages.getString(PKG, "MarketplaceDialog.Button.ApplyEnv.Tooltip")); + wApplyEnv.addListener(SWT.Selection, e -> applyEnvironment()); + FormData fdApplyEnv = new FormData(); + fdApplyEnv.right = new FormAttachment(100, 0); + fdApplyEnv.top = new FormAttachment(wlEnv, 0, SWT.CENTER); + wApplyEnv.setLayoutData(fdApplyEnv); + + Button wValidateEnv = new Button(shell, SWT.PUSH); + wValidateEnv.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.ValidateEnv")); + wValidateEnv.setToolTipText( + BaseMessages.getString(PKG, "MarketplaceDialog.Button.ValidateEnv.Tooltip")); + wValidateEnv.addListener(SWT.Selection, e -> validateEnvironment()); + FormData fdValidateEnv = new FormData(); + fdValidateEnv.right = new FormAttachment(wApplyEnv, -Const.MARGIN); + fdValidateEnv.top = new FormAttachment(wlEnv, 0, SWT.CENTER); + wValidateEnv.setLayoutData(fdValidateEnv); + + Button wBrowseEnv = new Button(shell, SWT.PUSH); + wBrowseEnv.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.BrowseEnv")); + wBrowseEnv.addListener(SWT.Selection, e -> browseEnvironmentFile()); + FormData fdBrowseEnv = new FormData(); + fdBrowseEnv.right = new FormAttachment(wValidateEnv, -Const.MARGIN); + fdBrowseEnv.top = new FormAttachment(wlEnv, 0, SWT.CENTER); + wBrowseEnv.setLayoutData(fdBrowseEnv); + + wEnvFile = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + props.setLook(wEnvFile); + FormData fdEnvFile = new FormData(); + fdEnvFile.left = new FormAttachment(wlEnv, Const.MARGIN); + fdEnvFile.top = new FormAttachment(wlEnv, 0, SWT.CENTER); + fdEnvFile.right = new FormAttachment(wBrowseEnv, -Const.MARGIN); + wEnvFile.setLayoutData(fdEnvFile); + suggestDefaultEnvFile(); + + wPrune = new Button(shell, SWT.CHECK); + props.setLook(wPrune); + wPrune.setText(BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Prune")); + wPrune.setToolTipText(BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Prune.Tooltip")); + FormData fdPrune = new FormData(); + fdPrune.left = new FormAttachment(wlEnv, Const.MARGIN); + fdPrune.top = new FormAttachment(wEnvFile, Const.MARGIN); + wPrune.setLayoutData(fdPrune); + + wStrict = new Button(shell, SWT.CHECK); + props.setLook(wStrict); + wStrict.setText(BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Strict")); + wStrict.setToolTipText(BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Strict.Tooltip")); + FormData fdStrict = new FormData(); + fdStrict.left = new FormAttachment(wPrune, Const.MARGIN * 3); + fdStrict.top = new FormAttachment(wEnvFile, Const.MARGIN); + wStrict.setLayoutData(fdStrict); + // Buttons (bottom) Button wClose = new Button(shell, SWT.PUSH); wClose.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.Close")); @@ -179,7 +257,7 @@ public void open() { FormData fdTable = new FormData(); fdTable.left = new FormAttachment(0, 0); - fdTable.top = new FormAttachment(wRepo, Const.MARGIN * 2); + fdTable.top = new FormAttachment(wPrune, Const.MARGIN * 2); fdTable.right = new FormAttachment(100, 0); fdTable.bottom = new FormAttachment(wStatus, -Const.MARGIN); wTable.setLayoutData(fdTable); @@ -351,6 +429,173 @@ private void uninstallSelected() { } } + private void suggestDefaultEnvFile() { + Path fullClient = hopHome.resolve("full-client-env.yaml"); + if (Files.isRegularFile(fullClient)) { + wEnvFile.setText(fullClient.toString()); + return; + } + Path discovered = EnvironmentApplier.resolveEnvironmentFile(hopHome, null); + if (discovered != null) { + wEnvFile.setText(discovered.toString()); + } + } + + private void browseEnvironmentFile() { + String path = + BaseDialog.presentFileDialog( + false, + shell, + new String[] {"*.yaml;*.yml;*.json", "*.*"}, + new String[] { + BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Filter.Env"), + BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Filter.All") + }, + false); + if (StringUtils.isNotBlank(path)) { + wEnvFile.setText(path); + } + } + + private Path requireEnvFilePath() { + String text = wEnvFile.getText(); + if (StringUtils.isBlank(text)) { + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_WARNING); + box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Missing.Header")); + box.setMessage(BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Missing.Message")); + box.open(); + return null; + } + Path path = Path.of(text.trim()).toAbsolutePath().normalize(); + if (!Files.isRegularFile(path)) { + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_WARNING); + box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.NotFound.Header")); + box.setMessage( + BaseMessages.getString( + PKG, "MarketplaceDialog.EnvFile.NotFound.Message", path.toString())); + box.open(); + return null; + } + return path; + } + + private void validateEnvironment() { + Path envPath = requireEnvFilePath(); + if (envPath == null) { + return; + } + try { + wStatus.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Status.Validating")); + shell.update(); + HopEnvironmentSpec env = HopEnvironmentLoader.load(envPath); + EnvironmentApplier applier = new EnvironmentApplier(log, hopHome, MarketplaceConfig.load()); + EnvironmentDrift drift = applier.validate(env); + if (wStrict.getSelection()) { + populateExtraPlugins(env, drift); + } + boolean hard = + !drift.getMissingPlugins().isEmpty() + || !drift.getVersionMismatches().isEmpty() + || !drift.getMissingDependencies().isEmpty() + || (wStrict.getSelection() && !drift.getExtraMarketplacePlugins().isEmpty()); + if (!hard) { + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION); + box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Validate.Ok.Header")); + box.setMessage( + BaseMessages.getString( + PKG, "MarketplaceDialog.Validate.Ok.Message", envPath.toString())); + box.open(); + wStatus.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Status.RestartHint")); + return; + } + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_WARNING); + box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Validate.Drift.Header")); + box.setMessage( + BaseMessages.getString(PKG, "MarketplaceDialog.Validate.Drift.Message") + + "\n\n" + + drift.formatReport() + + "\n" + + BaseMessages.getString(PKG, "MarketplaceDialog.Validate.Drift.Hint")); + box.open(); + wStatus.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Status.Drift")); + } catch (Exception e) { + new ErrorDialog( + shell, + BaseMessages.getString(PKG, "MarketplaceDialog.Error.Header"), + BaseMessages.getString(PKG, "MarketplaceDialog.Validate.Error"), + e); + } + } + + private void applyEnvironment() { + Path envPath = requireEnvFilePath(); + if (envPath == null) { + return; + } + boolean prune = wPrune.getSelection(); + if (prune) { + MessageBox confirm = new MessageBox(shell, SWT.YES | SWT.NO | SWT.ICON_QUESTION); + confirm.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Apply.PruneConfirm.Header")); + confirm.setMessage( + BaseMessages.getString(PKG, "MarketplaceDialog.Apply.PruneConfirm.Message")); + if (confirm.open() != SWT.YES) { + return; + } + } + try { + config = MarketplaceConfig.load(); + if (!config.isEnabled()) { + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_WARNING); + box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Error.Header")); + box.setMessage(BaseMessages.getString(PKG, "MarketplaceDialog.Apply.Disabled")); + box.open(); + return; + } + wStatus.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Status.Applying")); + shell.update(); + HopEnvironmentSpec env = HopEnvironmentLoader.load(envPath); + new EnvironmentApplier(log, hopHome, config).apply(env, prune); + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION); + box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Apply.Done.Header")); + box.setMessage( + BaseMessages.getString(PKG, "MarketplaceDialog.Apply.Done.Message", envPath.toString())); + box.open(); + refreshTable(); + wStatus.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Status.RestartHint")); + } catch (Exception e) { + new ErrorDialog( + shell, + BaseMessages.getString(PKG, "MarketplaceDialog.Error.Header"), + BaseMessages.getString(PKG, "MarketplaceDialog.Apply.Error"), + e); + } + } + + private void populateExtraPlugins(HopEnvironmentSpec env, EnvironmentDrift drift) + throws Exception { + Set desired = new HashSet<>(); + if (env.getPlugins() != null) { + for (HopEnvironmentSpec.PluginRef ref : env.getPlugins()) { + if (ref.getArtifactId() != null) { + desired.add(ref.getArtifactId()); + } + } + } + Path receipts = hopHome.resolve(PluginInstaller.RECEIPTS_DIR); + if (!Files.isDirectory(receipts)) { + return; + } + try (DirectoryStream stream = Files.newDirectoryStream(receipts, "*.json")) { + for (Path f : stream) { + String name = f.getFileName().toString(); + String id = name.substring(0, name.length() - ".json".length()); + if (!desired.contains(id)) { + drift.getExtraMarketplacePlugins().add(id); + } + } + } + } + private void close() { props.setScreen(new WindowProperty(shell)); shell.dispose(); diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties index d4161e31f20..941edcb677d 100644 --- a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties @@ -30,11 +30,30 @@ MarketplaceDialog.Button.Uninstall=Uninstall MarketplaceDialog.Button.Refresh=Refresh MarketplaceDialog.Button.Close=Close MarketplaceDialog.Button.ManageRepos=Manage… +MarketplaceDialog.Button.BrowseEnv=Browse… +MarketplaceDialog.Button.ValidateEnv=Validate +MarketplaceDialog.Button.ValidateEnv.Tooltip=Check the local install against the environment file without installing +MarketplaceDialog.Button.ApplyEnv=Apply +MarketplaceDialog.Button.ApplyEnv.Tooltip=Install plugins and dependencies declared in the environment file +MarketplaceDialog.EnvFile.Label=Environment file +MarketplaceDialog.EnvFile.Prune=Prune extras on apply +MarketplaceDialog.EnvFile.Prune.Tooltip=When applying, uninstall marketplace plugins that have a receipt but are not listed in the file +MarketplaceDialog.EnvFile.Strict=Strict validate +MarketplaceDialog.EnvFile.Strict.Tooltip=When validating, also fail if extra marketplace plugins are installed beyond the file +MarketplaceDialog.EnvFile.Filter.Env=Hop environment files (*.yaml, *.yml, *.json) +MarketplaceDialog.EnvFile.Filter.All=All files +MarketplaceDialog.EnvFile.Missing.Header=Environment file required +MarketplaceDialog.EnvFile.Missing.Message=Select a hop-env.yaml (or full-client-env.yaml) with Browse…, or type the path. +MarketplaceDialog.EnvFile.NotFound.Header=File not found +MarketplaceDialog.EnvFile.NotFound.Message=Environment file does not exist:\n{0} MarketplaceDialog.Status.Installed=Installed MarketplaceDialog.Status.Present=Present on disk MarketplaceDialog.Status.NotInstalled=Not installed -MarketplaceDialog.Status.RestartHint=Restart Hop after install or uninstall so plugins are reloaded. Install tries the primary repository, then other enabled repositories. +MarketplaceDialog.Status.RestartHint=Restart Hop after install, apply, or uninstall so plugins are reloaded. Install tries the primary repository, then other enabled repositories. MarketplaceDialog.Status.Installing=Installing {0}... +MarketplaceDialog.Status.Validating=Validating environment file... +MarketplaceDialog.Status.Applying=Applying environment file... +MarketplaceDialog.Status.Drift=Environment drift detected — use Apply to fix MarketplaceDialog.Error.Header=Marketplace error MarketplaceDialog.Error.ResolveHome=Could not determine the Hop installation directory. Start Hop from the install root using the hop launcher. MarketplaceDialog.Install.Done.Header=Plugin installed @@ -45,6 +64,18 @@ MarketplaceDialog.Uninstall.Confirm.Message=Remove marketplace-installed plugin MarketplaceDialog.Uninstall.NoReceipt.Header=Cannot uninstall MarketplaceDialog.Uninstall.NoReceipt.Message=No marketplace install receipt for {0}. Only plugins installed via the marketplace can be uninstalled here. MarketplaceDialog.Uninstall.Error=Failed to uninstall {0} +MarketplaceDialog.Validate.Ok.Header=Environment OK +MarketplaceDialog.Validate.Ok.Message=Local install matches:\n{0} +MarketplaceDialog.Validate.Drift.Header=Environment drift +MarketplaceDialog.Validate.Drift.Message=The local install does not match the environment file: +MarketplaceDialog.Validate.Drift.Hint=Use Apply to install missing plugins (or fix versions), then restart Hop. +MarketplaceDialog.Validate.Error=Failed to validate the environment file +MarketplaceDialog.Apply.PruneConfirm.Header=Prune marketplace plugins? +MarketplaceDialog.Apply.PruneConfirm.Message=Apply with prune will uninstall marketplace plugins that are not listed in the environment file.\n\nContinue? +MarketplaceDialog.Apply.Disabled=Marketplace is disabled in hop-config.json. +MarketplaceDialog.Apply.Done.Header=Environment applied +MarketplaceDialog.Apply.Done.Message=Applied:\n{0}\n\nPlease restart Hop so new plugins are loaded. +MarketplaceDialog.Apply.Error=Failed to apply the environment file ManageRepositoriesDialog.Shell.Title=Marketplace repositories ManageRepositoriesDialog.Help=Primary repository is tried first; other enabled repositories are fallbacks. Defaults: Apache Repository (repository.apache.org) then Maven Central. Settings are saved to hop-config.json under HOP_CONFIG_FOLDER. From 9e96b96f798d7057c7ded442021dc97ce01d8750 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Mon, 20 Jul 2026 00:30:20 +0200 Subject: [PATCH 20/28] issue #7547 : RAT --- .../src/main/samples/hop-env.example.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml b/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml index 1cd2558243b..52c3452e5a3 100644 --- a/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml +++ b/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml @@ -1,3 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + # Example declarative Hop environment (copy to hop-env.yaml in your project or install). # Apply with: # hop marketplace apply -f hop-env.yaml From b3c781ef836e036c99f1b7414ffc1c6ee2c3d53e Mon Sep 17 00:00:00 2001 From: mattcasters Date: Mon, 20 Jul 2026 01:03:30 +0200 Subject: [PATCH 21/28] issue #7547: move Beam SDKs to plugins/engines/beam/lib-beam Package Beam runners/libraries with the standard Beam marketplace plugin under lib-beam instead of lib/beam. Slim client libs keep spark-client and shared lib/core extras. Launch scripts add lib-beam only when present. Maven profile -Pbeam bakes the full Beam plugin into hop-client for IT/dev. --- assemblies/client/pom.xml | 26 +- assemblies/client/src/assembly/assembly.xml | 3 + assemblies/static/src/main/resources/hop | 19 +- .../static/src/main/resources/hop-conf.bat | 218 ++++++++------- .../static/src/main/resources/hop-conf.sh | 19 +- .../static/src/main/resources/hop-encrypt.bat | 224 +++++++-------- .../static/src/main/resources/hop-encrypt.sh | 19 +- .../src/main/resources/hop-gui-nolog.bat | 12 +- .../static/src/main/resources/hop-gui.bat | 258 ++++++++--------- .../static/src/main/resources/hop-gui.sh | 13 +- .../static/src/main/resources/hop-import.bat | 224 +++++++-------- .../static/src/main/resources/hop-import.sh | 19 +- .../static/src/main/resources/hop-run.bat | 262 +++++++++--------- .../static/src/main/resources/hop-run.sh | 19 +- .../static/src/main/resources/hop-search.bat | 218 ++++++++------- .../static/src/main/resources/hop-search.sh | 19 +- .../static/src/main/resources/hop-server.bat | 224 +++++++-------- .../static/src/main/resources/hop-server.sh | 19 +- assemblies/static/src/main/resources/hop.bat | 216 ++++++++------- docker/unified.Dockerfile | 2 +- docker/web.Dockerfile | 2 +- .../modules/ROOT/pages/hopweb/index.adoc | 4 +- .../ROOT/pages/hop-tools/hop-marketplace.adoc | 4 +- plugins/engines/beam/pom.xml | 5 +- .../src/assembly/assembly-beam-runtime.xml | 154 ++++++++++ .../beam/src/assembly/assembly-libs.xml | 134 +-------- .../engines/beam/src/assembly/assembly.xml | 6 +- .../apache/hop/beam/gui/HopBeamGuiPlugin.java | 23 +- .../catalog/OptionalPluginCatalog.java | 2 +- .../marketplace/install/PluginInstaller.java | 9 +- .../install/PluginUninstaller.java | 2 +- .../hop/marketplace/optional-plugins.yaml | 2 +- .../src/main/samples/hop-env.example.yaml | 2 +- .../install/PluginInstallerTest.java | 7 +- tools/install-wave1-plugins.sh | 2 +- 35 files changed, 1312 insertions(+), 1079 deletions(-) create mode 100644 plugins/engines/beam/src/assembly/assembly-beam-runtime.xml diff --git a/assemblies/client/pom.xml b/assemblies/client/pom.xml index 11b808b5eaa..155ae1ef27d 100644 --- a/assemblies/client/pom.xml +++ b/assemblies/client/pom.xml @@ -61,8 +61,9 @@ ${project.version} zip - + org.apache.hop hop-engines-beam @@ -142,4 +143,25 @@ + + + + beam + + + org.apache.hop + hop-engines-beam + ${project.version} + zip + + + + + diff --git a/assemblies/client/src/assembly/assembly.xml b/assemblies/client/src/assembly/assembly.xml index 405a244f878..58b15cad028 100644 --- a/assemblies/client/src/assembly/assembly.xml +++ b/assemblies/client/src/assembly/assembly.xml @@ -40,7 +40,10 @@ org.apache.hop:hop-core:zip org.apache.hop:hop-engine:zip org.apache.hop:hop-ui:zip + org.apache.hop:hop-engines-beam:zip:libs + + org.apache.hop:hop-engines-beam:zip org.apache.hop:hop-ui-rcp:zip true diff --git a/assemblies/static/src/main/resources/hop b/assemblies/static/src/main/resources/hop index 567efb609fe..ed52c6936f3 100755 --- a/assemblies/static/src/main/resources/hop +++ b/assemblies/static/src/main/resources/hop @@ -86,16 +86,16 @@ Linux) export GDK_BACKEND=x11 fi if "${_HOP_JAVA}" -XshowSettings:properties -version 2>&1 | grep -q "os.arch = aarch64"; then - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/linux/arm64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/linux/arm64/*" else - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/linux/$(uname -m)/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/linux/$(uname -m)/*" fi ;; Darwin) if "${_HOP_JAVA}" -XshowSettings:properties -version 2>&1 | grep -q "os.arch = aarch64"; then - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/osx/arm64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/osx/arm64/*" else - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/osx/x86_64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/osx/x86_64/*" fi HOP_OPTIONS="${HOP_OPTIONS} -XstartOnFirstThread" ;; @@ -108,6 +108,17 @@ if [ -n "${HOP_SPARK_CLIENT_VERSION:-}" ] && [ -d "lib/spark-clients/${HOP_SPARK CLASSPATH="${CLASSPATH}:lib/spark-clients/${HOP_SPARK_CLIENT_VERSION}/*" fi +# Beam SDKs/runners live with the optional Beam plugin (not lib/beam). +# Only on the system classpath when marketplace (or -Pbeam) has installed them. +if [ -d "plugins/engines/beam/lib-beam" ]; then + CLASSPATH="${CLASSPATH}:plugins/engines/beam/lib-beam/*" +fi +if [ -d "plugins/engines/beam" ]; then + # Hop Beam plugin jars at the plugin root (exclude subdirs via non-recursive glob is fine for /*.jar intent; + # shell * includes jars and may pick non-jars; match historical lib/* style) + CLASSPATH="${CLASSPATH}:plugins/engines/beam/*" +fi + "${_HOP_JAVA}" ${HOP_OPTIONS} -Djava.library.path="${LIBPATH}" -classpath "${CLASSPATH}" org.apache.hop.hop.Hop "$@" EXITCODE=$? diff --git a/assemblies/static/src/main/resources/hop-conf.bat b/assemblies/static/src/main/resources/hop-conf.bat index e33f891e3ec..12726246c83 100644 --- a/assemblies/static/src/main/resources/hop-conf.bat +++ b/assemblies/static/src/main/resources/hop-conf.bat @@ -1,105 +1,113 @@ -@echo off -REM -REM Licensed to the Apache Software Foundation (ASF) under one or more -REM contributor license agreements. See the NOTICE file distributed with -REM this work for additional information regarding copyright ownership. -REM The ASF licenses this file to You under the Apache License, Version 2.0 -REM (the "License"); you may not use this file except in compliance with -REM the License. You may obtain a copy of the License at -REM -REM http://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 - -setlocal - -REM switch to script directory -cd /D %~dp0 - -set LIBSPATH=lib\core;lib\beam -set CLASSPATH=lib\core\*;lib\beam\*;lib\spark-client\*;lib\swt\win64\* - -REM Optional versioned Spark client pack -if defined HOP_SPARK_CLIENT_VERSION if exist "lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\" ( - set CLASSPATH=%CLASSPATH%;lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\* -) - - - - -:NormalStart -REM set java primary is HOP_JAVA_HOME fallback to JAVA_HOME or default java -if not "%HOP_JAVA_HOME%"=="" ( - set _HOP_JAVA="%HOP_JAVA_HOME%\bin\java" -) else if not "%JAVA_HOME%"=="" ( - set _HOP_JAVA="%JAVA_HOME%\bin\java" -) else ( - set _HOP_JAVA=java -) - -REM # Settings for all OSses - -if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx2048m - -REM -REM If the user passes in DEBUG as the first parameter, it starts Hop in debugger mode and opens port 5009 -REM to allow attaching a debugger to step code. -if [%1]==[DEBUG] ( -REM # optional line for attaching a debugger -set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009) - -REM Pass HOP variables if they're set. -if not "%HOP_AUDIT_FOLDER%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%" -) else ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit -) -if not "%HOP_CONFIG_FOLDER%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%" -) -if not "%HOP_SHARED_JDBC_FOLDERS%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%" -) -if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%" -) -if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN% -) -if not "%HOP_AES_ENCODER_KEY%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY% -) -if not "%HOP_AES_ENCODER_KEY_FILE%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE% -) - -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Conf -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y -set HOP_OPTIONS=%HOP_OPTIONS% --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.nio.cs=ALL-UNNAMED --add-opens java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED - -echo ===[Environment Settings - hop-conf.bat]=================================== -echo. -echo Java identified as %_HOP_JAVA% -echo. -echo HOP_OPTIONS=%HOP_OPTIONS% -echo. -rem ===[Collect command line arguments...]====================================== -if [%1]==[DEBUG] ( -FOR /f "tokens=1*" %%x IN ("%*") DO set _cmdline=%%y -GOTO Run -) -set _cmdline=%* - -:Run -echo Command to start Hop will be: -echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.config.HopConfig %_cmdline% -echo. -echo ===[Starting HopConfig]========================================================= - -%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.config.HopConfig %_cmdline% +@echo off +REM +REM Licensed to the Apache Software Foundation (ASF) under one or more +REM contributor license agreements. See the NOTICE file distributed with +REM this work for additional information regarding copyright ownership. +REM The ASF licenses this file to You under the Apache License, Version 2.0 +REM (the "License"); you may not use this file except in compliance with +REM the License. You may obtain a copy of the License at +REM +REM http://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 + +setlocal + +REM switch to script directory +cd /D %~dp0 + +set LIBSPATH=lib\core +set CLASSPATH=lib\core\*;lib\spark-client\*;lib\swt\win64\* + +REM Optional versioned Spark client pack +if defined HOP_SPARK_CLIENT_VERSION if exist "lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\" ( + set CLASSPATH=%CLASSPATH%;lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\* +) + +REM Beam SDKs under optional plugin (plugins\engines\beam\lib-beam) +if exist "plugins\engines\beam\lib-beam\" ( + set CLASSPATH=%CLASSPATH%;plugins\engines\beam\lib-beam\* +) +if exist "plugins\engines\beam\" ( + set CLASSPATH=%CLASSPATH%;plugins\engines\beam\* +) + + + + +:NormalStart +REM set java primary is HOP_JAVA_HOME fallback to JAVA_HOME or default java +if not "%HOP_JAVA_HOME%"=="" ( + set _HOP_JAVA="%HOP_JAVA_HOME%\bin\java" +) else if not "%JAVA_HOME%"=="" ( + set _HOP_JAVA="%JAVA_HOME%\bin\java" +) else ( + set _HOP_JAVA=java +) + +REM # Settings for all OSses + +if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx2048m + +REM +REM If the user passes in DEBUG as the first parameter, it starts Hop in debugger mode and opens port 5009 +REM to allow attaching a debugger to step code. +if [%1]==[DEBUG] ( +REM # optional line for attaching a debugger +set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009) + +REM Pass HOP variables if they're set. +if not "%HOP_AUDIT_FOLDER%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%" +) else ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit +) +if not "%HOP_CONFIG_FOLDER%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%" +) +if not "%HOP_SHARED_JDBC_FOLDERS%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%" +) +if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%" +) +if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN% +) +if not "%HOP_AES_ENCODER_KEY%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY% +) +if not "%HOP_AES_ENCODER_KEY_FILE%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE% +) + +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Conf +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y +set HOP_OPTIONS=%HOP_OPTIONS% --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.nio.cs=ALL-UNNAMED --add-opens java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED + +echo ===[Environment Settings - hop-conf.bat]=================================== +echo. +echo Java identified as %_HOP_JAVA% +echo. +echo HOP_OPTIONS=%HOP_OPTIONS% +echo. +rem ===[Collect command line arguments...]====================================== +if [%1]==[DEBUG] ( +FOR /f "tokens=1*" %%x IN ("%*") DO set _cmdline=%%y +GOTO Run +) +set _cmdline=%* + +:Run +echo Command to start Hop will be: +echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.config.HopConfig %_cmdline% +echo. +echo ===[Starting HopConfig]========================================================= + +%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.config.HopConfig %_cmdline% diff --git a/assemblies/static/src/main/resources/hop-conf.sh b/assemblies/static/src/main/resources/hop-conf.sh index b279b2ad933..67dd91794e5 100755 --- a/assemblies/static/src/main/resources/hop-conf.sh +++ b/assemblies/static/src/main/resources/hop-conf.sh @@ -81,16 +81,16 @@ Linux) if "${_HOP_JAVA}" -XshowSettings:properties -version 2>&1 | grep -q "os.arch = aarch64"; then - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/linux/arm64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/linux/arm64/*" else - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/linux/$(uname -m)/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/linux/$(uname -m)/*" fi ;; Darwin) if "${_HOP_JAVA}" -XshowSettings:properties -version 2>&1 | grep -q "os.arch = aarch64"; then - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/osx/arm64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/osx/arm64/*" else - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/osx/x86_64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/osx/x86_64/*" fi HOP_OPTIONS="${HOP_OPTIONS} -XstartOnFirstThread" ;; @@ -103,6 +103,17 @@ if [ -n "${HOP_SPARK_CLIENT_VERSION:-}" ] && [ -d "lib/spark-clients/${HOP_SPARK CLASSPATH=$(echo "${CLASSPATH}" | sed 's|lib/spark-client/\*||g') CLASSPATH="${CLASSPATH}:lib/spark-clients/${HOP_SPARK_CLIENT_VERSION}/*" fi + +# Beam SDKs/runners live with the optional Beam plugin (not lib/beam). +# Only on the system classpath when marketplace (or -Pbeam) has installed them. +if [ -d "plugins/engines/beam/lib-beam" ]; then + CLASSPATH="${CLASSPATH}:plugins/engines/beam/lib-beam/*" +fi +if [ -d "plugins/engines/beam" ]; then + # Hop Beam plugin jars at the plugin root (exclude subdirs via non-recursive glob is fine for /*.jar intent; + # shell * includes jars and may pick non-jars; match historical lib/* style) + CLASSPATH="${CLASSPATH}:plugins/engines/beam/*" +fi "${_HOP_JAVA}" ${HOP_OPTIONS} -Djava.library.path="${LIBPATH}" -classpath "${CLASSPATH}" org.apache.hop.config.HopConfig "$@" EXITCODE=$? diff --git a/assemblies/static/src/main/resources/hop-encrypt.bat b/assemblies/static/src/main/resources/hop-encrypt.bat index a5877064c0d..66b37dea1e4 100644 --- a/assemblies/static/src/main/resources/hop-encrypt.bat +++ b/assemblies/static/src/main/resources/hop-encrypt.bat @@ -1,109 +1,117 @@ -echo off -REM -REM Licensed to the Apache Software Foundation (ASF) under one or more -REM contributor license agreements. See the NOTICE file distributed with -REM this work for additional information regarding copyright ownership. -REM The ASF licenses this file to You under the Apache License, Version 2.0 -REM (the "License"); you may not use this file except in compliance with -REM the License. You may obtain a copy of the License at -REM -REM http://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 - -echo off -setlocal - -REM switch to script directory -cd /D %~dp0 - -set LIBSPATH=lib\core;lib\beam -set CLASSPATH=lib\core\*;lib\beam\*;lib\spark-client\*;lib\swt\win64\* - -REM Optional versioned Spark client pack -if defined HOP_SPARK_CLIENT_VERSION if exist "lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\" ( - set CLASSPATH=%CLASSPATH%;lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\* -) - - - - -:NormalStart -REM set java primary is HOP_JAVA_HOME fallback to JAVA_HOME or default java -if not "%HOP_JAVA_HOME%"=="" ( - set _HOP_JAVA="%HOP_JAVA_HOME%\bin\java" -) else if not "%JAVA_HOME%"=="" ( - set _HOP_JAVA="%JAVA_HOME%\bin\java" -) else ( - set _HOP_JAVA=java -) - -REM # Settings for all OSses - -if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx64m - -REM -REM If the user passes in DEBUG as the first parameter, it starts Hop in debugger mode and opens port 5009 -REM to allow attaching a debugger to step code. -if [%1]==[DEBUG] ( -REM # optional line for attaching a debugger -set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009) - -REM Pass HOP variables if they're set. -if not "%HOP_AUDIT_FOLDER%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%" -) else ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit -) -if not "%HOP_CONFIG_FOLDER%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%" -) -if not "%HOP_SHARED_JDBC_FOLDERS%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%" -) -if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%" -) -if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN% -) -if not "%HOP_AES_ENCODER_KEY%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY% -) -if not "%HOP_AES_ENCODER_KEY_FILE%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE% -) - -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=GUI -set HOP_OPTIONS=%HOP_OPTIONS% --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.nio.cs=ALL-UNNAMED --add-opens java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED - - -echo ===[Environment Settings - hop-encrypt.bat]==================================== -echo. -echo Java identified as %_HOP_JAVA% -echo. -echo HOP_OPTIONS=%HOP_OPTIONS% -echo. -echo. -rem ===[Collect command line arguments...]====================================== -if [%1]==[DEBUG] ( -FOR /f "tokens=1*" %%x IN ("%*") DO set _cmdline=%%y -GOTO Run -) -set _cmdline=%* - -:Run -echo Command to start Hop will be: -echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.core.encryption.Encr %_cmdline% -echo. -echo ===[Starting HopEncrypt]========================================================= - -%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.encryption.HopEncrypt %_cmdline% -@echo off +echo off +REM +REM Licensed to the Apache Software Foundation (ASF) under one or more +REM contributor license agreements. See the NOTICE file distributed with +REM this work for additional information regarding copyright ownership. +REM The ASF licenses this file to You under the Apache License, Version 2.0 +REM (the "License"); you may not use this file except in compliance with +REM the License. You may obtain a copy of the License at +REM +REM http://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 + +echo off +setlocal + +REM switch to script directory +cd /D %~dp0 + +set LIBSPATH=lib\core +set CLASSPATH=lib\core\*;lib\spark-client\*;lib\swt\win64\* + +REM Optional versioned Spark client pack +if defined HOP_SPARK_CLIENT_VERSION if exist "lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\" ( + set CLASSPATH=%CLASSPATH%;lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\* +) + +REM Beam SDKs under optional plugin (plugins\engines\beam\lib-beam) +if exist "plugins\engines\beam\lib-beam\" ( + set CLASSPATH=%CLASSPATH%;plugins\engines\beam\lib-beam\* +) +if exist "plugins\engines\beam\" ( + set CLASSPATH=%CLASSPATH%;plugins\engines\beam\* +) + + + + +:NormalStart +REM set java primary is HOP_JAVA_HOME fallback to JAVA_HOME or default java +if not "%HOP_JAVA_HOME%"=="" ( + set _HOP_JAVA="%HOP_JAVA_HOME%\bin\java" +) else if not "%JAVA_HOME%"=="" ( + set _HOP_JAVA="%JAVA_HOME%\bin\java" +) else ( + set _HOP_JAVA=java +) + +REM # Settings for all OSses + +if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx64m + +REM +REM If the user passes in DEBUG as the first parameter, it starts Hop in debugger mode and opens port 5009 +REM to allow attaching a debugger to step code. +if [%1]==[DEBUG] ( +REM # optional line for attaching a debugger +set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009) + +REM Pass HOP variables if they're set. +if not "%HOP_AUDIT_FOLDER%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%" +) else ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit +) +if not "%HOP_CONFIG_FOLDER%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%" +) +if not "%HOP_SHARED_JDBC_FOLDERS%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%" +) +if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%" +) +if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN% +) +if not "%HOP_AES_ENCODER_KEY%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY% +) +if not "%HOP_AES_ENCODER_KEY_FILE%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE% +) + +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=GUI +set HOP_OPTIONS=%HOP_OPTIONS% --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.nio.cs=ALL-UNNAMED --add-opens java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED + + +echo ===[Environment Settings - hop-encrypt.bat]==================================== +echo. +echo Java identified as %_HOP_JAVA% +echo. +echo HOP_OPTIONS=%HOP_OPTIONS% +echo. +echo. +rem ===[Collect command line arguments...]====================================== +if [%1]==[DEBUG] ( +FOR /f "tokens=1*" %%x IN ("%*") DO set _cmdline=%%y +GOTO Run +) +set _cmdline=%* + +:Run +echo Command to start Hop will be: +echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.core.encryption.Encr %_cmdline% +echo. +echo ===[Starting HopEncrypt]========================================================= + +%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.encryption.HopEncrypt %_cmdline% +@echo off :End \ No newline at end of file diff --git a/assemblies/static/src/main/resources/hop-encrypt.sh b/assemblies/static/src/main/resources/hop-encrypt.sh index b89a53adedf..365b2e72d65 100755 --- a/assemblies/static/src/main/resources/hop-encrypt.sh +++ b/assemblies/static/src/main/resources/hop-encrypt.sh @@ -81,16 +81,16 @@ Linux) if "${_HOP_JAVA}" -XshowSettings:properties -version 2>&1 | grep -q "os.arch = aarch64"; then - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/linux/arm64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/linux/arm64/*" else - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/linux/$(uname -m)/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/linux/$(uname -m)/*" fi ;; Darwin) if "${_HOP_JAVA}" -XshowSettings:properties -version 2>&1 | grep -q "os.arch = aarch64"; then - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/osx/arm64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/osx/arm64/*" else - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/osx/x86_64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/osx/x86_64/*" fi HOP_OPTIONS="${HOP_OPTIONS} -XstartOnFirstThread" ;; @@ -103,6 +103,17 @@ if [ -n "${HOP_SPARK_CLIENT_VERSION:-}" ] && [ -d "lib/spark-clients/${HOP_SPARK CLASSPATH=$(echo "${CLASSPATH}" | sed 's|lib/spark-client/\*||g') CLASSPATH="${CLASSPATH}:lib/spark-clients/${HOP_SPARK_CLIENT_VERSION}/*" fi + +# Beam SDKs/runners live with the optional Beam plugin (not lib/beam). +# Only on the system classpath when marketplace (or -Pbeam) has installed them. +if [ -d "plugins/engines/beam/lib-beam" ]; then + CLASSPATH="${CLASSPATH}:plugins/engines/beam/lib-beam/*" +fi +if [ -d "plugins/engines/beam" ]; then + # Hop Beam plugin jars at the plugin root (exclude subdirs via non-recursive glob is fine for /*.jar intent; + # shell * includes jars and may pick non-jars; match historical lib/* style) + CLASSPATH="${CLASSPATH}:plugins/engines/beam/*" +fi "${_HOP_JAVA}" ${HOP_OPTIONS} -classpath "${CLASSPATH}" org.apache.hop.encryption.HopEncrypt "$@" EXITCODE=$? diff --git a/assemblies/static/src/main/resources/hop-gui-nolog.bat b/assemblies/static/src/main/resources/hop-gui-nolog.bat index b830fecc0f5..042384cd8ef 100644 --- a/assemblies/static/src/main/resources/hop-gui-nolog.bat +++ b/assemblies/static/src/main/resources/hop-gui-nolog.bat @@ -24,8 +24,16 @@ cd /D %~dp0 REM Option to change the Characterset of the Windows Shell to show foreign caracters if not "%HOP_WINDOWS_SHELL_ENCODING%"=="" chcp %HOP_WINDOWS_SHELL_ENCODING% -set LIBSPATH=lib\core;lib\beam -set CLASSPATH=lib\core\*;lib\beam\*;lib\swt\win64\* +set LIBSPATH=lib\core +set CLASSPATH=lib\core\*;lib\swt\win64\* + +REM Beam SDKs under optional plugin (plugins\engines\beam\lib-beam) +if exist "plugins\engines\beam\lib-beam\" ( + set CLASSPATH=%CLASSPATH%;plugins\engines\beam\lib-beam\* +) +if exist "plugins\engines\beam\" ( + set CLASSPATH=%CLASSPATH%;plugins\engines\beam\* +) set _temphelp=0 if [%1]==[help] set _temphelp=1 diff --git a/assemblies/static/src/main/resources/hop-gui.bat b/assemblies/static/src/main/resources/hop-gui.bat index fa830f4630c..d19321fd9a7 100755 --- a/assemblies/static/src/main/resources/hop-gui.bat +++ b/assemblies/static/src/main/resources/hop-gui.bat @@ -1,125 +1,133 @@ -@echo off -REM -REM Licensed to the Apache Software Foundation (ASF) under one or more -REM contributor license agreements. See the NOTICE file distributed with -REM this work for additional information regarding copyright ownership. -REM The ASF licenses this file to You under the Apache License, Version 2.0 -REM (the "License"); you may not use this file except in compliance with -REM the License. You may obtain a copy of the License at -REM -REM http://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 - -setlocal - -REM switch to script directory -cd /D %~dp0 - -REM Option to change the Characterset of the Windows Shell to show foreign caracters -if not "%HOP_WINDOWS_SHELL_ENCODING%"=="" chcp %HOP_WINDOWS_SHELL_ENCODING% - -set LIBSPATH=lib\core;lib\beam -set CLASSPATH=lib\core\*;lib\beam\*;lib\spark-client\*;lib\swt\win64\* - -REM Optional versioned Spark client pack -if defined HOP_SPARK_CLIENT_VERSION if exist "lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\" ( - set CLASSPATH=%CLASSPATH%;lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\* -) - - - - -set _temphelp=0 -if [%1]==[help] set _temphelp=1 -if [%1]==[Help] set _temphelp=1 -if %_temphelp%==1 (GOTO Help) ELSE (GOTO NormalStart) - -:Help -echo ===[Hop Help - hop-gui.bat]=============================================== -echo Starts Hop GUI and keeps this console window open so you can see log output. -echo To start without a console window, use hop-gui-nolog.bat instead. -echo. -echo Normally, no parameters are required to start Hop. There is a debug mode -echo that you can start by passing in DEBUG as the first parameter after hop-gui.bat -echo. -echo Example: -echo hop-gui.bat DEBUG -echo -echo The debug mode opens port 5005 locally when Hop starts allowing you to attaching -echo a debugger from your favorite Java IDE tool and step code. -echo ========================================================================== -GOTO End - -:NormalStart -REM set java primary is HOP_JAVA_HOME fallback to JAVA_HOME or default java -if not "%HOP_JAVA_HOME%"=="" ( - set _HOP_JAVA="%HOP_JAVA_HOME%\bin\java" -) else if not "%JAVA_HOME%"=="" ( - set _HOP_JAVA="%JAVA_HOME%\bin\java" -) else ( - set _HOP_JAVA=java -) - -REM # Settings for all OSses - -if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx2048m - -REM -REM If the user passes in DEBUG as the first parameter, it starts Hop in debugger mode and opens port 5005 -REM to allow attaching a debugger to step code. -if [%1]==[DEBUG] ( -REM # optional line for attaching a debugger -set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005) - -REM Pass HOP variables if they're set. -if not "%HOP_AUDIT_FOLDER%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%" -) else ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit -) -if not "%HOP_CONFIG_FOLDER%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%" -) -if not "%HOP_SHARED_JDBC_FOLDERS%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%" -) -if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%" -) -if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN% -) -if not "%HOP_AES_ENCODER_KEY%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY% -) -if not "%HOP_AES_ENCODER_KEY_FILE%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE% -) - -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=GUI -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y -set HOP_OPTIONS=%HOP_OPTIONS% --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.nio.cs=ALL-UNNAMED --add-opens java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED - -echo ===[Environment Settings - hop-gui.bat]=================================== -echo. -echo Java identified as %_HOP_JAVA% -echo. -echo HOP_OPTIONS=%HOP_OPTIONS% -echo. -echo Command to start Hop will be: -echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.ui.hopgui.HopGui -echo. -echo ===[Starting Hop]========================================================= - -%_HOP_JAVA% -classpath %CLASSPATH% -Dswt.autoScale=false -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.ui.hopgui.HopGui -if ERRORLEVEL 1 (pause) - -:End -endlocal +@echo off +REM +REM Licensed to the Apache Software Foundation (ASF) under one or more +REM contributor license agreements. See the NOTICE file distributed with +REM this work for additional information regarding copyright ownership. +REM The ASF licenses this file to You under the Apache License, Version 2.0 +REM (the "License"); you may not use this file except in compliance with +REM the License. You may obtain a copy of the License at +REM +REM http://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 + +setlocal + +REM switch to script directory +cd /D %~dp0 + +REM Option to change the Characterset of the Windows Shell to show foreign caracters +if not "%HOP_WINDOWS_SHELL_ENCODING%"=="" chcp %HOP_WINDOWS_SHELL_ENCODING% + +set LIBSPATH=lib\core +set CLASSPATH=lib\core\*;lib\spark-client\*;lib\swt\win64\* + +REM Optional versioned Spark client pack +if defined HOP_SPARK_CLIENT_VERSION if exist "lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\" ( + set CLASSPATH=%CLASSPATH%;lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\* +) + +REM Beam SDKs under optional plugin (plugins\engines\beam\lib-beam) +if exist "plugins\engines\beam\lib-beam\" ( + set CLASSPATH=%CLASSPATH%;plugins\engines\beam\lib-beam\* +) +if exist "plugins\engines\beam\" ( + set CLASSPATH=%CLASSPATH%;plugins\engines\beam\* +) + + + + +set _temphelp=0 +if [%1]==[help] set _temphelp=1 +if [%1]==[Help] set _temphelp=1 +if %_temphelp%==1 (GOTO Help) ELSE (GOTO NormalStart) + +:Help +echo ===[Hop Help - hop-gui.bat]=============================================== +echo Starts Hop GUI and keeps this console window open so you can see log output. +echo To start without a console window, use hop-gui-nolog.bat instead. +echo. +echo Normally, no parameters are required to start Hop. There is a debug mode +echo that you can start by passing in DEBUG as the first parameter after hop-gui.bat +echo. +echo Example: +echo hop-gui.bat DEBUG +echo +echo The debug mode opens port 5005 locally when Hop starts allowing you to attaching +echo a debugger from your favorite Java IDE tool and step code. +echo ========================================================================== +GOTO End + +:NormalStart +REM set java primary is HOP_JAVA_HOME fallback to JAVA_HOME or default java +if not "%HOP_JAVA_HOME%"=="" ( + set _HOP_JAVA="%HOP_JAVA_HOME%\bin\java" +) else if not "%JAVA_HOME%"=="" ( + set _HOP_JAVA="%JAVA_HOME%\bin\java" +) else ( + set _HOP_JAVA=java +) + +REM # Settings for all OSses + +if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx2048m + +REM +REM If the user passes in DEBUG as the first parameter, it starts Hop in debugger mode and opens port 5005 +REM to allow attaching a debugger to step code. +if [%1]==[DEBUG] ( +REM # optional line for attaching a debugger +set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005) + +REM Pass HOP variables if they're set. +if not "%HOP_AUDIT_FOLDER%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%" +) else ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit +) +if not "%HOP_CONFIG_FOLDER%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%" +) +if not "%HOP_SHARED_JDBC_FOLDERS%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%" +) +if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%" +) +if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN% +) +if not "%HOP_AES_ENCODER_KEY%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY% +) +if not "%HOP_AES_ENCODER_KEY_FILE%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE% +) + +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=GUI +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y +set HOP_OPTIONS=%HOP_OPTIONS% --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.nio.cs=ALL-UNNAMED --add-opens java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED + +echo ===[Environment Settings - hop-gui.bat]=================================== +echo. +echo Java identified as %_HOP_JAVA% +echo. +echo HOP_OPTIONS=%HOP_OPTIONS% +echo. +echo Command to start Hop will be: +echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.ui.hopgui.HopGui +echo. +echo ===[Starting Hop]========================================================= + +%_HOP_JAVA% -classpath %CLASSPATH% -Dswt.autoScale=false -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.ui.hopgui.HopGui +if ERRORLEVEL 1 (pause) + +:End +endlocal diff --git a/assemblies/static/src/main/resources/hop-gui.sh b/assemblies/static/src/main/resources/hop-gui.sh index 69f3c6a4b82..2cf6975e438 100755 --- a/assemblies/static/src/main/resources/hop-gui.sh +++ b/assemblies/static/src/main/resources/hop-gui.sh @@ -110,7 +110,7 @@ Darwin) HOP_OPTIONS="${HOP_OPTIONS} -XstartOnFirstThread" ;; esac -CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/$os_path/$arch_path/*" +CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/$os_path/$arch_path/*" @@ -121,6 +121,17 @@ if [ -n "${HOP_SPARK_CLIENT_VERSION:-}" ] && [ -d "lib/spark-clients/${HOP_SPARK CLASSPATH=$(echo "${CLASSPATH}" | sed 's|lib/spark-client/\*||g') CLASSPATH="${CLASSPATH}:lib/spark-clients/${HOP_SPARK_CLIENT_VERSION}/*" fi + +# Beam SDKs/runners live with the optional Beam plugin (not lib/beam). +# Only on the system classpath when marketplace (or -Pbeam) has installed them. +if [ -d "plugins/engines/beam/lib-beam" ]; then + CLASSPATH="${CLASSPATH}:plugins/engines/beam/lib-beam/*" +fi +if [ -d "plugins/engines/beam" ]; then + # Hop Beam plugin jars at the plugin root (exclude subdirs via non-recursive glob is fine for /*.jar intent; + # shell * includes jars and may pick non-jars; match historical lib/* style) + CLASSPATH="${CLASSPATH}:plugins/engines/beam/*" +fi "${_HOP_JAVA}" ${HOP_OPTIONS} -Djava.library.path="${LIBPATH}" -classpath "${CLASSPATH}" org.apache.hop.ui.hopgui.HopGui "$@" EXITCODE=$? diff --git a/assemblies/static/src/main/resources/hop-import.bat b/assemblies/static/src/main/resources/hop-import.bat index 582dcdb396f..5a4b91e88c8 100644 --- a/assemblies/static/src/main/resources/hop-import.bat +++ b/assemblies/static/src/main/resources/hop-import.bat @@ -1,108 +1,116 @@ -echo off -REM -REM Licensed to the Apache Software Foundation (ASF) under one or more -REM contributor license agreements. See the NOTICE file distributed with -REM this work for additional information regarding copyright ownership. -REM The ASF licenses this file to You under the Apache License, Version 2.0 -REM (the "License"); you may not use this file except in compliance with -REM the License. You may obtain a copy of the License at -REM -REM http://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 - -echo off -setlocal - -REM switch to script directory -cd /D %~dp0 - -set LIBSPATH=lib\core;lib\beam -set CLASSPATH=lib\core\*;lib\beam\*;lib\spark-client\*;lib\swt\win64\* - -REM Optional versioned Spark client pack -if defined HOP_SPARK_CLIENT_VERSION if exist "lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\" ( - set CLASSPATH=%CLASSPATH%;lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\* -) - - - - -:NormalStart -REM set java primary is HOP_JAVA_HOME fallback to JAVA_HOME or default java -if not "%HOP_JAVA_HOME%"=="" ( - set _HOP_JAVA="%HOP_JAVA_HOME%\bin\java" -) else if not "%JAVA_HOME%"=="" ( - set _HOP_JAVA="%JAVA_HOME%\bin\java" -) else ( - set _HOP_JAVA=java -) - -REM # Settings for all OSses - -if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx2048m - -REM -REM If the user passes in DEBUG as the first parameter, it starts Hop in debugger mode and opens port 5009 -REM to allow attaching a debugger to step code. -if [%1]==[DEBUG] ( -REM # optional line for attaching a debugger -set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009) - -REM Pass HOP variables if they're set. -if not "%HOP_AUDIT_FOLDER%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%" -) else ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit -) -if not "%HOP_CONFIG_FOLDER%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%" -) -if not "%HOP_SHARED_JDBC_FOLDERS%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%" -) -if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%" -) -if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN% -) -if not "%HOP_AES_ENCODER_KEY%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY% -) -if not "%HOP_AES_ENCODER_KEY_FILE%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE% -) - -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Import -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y -set HOP_OPTIONS=%HOP_OPTIONS% --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.nio.cs=ALL-UNNAMED --add-opens java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED - -echo ===[Environment Settings - hop-import.bat]=================================== -echo. -echo Java identified as %_HOP_JAVA% -echo. -echo HOP_OPTIONS=%HOP_OPTIONS% -echo. -rem ===[Collect command line arguments...]====================================== -if [%1]==[DEBUG] ( -FOR /f "tokens=1*" %%x IN ("%*") DO set _cmdline=%%y -GOTO Run -) -set _cmdline=%* - -:Run -echo Command to start Hop will be: -echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.config.HopConfig %_cmdline% -echo. -echo ===[Starting HopConfig]========================================================= - -%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.imp.HopImport %_cmdline% -@echo off -:End +echo off +REM +REM Licensed to the Apache Software Foundation (ASF) under one or more +REM contributor license agreements. See the NOTICE file distributed with +REM this work for additional information regarding copyright ownership. +REM The ASF licenses this file to You under the Apache License, Version 2.0 +REM (the "License"); you may not use this file except in compliance with +REM the License. You may obtain a copy of the License at +REM +REM http://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 + +echo off +setlocal + +REM switch to script directory +cd /D %~dp0 + +set LIBSPATH=lib\core +set CLASSPATH=lib\core\*;lib\spark-client\*;lib\swt\win64\* + +REM Optional versioned Spark client pack +if defined HOP_SPARK_CLIENT_VERSION if exist "lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\" ( + set CLASSPATH=%CLASSPATH%;lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\* +) + +REM Beam SDKs under optional plugin (plugins\engines\beam\lib-beam) +if exist "plugins\engines\beam\lib-beam\" ( + set CLASSPATH=%CLASSPATH%;plugins\engines\beam\lib-beam\* +) +if exist "plugins\engines\beam\" ( + set CLASSPATH=%CLASSPATH%;plugins\engines\beam\* +) + + + + +:NormalStart +REM set java primary is HOP_JAVA_HOME fallback to JAVA_HOME or default java +if not "%HOP_JAVA_HOME%"=="" ( + set _HOP_JAVA="%HOP_JAVA_HOME%\bin\java" +) else if not "%JAVA_HOME%"=="" ( + set _HOP_JAVA="%JAVA_HOME%\bin\java" +) else ( + set _HOP_JAVA=java +) + +REM # Settings for all OSses + +if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx2048m + +REM +REM If the user passes in DEBUG as the first parameter, it starts Hop in debugger mode and opens port 5009 +REM to allow attaching a debugger to step code. +if [%1]==[DEBUG] ( +REM # optional line for attaching a debugger +set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009) + +REM Pass HOP variables if they're set. +if not "%HOP_AUDIT_FOLDER%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%" +) else ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit +) +if not "%HOP_CONFIG_FOLDER%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%" +) +if not "%HOP_SHARED_JDBC_FOLDERS%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%" +) +if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%" +) +if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN% +) +if not "%HOP_AES_ENCODER_KEY%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY% +) +if not "%HOP_AES_ENCODER_KEY_FILE%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE% +) + +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Import +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y +set HOP_OPTIONS=%HOP_OPTIONS% --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.nio.cs=ALL-UNNAMED --add-opens java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED + +echo ===[Environment Settings - hop-import.bat]=================================== +echo. +echo Java identified as %_HOP_JAVA% +echo. +echo HOP_OPTIONS=%HOP_OPTIONS% +echo. +rem ===[Collect command line arguments...]====================================== +if [%1]==[DEBUG] ( +FOR /f "tokens=1*" %%x IN ("%*") DO set _cmdline=%%y +GOTO Run +) +set _cmdline=%* + +:Run +echo Command to start Hop will be: +echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.config.HopConfig %_cmdline% +echo. +echo ===[Starting HopConfig]========================================================= + +%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.imp.HopImport %_cmdline% +@echo off +:End diff --git a/assemblies/static/src/main/resources/hop-import.sh b/assemblies/static/src/main/resources/hop-import.sh index 5669e164e5e..5ee373c1ae9 100755 --- a/assemblies/static/src/main/resources/hop-import.sh +++ b/assemblies/static/src/main/resources/hop-import.sh @@ -81,16 +81,16 @@ Linux) if "${_HOP_JAVA}" -XshowSettings:properties -version 2>&1 | grep -q "os.arch = aarch64"; then - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/linux/arm64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/linux/arm64/*" else - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/linux/$(uname -m)/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/linux/$(uname -m)/*" fi ;; Darwin) if "${_HOP_JAVA}" -XshowSettings:properties -version 2>&1 | grep -q "os.arch = aarch64"; then - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/osx/arm64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/osx/arm64/*" else - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/osx/x86_64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/osx/x86_64/*" fi HOP_OPTIONS="${HOP_OPTIONS} -XstartOnFirstThread" ;; @@ -103,6 +103,17 @@ if [ -n "${HOP_SPARK_CLIENT_VERSION:-}" ] && [ -d "lib/spark-clients/${HOP_SPARK CLASSPATH=$(echo "${CLASSPATH}" | sed 's|lib/spark-client/\*||g') CLASSPATH="${CLASSPATH}:lib/spark-clients/${HOP_SPARK_CLIENT_VERSION}/*" fi + +# Beam SDKs/runners live with the optional Beam plugin (not lib/beam). +# Only on the system classpath when marketplace (or -Pbeam) has installed them. +if [ -d "plugins/engines/beam/lib-beam" ]; then + CLASSPATH="${CLASSPATH}:plugins/engines/beam/lib-beam/*" +fi +if [ -d "plugins/engines/beam" ]; then + # Hop Beam plugin jars at the plugin root (exclude subdirs via non-recursive glob is fine for /*.jar intent; + # shell * includes jars and may pick non-jars; match historical lib/* style) + CLASSPATH="${CLASSPATH}:plugins/engines/beam/*" +fi "${_HOP_JAVA}" ${HOP_OPTIONS} -Djava.library.path="${LIBPATH}" -classpath "${CLASSPATH}" org.apache.hop.imp.HopImport "$@" EXITCODE=$? diff --git a/assemblies/static/src/main/resources/hop-run.bat b/assemblies/static/src/main/resources/hop-run.bat index 424a2737daa..9c4e2152278 100755 --- a/assemblies/static/src/main/resources/hop-run.bat +++ b/assemblies/static/src/main/resources/hop-run.bat @@ -1,128 +1,136 @@ -@echo off -REM -REM Licensed to the Apache Software Foundation (ASF) under one or more -REM contributor license agreements. See the NOTICE file distributed with -REM this work for additional information regarding copyright ownership. -REM The ASF licenses this file to You under the Apache License, Version 2.0 -REM (the "License"); you may not use this file except in compliance with -REM the License. You may obtain a copy of the License at -REM -REM http://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 - -setlocal - -REM switch to script directory -cd /D %~dp0 - -REM Option to change the Characterset of the Windows Shell to show foreign caracters -if not "%HOP_WINDOWS_SHELL_ENCODING%"=="" chcp %HOP_WINDOWS_SHELL_ENCODING% - -set LIBSPATH=lib\core;lib\beam -set CLASSPATH=lib\core\*;lib\beam\*;lib\spark-client\*;lib\swt\win64\* - -REM Optional versioned Spark client pack -if defined HOP_SPARK_CLIENT_VERSION if exist "lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\" ( - set CLASSPATH=%CLASSPATH%;lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\* -) - - - - -set _temphelp=0 -if [%1]==[help] set _temphelp=1 -if [%1]==[Help] set _temphelp=1 -if %_temphelp%==1 (GOTO Help) ELSE (GOTO NormalStart) - -:Help -echo ===[HopRun - hop-run.bat]================================================= -echo. -echo Example: -echo hop-run.bat --file=C:\Users\usbra\Desktop\converted_financial_metrics\update_dashboard_financials.hwf --environment=converted_financial_metrics --project=converted_financial_metrics --runconfig=local -echo -echo The above gives a full path to a file. It assumes a project has been created for that file called 'converted_financial_metrics' -echo The project also has an environment called 'converted_financial_metrics', that was created when creating the project. -echo Finally, 'local' is the name of the local configuration json file present in the project's metadata folder. There is one for workflows and another for pipelines. -echo ========================================================================== -GOTO End - -:NormalStart -REM set java primary is HOP_JAVA_HOME fallback to JAVA_HOME or default java -if not "%HOP_JAVA_HOME%"=="" ( - set _HOP_JAVA="%HOP_JAVA_HOME%\bin\java" -) else if not "%JAVA_HOME%"=="" ( - set _HOP_JAVA="%JAVA_HOME%\bin\java" -) else ( - set _HOP_JAVA="java" -) - -REM # Settings for all OSses - -if "%HOP_OPTIONS%"=="" set HOP_OPTIONS="-Xmx2048m" - -REM -REM If the user passes in DEBUG as the first parameter, it starts Hop in debugger mode and opens port 5005 -REM to allow attaching a debugger to step code. -if [%1]==[DEBUG] ( -REM # optional line for attaching a debugger -set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005) - -REM Pass HOP variables if they're set. -if not "%HOP_AUDIT_FOLDER%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%" -) else ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit -) -if not "%HOP_CONFIG_FOLDER%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%" -) -if not "%HOP_SHARED_JDBC_FOLDERS%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%" -) -if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%" -) -if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN% -) -if not "%HOP_AES_ENCODER_KEY%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY% -) -if not "%HOP_AES_ENCODER_KEY_FILE%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE% -) - -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Run -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y -set HOP_OPTIONS=%HOP_OPTIONS% --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.nio.cs=ALL-UNNAMED --add-opens java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED - -echo ===[Environment Settings - hop-run.bat]=================================== -echo. -echo Java identified as %_HOP_JAVA% -echo. -echo HOP_OPTIONS=%HOP_OPTIONS% -echo. -rem ===[Collect command line arguments...]====================================== -if [%1]==[DEBUG] ( -FOR /f "tokens=1*" %%x IN ("%*") DO set _cmdline=%%y -GOTO Run -) -set _cmdline=%* - -:Run -echo. -echo Consolidated parameters to pass to HopRun are -echo %_cmdline%% -echo. -echo Command to start HopRun will be: -echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.run.HopRun %_cmdline%% -echo. -echo ===[Starting HopRun]========================================================= +@echo off +REM +REM Licensed to the Apache Software Foundation (ASF) under one or more +REM contributor license agreements. See the NOTICE file distributed with +REM this work for additional information regarding copyright ownership. +REM The ASF licenses this file to You under the Apache License, Version 2.0 +REM (the "License"); you may not use this file except in compliance with +REM the License. You may obtain a copy of the License at +REM +REM http://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 + +setlocal + +REM switch to script directory +cd /D %~dp0 + +REM Option to change the Characterset of the Windows Shell to show foreign caracters +if not "%HOP_WINDOWS_SHELL_ENCODING%"=="" chcp %HOP_WINDOWS_SHELL_ENCODING% + +set LIBSPATH=lib\core +set CLASSPATH=lib\core\*;lib\spark-client\*;lib\swt\win64\* + +REM Optional versioned Spark client pack +if defined HOP_SPARK_CLIENT_VERSION if exist "lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\" ( + set CLASSPATH=%CLASSPATH%;lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\* +) + +REM Beam SDKs under optional plugin (plugins\engines\beam\lib-beam) +if exist "plugins\engines\beam\lib-beam\" ( + set CLASSPATH=%CLASSPATH%;plugins\engines\beam\lib-beam\* +) +if exist "plugins\engines\beam\" ( + set CLASSPATH=%CLASSPATH%;plugins\engines\beam\* +) + + + + +set _temphelp=0 +if [%1]==[help] set _temphelp=1 +if [%1]==[Help] set _temphelp=1 +if %_temphelp%==1 (GOTO Help) ELSE (GOTO NormalStart) + +:Help +echo ===[HopRun - hop-run.bat]================================================= +echo. +echo Example: +echo hop-run.bat --file=C:\Users\usbra\Desktop\converted_financial_metrics\update_dashboard_financials.hwf --environment=converted_financial_metrics --project=converted_financial_metrics --runconfig=local +echo +echo The above gives a full path to a file. It assumes a project has been created for that file called 'converted_financial_metrics' +echo The project also has an environment called 'converted_financial_metrics', that was created when creating the project. +echo Finally, 'local' is the name of the local configuration json file present in the project's metadata folder. There is one for workflows and another for pipelines. +echo ========================================================================== +GOTO End + +:NormalStart +REM set java primary is HOP_JAVA_HOME fallback to JAVA_HOME or default java +if not "%HOP_JAVA_HOME%"=="" ( + set _HOP_JAVA="%HOP_JAVA_HOME%\bin\java" +) else if not "%JAVA_HOME%"=="" ( + set _HOP_JAVA="%JAVA_HOME%\bin\java" +) else ( + set _HOP_JAVA="java" +) + +REM # Settings for all OSses + +if "%HOP_OPTIONS%"=="" set HOP_OPTIONS="-Xmx2048m" + +REM +REM If the user passes in DEBUG as the first parameter, it starts Hop in debugger mode and opens port 5005 +REM to allow attaching a debugger to step code. +if [%1]==[DEBUG] ( +REM # optional line for attaching a debugger +set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005) + +REM Pass HOP variables if they're set. +if not "%HOP_AUDIT_FOLDER%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%" +) else ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit +) +if not "%HOP_CONFIG_FOLDER%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%" +) +if not "%HOP_SHARED_JDBC_FOLDERS%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%" +) +if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%" +) +if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN% +) +if not "%HOP_AES_ENCODER_KEY%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY% +) +if not "%HOP_AES_ENCODER_KEY_FILE%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE% +) + +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Run +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y +set HOP_OPTIONS=%HOP_OPTIONS% --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.nio.cs=ALL-UNNAMED --add-opens java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED + +echo ===[Environment Settings - hop-run.bat]=================================== +echo. +echo Java identified as %_HOP_JAVA% +echo. +echo HOP_OPTIONS=%HOP_OPTIONS% +echo. +rem ===[Collect command line arguments...]====================================== +if [%1]==[DEBUG] ( +FOR /f "tokens=1*" %%x IN ("%*") DO set _cmdline=%%y +GOTO Run +) +set _cmdline=%* + +:Run +echo. +echo Consolidated parameters to pass to HopRun are +echo %_cmdline%% +echo. +echo Command to start HopRun will be: +echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.run.HopRun %_cmdline%% +echo. +echo ===[Starting HopRun]========================================================= %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.run.HopRun %_cmdline%% \ No newline at end of file diff --git a/assemblies/static/src/main/resources/hop-run.sh b/assemblies/static/src/main/resources/hop-run.sh index f25c19bac80..83c03b7f5f4 100755 --- a/assemblies/static/src/main/resources/hop-run.sh +++ b/assemblies/static/src/main/resources/hop-run.sh @@ -81,16 +81,16 @@ Linux) if "${_HOP_JAVA}" -XshowSettings:properties -version 2>&1 | grep -q "os.arch = aarch64"; then - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/linux/arm64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/linux/arm64/*" else - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/linux/$(uname -m)/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/linux/$(uname -m)/*" fi ;; Darwin) if "${_HOP_JAVA}" -XshowSettings:properties -version 2>&1 | grep -q "os.arch = aarch64"; then - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/osx/arm64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/osx/arm64/*" else - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/osx/x86_64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/osx/x86_64/*" fi HOP_OPTIONS="${HOP_OPTIONS} -XstartOnFirstThread" ;; @@ -103,6 +103,17 @@ if [ -n "${HOP_SPARK_CLIENT_VERSION:-}" ] && [ -d "lib/spark-clients/${HOP_SPARK CLASSPATH=$(echo "${CLASSPATH}" | sed 's|lib/spark-client/\*||g') CLASSPATH="${CLASSPATH}:lib/spark-clients/${HOP_SPARK_CLIENT_VERSION}/*" fi + +# Beam SDKs/runners live with the optional Beam plugin (not lib/beam). +# Only on the system classpath when marketplace (or -Pbeam) has installed them. +if [ -d "plugins/engines/beam/lib-beam" ]; then + CLASSPATH="${CLASSPATH}:plugins/engines/beam/lib-beam/*" +fi +if [ -d "plugins/engines/beam" ]; then + # Hop Beam plugin jars at the plugin root (exclude subdirs via non-recursive glob is fine for /*.jar intent; + # shell * includes jars and may pick non-jars; match historical lib/* style) + CLASSPATH="${CLASSPATH}:plugins/engines/beam/*" +fi "${_HOP_JAVA}" ${HOP_OPTIONS} -Djava.library.path="${LIBPATH}" -classpath "${CLASSPATH}" org.apache.hop.run.HopRun "$@" EXITCODE=$? diff --git a/assemblies/static/src/main/resources/hop-search.bat b/assemblies/static/src/main/resources/hop-search.bat index be6d8e37a5d..35571bb4640 100644 --- a/assemblies/static/src/main/resources/hop-search.bat +++ b/assemblies/static/src/main/resources/hop-search.bat @@ -1,105 +1,113 @@ -@echo off -REM -REM Licensed to the Apache Software Foundation (ASF) under one or more -REM contributor license agreements. See the NOTICE file distributed with -REM this work for additional information regarding copyright ownership. -REM The ASF licenses this file to You under the Apache License, Version 2.0 -REM (the "License"); you may not use this file except in compliance with -REM the License. You may obtain a copy of the License at -REM -REM http://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 - -setlocal - -REM switch to script directory -cd /D %~dp0 - -set LIBSPATH=lib\core;lib\beam -set CLASSPATH=lib\core\*;lib\beam\*;lib\spark-client\*;lib\swt\win64\* - -REM Optional versioned Spark client pack -if defined HOP_SPARK_CLIENT_VERSION if exist "lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\" ( - set CLASSPATH=%CLASSPATH%;lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\* -) - - - - -:NormalStart -REM set java primary is HOP_JAVA_HOME fallback to JAVA_HOME or default java -if not "%HOP_JAVA_HOME%"=="" ( - set _HOP_JAVA="%HOP_JAVA_HOME%\bin\java" -) else if not "%JAVA_HOME%"=="" ( - set _HOP_JAVA="%JAVA_HOME%\bin\java" -) else ( - set _HOP_JAVA=java -) - -REM # Settings for all OSses - -if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx2048m - -REM -REM If the user passes in DEBUG as the first parameter, it starts Hop in debugger mode and opens port 5009 -REM to allow attaching a debugger to step code. -if [%1]==[DEBUG] ( -REM # optional line for attaching a debugger -set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009) - -REM Pass HOP variables if they're set. -if not "%HOP_AUDIT_FOLDER%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%" -) else ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit -) -if not "%HOP_CONFIG_FOLDER%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%" -) -if not "%HOP_SHARED_JDBC_FOLDERS%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%" -) -if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%" -) -if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN% -) -if not "%HOP_AES_ENCODER_KEY%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY% -) -if not "%HOP_AES_ENCODER_KEY_FILE%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE% -) - -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Search -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y -set HOP_OPTIONS=%HOP_OPTIONS% --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.nio.cs=ALL-UNNAMED --add-opens java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED - -echo ===[Environment Settings - hop-search.bat]=================================== -echo. -echo Java identified as %_HOP_JAVA% -echo. -echo HOP_OPTIONS=%HOP_OPTIONS% -echo. -rem ===[Collect command line arguments...]====================================== -if [%1]==[DEBUG] ( -FOR /f "tokens=1*" %%x IN ("%*") DO set _cmdline=%%y -GOTO Run -) -set _cmdline=%* - -:Run -echo Command to start Hop will be: -echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.config.HopConfig %_cmdline% -echo. -echo ===[Starting HopConfig]========================================================= - -%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.search.HopSearch %_cmdline% +@echo off +REM +REM Licensed to the Apache Software Foundation (ASF) under one or more +REM contributor license agreements. See the NOTICE file distributed with +REM this work for additional information regarding copyright ownership. +REM The ASF licenses this file to You under the Apache License, Version 2.0 +REM (the "License"); you may not use this file except in compliance with +REM the License. You may obtain a copy of the License at +REM +REM http://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 + +setlocal + +REM switch to script directory +cd /D %~dp0 + +set LIBSPATH=lib\core +set CLASSPATH=lib\core\*;lib\spark-client\*;lib\swt\win64\* + +REM Optional versioned Spark client pack +if defined HOP_SPARK_CLIENT_VERSION if exist "lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\" ( + set CLASSPATH=%CLASSPATH%;lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\* +) + +REM Beam SDKs under optional plugin (plugins\engines\beam\lib-beam) +if exist "plugins\engines\beam\lib-beam\" ( + set CLASSPATH=%CLASSPATH%;plugins\engines\beam\lib-beam\* +) +if exist "plugins\engines\beam\" ( + set CLASSPATH=%CLASSPATH%;plugins\engines\beam\* +) + + + + +:NormalStart +REM set java primary is HOP_JAVA_HOME fallback to JAVA_HOME or default java +if not "%HOP_JAVA_HOME%"=="" ( + set _HOP_JAVA="%HOP_JAVA_HOME%\bin\java" +) else if not "%JAVA_HOME%"=="" ( + set _HOP_JAVA="%JAVA_HOME%\bin\java" +) else ( + set _HOP_JAVA=java +) + +REM # Settings for all OSses + +if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx2048m + +REM +REM If the user passes in DEBUG as the first parameter, it starts Hop in debugger mode and opens port 5009 +REM to allow attaching a debugger to step code. +if [%1]==[DEBUG] ( +REM # optional line for attaching a debugger +set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009) + +REM Pass HOP variables if they're set. +if not "%HOP_AUDIT_FOLDER%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%" +) else ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit +) +if not "%HOP_CONFIG_FOLDER%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%" +) +if not "%HOP_SHARED_JDBC_FOLDERS%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%" +) +if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%" +) +if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN% +) +if not "%HOP_AES_ENCODER_KEY%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY% +) +if not "%HOP_AES_ENCODER_KEY_FILE%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE% +) + +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Search +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y +set HOP_OPTIONS=%HOP_OPTIONS% --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.nio.cs=ALL-UNNAMED --add-opens java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED + +echo ===[Environment Settings - hop-search.bat]=================================== +echo. +echo Java identified as %_HOP_JAVA% +echo. +echo HOP_OPTIONS=%HOP_OPTIONS% +echo. +rem ===[Collect command line arguments...]====================================== +if [%1]==[DEBUG] ( +FOR /f "tokens=1*" %%x IN ("%*") DO set _cmdline=%%y +GOTO Run +) +set _cmdline=%* + +:Run +echo Command to start Hop will be: +echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.config.HopConfig %_cmdline% +echo. +echo ===[Starting HopConfig]========================================================= + +%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.search.HopSearch %_cmdline% diff --git a/assemblies/static/src/main/resources/hop-search.sh b/assemblies/static/src/main/resources/hop-search.sh index 6bba102dea0..607f53261e0 100755 --- a/assemblies/static/src/main/resources/hop-search.sh +++ b/assemblies/static/src/main/resources/hop-search.sh @@ -81,16 +81,16 @@ Linux) if "${_HOP_JAVA}" -XshowSettings:properties -version 2>&1 | grep -q "os.arch = aarch64"; then - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/linux/arm64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/linux/arm64/*" else - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/linux/$(uname -m)/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/linux/$(uname -m)/*" fi ;; Darwin) if "${_HOP_JAVA}" -XshowSettings:properties -version 2>&1 | grep -q "os.arch = aarch64"; then - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/osx/arm64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/osx/arm64/*" else - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/osx/x86_64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/osx/x86_64/*" fi HOP_OPTIONS="${HOP_OPTIONS} -XstartOnFirstThread" ;; @@ -103,6 +103,17 @@ if [ -n "${HOP_SPARK_CLIENT_VERSION:-}" ] && [ -d "lib/spark-clients/${HOP_SPARK CLASSPATH=$(echo "${CLASSPATH}" | sed 's|lib/spark-client/\*||g') CLASSPATH="${CLASSPATH}:lib/spark-clients/${HOP_SPARK_CLIENT_VERSION}/*" fi + +# Beam SDKs/runners live with the optional Beam plugin (not lib/beam). +# Only on the system classpath when marketplace (or -Pbeam) has installed them. +if [ -d "plugins/engines/beam/lib-beam" ]; then + CLASSPATH="${CLASSPATH}:plugins/engines/beam/lib-beam/*" +fi +if [ -d "plugins/engines/beam" ]; then + # Hop Beam plugin jars at the plugin root (exclude subdirs via non-recursive glob is fine for /*.jar intent; + # shell * includes jars and may pick non-jars; match historical lib/* style) + CLASSPATH="${CLASSPATH}:plugins/engines/beam/*" +fi "${_HOP_JAVA}" ${HOP_OPTIONS} -Djava.library.path="${LIBPATH}" -classpath "${CLASSPATH}" org.apache.hop.search.HopSearch "$@" EXITCODE=$? diff --git a/assemblies/static/src/main/resources/hop-server.bat b/assemblies/static/src/main/resources/hop-server.bat index 40227e5c65e..d47d761bf04 100644 --- a/assemblies/static/src/main/resources/hop-server.bat +++ b/assemblies/static/src/main/resources/hop-server.bat @@ -1,109 +1,117 @@ -@echo off -REM -REM Licensed to the Apache Software Foundation (ASF) under one or more -REM contributor license agreements. See the NOTICE file distributed with -REM this work for additional information regarding copyright ownership. -REM The ASF licenses this file to You under the Apache License, Version 2.0 -REM (the "License"); you may not use this file except in compliance with -REM the License. You may obtain a copy of the License at -REM -REM http://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 - -setlocal - -REM switch to script directory -cd /D %~dp0 - -REM Option to change the Characterset of the Windows Shell to show foreign caracters -if not "%HOP_WINDOWS_SHELL_ENCODING%"=="" chcp %HOP_WINDOWS_SHELL_ENCODING% - -set LIBSPATH=lib\core;lib\beam -set CLASSPATH=lib\core\*;lib\beam\*;lib\spark-client\*;lib\swt\win64\* - -REM Optional versioned Spark client pack -if defined HOP_SPARK_CLIENT_VERSION if exist "lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\" ( - set CLASSPATH=%CLASSPATH%;lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\* -) - - - - -:NormalStart -REM set java primary is HOP_JAVA_HOME fallback to JAVA_HOME or default java -if not "%HOP_JAVA_HOME%"=="" ( - set _HOP_JAVA="%HOP_JAVA_HOME%\bin\java" -) else if not "%JAVA_HOME%"=="" ( - set _HOP_JAVA="%JAVA_HOME%\bin\java" -) else ( - set _HOP_JAVA=java -) - -REM # Settings for all OSses - -if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx2048m - -REM -REM If the user passes in DEBUG as the first parameter, it starts Hop in debugger mode and opens port 5009 -REM to allow attaching a debugger to step code. -if [%1]==[DEBUG] ( -REM # optional line for attaching a debugger -set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009) - -REM Pass HOP variables if they're set. -if not "%HOP_AUDIT_FOLDER%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%" -) else ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit -) -if not "%HOP_CONFIG_FOLDER%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%" -) -if not "%HOP_SHARED_JDBC_FOLDERS%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%" -) -if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%" -) -if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN% -) -if not "%HOP_AES_ENCODER_KEY%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY% -) -if not "%HOP_AES_ENCODER_KEY_FILE%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE% -) - -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Server -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y -set HOP_OPTIONS=%HOP_OPTIONS% --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.nio.cs=ALL-UNNAMED --add-opens java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED - -echo ===[Environment Settings - hop-server.bat]==================================== -echo. -echo Java identified as %_HOP_JAVA% -echo. -echo HOP_OPTIONS=%HOP_OPTIONS% -echo. -echo. -rem ===[Collect command line arguments...]====================================== -if [%1]==[DEBUG] ( -FOR /f "tokens=1*" %%x IN ("%*") DO set _cmdline=%%y -GOTO Run -) -set _cmdline=%* - -:Run -echo Command to start Hop will be: -echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.www.HopServer %_cmdline% -echo. -echo ===[Starting HopServer]========================================================= - +@echo off +REM +REM Licensed to the Apache Software Foundation (ASF) under one or more +REM contributor license agreements. See the NOTICE file distributed with +REM this work for additional information regarding copyright ownership. +REM The ASF licenses this file to You under the Apache License, Version 2.0 +REM (the "License"); you may not use this file except in compliance with +REM the License. You may obtain a copy of the License at +REM +REM http://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 + +setlocal + +REM switch to script directory +cd /D %~dp0 + +REM Option to change the Characterset of the Windows Shell to show foreign caracters +if not "%HOP_WINDOWS_SHELL_ENCODING%"=="" chcp %HOP_WINDOWS_SHELL_ENCODING% + +set LIBSPATH=lib\core +set CLASSPATH=lib\core\*;lib\spark-client\*;lib\swt\win64\* + +REM Optional versioned Spark client pack +if defined HOP_SPARK_CLIENT_VERSION if exist "lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\" ( + set CLASSPATH=%CLASSPATH%;lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\* +) + +REM Beam SDKs under optional plugin (plugins\engines\beam\lib-beam) +if exist "plugins\engines\beam\lib-beam\" ( + set CLASSPATH=%CLASSPATH%;plugins\engines\beam\lib-beam\* +) +if exist "plugins\engines\beam\" ( + set CLASSPATH=%CLASSPATH%;plugins\engines\beam\* +) + + + + +:NormalStart +REM set java primary is HOP_JAVA_HOME fallback to JAVA_HOME or default java +if not "%HOP_JAVA_HOME%"=="" ( + set _HOP_JAVA="%HOP_JAVA_HOME%\bin\java" +) else if not "%JAVA_HOME%"=="" ( + set _HOP_JAVA="%JAVA_HOME%\bin\java" +) else ( + set _HOP_JAVA=java +) + +REM # Settings for all OSses + +if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx2048m + +REM +REM If the user passes in DEBUG as the first parameter, it starts Hop in debugger mode and opens port 5009 +REM to allow attaching a debugger to step code. +if [%1]==[DEBUG] ( +REM # optional line for attaching a debugger +set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009) + +REM Pass HOP variables if they're set. +if not "%HOP_AUDIT_FOLDER%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%" +) else ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit +) +if not "%HOP_CONFIG_FOLDER%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%" +) +if not "%HOP_SHARED_JDBC_FOLDERS%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%" +) +if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%" +) +if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN% +) +if not "%HOP_AES_ENCODER_KEY%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY% +) +if not "%HOP_AES_ENCODER_KEY_FILE%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE% +) + +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Server +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y +set HOP_OPTIONS=%HOP_OPTIONS% --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.nio.cs=ALL-UNNAMED --add-opens java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED + +echo ===[Environment Settings - hop-server.bat]==================================== +echo. +echo Java identified as %_HOP_JAVA% +echo. +echo HOP_OPTIONS=%HOP_OPTIONS% +echo. +echo. +rem ===[Collect command line arguments...]====================================== +if [%1]==[DEBUG] ( +FOR /f "tokens=1*" %%x IN ("%*") DO set _cmdline=%%y +GOTO Run +) +set _cmdline=%* + +:Run +echo Command to start Hop will be: +echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.www.HopServer %_cmdline% +echo. +echo ===[Starting HopServer]========================================================= + %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.www.HopServer %_cmdline% \ No newline at end of file diff --git a/assemblies/static/src/main/resources/hop-server.sh b/assemblies/static/src/main/resources/hop-server.sh index 06cedd3d4a7..d732505d4d8 100755 --- a/assemblies/static/src/main/resources/hop-server.sh +++ b/assemblies/static/src/main/resources/hop-server.sh @@ -81,16 +81,16 @@ Linux) if "${_HOP_JAVA}" -XshowSettings:properties -version 2>&1 | grep -q "os.arch = aarch64"; then - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/linux/arm64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/linux/arm64/*" else - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/linux/$(uname -m)/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/linux/$(uname -m)/*" fi ;; Darwin) if "${_HOP_JAVA}" -XshowSettings:properties -version 2>&1 | grep -q "os.arch = aarch64"; then - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/osx/arm64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/osx/arm64/*" else - CLASSPATH="lib/core/*:lib/beam/*:lib/spark-client/*:lib/swt/osx/x86_64/*" + CLASSPATH="lib/core/*:lib/spark-client/*:lib/swt/osx/x86_64/*" fi HOP_OPTIONS="${HOP_OPTIONS} -XstartOnFirstThread" ;; @@ -108,6 +108,17 @@ if [ -n "${HOP_SPARK_CLIENT_VERSION:-}" ] && [ -d "lib/spark-clients/${HOP_SPARK CLASSPATH=$(echo "${CLASSPATH}" | sed 's|lib/spark-client/\*||g') CLASSPATH="${CLASSPATH}:lib/spark-clients/${HOP_SPARK_CLIENT_VERSION}/*" fi + +# Beam SDKs/runners live with the optional Beam plugin (not lib/beam). +# Only on the system classpath when marketplace (or -Pbeam) has installed them. +if [ -d "plugins/engines/beam/lib-beam" ]; then + CLASSPATH="${CLASSPATH}:plugins/engines/beam/lib-beam/*" +fi +if [ -d "plugins/engines/beam" ]; then + # Hop Beam plugin jars at the plugin root (exclude subdirs via non-recursive glob is fine for /*.jar intent; + # shell * includes jars and may pick non-jars; match historical lib/* style) + CLASSPATH="${CLASSPATH}:plugins/engines/beam/*" +fi "${_HOP_JAVA}" ${HOP_OPTIONS} -Djava.library.path="${LIBPATH}" -classpath "${CLASSPATH}" org.apache.hop.www.HopServer "$@" EXITCODE=$? diff --git a/assemblies/static/src/main/resources/hop.bat b/assemblies/static/src/main/resources/hop.bat index 635a87f575b..0b624c33644 100755 --- a/assemblies/static/src/main/resources/hop.bat +++ b/assemblies/static/src/main/resources/hop.bat @@ -1,104 +1,112 @@ -@echo off - -REM -REM Licensed to the Apache Software Foundation (ASF) under one or more -REM contributor license agreements. See the NOTICE file distributed with -REM this work for additional information regarding copyright ownership. -REM The ASF licenses this file to You under the Apache License, Version 2.0 -REM (the "License"); you may not use this file except in compliance with -REM the License. You may obtain a copy of the License at -REM -REM http://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 - -setlocal EnableDelayedExpansion - -REM switch to script directory -cd /D %~dp0 - -REM Option to change the character set of the Windows Shell to show foreign characters -if not "%HOP_WINDOWS_SHELL_ENCODING%"=="" chcp %HOP_WINDOWS_SHELL_ENCODING% - -set LIBSPATH=lib\core;lib\beam -set CLASSPATH=lib\core\*;lib\beam\*;lib\spark-client\*;lib\swt\win64\* - -REM Optional versioned Spark client pack -if defined HOP_SPARK_CLIENT_VERSION if exist "lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\" ( - set CLASSPATH=%CLASSPATH%;lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\* -) - - - - -:NormalStart -REM set java primary is HOP_JAVA_HOME fallback to JAVA_HOME or default java -REM -if not "%HOP_JAVA_HOME%"=="" ( - set _HOP_JAVA="%HOP_JAVA_HOME%\bin\java" -) else if not "%JAVA_HOME%"=="" ( - set _HOP_JAVA="%JAVA_HOME%\bin\java" -) else ( - set _HOP_JAVA="java" -) - -REM # Settings for all OSses -REM - -if "%HOP_OPTIONS%"=="" set HOP_OPTIONS="-Xmx2048m" - -REM See if we need to enable some remote debugging options for our developers. -REM -FOR %%a in (%*) DO ( - if "%%~a" == "--dev-debug" ( - set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5010 - ) - if "%%~a" == "--dev-debug-wait" ( - set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5010 - ) -) - -REM Pass HOP variables if they're set. -REM -if not "%HOP_AUDIT_FOLDER%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%" -) else ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit -) -if not "%HOP_CONFIG_FOLDER%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%" -) -if not "%HOP_SHARED_JDBC_FOLDERS%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%" -) -if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%" -) -if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN% -) -if not "%HOP_AES_ENCODER_KEY%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY% -) -if not "%HOP_AES_ENCODER_KEY_FILE%"=="" ( - set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE% -) - -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Run -set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y -set HOP_OPTIONS=%HOP_OPTIONS% --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.nio.cs=ALL-UNNAMED --add-opens java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED - -REM ===[Collect command line arguments...]====================================== -REM -set _cmdline=%* - -:Run - -%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.hop.Hop %_cmdline%% - +@echo off + +REM +REM Licensed to the Apache Software Foundation (ASF) under one or more +REM contributor license agreements. See the NOTICE file distributed with +REM this work for additional information regarding copyright ownership. +REM The ASF licenses this file to You under the Apache License, Version 2.0 +REM (the "License"); you may not use this file except in compliance with +REM the License. You may obtain a copy of the License at +REM +REM http://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 + +setlocal EnableDelayedExpansion + +REM switch to script directory +cd /D %~dp0 + +REM Option to change the character set of the Windows Shell to show foreign characters +if not "%HOP_WINDOWS_SHELL_ENCODING%"=="" chcp %HOP_WINDOWS_SHELL_ENCODING% + +set LIBSPATH=lib\core +set CLASSPATH=lib\core\*;lib\spark-client\*;lib\swt\win64\* + +REM Optional versioned Spark client pack +if defined HOP_SPARK_CLIENT_VERSION if exist "lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\" ( + set CLASSPATH=%CLASSPATH%;lib\spark-clients\%HOP_SPARK_CLIENT_VERSION%\* +) + +REM Beam SDKs under optional plugin (plugins\engines\beam\lib-beam) +if exist "plugins\engines\beam\lib-beam\" ( + set CLASSPATH=%CLASSPATH%;plugins\engines\beam\lib-beam\* +) +if exist "plugins\engines\beam\" ( + set CLASSPATH=%CLASSPATH%;plugins\engines\beam\* +) + + + + +:NormalStart +REM set java primary is HOP_JAVA_HOME fallback to JAVA_HOME or default java +REM +if not "%HOP_JAVA_HOME%"=="" ( + set _HOP_JAVA="%HOP_JAVA_HOME%\bin\java" +) else if not "%JAVA_HOME%"=="" ( + set _HOP_JAVA="%JAVA_HOME%\bin\java" +) else ( + set _HOP_JAVA="java" +) + +REM # Settings for all OSses +REM + +if "%HOP_OPTIONS%"=="" set HOP_OPTIONS="-Xmx2048m" + +REM See if we need to enable some remote debugging options for our developers. +REM +FOR %%a in (%*) DO ( + if "%%~a" == "--dev-debug" ( + set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5010 + ) + if "%%~a" == "--dev-debug-wait" ( + set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5010 + ) +) + +REM Pass HOP variables if they're set. +REM +if not "%HOP_AUDIT_FOLDER%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%" +) else ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit +) +if not "%HOP_CONFIG_FOLDER%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%" +) +if not "%HOP_SHARED_JDBC_FOLDERS%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%" +) +if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%" +) +if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN% +) +if not "%HOP_AES_ENCODER_KEY%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY% +) +if not "%HOP_AES_ENCODER_KEY_FILE%"=="" ( + set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE% +) + +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Run +set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y +set HOP_OPTIONS=%HOP_OPTIONS% --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.nio.cs=ALL-UNNAMED --add-opens java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED + +REM ===[Collect command line arguments...]====================================== +REM +set _cmdline=%* + +:Run + +%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.hop.Hop %_cmdline%% + diff --git a/docker/unified.Dockerfile b/docker/unified.Dockerfile index e2390351010..4fe12081b88 100644 --- a/docker/unified.Dockerfile +++ b/docker/unified.Dockerfile @@ -193,7 +193,7 @@ RUN mkdir -p /build/hop-web-prepared/webapps/ROOT && \ cp -r /build/assemblies/client/target/hop/config /build/hop-web-prepared/webapps/ROOT/ && \ cp -r /build/assemblies/client/target/hop/plugins /build/hop-web-prepared/ && \ cp -r /build/assemblies/client/target/hop/lib/jdbc/ /build/hop-web-prepared/jdbc-drivers && \ - cp -r /build/assemblies/client/target/hop/lib/beam/* /build/hop-web-prepared/webapps/ROOT/WEB-INF/lib/ && \ + if [ -d /build/assemblies/client/target/hop/plugins/engines/beam/lib-beam ]; then cp -r /build/assemblies/client/target/hop/plugins/engines/beam/lib-beam/* /build/hop-web-prepared/webapps/ROOT/WEB-INF/lib/; fi && \ cp -r /build/assemblies/client/target/hop/lib/core/* /build/hop-web-prepared/webapps/ROOT/WEB-INF/lib/ && \ rm /build/hop-web-prepared/webapps/ROOT/WEB-INF/lib/hop-ui-rcp* && \ cp /build/docker/resources/run-web.sh /build/hop-web-prepared/run-web.sh && \ diff --git a/docker/web.Dockerfile b/docker/web.Dockerfile index 7dfd19c72bf..656c80cb7c0 100644 --- a/docker/web.Dockerfile +++ b/docker/web.Dockerfile @@ -73,7 +73,7 @@ RUN groupadd -r hop -g ${HOP_GID} \ COPY ./assemblies/web/target/webapp/ "${CATALINA_HOME}"/webapps/ROOT/ COPY ./assemblies/client/target/hop/config "${CATALINA_HOME}"/webapps/ROOT/config COPY ./assemblies/client/target/hop/lib/core "${CATALINA_HOME}"/webapps/ROOT/WEB-INF/lib -COPY ./assemblies/client/target/hop/lib/beam "${CATALINA_HOME}"/webapps/ROOT/WEB-INF/lib +COPY ./assemblies/client/target/hop/plugins/engines/beam/lib-beam "${CATALINA_HOME}"/webapps/ROOT/WEB-INF/lib COPY ./assemblies/client/target/hop/plugins "${CATALINA_HOME}"/plugins COPY ./assemblies/client/target/hop/lib/jdbc/ "${CATALINA_HOME}"/jdbc-drivers COPY --chown=hop ./docker/resources/run-web.sh /tmp/ diff --git a/docs/hop-dev-manual/modules/ROOT/pages/hopweb/index.adoc b/docs/hop-dev-manual/modules/ROOT/pages/hopweb/index.adoc index 2174dff2bb4..5af4905ea6d 100644 --- a/docs/hop-dev-manual/modules/ROOT/pages/hopweb/index.adoc +++ b/docs/hop-dev-manual/modules/ROOT/pages/hopweb/index.adoc @@ -80,7 +80,7 @@ cp -r /tmp/hop-client/hop/lib/core/* $CATALINA_HOME/webapps/ROOT/WEB-INF/lib/ rm -f $CATALINA_HOME/webapps/ROOT/WEB-INF/lib/hop-ui-rcp-*.jar # Step 5: Copy beam libraries -cp -r /tmp/hop-client/hop/lib/beam/* $CATALINA_HOME/webapps/ROOT/WEB-INF/lib/ +cp -r /tmp/hop-client/hop/plugins/engines/beam/lib-beam/* $CATALINA_HOME/webapps/ROOT/WEB-INF/lib/ # Step 6: Copy plugins cp -r /tmp/hop-client/hop/plugins $CATALINA_HOME/ @@ -200,7 +200,7 @@ sed -i '' 's&lib/core/*&../../lib/*:WEB-INF/lib/*:lib/core/*&g' ${CATALINA_HOME} The `CLASSPATH` lines in the various scripts should look similar to the one below after editing: -`CLASSPATH="../../lib/*:WEB-INF/lib/*:lib/core/**:lib/beam/*:lib/swt/osx/arm64/*"` +`CLASSPATH="../../lib/*:WEB-INF/lib/*:lib/core/**:plugins/engines/beam/lib-beam/*:lib/swt/osx/arm64/*"` Once the classpaths have been updated, make sure to make the scripts executable: diff --git a/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc b/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc index df4ca6870b0..80509af4f30 100644 --- a/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc +++ b/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc @@ -43,6 +43,8 @@ Notes: A copy is also under `config/projects/samples/marketplace/full-client-env.yaml`. +Beam SDKs/runners live under `plugins/engines/beam/lib-beam` (installed with the Beam plugin), not under `lib/beam`. Launch scripts add that folder to the classpath only when it exists. Developers who want Beam baked into a local hop-client build can use Maven profile `-Pbeam` (for example `./mvnw -pl assemblies/client -am package -Pbeam`). + == Defaults Without extra configuration, Hop uses: @@ -237,7 +239,7 @@ plugins: - groupId: org.apache.hop # optional; default org.apache.hop artifactId: hop-engines-spark version: "2.19.0" - # Beam engine plugin only (lib/beam stays in the core client): + # Beam engine plugin only (Beam SDKs ship under plugins/engines/beam/lib-beam with the plugin): # - artifactId: hop-engines-beam # version: "2.19.0" diff --git a/plugins/engines/beam/pom.xml b/plugins/engines/beam/pom.xml index 266a4f5e674..e13686c5270 100644 --- a/plugins/engines/beam/pom.xml +++ b/plugins/engines/beam/pom.xml @@ -1662,8 +1662,9 @@ diff --git a/plugins/engines/beam/src/assembly/assembly-beam-runtime.xml b/plugins/engines/beam/src/assembly/assembly-beam-runtime.xml new file mode 100644 index 00000000000..369c7ca8325 --- /dev/null +++ b/plugins/engines/beam/src/assembly/assembly-beam-runtime.xml @@ -0,0 +1,154 @@ + + + + + + runtime + + org.apache.hop:hop-engines-beam:jar + org.apache.hadoop:*:jar + org.apache.hadoop.thirdparty:*:jar + org.yaml:snakeyaml:jar + com.google.protobuf:protobuf-java:jar + com.google.protobuf:protobuf-java-util:jar + org.jetbrains:annotations:jar + com.google.auto.value:auto-value-annotations:jar + org.apache.beam:beam-vendor-guava-32_1_2-jre:jar + com.github.luben:zstd-jni:jar + com.google.auth:google-auth-library-oauth2-http:jar + com.google.oauth-client:google-oauth-client:jar + com.google.api-client:google-api-client:jar + com.google.http-client:google-http-client:jar + com.google.http-client:google-http-client-apache-v2:jar + com.google.http-client:google-http-client-appengine:jar + google-http-client-gson:jar + com.google.http-client:google-http-client-jackson2:jar + com.google.android:annotations:jar + org.codehaus.mojo:animal-sniffer-annotations:jar + com.google.api:api-common:jar + com.google.auto.value:auto-value-annotations:jar + com.google.guava::jar + org.jetbrains.kotlin::jar + io.netty::jar + org.codehaus.mojo:animal-sniffer-annotations:jar + io.projectreactor.netty::jar + io.grpc:grpc-netty-shaded:jar + io.grpc:grpc-xds:jar + org.apache.kafka::jar + org.xerial.snappy:snappy-java:jar + org.eclipse.jetty::jar + org.eclipse.jetty.compression::jar + com.google.cloud:google-cloud-storage:jar + io.grpc::jar + com.google.cloud:google-cloud-core-grpc:jar + com.google.api.grpc:grpc-google-cloud-storage-v2:jar + com.google.api:gax-grpc:jar + com.google.api.grpc::jar + org.checkerframework:checker-qual:jar + io.confluent:common-utils:jar + commons-cli:commons-cli:jar + commons-codec:commons-codec:jar + commons-logging:commons-logging:jar + org.apache.commons:commons-text:jar + com.google.cloud.opentelemetry:detector-resources-support:jar + com.google.errorprone:error_prone_annotations:jar + com.google.cloud.opentelemetry:exporter-metrics:jar + com.google.api:gax:jar + com.google.api:gax-httpjson:jar + com.google.apis:google-api-services-storage:jar + com.google.auth:google-auth-library-credentials:jar + com.google.auth:google-auth-library-oauth2-http:jar + com.google.cloud:google-cloud-core:jar + com.google.cloud:google-cloud-core-http:jar + com.google.cloud:google-cloud-monitoring:jar + com.google.http-client:google-http-client-gson:jar + org.apache.httpcomponents:httpclient:jar + org.apache.httpcomponents:httpcore:jar + com.google.j2objc:j2objc-annotations:jar + com.fasterxml.jackson.core::jar + com.fasterxml.jackson.dataformat::jar + com.fasterxml.jackson.datatype::jar + com.fasterxml.jackson::jar + com.github.stephenc.jcip:jcip-annotations:jar + net.java.dev.jna::jar + com.google.code.findbugs:jsr305:jar + com.squareup.okhttp3:okhttp:jar + com.squareup.okio::jar + io.opentelemetry::jar + com.google.cloud.opentelemetry:shared-resourcemapping:jar + org.codehaus.woodstox:stax2-api:jar + org.threeten::jar + org.lz4:lz4-java:jar + io.opentelemetry.contrib::jar + io.opentelemetry.semconv::jar + io.perfmark:perfmark-api:jar + com.google.re2j:re2j:jar + org.reactivestreams:reactive-streams:jar + io.projectreactor:reactor-core:jar + org.bouncycastle::jar + com.microsoft.azure:msal4j:jar + com.microsoft.azure:msal4j-persistence-extension:jar + com.amazonaws:aws-java-sdk-core:jar + com.amazonaws:aws-java-sdk-kms:jar + com.amazonaws:aws-java-sdk-s3:jar + com.nimbusds:oauth2-oidc-sdk:jar + com.azure:azure-core:jar + com.azure:azure-identity:jar + com.azure:azure-core-http-netty:jar + com.azure:azure-json:jar + com.microsoft.azure:azure-keyvault-core:jar + com.azure:azure-security-keyvault-secrets:jar + com.azure:azure-storage-blob:jar + com.azure:azure-storage-common:jar + com.azure:azure-storage-internal-avro:jar + com.azure:azure-xml:jar + com.nimbusds:nimbus-jose-jwt:jar + io.confluent::jar + com.google.code.gson:gson:jar + org.apache.commons:commons-collections4:jar + org.jspecify:jspecify:jar + org.apache.commons:commons-lang3:jar + commons-collections:commons-collections:jar + com.fasterxml.woodstox:woodstox-core:jar + com.ibm.icu:icu4j:jar + com.fasterxml.jackson.core:jackson-annotations:jar + software.amazon.awssdk:*:jar + software.amazon.eventstream:eventstream:jar + javax.annotation:javax.annotation-api:jar + javax.inject:javax.inject:jar + org.jctools:jctools-core:jar + com.nimbusds:lang-tag:jar + io.dropwizard.metrics:*:jar + com.eclipsesource.minimal-json:minimal-json:jar + org.slf4j:slf4j-api:jar + + org.apache.spark:spark-core_2.12:jar + org.apache.spark:spark-streaming_2.12:jar + org.apache.spark:spark-launcher_2.12:jar + org.apache.spark:spark-kvstore_2.12:jar + org.apache.spark:spark-network-common_2.12:jar + org.apache.spark:spark-network-shuffle_2.12:jar + org.apache.spark:spark-unsafe_2.12:jar + org.apache.spark:spark-tags_2.12:jar + + plugins/engines/beam/lib-beam + + + diff --git a/plugins/engines/beam/src/assembly/assembly-libs.xml b/plugins/engines/beam/src/assembly/assembly-libs.xml index 901d8b1ea19..4736424a1ca 100644 --- a/plugins/engines/beam/src/assembly/assembly-libs.xml +++ b/plugins/engines/beam/src/assembly/assembly-libs.xml @@ -18,7 +18,7 @@ - + libs zip @@ -27,137 +27,7 @@ - - runtime - - org.apache.hop:hop-engines-beam:jar - org.apache.hadoop:*:jar - org.apache.hadoop.thirdparty:*:jar - org.yaml:snakeyaml:jar - com.google.protobuf:protobuf-java:jar - com.google.protobuf:protobuf-java-util:jar - org.jetbrains:annotations:jar - com.google.auto.value:auto-value-annotations:jar - org.apache.beam:beam-vendor-guava-32_1_2-jre:jar - com.github.luben:zstd-jni:jar - com.google.auth:google-auth-library-oauth2-http:jar - com.google.oauth-client:google-oauth-client:jar - com.google.api-client:google-api-client:jar - com.google.http-client:google-http-client:jar - com.google.http-client:google-http-client-apache-v2:jar - com.google.http-client:google-http-client-appengine:jar - google-http-client-gson:jar - com.google.http-client:google-http-client-jackson2:jar - com.google.android:annotations:jar - org.codehaus.mojo:animal-sniffer-annotations:jar - com.google.api:api-common:jar - com.google.auto.value:auto-value-annotations:jar - com.google.guava::jar - org.jetbrains.kotlin::jar - io.netty::jar - org.codehaus.mojo:animal-sniffer-annotations:jar - io.projectreactor.netty::jar - io.grpc:grpc-netty-shaded:jar - io.grpc:grpc-xds:jar - org.apache.kafka::jar - org.xerial.snappy:snappy-java:jar - org.eclipse.jetty::jar - org.eclipse.jetty.compression::jar - com.google.cloud:google-cloud-storage:jar - io.grpc::jar - com.google.cloud:google-cloud-core-grpc:jar - com.google.api.grpc:grpc-google-cloud-storage-v2:jar - com.google.api:gax-grpc:jar - com.google.api.grpc::jar - org.checkerframework:checker-qual:jar - io.confluent:common-utils:jar - commons-cli:commons-cli:jar - commons-codec:commons-codec:jar - commons-logging:commons-logging:jar - org.apache.commons:commons-text:jar - com.google.cloud.opentelemetry:detector-resources-support:jar - com.google.errorprone:error_prone_annotations:jar - com.google.cloud.opentelemetry:exporter-metrics:jar - com.google.api:gax:jar - com.google.api:gax-httpjson:jar - com.google.apis:google-api-services-storage:jar - com.google.auth:google-auth-library-credentials:jar - com.google.auth:google-auth-library-oauth2-http:jar - com.google.cloud:google-cloud-core:jar - com.google.cloud:google-cloud-core-http:jar - com.google.cloud:google-cloud-monitoring:jar - com.google.http-client:google-http-client-gson:jar - org.apache.httpcomponents:httpclient:jar - org.apache.httpcomponents:httpcore:jar - com.google.j2objc:j2objc-annotations:jar - com.fasterxml.jackson.core::jar - com.fasterxml.jackson.dataformat::jar - com.fasterxml.jackson.datatype::jar - com.fasterxml.jackson::jar - com.github.stephenc.jcip:jcip-annotations:jar - net.java.dev.jna::jar - com.google.code.findbugs:jsr305:jar - com.squareup.okhttp3:okhttp:jar - com.squareup.okio::jar - io.opentelemetry::jar - com.google.cloud.opentelemetry:shared-resourcemapping:jar - org.codehaus.woodstox:stax2-api:jar - org.threeten::jar - org.lz4:lz4-java:jar - io.opentelemetry.contrib::jar - io.opentelemetry.semconv::jar - io.perfmark:perfmark-api:jar - com.google.re2j:re2j:jar - org.reactivestreams:reactive-streams:jar - io.projectreactor:reactor-core:jar - org.bouncycastle::jar - com.microsoft.azure:msal4j:jar - com.microsoft.azure:msal4j-persistence-extension:jar - com.amazonaws:aws-java-sdk-core:jar - com.amazonaws:aws-java-sdk-kms:jar - com.amazonaws:aws-java-sdk-s3:jar - com.nimbusds:oauth2-oidc-sdk:jar - com.azure:azure-core:jar - com.azure:azure-identity:jar - com.azure:azure-core-http-netty:jar - com.azure:azure-json:jar - com.microsoft.azure:azure-keyvault-core:jar - com.azure:azure-security-keyvault-secrets:jar - com.azure:azure-storage-blob:jar - com.azure:azure-storage-common:jar - com.azure:azure-storage-internal-avro:jar - com.azure:azure-xml:jar - com.nimbusds:nimbus-jose-jwt:jar - io.confluent::jar - com.google.code.gson:gson:jar - org.apache.commons:commons-collections4:jar - org.jspecify:jspecify:jar - org.apache.commons:commons-lang3:jar - commons-collections:commons-collections:jar - com.fasterxml.woodstox:woodstox-core:jar - com.ibm.icu:icu4j:jar - com.fasterxml.jackson.core:jackson-annotations:jar - software.amazon.awssdk:*:jar - software.amazon.eventstream:eventstream:jar - javax.annotation:javax.annotation-api:jar - javax.inject:javax.inject:jar - org.jctools:jctools-core:jar - com.nimbusds:lang-tag:jar - io.dropwizard.metrics:*:jar - com.eclipsesource.minimal-json:minimal-json:jar - org.slf4j:slf4j-api:jar - - org.apache.spark:spark-core_2.12:jar - org.apache.spark:spark-streaming_2.12:jar - org.apache.spark:spark-launcher_2.12:jar - org.apache.spark:spark-kvstore_2.12:jar - org.apache.spark:spark-network-common_2.12:jar - org.apache.spark:spark-network-shuffle_2.12:jar - org.apache.spark:spark-unsafe_2.12:jar - org.apache.spark:spark-tags_2.12:jar - - lib/beam - + diff --git a/plugins/engines/beam/src/assembly/assembly.xml b/plugins/engines/beam/src/assembly/assembly.xml index cf9fe298760..fe175665fb7 100644 --- a/plugins/engines/beam/src/assembly/assembly.xml +++ b/plugins/engines/beam/src/assembly/assembly.xml @@ -18,7 +18,7 @@ - + plugin zip @@ -52,4 +52,8 @@ plugins/engines/beam + + + ${project.basedir}/src/assembly/assembly-beam-runtime.xml + diff --git a/plugins/engines/beam/src/main/java/org/apache/hop/beam/gui/HopBeamGuiPlugin.java b/plugins/engines/beam/src/main/java/org/apache/hop/beam/gui/HopBeamGuiPlugin.java index c6119d456e6..6801d5eb756 100644 --- a/plugins/engines/beam/src/main/java/org/apache/hop/beam/gui/HopBeamGuiPlugin.java +++ b/plugins/engines/beam/src/main/java/org/apache/hop/beam/gui/HopBeamGuiPlugin.java @@ -459,8 +459,9 @@ public static File resolveSparkClientPackDir(String sparkClientVersion) { } /** - * @param versionedPack when true, also skip {@code spark-*.jar} under {@code lib/beam} so Beam's - * fixed Spark fragments cannot mix with an alternate client pack + * @param versionedPack when true, also skip {@code spark-*.jar} under Beam SDK folders ({@code + * lib/beam} legacy or {@code plugins/engines/beam/lib-beam}) so Beam's fixed Spark fragments + * cannot mix with an alternate client pack */ private static void collectJarsExcludingSparkClientPacks( File dir, Set jarFiles, boolean versionedPack) { @@ -483,11 +484,12 @@ private static void collectJarsExcludingSparkClientPacks( if (child.isDirectory()) { collectJarsExcludingSparkClientPacks(child, jarFiles, versionedPack); } else if (child.isFile() && child.getName().endsWith(".jar")) { - // Versioned packs own all spark-* jars; drop Beam's spark fragments from lib/beam + // Versioned packs own all spark-* jars; drop Beam's spark fragments from lib-beam / + // lib/beam if (versionedPack && child.getName().startsWith("spark-") && parent != null - && "beam".equals(parent.getName())) { + && isBeamSdkJarFolder(parent)) { continue; } jarFiles.add(child); @@ -495,6 +497,19 @@ private static void collectJarsExcludingSparkClientPacks( } } + /** True for legacy {@code lib/beam} or marketplace {@code …/beam/lib-beam}. */ + static boolean isBeamSdkJarFolder(File folder) { + if (folder == null) { + return false; + } + String name = folder.getName(); + if ("lib-beam".equals(name)) { + return true; + } + File parent = folder.getParentFile(); + return "beam".equals(name) && parent != null && "lib".equals(parent.getName()); + } + /** * Add a toolbar item just above the pipeline graph to quickly visit the execution of a Dataflow * pipeline in the GCP console. diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java index d90a8a9b6d0..0e35f582974 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java @@ -120,7 +120,7 @@ private static List fallbackCatalog() { "hop-engines-beam", "Apache Beam engine", "Engines", - "Beam pipeline engine and transforms (plugin only; lib/beam stays in the core install).", + "Beam pipeline engine and transforms (includes Beam SDKs under lib-beam).", "plugins/engines/beam")); wave1.add( new OptionalPluginInfo( diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java index 432e4df5a6e..8dc863f594a 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java @@ -214,12 +214,13 @@ private void activateStaged(String artifactId, List relativePaths) throw } } + /** + * Core install paths marketplace zips must not overwrite. Beam SDKs live under the Beam plugin + * ({@code plugins/engines/beam/lib-beam}) and are installed/uninstalled with that plugin. + */ static boolean isProtectedPath(String relative) { String normalized = relative.replace('\\', '/'); - return normalized.equals("lib/beam") - || normalized.startsWith("lib/beam/") - || normalized.equals("lib/core") - || normalized.startsWith("lib/core/"); + return normalized.equals("lib/core") || normalized.startsWith("lib/core/"); } private List unzipAllowedEntries(Path zipFile, Path stageRoot) diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginUninstaller.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginUninstaller.java index 4b44776da38..e4b1ddb8c41 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginUninstaller.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginUninstaller.java @@ -46,7 +46,7 @@ public void uninstall(String artifactId) throws HopException { + "'. Only plugins installed via the marketplace can be uninstalled this way."); } - // Delete files deepest-first; skip protected paths (e.g. lib/beam) + // Delete files deepest-first; skip protected paths (e.g. lib/core) Set dirs = new HashSet<>(); for (String relative : receipt.getPaths()) { if (PluginInstaller.isProtectedPath(relative)) { diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml index fb53a97b91c..2a0b01ea72c 100644 --- a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml @@ -29,7 +29,7 @@ plugins: - artifactId: hop-engines-beam name: Apache Beam engine category: Engines - description: Beam pipeline engine and transforms (plugin only; lib/beam stays in the core install). + description: Beam pipeline engine and transforms; SDKs under plugins/engines/beam/lib-beam. installPath: plugins/engines/beam modulePath: plugins/engines/beam - artifactId: hop-transform-script diff --git a/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml b/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml index 52c3452e5a3..740c04ff62e 100644 --- a/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml +++ b/plugins/misc/marketplace/src/main/samples/hop-env.example.yaml @@ -42,7 +42,7 @@ plugins: version: "2.19.0-SNAPSHOT" - artifactId: hop-engines-spark version: "2.19.0-SNAPSHOT" - # Beam engine plugin only (lib/beam stays in the core client): + # Beam engine plugin only (Beam SDKs ship under plugins/engines/beam/lib-beam with the plugin): # - artifactId: hop-engines-beam # version: "2.19.0-SNAPSHOT" diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/PluginInstallerTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/PluginInstallerTest.java index 30cf2130767..112bb7cae79 100644 --- a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/PluginInstallerTest.java +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/install/PluginInstallerTest.java @@ -50,7 +50,8 @@ static void initLogging() { @Test void protectedPaths() { - assertTrue(PluginInstaller.isProtectedPath("lib/beam/foo.jar")); + assertFalse(PluginInstaller.isProtectedPath("lib/beam/foo.jar")); + assertFalse(PluginInstaller.isProtectedPath("plugins/engines/beam/lib-beam/x.jar")); assertTrue(PluginInstaller.isProtectedPath("lib/core/bar.jar")); assertFalse(PluginInstaller.isProtectedPath("plugins/engines/beam/hop.jar")); assertFalse(PluginInstaller.isProtectedPath("plugins/tech/parquet/lib/x.jar")); @@ -93,7 +94,7 @@ void installAndUninstallFromLocalHttpRepo() throws Exception { Files.isRegularFile( hopHome.resolve(PluginInstaller.RECEIPTS_DIR).resolve("hop-test-plugin.json"))); // protected path from zip must not be written - assertFalse(Files.exists(hopHome.resolve("lib/beam/evil.jar"))); + assertFalse(Files.exists(hopHome.resolve("lib/core/evil.jar"))); new PluginUninstaller(log, hopHome).uninstall("hop-test-plugin"); assertFalse(Files.exists(pluginJar)); @@ -208,7 +209,7 @@ private static byte[] buildPluginZip() throws IOException { zos.write("1.0.0".getBytes(StandardCharsets.UTF_8)); zos.closeEntry(); // Should be ignored on activate - zos.putNextEntry(new ZipEntry("lib/beam/evil.jar")); + zos.putNextEntry(new ZipEntry("lib/core/evil.jar")); zos.write("nope".getBytes(StandardCharsets.UTF_8)); zos.closeEntry(); } diff --git a/tools/install-wave1-plugins.sh b/tools/install-wave1-plugins.sh index 471230a2908..4b64a4ca4f8 100755 --- a/tools/install-wave1-plugins.sh +++ b/tools/install-wave1-plugins.sh @@ -61,4 +61,4 @@ for entry in "${PLUGINS[@]}"; do done echo "Wave 1 plugins: installed=${installed} skipped=${skipped} into ${INSTALL_DIR}" -# Note: beam plugin zip does not include lib/beam (already in core client). +# Note: beam plugin zip includes lib-beam (Beam SDKs). From 2dafe912bd7263f11c8a98f472096bcf72a02bd3 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Mon, 20 Jul 2026 01:13:13 +0200 Subject: [PATCH 22/28] issue #7547: add hop marketplace query for optional plugin catalog Add CLI query FILTER to search the local optional-plugins registry by case-insensitive substring across artifact id, name, category, description, and install path, with optional [installed] markers and docs. --- .../ROOT/pages/hop-tools/hop-marketplace.adoc | 7 +++ plugins/misc/marketplace/README.md | 2 + .../catalog/OptionalPluginCatalog.java | 30 ++++++++++ .../command/MarketplaceCommand.java | 57 +++++++++++++++++++ .../catalog/OptionalPluginCatalogTest.java | 23 ++++++++ 5 files changed, 119 insertions(+) diff --git a/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc b/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc index 80509af4f30..64dae341c3d 100644 --- a/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc +++ b/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc @@ -66,6 +66,8 @@ From the Hop install directory: ./hop marketplace install hop-engines-spark:2.19.0 ./hop marketplace install hop-engines-spark:2.19.0 --repo asf ./hop marketplace list +./hop marketplace query parquet +./hop marketplace query "spark engine" ./hop marketplace uninstall hop-tech-parquet # Repositories @@ -86,6 +88,11 @@ After install, apply, or uninstall, *restart Hop* so the plugin registry reloads Coordinates for `install`: `artifactId`, `artifactId:version`, or `groupId:artifactId:version`. Optional `--repo ` forces a single repository (skips the fallback chain). +`query` searches the local optional-plugin catalog (not Maven Central). The filter is a +case-insensitive substring matched against artifact id, name, category, description, and install +path. Omit the filter (or pass an empty string) to list every optional plugin. Matches may show +`[installed]` when the plugin folder is present under the Hop install. + == GUI *Tools → Marketplace…* lists featured optional plugins, installs/uninstalls them, and opens *Manage…* to edit repositories (same config as the CLI). diff --git a/plugins/misc/marketplace/README.md b/plugins/misc/marketplace/README.md index 93e95ea19dc..bea7d138b38 100644 --- a/plugins/misc/marketplace/README.md +++ b/plugins/misc/marketplace/README.md @@ -33,6 +33,8 @@ From the Hop install directory (or invoke the `hop` script by path — it alread ./hop marketplace install hop-engines-spark:2.19.0 --repo asf ./hop marketplace install hop-engines-beam ./hop marketplace list +./hop marketplace query parquet +./hop marketplace query engines ./hop marketplace uninstall hop-tech-parquet # Repositories (saved to ${HOP_CONFIG_FOLDER}/hop-config.json) diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java index 0e35f582974..2f5cd7b94c0 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java @@ -50,6 +50,36 @@ public static List listOptional() { return PLUGINS; } + /** + * Case-insensitive substring filter over artifactId, name, category, description, and + * installPath. Blank filter returns all optional plugins. + */ + public static List query(String filter) { + if (StringUtils.isBlank(filter)) { + return listOptional(); + } + String needle = filter.trim().toLowerCase(); + List matches = new ArrayList<>(); + for (OptionalPluginInfo info : PLUGINS) { + if (matchesFilter(info, needle)) { + matches.add(info); + } + } + return Collections.unmodifiableList(matches); + } + + private static boolean matchesFilter(OptionalPluginInfo info, String needleLower) { + return containsIgnoreCase(info.getArtifactId(), needleLower) + || containsIgnoreCase(info.getName(), needleLower) + || containsIgnoreCase(info.getCategory(), needleLower) + || containsIgnoreCase(info.getDescription(), needleLower) + || containsIgnoreCase(info.getInstallPath(), needleLower); + } + + private static boolean containsIgnoreCase(String value, String needleLower) { + return value != null && value.toLowerCase().contains(needleLower); + } + public static boolean isInstalledOnDisk(Path hopHome, OptionalPluginInfo info) { if (info.getInstallPath() == null) { return false; diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java index b7432655931..ab7bcce0443 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java @@ -32,6 +32,8 @@ import org.apache.hop.core.variables.IVariables; import org.apache.hop.hop.plugin.HopCommand; import org.apache.hop.hop.plugin.IHopCommand; +import org.apache.hop.marketplace.catalog.OptionalPluginCatalog; +import org.apache.hop.marketplace.catalog.OptionalPluginInfo; import org.apache.hop.marketplace.config.MarketplaceConfig; import org.apache.hop.marketplace.config.MarketplaceRepository; import org.apache.hop.marketplace.env.EnvironmentApplier; @@ -60,6 +62,7 @@ MarketplaceCommand.InstallCommand.class, MarketplaceCommand.UninstallCommand.class, MarketplaceCommand.ListCommand.class, + MarketplaceCommand.QueryCommand.class, MarketplaceCommand.ApplyCommand.class, MarketplaceCommand.ValidateCommand.class, MarketplaceCommand.RepoCommand.class @@ -231,6 +234,60 @@ public void run() { } } + @Command( + name = "query", + description = + "Search the optional-plugin catalog (local registry). Filter is a case-insensitive" + + " substring over artifactId, name, category, description, and install path.") + static class QueryCommand extends MarketplaceSubCommand { + @Parameters( + index = "0", + arity = "0..1", + paramLabel = "FILTER", + description = + "Case-insensitive substring to match. Omit or use empty string to list all optional" + + " plugins.") + private String filter; + + @Override + public void run() { + try { + Path hopHome = null; + try { + hopHome = HopHome.resolve(); + } catch (Exception ignored) { + // installed status is optional + } + java.util.List matches = OptionalPluginCatalog.query(filter); + if (matches.isEmpty()) { + System.out.println( + "No optional plugins match filter: " + + (StringUtils.isBlank(filter) ? "(all)" : filter)); + return; + } + for (OptionalPluginInfo info : matches) { + String installed = ""; + if (hopHome != null && OptionalPluginCatalog.isInstalledOnDisk(hopHome, info)) { + installed = " [installed]"; + } + System.out.printf( + "%-28s %-22s %-12s %s%s%n %s%n", + Const.NVL(info.getArtifactId(), ""), + Const.NVL(info.getName(), ""), + Const.NVL(info.getCategory(), ""), + Const.NVL(info.getInstallPath(), ""), + installed, + Const.NVL(info.getDescription(), "")); + } + System.out.println(matches.size() + " plugin(s) matched."); + } catch (Exception e) { + System.err.println("ERROR: " + e.getMessage()); + throw new CommandLine.ExecutionException( + new CommandLine(this), e.getMessage() == null ? "query failed" : e.getMessage(), e); + } + } + } + @Command( name = "apply", description = diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalogTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalogTest.java index f93f8c83af0..15ceb200908 100644 --- a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalogTest.java +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalogTest.java @@ -17,6 +17,7 @@ package org.apache.hop.marketplace.catalog; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -44,4 +45,26 @@ void eachPluginHasInstallPath() { "installPath for " + info.getArtifactId()); } } + + @Test + void queryFiltersCaseInsensitive() { + List parquet = OptionalPluginCatalog.query("parquet"); + assertFalse(parquet.isEmpty()); + assertTrue(parquet.stream().anyMatch(p -> "hop-tech-parquet".equals(p.getArtifactId()))); + + List engines = OptionalPluginCatalog.query("ENGINES"); + assertTrue(engines.stream().anyMatch(p -> "hop-engines-spark".equals(p.getArtifactId()))); + assertTrue(engines.stream().anyMatch(p -> "hop-engines-beam".equals(p.getArtifactId()))); + + List none = OptionalPluginCatalog.query("zzz-no-such-plugin-zzz"); + assertTrue(none.isEmpty()); + } + + @Test + void queryBlankReturnsAll() { + assertFalse(OptionalPluginCatalog.query("").isEmpty()); + assertFalse(OptionalPluginCatalog.query(null).isEmpty()); + assertEquals( + OptionalPluginCatalog.listOptional().size(), OptionalPluginCatalog.query(" ").size()); + } } From 7ccdd99fc939b15c53057af1e89f2e2b8570fcc2 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Mon, 20 Jul 2026 01:25:31 +0200 Subject: [PATCH 23/28] issue #7547: document publishing third-party plugins to private Nexus Add a developer-manual guide for packaging marketplace-compatible plugin zips, declaring Hop version and plugin dependencies, configuring Nexus, and automating releases with a template script for a specific plugin version. --- .../marketplace/plugin-env.example.yaml | 26 + .../marketplace/release-plugin-to-nexus.sh | 192 +++++++ docs/hop-dev-manual/modules/ROOT/nav.adoc | 1 + .../pages/marketplace-publish-plugin.adoc | 484 ++++++++++++++++++ .../ROOT/pages/start-your-own-plugin.adoc | 2 + .../ROOT/pages/hop-tools/hop-marketplace.adoc | 4 + 6 files changed, 709 insertions(+) create mode 100644 docs/hop-dev-manual/modules/ROOT/examples/marketplace/plugin-env.example.yaml create mode 100755 docs/hop-dev-manual/modules/ROOT/examples/marketplace/release-plugin-to-nexus.sh create mode 100644 docs/hop-dev-manual/modules/ROOT/pages/marketplace-publish-plugin.adoc diff --git a/docs/hop-dev-manual/modules/ROOT/examples/marketplace/plugin-env.example.yaml b/docs/hop-dev-manual/modules/ROOT/examples/marketplace/plugin-env.example.yaml new file mode 100644 index 00000000000..9c12a1d4c82 --- /dev/null +++ b/docs/hop-dev-manual/modules/ROOT/examples/marketplace/plugin-env.example.yaml @@ -0,0 +1,26 @@ +# Example hop-env for a third-party plugin published to a private Nexus. +# Adjust groupId, versions, and repository URL for your environment. +# +# ./hop marketplace apply -f plugin-env.example.yaml +# # restart Hop +# +version: "1.0" +# Hop client line users should run (optional Apache plugins use this as default version) +hopVersion: "2.19.0" +enforceOnRun: false + +repositories: + - id: sandbox + url: "https://nexus.sandbox.example/repository/hop-plugins/" + - id: asf + url: "https://repository.apache.org/content/groups/public/" + +plugins: + # Other plugins this product needs (install first) + - groupId: org.apache.hop + artifactId: hop-tech-parquet + version: "2.19.0" + # Your plugin (groupId:artifactId:version) + - groupId: com.example + artifactId: hop-data-vault + version: "1.2.0" diff --git a/docs/hop-dev-manual/modules/ROOT/examples/marketplace/release-plugin-to-nexus.sh b/docs/hop-dev-manual/modules/ROOT/examples/marketplace/release-plugin-to-nexus.sh new file mode 100755 index 00000000000..90e355535da --- /dev/null +++ b/docs/hop-dev-manual/modules/ROOT/examples/marketplace/release-plugin-to-nexus.sh @@ -0,0 +1,192 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Template: release a third-party Hop plugin zip to a Maven repository (Nexus). +# Copy into your plugin repo as scripts/release-to-nexus.sh and adjust defaults. +# +# Usage: +# export NEXUS_USER=ci NEXUS_PASSWORD=secret +# export NEXUS_URL=https://nexus.example/repository/hop-plugins/ +# ./release-plugin-to-nexus.sh 1.2.0 --hop-version 2.19.0 +# ./release-plugin-to-nexus.sh 1.2.0 --dry-run +# +set -euo pipefail + +GROUP_ID="${GROUP_ID:-com.example}" +ARTIFACT_ID="${ARTIFACT_ID:-hop-data-vault}" +# Path to the packaged zip after mvn package (override if your layout differs) +ZIP_GLOB="${ZIP_GLOB:-target/${ARTIFACT_ID}-*.zip}" + +NEXUS_URL="${NEXUS_URL:-http://127.0.0.1:8081/repository/hop-plugins/}" +NEXUS_REPO_ID="${NEXUS_REPO_ID:-sandbox-hop-plugins}" +HOP_VERSION="${HOP_VERSION:-2.19.0}" +DRY_RUN=false +DO_TAG=false +PLUGIN_VERSION="" + +usage() { + cat < [options] + + Plugin release version (e.g. 1.2.0 or 1.2.0-SNAPSHOT) + +Options: + --hop-version VER Hop APIs to compile/test against (default: ${HOP_VERSION}) + --nexus-url URL Maven repo URL (default: ${NEXUS_URL}) + --repo-id ID settings.xml server id (default: ${NEXUS_REPO_ID}) + --group-id G Maven groupId (default: ${GROUP_ID}) + --artifact-id A Maven artifactId (default: ${ARTIFACT_ID}) + --tag Create git tag plugin- after successful deploy + --dry-run Print actions only + -h, --help Show this help + +Environment: + NEXUS_USER / NEXUS_PASSWORD Deploy credentials (or configure settings.xml) + MVN Maven command (default: mvn) +EOF +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --hop-version) HOP_VERSION="$2"; shift 2 ;; + --nexus-url) NEXUS_URL="$2"; shift 2 ;; + --repo-id) NEXUS_REPO_ID="$2"; shift 2 ;; + --group-id) GROUP_ID="$2"; shift 2 ;; + --artifact-id) ARTIFACT_ID="$2"; shift 2 ;; + --tag) DO_TAG=true; shift ;; + --dry-run) DRY_RUN=true; shift ;; + -h|--help) usage; exit 0 ;; + -*) + echo "Unknown option: $1" >&2 + usage >&2 + exit 1 + ;; + *) + if [[ -z "${PLUGIN_VERSION}" ]]; then + PLUGIN_VERSION="$1" + shift + else + echo "Unexpected argument: $1" >&2 + exit 1 + fi + ;; + esac +done + +if [[ -z "${PLUGIN_VERSION}" ]]; then + echo "ERROR: plugin version is required" >&2 + usage >&2 + exit 1 +fi + +MVN="${MVN:-mvn}" +NEXUS_URL="${NEXUS_URL%/}/" + +run() { + if [[ "${DRY_RUN}" == "true" ]]; then + echo "DRY-RUN: $*" + else + "$@" + fi +} + +echo "==> Plugin ${GROUP_ID}:${ARTIFACT_ID}:${PLUGIN_VERSION}" +echo " Hop compile version: ${HOP_VERSION}" +echo " Nexus: ${NEXUS_URL} (repo id ${NEXUS_REPO_ID})" + +if [[ "${DRY_RUN}" != "true" ]]; then + if [[ -z "${NEXUS_USER:-}" || -z "${NEXUS_PASSWORD:-}" ]]; then + echo "NOTE: NEXUS_USER/NEXUS_PASSWORD not set; relying on Maven settings.xml server '${NEXUS_REPO_ID}'" + fi +fi + +# Optional: align Maven project version (requires versions-maven-plugin or CI-friendly versions) +# Uncomment if your pom version should match the release argument: +# run ${MVN} -B versions:set -DnewVersion="${PLUGIN_VERSION}" -DgenerateBackupPoms=false + +echo "==> verify (hop.version=${HOP_VERSION})" +run ${MVN} -B clean verify -Dhop.version="${HOP_VERSION}" + +echo "==> package zip" +run ${MVN} -B package -DskipTests -Dhop.version="${HOP_VERSION}" + +ZIP_FILE="" +# shellcheck disable=SC2086 +for f in ${ZIP_GLOB}; do + if [[ -f "$f" && "$f" == *"${PLUGIN_VERSION}.zip" ]]; then + ZIP_FILE="$f" + break + fi +done +if [[ -z "${ZIP_FILE}" ]]; then + # fallback: first matching zip + # shellcheck disable=SC2086 + for f in ${ZIP_GLOB}; do + if [[ -f "$f" ]]; then + ZIP_FILE="$f" + break + fi + done +fi + +if [[ -z "${ZIP_FILE}" || ! -f "${ZIP_FILE}" ]]; then + echo "ERROR: zip not found (looked for ${ZIP_GLOB}). Check assembly appendAssemblyId=false." >&2 + exit 1 +fi + +echo "==> deploy ${ZIP_FILE}" +DEPLOY=( + ${MVN} -B org.apache.maven.plugins:maven-deploy-plugin:3.1.3:deploy-file + -DgroupId="${GROUP_ID}" + -DartifactId="${ARTIFACT_ID}" + -Dversion="${PLUGIN_VERSION}" + -Dpackaging=zip + -Dfile="${ZIP_FILE}" + -DrepositoryId="${NEXUS_REPO_ID}" + -Durl="${NEXUS_URL}" + -DgeneratePom=true +) +if [[ -n "${NEXUS_USER:-}" && -n "${NEXUS_PASSWORD:-}" ]]; then + # Temporary settings so CI need not write ~/.m2/settings.xml + SETTINGS="$(mktemp)" + trap 'rm -f "${SETTINGS}"' EXIT + cat >"${SETTINGS}" < + + + ${NEXUS_REPO_ID} + ${NEXUS_USER} + ${NEXUS_PASSWORD} + + + +EOF + DEPLOY+=(-s "${SETTINGS}") +fi +run "${DEPLOY[@]}" + +if [[ "${DO_TAG}" == "true" ]]; then + TAG="plugin-${PLUGIN_VERSION}" + echo "==> git tag ${TAG}" + run git tag -a "${TAG}" -m "Release ${GROUP_ID}:${ARTIFACT_ID}:${PLUGIN_VERSION} (Hop ${HOP_VERSION})" +fi + +cat < + plugin + zip + . + + + + ${project.groupId}:${project.artifactId}:jar + + plugins/tech/data-vault + + + false + runtime + + org.apache.hop:* + + + plugins/tech/data-vault/lib + + + + + src/main/resources/version.xml + plugins/tech/data-vault + true + + + +---- + +Apache Hop in-tree plugins use a shared component (`assemblies/shared/hop-plugin-libs.xml`) and `${hop.plugin.libdir}`; third-party projects usually inline the layout as above. + +== Plugin version vs Hop version + +These are *different* numbers. Mixing them up is the most common packaging mistake. + +[cols="1,2,3"] +|=== +| Concept | Where you set it | What it means + +| *Plugin release version* +| Maven `project.version` (for example `1.2.0`) +| The version users install: `com.example:hop-data-vault:1.2.0` + +| *Hop compile version* +| Maven property `hop.version` (for example `2.19.0`) +| Hop APIs you compiled against (`hop-engine` *provided* dependency) + +| *Hop runtime expectation* +| README, release notes, sample hop-env `hopVersion` +| Which Hop clients you support at runtime +|=== + +=== Compile against Hop + +[source,xml] +---- + + 2.19.0 + + + + + org.apache.hop + hop-engine + ${hop.version} + provided + + + org.apache.hop + hop-core + ${hop.version} + provided + + + +---- + +Resolve Hop artifacts from Maven Central (released versions) or your mirror of `org.apache.hop`. + +=== Runtime compatibility (document it) + +Today the marketplace *does not hard-enforce* a minimum Hop version from the plugin zip. Authors should: + +. State supported Hop versions in the plugin README (for example “requires Hop 2.19.x”). +. Ship a sample hop-env that sets `hopVersion` to the Hop line you target (for optional Apache plugins installed alongside yours). +. Optionally add a small machine-readable file inside the plugin folder (convention for future tooling), for example: + +[source,json] +---- +{ + "groupId": "com.example", + "artifactId": "hop-data-vault", + "version": "1.2.0", + "hopVersionMin": "2.19.0", + "hopVersionMax": "2.19.999", + "requiresPlugins": [ + { "groupId": "org.apache.hop", "artifactId": "hop-tech-parquet", "version": "2.19.0" } + ] +} +---- + +Hop does not read this file yet; it is useful for your own installers and as a future marketplace extension. + +*Versioning advice:* + +* Treat Hop *minor* (2.19, 2.20) as an API line; re-test when users move minors. +* Bump your plugin *major* when you break APIs or require a new Hop minor. +* Keep a simple matrix in your README: + +[cols="1,1,1"] +|=== +| Plugin version | Built with Hop | Tested on Hop + +| 1.2.0 | 2.19.0 | 2.19.0–2.19.x +| 1.3.0 | 2.20.0 | 2.20.x +|=== + +== Other plugin dependencies + +There are three different “dependency” stories. + +=== Classpath dependencies between installed plugins (`dependencies.xml`) + +After install, Hop’s plugin classloader can add jars from *sibling plugin folders* using a `dependencies.xml` next to your plugin jar (same pattern as some Apache plugins such as Beam). + +[source,xml] +---- + + + + ../../tech/parquet + +---- + +Requirements: + +* The other plugin must already be installed under that path. +* Paths must match the real layout under the Hop install’s `plugins/` tree. +* This does *not* download anything; it only wires classloaders. + +=== Install-time dependencies (`hop-env.yaml`) + +Marketplace `apply` does *not* resolve a dependency graph. List every required plugin explicitly, *dependency plugins first*, then yours: + +[source,yaml] +---- +version: "1.0" +hopVersion: "2.19.0" +repositories: + - id: sandbox + url: "https://nexus.sandbox.example/repository/hop-plugins/" + - id: asf + url: "https://repository.apache.org/content/groups/public/" +plugins: + # Apache optional plugin your code needs on disk + - groupId: org.apache.hop + artifactId: hop-tech-parquet + version: "2.19.0" + # Your plugin + - groupId: com.example + artifactId: hop-data-vault + version: "1.2.0" +---- + +Document the same list in your README so users who install with a single `marketplace install` command know what else to install. + +=== Third-party Java libraries + +* Put them on the plugin classpath via assembly (`runtime` scope → plugin `lib/`). +* Prefer versions compatible with jars already in Hop `lib/core`. +* Check licenses before distributing binaries (https://www.apache.org/legal/resolved.html[ASF third-party policy] for Apache-hosted plugins; private plugins still need your own legal review). + +== Configure Maven and Nexus + +=== Server credentials + +In `~/.m2/settings.xml` (or CI secret injection): + +[source,xml] +---- + + + sandbox-hop-plugins + ${env.NEXUS_USER} + ${env.NEXUS_PASSWORD} + + +---- + +The `` must match `repositoryId` / `distributionManagement` below. + +=== distributionManagement (optional if you only use deploy-file) + +[source,xml] +---- + + + sandbox-hop-plugins + https://nexus.sandbox.example/repository/hop-plugins/ + + + sandbox-hop-plugins + https://nexus.sandbox.example/repository/hop-plugins/ + + +---- + +=== Deploy the zip + +After `mvn package` produces `target/hop-data-vault-1.2.0.zip`: + +[source,bash] +---- +mvn deploy:deploy-file \ + -DgroupId=com.example \ + -DartifactId=hop-data-vault \ + -Dversion=1.2.0 \ + -Dpackaging=zip \ + -Dfile=target/hop-data-vault-1.2.0.zip \ + -DrepositoryId=sandbox-hop-plugins \ + -Durl=https://nexus.sandbox.example/repository/hop-plugins/ \ + -DgeneratePom=true +---- + +If your Maven module is set up so the zip is attached with `appendAssemblyId=false` and packaging is wired for deploy, `mvn deploy` can replace deploy-file. + +Verify anonymous (or authenticated) download: + +[source,bash] +---- +curl -sI \ + "https://nexus.sandbox.example/repository/hop-plugins/com/example/hop-data-vault/1.2.0/hop-data-vault-1.2.0.zip" \ + | head -1 +# Expect HTTP 200 (or 401 only if you require auth for install) +---- + +IMPORTANT: Prefer *anonymous read* for marketplace installs. Wrong Basic auth credentials can cause HTTP 401 even when anonymous would work. Deploy credentials should stay in CI, not in hop-config for every user. + +== Release script (specific plugin version) + +A copyable template lives in the Hop repository: + +`docs/hop-dev-manual/modules/ROOT/examples/marketplace/release-plugin-to-nexus.sh` + +Copy it into your plugin repo as `scripts/release-to-nexus.sh` and adjust defaults (`GROUP_ID`, `ARTIFACT_ID`, paths). + +=== What the script does + +. Requires a *plugin version* argument (for example `1.2.0`). +. Optional `--hop-version 2.19.0` (compile/test against that Hop line). +. Optional Nexus URL / repository id; credentials from env or Maven settings. +. Runs `mvn clean verify` with `-Dhop.version=…`. +. Packages the assembly zip. +. Deploys the zip with `deploy:deploy-file`. +. Prints end-user install commands. +. Supports `--dry-run` and optional `git tag`. + +=== Example + +[source,bash] +---- +export NEXUS_USER=ci-deploy +export NEXUS_PASSWORD='…' +export NEXUS_URL=https://nexus.sandbox.example/repository/hop-plugins/ + +./scripts/release-to-nexus.sh 1.2.0 --hop-version 2.19.0 + +# SNAPSHOT to the same (or snapshot) repo: +./scripts/release-to-nexus.sh 1.3.0-SNAPSHOT --hop-version 2.19.0-SNAPSHOT +---- + +=== SNAPSHOT vs release + +* *Release* versions (`1.2.0`) should be immutable — do not redeploy over them. +* *SNAPSHOT* versions can be redeployed; Nexus stores unique timestamps. Marketplace resolves SNAPSHOTs via `maven-metadata.xml` when needed. +* Use separate Nexus repos or policies for snapshots vs releases if your ops team requires it. + +== End-user install on a sandbox Hop + +. Ensure Hop is the supported line (for example 2.19.x). +. Add your repository (CLI or hop-config): + +[source,bash] +---- +./hop marketplace repo add --id sandbox \ + --url https://nexus.sandbox.example/repository/hop-plugins/ +# optional: make it primary if ASF/Central should not be tried first +./hop marketplace repo set-primary sandbox +---- + +. Install: + +[source,bash] +---- +./hop marketplace install com.example:hop-data-vault:1.2.0 +# or apply a hop-env that lists dependencies + your plugin +./hop marketplace apply -f hop-env-data-vault.yaml +---- + +. Restart Hop so the plugin registry reloads. + +. Smoke-test: open a pipeline that uses your transform/action; check logs for classloader errors. + +=== Troubleshooting + +[cols="1,2"] +|=== +| Symptom | Likely cause + +| HTTP 401 / 403 +| Repo requires auth, or *wrong* Basic auth is set (clear `HOP_MARKETPLACE_*` for anonymous repos) + +| HTTP 404 +| Wrong groupId/artifactId/version, or zip not named `{artifactId}-{version}.zip` + +| Install OK but plugin missing in GUI +| Zip layout not under `plugins/…`, or restart not done + +| `NoClassDefFoundError` for another plugin +| Missing `dependencies.xml` peer or peer not installed; fix hop-env order + +| API / method mismatch errors +| Plugin built against a different Hop line than the running client +|=== + +== Author checklist + +* [ ] `hop.version` set for compile (`provided` hop-engine / hop-core) +* [ ] Plugin `version` chosen for this release +* [ ] Assembly zip expands under `plugins/…` with correct jar + `version.xml` +* [ ] No hop-core / hop-engine / hop-ui jars inside the zip +* [ ] Third-party libs reviewed (size, license, overlap with Hop) +* [ ] Other plugins documented (`dependencies.xml` and/or hop-env list) +* [ ] Nexus allows read for installs; deploy credentials only for CI +* [ ] Smoke install into a clean Hop client matching the supported line +* [ ] Release script run for this version; git tag if you use tags +* [ ] README updated with install commands and Hop compatibility matrix + +== Limitations (current Hop marketplace) + +[cols="1,2,2"] +|=== +| Need | Today | Possible later + +| Minimum Hop version enforcement +| Document in README / hop-env only +| Marketplace reads author metadata from the zip + +| Automatic install of dependent plugins +| List them explicitly in hop-env / docs +| Dependency graph resolution + +| Catalog search for private plugins +| Users install by GAV or private `query` if you add to a registry +| Configurable search API against your Nexus + +| Signing +| Optional; use Nexus checksums +| Document signing workflow if required by your org +|=== diff --git a/docs/hop-dev-manual/modules/ROOT/pages/start-your-own-plugin.adoc b/docs/hop-dev-manual/modules/ROOT/pages/start-your-own-plugin.adoc index c51e0bd94fb..2d2d6c7eec5 100644 --- a/docs/hop-dev-manual/modules/ROOT/pages/start-your-own-plugin.adoc +++ b/docs/hop-dev-manual/modules/ROOT/pages/start-your-own-plugin.adoc @@ -22,6 +22,8 @@ under the License. This guide is to help you set up and start development on a plugin that will not be included in the Hop repository. For more information on plugin types and how to add them to the Hop repository check out xref:plugin-development.adoc[following guide]. +To package a marketplace zip and publish releases to your own Nexus (including Hop version requirements and plugin dependencies), see xref:marketplace-publish-plugin.adoc[Publishing a Hop plugin to your own Maven repository]. + The Apache software foundation has a strict policy on source licenses including all dependencies used to provide certain functionality. To see which dependencies are allowed in an Apache project check https://www.apache.org/legal/resolved.html[following page]. If your plugin consists of code and dependencies in category A it can safely be added to the Hop repository and community can help maintain the code. diff --git a/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc b/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc index 64dae341c3d..d8d6a5a1471 100644 --- a/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc +++ b/docs/hop-user-manual/modules/ROOT/pages/hop-tools/hop-marketplace.adoc @@ -323,3 +323,7 @@ A longer sample ships with the marketplace plugin sources (`plugins/misc/marketp == Enterprise / air-gapped Point marketplace repositories at your internal Nexus or Artifactory mirror of `org.apache.hop` plugin zips. Prefer anonymous read where possible; for private repos set Basic auth on the repository entry (in hop-config or in hop-env `repositories`) or use `HOP_MARKETPLACE_USERNAME` / `HOP_MARKETPLACE_PASSWORD`. Wrong credentials can cause HTTP 401 even when anonymous access would work. + +== For plugin authors + +If you develop a third-party plugin (outside the Hop repository) and want to publish installable zips to your own Nexus, see the developer guide *Publishing a Hop plugin to your own Maven repository* in the Hop Development Manual (`marketplace-publish-plugin.adoc`). It covers packaging, Hop version requirements, other plugin dependencies, and a sample release script. From b11d36cc863a69cfa0b5b7eb3cfd99b457199761 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Mon, 20 Jul 2026 01:29:59 +0200 Subject: [PATCH 24/28] issue #7547 : RAT --- .../marketplace/plugin-env.example.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/hop-dev-manual/modules/ROOT/examples/marketplace/plugin-env.example.yaml b/docs/hop-dev-manual/modules/ROOT/examples/marketplace/plugin-env.example.yaml index 9c12a1d4c82..58b59c2e520 100644 --- a/docs/hop-dev-manual/modules/ROOT/examples/marketplace/plugin-env.example.yaml +++ b/docs/hop-dev-manual/modules/ROOT/examples/marketplace/plugin-env.example.yaml @@ -1,3 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Source of truth for marketplace-optional plugins (not bundled in hop-client). +# full-client-env.yaml is generated from this list; GUI catalog loads it at runtime. +# When moving a plugin out of the fat assembly, add an entry here only. + # Example hop-env for a third-party plugin published to a private Nexus. # Adjust groupId, versions, and repository URL for your environment. # From ca1a471b5dcae58991f2c0f3c398b2157a413799 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Mon, 20 Jul 2026 15:47:34 +0200 Subject: [PATCH 25/28] issue #7547: tabbed marketplace GUI, projects integration, and docs Improve the marketplace GUI with Plugins/Environment/Repositories tabs, inline repository and hop-env editors, search, and TableView lists. Add AttributesContext and IAttributes-based lifecycle environment hooks so marketplace can validate or enforce hop-env on project enable without a hard dependency between plugins. Include GUI screenshots, user manual updates, 13 locale translations, and related tooling. --- assemblies/plugins/pom.xml | 119 +- .../apache/hop/core/AttributesContext.java | 145 ++ .../hop/core/extension/HopExtensionPoint.java | 17 + .../hop/core/AttributesContextTest.java | 76 + docker/marketplace-nexus/README.md | 36 +- .../publish-marketplace-plugins.sh | 178 ++ .../publish-wave1-plugins.sh | 96 +- docker/marketplace-nexus/smoke-test.sh | 4 +- docker/marketplace-nexus/start.sh | 2 +- .../marketplace-dialog-environment.png | Bin 0 -> 149538 bytes .../marketplace-dialog-plugins.png | Bin 0 -> 229657 bytes .../marketplace-dialog-repositories.png | Bin 0 -> 114604 bytes .../marketplace-dialog-repository-editor.png | Bin 0 -> 46033 bytes .../marketplace-environment-drift.png | Bin 0 -> 240648 bytes .../marketplace-hopgui-toolbar-icon.png | Bin 0 -> 7430 bytes ...ycle-enviromnent-enforce-configuration.png | Bin 0 -> 106879 bytes .../marketplace-welcome-dialog.png | Bin 0 -> 176980 bytes .../pages/hop-tools/hop-conf/hop-conf.adoc | 2 +- .../ROOT/pages/hop-tools/hop-marketplace.adoc | 162 +- plugins/misc/marketplace/README.md | 189 +- .../catalog/OptionalPluginCatalog.java | 1 - .../marketplace/config/MarketplaceConfig.java | 4 - .../marketplace/env/HopEnvironmentLoader.java | 128 +- .../marketplace/env/HopEnvironmentSpec.java | 2 +- .../env/MarketplaceAttributes.java | 103 ++ .../gui/AddPluginsFromCatalogDialog.java | 195 +++ .../marketplace/gui/HopEnvironmentDialog.java | 1516 +++++++++++++++++ .../marketplace/gui/MarketplaceDialog.java | 582 +++---- .../marketplace/gui/MarketplaceGuiPlugin.java | 10 + ...java => MarketplaceRepositoriesPanel.java} | 243 +-- .../marketplace/gui/WelcomeMarketplace.java | 145 ++ .../marketplace/install/PluginInstaller.java | 2 +- .../resolve/MavenRepositoryClient.java | 4 +- ...leEnvironmentDialogTabsExtensionPoint.java | 252 +++ ...EnvironmentAfterEnabledExtensionPoint.java | 209 +++ .../gui/messages/messages_de_DE.properties | 209 +++ .../gui/messages/messages_en_US.properties | 107 +- .../gui/messages/messages_es_AR.properties | 209 +++ .../gui/messages/messages_es_ES.properties | 209 +++ .../gui/messages/messages_fr_FR.properties | 209 +++ .../gui/messages/messages_it_IT.properties | 209 +++ .../gui/messages/messages_ja_JP.properties | 209 +++ .../gui/messages/messages_ko_KR.properties | 209 +++ .../gui/messages/messages_nl_NL.properties | 209 +++ .../gui/messages/messages_no_NO.properties | 209 +++ .../gui/messages/messages_pl_PL.properties | 209 +++ .../gui/messages/messages_pt_BR.properties | 209 +++ .../gui/messages/messages_pt_PT.properties | 209 +++ .../gui/messages/messages_zh_CN.properties | 209 +++ .../hop/marketplace/optional-plugins.yaml | 146 +- .../env/HopEnvironmentLoaderTest.java | 90 + .../env/MarketplaceAttributesTest.java | 68 + .../environment/LifecycleEnvironment.java | 86 +- .../LifecycleEnvironmentDialog.java | 143 +- .../hop/projects/util/ProjectsUtil.java | 54 + .../messages/messages_en_US.properties | 2 + tools/build-marketplace-list.sh | 18 + tools/install-wave1-plugins.sh | 30 +- tools/list-marketplace-plugins.sh | 86 + .../dialog/AttributesDialogExtension.java | 79 + 60 files changed, 7239 insertions(+), 809 deletions(-) create mode 100644 core/src/main/java/org/apache/hop/core/AttributesContext.java create mode 100644 core/src/test/java/org/apache/hop/core/AttributesContextTest.java create mode 100755 docker/marketplace-nexus/publish-marketplace-plugins.sh create mode 100644 docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-dialog-environment.png create mode 100644 docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-dialog-plugins.png create mode 100644 docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-dialog-repositories.png create mode 100644 docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-dialog-repository-editor.png create mode 100644 docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-environment-drift.png create mode 100644 docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-hopgui-toolbar-icon.png create mode 100644 docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-lifecycle-enviromnent-enforce-configuration.png create mode 100644 docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-welcome-dialog.png create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/MarketplaceAttributes.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/AddPluginsFromCatalogDialog.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/HopEnvironmentDialog.java rename plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/{ManageRepositoriesDialog.java => MarketplaceRepositoriesPanel.java} (71%) create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/WelcomeMarketplace.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/xp/LifecycleEnvironmentDialogTabsExtensionPoint.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/xp/ProjectEnvironmentAfterEnabledExtensionPoint.java create mode 100644 plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_de_DE.properties create mode 100644 plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_es_AR.properties create mode 100644 plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_es_ES.properties create mode 100644 plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_fr_FR.properties create mode 100644 plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_it_IT.properties create mode 100644 plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_ja_JP.properties create mode 100644 plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_ko_KR.properties create mode 100644 plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_nl_NL.properties create mode 100644 plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_no_NO.properties create mode 100644 plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_pl_PL.properties create mode 100644 plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_pt_BR.properties create mode 100644 plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_pt_PT.properties create mode 100644 plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_zh_CN.properties create mode 100644 plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/env/MarketplaceAttributesTest.java create mode 100755 tools/build-marketplace-list.sh create mode 100755 tools/list-marketplace-plugins.sh create mode 100644 ui/src/main/java/org/apache/hop/ui/core/dialog/AttributesDialogExtension.java diff --git a/assemblies/plugins/pom.xml b/assemblies/plugins/pom.xml index 84c35c81464..36486762b9c 100644 --- a/assemblies/plugins/pom.xml +++ b/assemblies/plugins/pom.xml @@ -631,30 +631,15 @@ ${project.version} zip - - org.apache.hop - hop-misc-documentation - ${project.version} - zip - + org.apache.hop hop-misc-git ${project.version} zip - - org.apache.hop - hop-misc-import - ${project.version} - zip - - - org.apache.hop - hop-misc-mail - ${project.version} - zip - + + org.apache.hop hop-misc-marketplace @@ -673,18 +658,14 @@ ${project.version} zip - - org.apache.hop - hop-misc-py4j - 2.19.0-SNAPSHOT - zip - + org.apache.hop hop-misc-reflection ${project.version} zip + org.apache.hop hop-misc-rest @@ -710,75 +691,19 @@ zip - - org.apache.hop - hop-tech-avro - ${project.version} - zip - - - org.apache.hop - hop-tech-aws - ${project.version} - zip - - - org.apache.hop - hop-tech-azure - ${project.version} - zip - + + + - - org.apache.hop - hop-tech-databricks - ${project.version} - zip - + - - org.apache.hop - hop-tech-elastic - ${project.version} - zip - - - org.apache.hop - hop-tech-google - ${project.version} - zip - - - org.apache.hop - hop-tech-minio - ${project.version} - zip - - - org.apache.hop - hop-tech-mongodb - ${project.version} - zip - - - org.apache.hop - hop-tech-neo4j - ${project.version} - zip - - - org.apache.hop - hop-tech-opensearch - ${project.version} - zip - + + + + + - - org.apache.hop - hop-tech-salesforce - ${project.version} - zip - + org.apache.hop hop-tech-vault @@ -1021,12 +946,7 @@ ${project.version} zip - - org.apache.hop - hop-transform-fake - ${project.version} - zip - + org.apache.hop hop-transform-fieldschangesequence @@ -1588,12 +1508,7 @@ ${project.version} zip - - org.apache.hop - hop-transform-vcard - ${project.version} - zip - + org.apache.hop hop-transform-webserviceavailable diff --git a/core/src/main/java/org/apache/hop/core/AttributesContext.java b/core/src/main/java/org/apache/hop/core/AttributesContext.java new file mode 100644 index 00000000000..c0d8dcc0057 --- /dev/null +++ b/core/src/main/java/org/apache/hop/core/AttributesContext.java @@ -0,0 +1,145 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.core; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lombok.Getter; +import lombok.Setter; + +/** + * Generic carrier for cross-plugin extension points. + * + *

Implements {@link IAttributes} so optional plugins can exchange namespaced group/key/value + * data without depending on each other. Typical groups: {@code marketplace}, resource checks + * ({@code resources}), etc. + * + *

Optional identity fields ({@link #projectName}, {@link #environmentName}, {@link #purpose}, + * {@link #projectHome}, {@link #configurationFiles}) describe the surrounding project/lifecycle + * context when that is what is being activated; they are not required for every use of this class. + */ +@Getter +@Setter +public class AttributesContext implements IAttributes { + + private String projectName; + private String environmentName; + private String purpose; + private String projectHome; + private List configurationFiles = new ArrayList<>(); + + private Map> attributesMap = new HashMap<>(); + + public AttributesContext() { + // empty + } + + /** Deep-copy attributes from any {@link IAttributes} source. */ + public AttributesContext(IAttributes source) { + copyAttributesFrom(source); + } + + /** + * Replace this context's attributes map with a deep copy of {@code source}. Does not clear + * identity fields. + */ + public void copyAttributesFrom(IAttributes source) { + attributesMap = deepCopy(source != null ? source.getAttributesMap() : null); + } + + /** Copy this context's attributes into {@code target} (deep copy). */ + public void copyAttributesTo(IAttributes target) { + if (target == null) { + return; + } + target.setAttributesMap(deepCopy(attributesMap)); + } + + private static Map> deepCopy( + Map> source) { + Map> copy = new HashMap<>(); + if (source == null) { + return copy; + } + for (Map.Entry> entry : source.entrySet()) { + if (entry.getKey() == null) { + continue; + } + Map group = + entry.getValue() == null ? new HashMap<>() : new HashMap<>(entry.getValue()); + copy.put(entry.getKey(), group); + } + return copy; + } + + @Override + public void setAttributesMap(Map> attributesMap) { + this.attributesMap = attributesMap != null ? attributesMap : new HashMap<>(); + } + + @Override + public Map> getAttributesMap() { + return attributesMap; + } + + @Override + public void setAttributes(String groupName, Map attributes) { + if (groupName == null) { + return; + } + attributesMap.put(groupName, attributes != null ? attributes : new HashMap<>()); + } + + @Override + public void setAttribute(String groupName, String key, String value) { + if (groupName == null || key == null) { + return; + } + Map attributes = attributesMap.get(groupName); + if (attributes == null) { + attributes = new HashMap<>(); + attributesMap.put(groupName, attributes); + } + attributes.put(key, value); + } + + @Override + public Map getAttributes(String groupName) { + return attributesMap.get(groupName); + } + + @Override + public String getAttribute(String groupName, String key) { + Map attributes = attributesMap.get(groupName); + if (attributes == null) { + return null; + } + return attributes.get(key); + } + + public List getConfigurationFiles() { + return configurationFiles; + } + + public void setConfigurationFiles(List configurationFiles) { + this.configurationFiles = + configurationFiles != null ? new ArrayList<>(configurationFiles) : new ArrayList<>(); + } +} diff --git a/core/src/main/java/org/apache/hop/core/extension/HopExtensionPoint.java b/core/src/main/java/org/apache/hop/core/extension/HopExtensionPoint.java index c68f78f705b..c145a789a83 100644 --- a/core/src/main/java/org/apache/hop/core/extension/HopExtensionPoint.java +++ b/core/src/main/java/org/apache/hop/core/extension/HopExtensionPoint.java @@ -145,6 +145,23 @@ public enum HopExtensionPoint { HopGuiProjectAfterEnabled("Called after a project is enabled in Hop GUI"), + /** + * Called after a project (and optional lifecycle environment) is enabled. Payload is {@link + * org.apache.hop.core.AttributesContext}: identity fields plus namespaced {@link + * org.apache.hop.core.IAttributes} groups for optional plugins (marketplace, resource checks, …). + * Thrown {@link org.apache.hop.core.exception.HopException} aborts enablement. + */ + HopProjectEnvironmentAfterEnabled( + "Called after a project/lifecycle environment is enabled (AttributesContext)"), + + /** + * Called when the lifecycle environment dialog builds its tab folder so optional plugins can + * contribute tabs. Payload is a GUI extension object (see ui module) that carries a mutable + * {@link org.apache.hop.core.AttributesContext}. + */ + HopGuiLifecycleEnvironmentDialogTabs( + "Contribute tabs to the lifecycle environment dialog (AttributesContext)"), + HopGuiGetControlSpaceSortOrderPrefix( "Gets a prefix to steer the sort order of variables when using CTRL-SPACE. Defaults range from 900_ to 400_. Set prefixes in Map"), diff --git a/core/src/test/java/org/apache/hop/core/AttributesContextTest.java b/core/src/test/java/org/apache/hop/core/AttributesContextTest.java new file mode 100644 index 00000000000..1deaa1fea06 --- /dev/null +++ b/core/src/test/java/org/apache/hop/core/AttributesContextTest.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.core; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertNull; + +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class AttributesContextTest { + + @Test + void setAndGetAttribute() { + AttributesContext ctx = new AttributesContext(); + ctx.setAttribute("marketplace", "onEnable", "enforce"); + assertEquals("enforce", ctx.getAttribute("marketplace", "onEnable")); + assertNull(ctx.getAttribute("marketplace", "missing")); + assertNull(ctx.getAttribute("other", "onEnable")); + } + + @Test + void copyAttributesFromIsDeep() { + AttributesContext source = new AttributesContext(); + source.setAttribute("resources", "minDiskGb", "10"); + Map group = source.getAttributes("resources"); + assertNotNull(group); + + AttributesContext target = new AttributesContext(source); + assertEquals("10", target.getAttribute("resources", "minDiskGb")); + + // Mutating source group must not change the copy + group.put("minDiskGb", "99"); + assertEquals("10", target.getAttribute("resources", "minDiskGb")); + assertNotSame(source.getAttributesMap(), target.getAttributesMap()); + } + + @Test + void copyAttributesTo() { + AttributesContext source = new AttributesContext(); + source.setAttribute("marketplace", "envFile", "hop-env.yaml"); + + AttributesContext target = new AttributesContext(); + source.copyAttributesTo(target); + assertEquals("hop-env.yaml", target.getAttribute("marketplace", "envFile")); + } + + @Test + void setAttributesReplacesGroup() { + AttributesContext ctx = new AttributesContext(); + ctx.setAttribute("g", "a", "1"); + Map replacement = new HashMap<>(); + replacement.put("b", "2"); + ctx.setAttributes("g", replacement); + assertNull(ctx.getAttribute("g", "a")); + assertEquals("2", ctx.getAttribute("g", "b")); + } +} diff --git a/docker/marketplace-nexus/README.md b/docker/marketplace-nexus/README.md index 4f61d9dcc2a..261d0e75e31 100644 --- a/docker/marketplace-nexus/README.md +++ b/docker/marketplace-nexus/README.md @@ -29,7 +29,7 @@ It is fully scriptable (no Pro-only APIs, no Postgres, no join keys). | Action | Who | |--------|-----| | `hop marketplace install` / GUI install | **Anonymous** read | -| `publish-wave1-plugins.sh` | **admin** (or a deploy user) | +| `publish-marketplace-plugins.sh` | **admin** (or a deploy user) | Do not put admin credentials in day-to-day `hop-config.json`. @@ -59,19 +59,32 @@ to IPv6 (`::1`) while Docker only publishes IPv4, which surfaces as First start can take **1–3 minutes** while Nexus initializes. -## Publish Wave 1 plugin zips +## Publish marketplace plugin zips -```bash -# Package plugins first (from repo root) -./mvnw -pl plugins/engines/spark,plugins/engines/beam,plugins/transforms/script,\ -plugins/tech/cassandra,plugins/transforms/tika,plugins/transforms/drools,\ -plugins/tech/parquet,plugins/transforms/stanfordnlp,plugins/tech/arrow,\ -plugins/tech/dropbox,plugins/transforms/edi2xml -am package -DskipTests +Plugin list and module paths come **only** from +`plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml`. +Add a plugin there once; this script packages/deploys it automatically. +```bash export NEXUS_PASSWORD=hop-nexus-dev # or your NEXUS_ADMIN_PASSWORD -./docker/marketplace-nexus/publish-wave1-plugins.sh + +# Package every registry module, then deploy zips to local Nexus: +./docker/marketplace-nexus/publish-marketplace-plugins.sh --package + +# Or package yourself, then deploy only: +# ./mvnw -pl … -am package -DskipTests +./docker/marketplace-nexus/publish-marketplace-plugins.sh + +# Artifactory (or any Maven 2 repo): +# export ARTIFACTORY_URL='https://artifactory.example/artifactory/hop-plugins-local' +# export ARTIFACTORY_USER=deploy +# export ARTIFACTORY_PASSWORD=… +# export NEXUS_REPO_ID=artifactory +# ./docker/marketplace-nexus/publish-marketplace-plugins.sh --package ``` +`publish-wave1-plugins.sh` remains as a deprecated alias of this script. + ## Hop marketplace (anonymous install) Config is always **`${HOP_CONFIG_FOLDER}/hop-config.json`**. Defaults are ASF @@ -98,7 +111,7 @@ curl -sI "http://127.0.0.1:8081/repository/hop-plugins/" | head -1 ## Smoke test (CLI install / list / validate / apply / uninstall) ```bash -# Nexus up + Wave 1 published + hop client unzipped +# Nexus up + marketplace plugins published + hop client unzipped ./docker/marketplace-nexus/smoke-test.sh ``` @@ -112,7 +125,8 @@ installs two small plugins into `assemblies/client/target/hop` (override with |--------|------| | `start.sh` | Compose up + wait + configure | | `configure-nexus.sh` | Anonymous + hosted repo (idempotent) | -| `publish-wave1-plugins.sh` | `mvn deploy:deploy-file` of Wave 1 zips | +| `publish-marketplace-plugins.sh` | `deploy-file` of all zips from `optional-plugins.yaml` | +| `publish-wave1-plugins.sh` | Deprecated alias of `publish-marketplace-plugins.sh` | | `smoke-test.sh` | Anonymous install / list / validate / apply / uninstall | ## Stop diff --git a/docker/marketplace-nexus/publish-marketplace-plugins.sh b/docker/marketplace-nexus/publish-marketplace-plugins.sh new file mode 100755 index 00000000000..191d2721541 --- /dev/null +++ b/docker/marketplace-nexus/publish-marketplace-plugins.sh @@ -0,0 +1,178 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Deploy marketplace-optional plugin zips to local Nexus, Artifactory, or any +# Maven 2 repository. Plugin list and module paths come only from: +# +# plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml +# +# Env: +# NEXUS_REPO_URL or ARTIFACTORY_URL e.g. http://127.0.0.1:8081/repository/hop-plugins +# NEXUS_USER / NEXUS_PASSWORD (or ARTIFACTORY_USER / ARTIFACTORY_PASSWORD) +# NEXUS_REPO_ID Maven server id in settings (default hop-plugins) +# HOP_VERSION default 2.19.0-SNAPSHOT +# GROUP_ID default org.apache.hop (or groupId: in registry) +# +# Flags: +# --package run mvn package for all registry modules before deploy +# --dry-run print what would be deployed without calling Maven +# +# Usage (from repo root): +# export NEXUS_PASSWORD=hop-nexus-dev +# ./docker/marketplace-nexus/publish-marketplace-plugins.sh +# ./docker/marketplace-nexus/publish-marketplace-plugins.sh --package +# +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +LIST_SCRIPT="${ROOT}/tools/list-marketplace-plugins.sh" +REGISTRY="${ROOT}/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml" + +PACKAGE=0 +DRY_RUN=0 +for arg in "$@"; do + case "${arg}" in + --package) PACKAGE=1 ;; + --dry-run) DRY_RUN=1 ;; + -h | --help) + sed -n '2,40p' "$0" | sed 's/^# \{0,1\}//' + exit 0 + ;; + *) + echo "Unknown argument: ${arg}" >&2 + echo "Usage: $0 [--package] [--dry-run]" >&2 + exit 2 + ;; + esac +done + +# Load .env from start/configure if present +if [[ -f "${SCRIPT_DIR}/.env" ]]; then + # shellcheck disable=SC1091 + set -a + source "${SCRIPT_DIR}/.env" + set +a +fi + +REPO_URL="${NEXUS_REPO_URL:-${ARTIFACTORY_URL:-http://127.0.0.1:8081/repository/hop-plugins}}" +REPO_URL="${REPO_URL%/}" +REPO_ID="${NEXUS_REPO_ID:-hop-plugins}" +USER="${NEXUS_USER:-${NEXUS_ADMIN_USER:-${ARTIFACTORY_USER:-admin}}}" +PASS="${NEXUS_PASSWORD:-${NEXUS_ADMIN_PASSWORD:-${ARTIFACTORY_PASSWORD:-}}}" +VERSION="${HOP_VERSION:-2.19.0-SNAPSHOT}" + +# Prefer groupId from registry when set +GROUP_ID="${GROUP_ID:-}" +if [[ -z "${GROUP_ID}" && -f "${REGISTRY}" ]]; then + GROUP_ID="$(sed -n 's/^groupId:[[:space:]]*//p' "${REGISTRY}" | head -1 | tr -d '[:space:]"'"'"'')" +fi +GROUP_ID="${GROUP_ID:-org.apache.hop}" + +if [[ ! -x "${LIST_SCRIPT}" ]]; then + chmod +x "${LIST_SCRIPT}" 2>/dev/null || true +fi +if [[ ! -f "${LIST_SCRIPT}" ]]; then + echo "Missing ${LIST_SCRIPT}" >&2 + exit 1 +fi + +mapfile -t ENTRIES < <(HOP_VERSION="${VERSION}" "${LIST_SCRIPT}" --zips) +if [[ ${#ENTRIES[@]} -eq 0 ]]; then + echo "No plugins found in ${REGISTRY}" >&2 + exit 1 +fi + +MVN="${ROOT}/mvnw" +if [[ ! -x "${MVN}" ]]; then + MVN=mvn +fi + +if [[ "${PACKAGE}" -eq 1 ]]; then + mapfile -t MODULES < <("${LIST_SCRIPT}" --modules | awk 'NF && !seen[$0]++') + if [[ ${#MODULES[@]} -eq 0 ]]; then + echo "No modulePath entries to package" >&2 + exit 1 + fi + PL_LIST="$(IFS=,; echo "${MODULES[*]}")" + echo "Packaging ${#MODULES[@]} module(s) (HOP_VERSION=${VERSION})…" + if [[ "${DRY_RUN}" -eq 1 ]]; then + echo "DRY-RUN: ${MVN} -pl ${PL_LIST} -am package -DskipTests" + else + "${MVN}" -pl "${PL_LIST}" -am package -DskipTests + fi +fi + +if [[ "${DRY_RUN}" -eq 0 && -z "${PASS}" ]]; then + echo "Set NEXUS_PASSWORD (or NEXUS_ADMIN_PASSWORD / ARTIFACTORY_PASSWORD)." >&2 + echo "After ./docker/marketplace-nexus/start.sh the default is hop-nexus-dev." >&2 + exit 1 +fi + +SETTINGS="" +if [[ "${DRY_RUN}" -eq 0 ]]; then + SETTINGS="$(mktemp)" + trap 'rm -f "${SETTINGS}"' EXIT + cat >"${SETTINGS}" < + + + ${REPO_ID} + ${USER} + ${PASS} + + + +EOF +fi + +deploy_one() { + local artifactId="$1" + local rel="$2" + local file="${ROOT}/${rel}" + if [[ ! -f "${file}" ]]; then + echo "SKIP (not built): ${artifactId} — missing ${rel}" + return 0 + fi + echo "Deploying ${GROUP_ID}:${artifactId}:${VERSION} → ${REPO_URL}" + if [[ "${DRY_RUN}" -eq 1 ]]; then + echo "DRY-RUN: deploy-file ${file}" + return 0 + fi + "${MVN}" -q -s "${SETTINGS}" \ + org.apache.maven.plugins:maven-deploy-plugin:3.1.3:deploy-file \ + -DgroupId="${GROUP_ID}" \ + -DartifactId="${artifactId}" \ + -Dversion="${VERSION}" \ + -Dpackaging=zip \ + -Dfile="${file}" \ + -DrepositoryId="${REPO_ID}" \ + -Durl="${REPO_URL}" \ + -DgeneratePom=true \ + -DretryFailedDeploymentCount=2 +} + +deployed=0 +skipped=0 +for entry in "${ENTRIES[@]}"; do + artifactId="${entry%%|*}" + rel="${entry#*|}" + if [[ ! -f "${ROOT}/${rel}" ]]; then + echo "SKIP (not built): ${artifactId} — missing ${rel}" + skipped=$((skipped + 1)) + continue + fi + deploy_one "${artifactId}" "${rel}" + deployed=$((deployed + 1)) +done + +echo "Done. deployed=${deployed} skipped=${skipped} base URL: ${REPO_URL}/" +echo "Example: hop marketplace install hop-tech-parquet" +echo "Registry: ${REGISTRY}" diff --git a/docker/marketplace-nexus/publish-wave1-plugins.sh b/docker/marketplace-nexus/publish-wave1-plugins.sh index dfe7b160b42..6e7ccd3bb7a 100755 --- a/docker/marketplace-nexus/publish-wave1-plugins.sh +++ b/docker/marketplace-nexus/publish-wave1-plugins.sh @@ -8,98 +8,10 @@ # # http://www.apache.org/licenses/LICENSE-2.0 # -# Deploy Wave 1 marketplace plugin zips to local Nexus (or any Maven repo). -# -# Env: -# NEXUS_REPO_URL or ARTIFACTORY_URL e.g. http://localhost:8081/repository/hop-plugins -# NEXUS_USER / NEXUS_PASSWORD (or ARTIFACTORY_USER / ARTIFACTORY_PASSWORD) -# HOP_VERSION default 2.19.0-SNAPSHOT +# Deprecated name: use publish-marketplace-plugins.sh +# Forwards all arguments and environment to the registry-driven publisher. # set -euo pipefail - -ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -# Load .env from start/configure if present -if [[ -f "${SCRIPT_DIR}/.env" ]]; then - # shellcheck disable=SC1091 - set -a - source "${SCRIPT_DIR}/.env" - set +a -fi - -REPO_URL="${NEXUS_REPO_URL:-${ARTIFACTORY_URL:-http://localhost:8081/repository/hop-plugins}}" -REPO_URL="${REPO_URL%/}" -REPO_ID="${NEXUS_REPO_ID:-hop-plugins}" -USER="${NEXUS_USER:-${NEXUS_ADMIN_USER:-${ARTIFACTORY_USER:-admin}}}" -PASS="${NEXUS_PASSWORD:-${NEXUS_ADMIN_PASSWORD:-${ARTIFACTORY_PASSWORD:-}}}" -VERSION="${HOP_VERSION:-2.19.0-SNAPSHOT}" -GROUP_ID="org.apache.hop" - -declare -A ZIPS=( - [hop-engines-spark]="plugins/engines/spark/target/hop-engines-spark-${VERSION}.zip" - [hop-engines-beam]="plugins/engines/beam/target/hop-engines-beam-${VERSION}.zip" - [hop-transform-script]="plugins/transforms/script/target/hop-transform-script-${VERSION}.zip" - [hop-tech-cassandra]="plugins/tech/cassandra/target/hop-tech-cassandra-${VERSION}.zip" - [hop-transform-tika]="plugins/transforms/tika/target/hop-transform-tika-${VERSION}.zip" - [hop-transform-drools]="plugins/transforms/drools/target/hop-transform-drools-${VERSION}.zip" - [hop-tech-parquet]="plugins/tech/parquet/target/hop-tech-parquet-${VERSION}.zip" - [hop-transform-stanfordnlp]="plugins/transforms/stanfordnlp/target/hop-transform-stanfordnlp-${VERSION}.zip" - [hop-tech-arrow]="plugins/tech/arrow/target/hop-tech-arrow-${VERSION}.zip" - [hop-tech-dropbox]="plugins/tech/dropbox/target/hop-tech-dropbox-${VERSION}.zip" - [hop-transform-edi2xml]="plugins/transforms/edi2xml/target/hop-transform-edi2xml-${VERSION}.zip" -) - -if [[ -z "${PASS}" ]]; then - echo "Set NEXUS_PASSWORD (or NEXUS_ADMIN_PASSWORD). After start.sh the default is hop-nexus-dev." >&2 - exit 1 -fi - -MVN="${ROOT}/mvnw" -if [[ ! -x "${MVN}" ]]; then - MVN=mvn -fi - -# Temporary settings.xml so deploy-file can authenticate without editing ~/.m2 -SETTINGS="$(mktemp)" -trap 'rm -f "${SETTINGS}"' EXIT -cat > "${SETTINGS}" < - - - ${REPO_ID} - ${USER} - ${PASS} - - - -EOF - -deploy_one() { - local artifactId="$1" - local rel="$2" - local file="${ROOT}/${rel}" - if [[ ! -f "${file}" ]]; then - echo "SKIP (not built): ${artifactId} — missing ${rel}" - return 0 - fi - echo "Deploying ${artifactId} → ${REPO_URL}" - "${MVN}" -q -s "${SETTINGS}" \ - org.apache.maven.plugins:maven-deploy-plugin:3.1.3:deploy-file \ - -DgroupId="${GROUP_ID}" \ - -DartifactId="${artifactId}" \ - -Dversion="${VERSION}" \ - -Dpackaging=zip \ - -Dfile="${file}" \ - -DrepositoryId="${REPO_ID}" \ - -Durl="${REPO_URL}" \ - -DgeneratePom=true \ - -DretryFailedDeploymentCount=2 -} - -for artifactId in "${!ZIPS[@]}"; do - deploy_one "${artifactId}" "${ZIPS[${artifactId}]}" -done - -echo "Done. Marketplace base URL: ${REPO_URL}/" -echo "Example: hop marketplace install hop-tech-parquet" +echo "NOTE: publish-wave1-plugins.sh is deprecated; use publish-marketplace-plugins.sh" >&2 +exec "${SCRIPT_DIR}/publish-marketplace-plugins.sh" "$@" diff --git a/docker/marketplace-nexus/smoke-test.sh b/docker/marketplace-nexus/smoke-test.sh index 947dff216d0..6b3eccf8d23 100755 --- a/docker/marketplace-nexus/smoke-test.sh +++ b/docker/marketplace-nexus/smoke-test.sh @@ -12,7 +12,7 @@ # # Prerequisites: # - ./docker/marketplace-nexus/start.sh -# - ./docker/marketplace-nexus/publish-wave1-plugins.sh +# - ./docker/marketplace-nexus/publish-marketplace-plugins.sh # - Unzipped hop client at assemblies/client/target/hop (or HOP_DIR) # # Usage (from repo root): @@ -26,7 +26,7 @@ REPO_URL="${NEXUS_REPO_URL:-http://127.0.0.1:8081/repository/hop-plugins/}" REPO_URL="${REPO_URL%/}/" VERSION="${HOP_VERSION:-2.19.0-SNAPSHOT}" -# Small plugins for a fast round-trip (publish-wave1 must have deployed them) +# Small plugins for a fast round-trip (publish-marketplace-plugins must have deployed them) INSTALL_A="${SMOKE_PLUGIN_A:-hop-tech-dropbox}" INSTALL_B="${SMOKE_PLUGIN_B:-hop-transform-edi2xml}" diff --git a/docker/marketplace-nexus/start.sh b/docker/marketplace-nexus/start.sh index 3ecb41354c0..bd6ad60cef2 100755 --- a/docker/marketplace-nexus/start.sh +++ b/docker/marketplace-nexus/start.sh @@ -85,7 +85,7 @@ echo "Publish (authenticated):" echo " export NEXUS_URL=${BASE_URL}/repository/hop-plugins" echo " export NEXUS_USER=${ADMIN_USER}" echo " export NEXUS_PASSWORD=${ADMIN_PASSWORD}" -echo " ./publish-wave1-plugins.sh" +echo " ./publish-marketplace-plugins.sh [--package]" echo echo "Hop marketplace (anonymous read):" echo " \"url\": \"${BASE_URL}/repository/hop-plugins/\"" diff --git a/docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-dialog-environment.png b/docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-dialog-environment.png new file mode 100644 index 0000000000000000000000000000000000000000..3dd4005ce2d8292880ecee7a8f37a17792682615 GIT binary patch literal 149538 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

DG$wSMiPxp$=>c_077iZ6{3#; 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 literal 0 HcmV?d00001 diff --git a/docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-dialog-plugins.png b/docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-dialog-plugins.png new file mode 100644 index 0000000000000000000000000000000000000000..2d7126d41be36b0bd36153193db23da5f574a8f1 GIT binary patch literal 229657 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 z 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%0A&1Q~t`1 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 RW#K2;09Bobi2ILU{xA4swle?# literal 0 HcmV?d00001 diff --git a/docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-dialog-repositories.png b/docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-dialog-repositories.png new file mode 100644 index 0000000000000000000000000000000000000000..ba86410f1041788e720759fe3ad15fe94358b15c GIT binary patch literal 114604 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

##Fm@Nm`Z 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

vVV-`?s)y~Lu_9J6=O31KMV~Il; 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 literal 0 HcmV?d00001 diff --git a/docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-environment-drift.png b/docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-environment-drift.png new file mode 100644 index 0000000000000000000000000000000000000000..c531ed1a024506c0f94ce95c84b5324cb9e7f652 GIT binary patch literal 240648 zcmd42byU=A_Xmo{gC0@9AOr+N$|0p2R74oMh8~cX9J)h6KpKXU?v9aeP>>vHh7M_F z=on&#xPzYGdwkD(|GjJ7?^*-HeCNBL-TSlm^AN18C{0K}Nq~okM+lU8rHY65S0f(Y zpWA=kz)q+oUpxB7oBO{$=gvcZal5Md9Qy*+Xh zru9Gma}N*iU2)u`$q+Jz8PuYhQ<9eU1o_{0lO~N+4+~=m2#cRj;Q#gdr zK^w>KpFX`Nuh@|m&b0YoRG?qY9PhgP&eijtH~hh$Z~y+NEYZJ6ab2nOpDW{AowXr( z3IAti&NV(NR3Fu3f|%FVEzD zl=vi(z4N~qe_j?MwrOO;qdsQl4Q|!#1;tb&`Y1epr-J9MR$@pl*Qc?+=^k0Got6qo zs8=s2r}+Il-74h);P08BWwAr;MES(a4?S?rv}PvCjzerx+ zrxO|~ea=y#Ze?bD4iQFra9R(<6~)ABC$%5BySzY5sYlsJH1Y7yuhhT_*gKsd2yjbT9eq zkju_lUEM)U`>V68oa^yU&?l`?UxnotI*RN>q*G0eliRepAyD9;3hjv#r} z_wzn4IjU|NlyV2<%s!G`6LfxF!!8%sVB4aq(X2H1(<|SFemAQ;J3k|#xR*&Y+kgt! zG#F;4ZHE2$@z{90cn(9@+G|#6fsIHN_C{5edugM$X5kaDrGbQ0b$%S<6_ki#srz!va4)RPKBlBb7+rsJOquZ z&?sFS+eTWc7OwW09HE`9ZeA(thfWpb(#LsgQWNZX1d5zHcRu(W?QvFUe%KW+!3ace zAP~BcCJi|m`lBk z-Tx-h;H>eEI^geMA*qjwdK2*BPpV{?utqV6uSj!bMrdc1b@x8y{j7S&IZ!wXVN$IV zzVbw6*^r#r*Eg=&BC4oGP$7lFQP;G;6oN^qkcc^94nIFp>&x;mBaUQ*nFmMhF3?Za z`nJk5#dsW}4B5;Vk;p=vIb@+Y{|LzRu(24g2`|6()0IfxWLB5%L_Z4`6H4< zK^>)$9VsbC{*!F2Q`PDg`^`my+Z^t(i^(s4E@Q&$-6>M`MP?(O{SIikv#U#5f=!zZc=1Pjnuh^6r=H728nA> z))gnGs_nXsZPAn6v~<6x?G$R0ZpL7R|!9T!H&C#Em9D zG+Wc2(0DxWn)6lyj_>v{{G`n-DyITEuye;V0>wO?#ufZ;6qtph_7C@mgC8(gd!Q-3clSh7C4BWI z*w6J14GmFtk^-sW;m+Yyd`6%06cbBs+uK`?Tm;^MxfSy7j0~VrR3o5bGlg(UA$j&P zNM1(9V@3uB%i}aLox@g0l?l?Jw)}JfXSoi!1mv7&CoA`pmuS@3&=Ivr_^ciVy+sei zTm&)h@ArBswHH{#bfV@;i<9_mbM_ZjR+hF(9oPCTu>HQgm!X{1KJBnhx*||z9+}Tx zq09D}w4`)Ie239cRPv3Dysy{Q>s1-GOEn0o?L%EID&c~>4?-tP1Ppwos70#ACnvOK zg;y1+1>L$!BlGj~F-O~l7w4EFhZWiVy`!-!;mx)P?b zY8=@fDX#K;veFh7qZxhg9tu&}sKeW;4|+mRdiMwH!?#yk^R)({3GCx-0ih0hOvO5g zB1*xGR-IbQ%+H^nC7P(JtH&N~&BJ!cIT5&srVJ|Zs4k)uGWwLnYn$V+(u-^hxINYA znoh=nN!KXRGu`~@XHOY^Wg50(M3MaxGnw$Cd$`cm<}rWD#|LVE9l;T=Ek*Fe`0nyc zy%dJ}KNvbF2mmFAU*s?~=C#cUJnK(LUrcnEa09$H!TZHvxE6Fa@w784h|zIE3M%>s zykPkJ7`bZ&VL3gqH~v|x-dRB>q5J@=moKw2Rhw{mGfxZ~i#bFg$MkXj2ePFqZSnTB zYWoIc(dFNvdz9VXErZ^e)*TQ%tz(Oq<7toQutA{vl28~k1w@?+z1Za6+`65o0KG4d7t|KhRXUoQ^M?^tI8l_o9pyIbb!q1&AM}w+PBiW%j-Q9m7V49ld z1Dz~_f-+DNXH@K_OQV&Skr8xb%_;g`9Qw>rsTi`OA9(baR78mK{G1q{ZCmpcddIfb z!v!n%tL%=j+R7J@K57ieDMN+Q)bL{$^#9y^zC+@~i|>-`%Zl{z7*C za%5;Iv5mw3CgGqlvBY`<4K-2FOUaicIIC)~>%Q$7Ub(6QCY6&joj>y|L6>E9(QCBj z4j$n1ixr6YB0Yo&POb4Z))-I6RdGlW))p0TAC>m_y4uD7hVrQugC zopx4*wOl_OW`)7wBWkq$scHp)_sKXf&8P8I_l3;n*+19@b@k68%H@b>y$8If8X>I= z7TpT|qXmZ7+q;{}_3sFIUAEr`sz%bxa^uquqqh-~WT8^6keQMKwfvbj0d4JihiW2P z@vPcQNZyS*G(}8(y2aX|{FMCr8k!kqiys@-55(L&C+(H`98&A246pGcGBq2&hIg8j-q9M^iajLNPM0oGM)Hyl)cAq>xy& zS~^t-JQ%woZ!_H@`Tl(_8dJ;(D3GTB4tFXfBeGq66}(SW#y4h!S2@t@v-9Yk@p&It z#Bg{$nhcFYCI{l@dj5fTG&fvQN1I(GnlYGUS$TPNW#y>6*1e*$Gp}$-$0~0u(bi<8 zX1Z_r^K9E@aGy>MXoSpWv~nOEvmMj{&7l%@R!$x(y+fZ{1{U7wx}25reTeX@_v=XGmb)XNNz}yRpV&zg*g+T&rq*12S5?gU4q%rn)8UJY)rF zVr*>B)E8^qC==If5mVrI1`b0;qhjScq;_Jkwkz?J!rcsZXMnYK0i?0OKykCAH=r4S0bGMdEt92NG z5*Jl%%IxATEiDZjN7D?zjWNjJxf<;luI#gNi0ey7Qje?|unmHjn0u$Y&gD2xSJu{w zo3Te5{q_&47RKjE9FIzjjEt&qDZc@mhK-F)aiPtWTT={-c8?Kf?N?&eU;zkeoBnaV z^3H1+)mCwfN~o7F*Q;pVk86Vq?I_2k$9?BN=(na@4TypyT^hk6F59CxRmC&7d%71| zJUC`dA8~hcdpr8k5aTvy-eA1x#(rrLP_r{pXfS5;%%#s{c{j7+yk^Kj@R7&iUjE_q z4plgq*Y3G5qF7fNNAJOQY7VH_S3}jI0+%UVHfIWhk7r@uzP*aOb!U{FK8Px4P44;g zcdI_T(fZ!T4M&@k#dRlcse<;Z2ja;v=5!xLD2aYc(+%S9^XD`;yL^?DUeDFkAD`E) z1u!y7DdwwnMbM5vP!cO{4~mq5PSw~;-u<&%e4+C+KFYM@#iNoX^BUE5i}x9Kw;PICh^ll9`CcBeCTkS*tLs` zvhph*c-IE!kcrmRWU-4*o~bGRjP#I!9h^ zOGXt3In{Ca0tYJIb`&8x9a^rGsFJS;g!U%f=27RIZ1#-IYvpU7NXb2P94t0>RY>L5 zhF)bO3wM6H0v~S=IVc&YcKk|JAD8)nWlseyBM>Y+|E6Fya@KadX`n*C4B17>>b%^o z0#rS=1rs9t9EDS-YP^FO3iY&vYISfSsLu3E8G4A?fUqz!c9f>YZ6x!7PWLTf2S;Iv zftE?923`QbmiJVPx2`1Vl}?qlIv-2v`_tCr%a+A9*=oKx#>xWc=jf#)id1t$iqs3U zA|44PZC#Ki{1F89vQkfQHTh6J89rSp~cWno3X-YVX&V+bz784kJaTw}BQfat|rMVOff)s(M~c3;^yYYo10wJ=CuUvP%zp4~4V0PRGrk2gagb zBHVwBKVCyuq*ioq%O_h3r3L{YJdH9?-`NJ}B-_ef9`V(ac$cJHTwGIUUFn$pVyUS* zi^_7n&0+I8K`#cI#7~=#M0{o@VmS*73qvBrjjdhEC#|6jj`#j#7=xUE%#DpfIJ3_- zxQu08db0v6KJ{H;I0j^6sNBPqfJy5y!c^fRt2M__VY62NP*H4uXD6kH3CyRt0X5y2K*?JGBUo72KRAdBlJ2jqeED+3_QtBqxtTgg zNl8wXmG4IUclb*ReEc{r{+}=)M8;#6UW|>~wZBn2P->s*X}umn1K53bhn3y?a@gD{ zdbmZ#vA$Mdt?|0hE=;p)V!3mBmzTe%9eVsZv|~V198~<2E41*}nB@dE(R%rgX(qXb zExgZcB%n@^ks+r~%Rcwy;^}_N|K1&Ed9{ zn;VH2GMRM&+aY(ABrS*QqFFu!ZA|Pfp{DZ_7?44Xax2|Sn-v4%=N~9XVfi0E{3&+& z-BG99!8xxSPUf3zdN(`ckF#?=tA0KF8#gT1`~3Or&jf9zs!BIJnvDxGekV`MqSqf}@xKWA$LB_Vfxq1rDe zLy>zk@&e;o+&LrEul#cmqIYW&Um{0tA;j-b*^tm4li`v?9)f0Y=Xn~RW8e*93Xc2{ zi%k!0Q&K13d}~R++KVGG32tW9{V$tq%xYy;LgwOwOlqq&DQ>YGHrBsJA@%ic2kp@I z%f^HOx{vpqQB@3uFWu@g7df6j?VfM~O}7~56VV7?bun|z9^LZ;O1MTVDwga+PiRGE zrX{Z9XRzp>AwFDEV&%aH=geGxe0n9&+tm^wkMlm{RsYRK7OL-KpM;y=gn?({NsDxH zWdmjRy4go#S_pwXJq>o^>>r`YFRnvk8A^3qU+|ds^^iD4Gtj1&v}+;ZTvD&p`PD1P zo%cRTy?*tO<;oY{u>!M zRd(wGg>Za*U$fXwaV4dM)_k|K2WU-nBw;^1V>0$<$mcn>r${W-Fn(}F7_VCjvq`Z6 z51?R4;B9S5EblSx>Q9B{?61IAPIg;y!QYuzJcny`7=X>5Xmwn5THad8r515TeR=P{ zOWT4eV_mHNOM#79A2a?0}NA7b&^6AstWsqRgu68Kf z(k2Js=*+vghs?8o;?JLIa@Y2zJMU52am!B5Zy7h45*1odXNn@8Rv;|8Csceu@_0pSi5P;(9RL7k-Ii?8C zIa9l%&Dnf``6N0ZYO*=`#^H|nI-NImmKd57&z^+qL{r}# z#|?J+a0MJf$D*C_^Wr%!hm`yDF{<*Uta$cIPJ55 z8)9*jgu<(t-AZp9&IQQcatZrhG>KzO(ijTOBey*;JzeVc4vdL?X83>pS#Us@did3| zav6!Vc<7E6@!0%yG1s7=Iz>o@>r+kP`!sEWc0V$3h@1iVpfeJ5u#wzjRNg&4u8Erq zjcz7h=8HFbHpCADIMVwJGH?(&ia~6D@OqIdBe${k?N*G=6=Y>V)|;n|8b^xe1QMcH zam_r=T1DEGfj0=7R2=8dCBkX=+H5u#=%t-k<)_5wMC|>_ia}~*mD;%PY0qWIDk=_r zG?YBt^;c7G)&ZTKoD_JSI#A+l@e36P5z`J`ww(4qTlnNbF)=@=9*795DqW6BDXhU=HWd{zF)tmasK8>U5%dS17i`;(}Z?txMr{_#;jO!dh$47~KyA_)VyiR-M- zxFGIT_vkwLQ%YP^Rhsp8I}S3Ya_w?kt%ez$F3Mbtk@i0J8K8-?occDg**S6_rjE^p zv@uNfc5hep8ufZB0P<(czMbC;>-$OeF?sRWSxH>6MlsG->a~j0-h!?*y0hDM>qzr_ zi`_5REGIHrblGP&kLNVeD8y*JnlxckdFze2iTP5R2M@9n47|ZgVtb!-J%PLD#BzFa zh_edY=Kj?sIKNAfBxmbUp1#M0b{rugVrG)Z)K$=gE8jc48z(+;Elsn!2*eX06EgKc zNupTlwz#I9U6j7}o;zXd3cu#No^89g`>{9C!?y}j^kPe@<*vCxo z;4neuS_@2?HmQgu`X0vNBEM`Z6xNi7gUyMVwTH9B5(Q3$!<6Dq9|MW07d2vrZ5?J^ zFVz_t87br@F|DrV#i!`26a^4NpJZRPx65|I;4XKZv9AVWmYs*=g!Ch9dWY37B_*B4 zsf|Z-?CJR|X1XV&Zj;vsXcK56=W6lNC5i`08*ihsHV zA7r%(_B`&1j;iSt{As6dk^GTD0I_)1`|FrugY-Gv6sgFoso8n;JB7`~l9Km6(i~$x z-ij;zDm8}Wxah*ty2*HZ9uL2x!WLeQV)yq|)kguP+St&!%UxqcfqtK0$t$gk5dyKZ zA0*nPV_xirv9`#Hm5`8-;ZM`Ai&gwF`)D+xkjMOR+&~w-&~;E{yrziW9GVp@>F)UU zZ9O! zUoL^&H5_={;TO{nY5tru##H&t*8y*nac~n25zED+23jx1!q2fq zl2{iOgR+#f>t|OJJmap2jYxK1%bsD=PQ#yeI9n6^S$d|>jy|ao5o15-EZ}d+O}uR7 zohf+%gT+arVxX{sdAow*OA=jq@oOTAmobskcdmoiA4`&|-7q?l z0tBRIbN7fTIdYU&a4-b0Hts48FVG9Onuh+p-KQt@($AkU*IR^HoTFd4qq? zF3xFSyD+;Gg}(7gG{4GBaxjM{sEpYBD>S!J-|~N>%i8F}&w{ z0Cn7aSk>6r`7qVhR3usGJG9>f>UVb3GtSeg1!WLQp^=rjrP?MTLfYt%SpI9fm7}t; zYc6v@{8X7fkWd9TeIvbl_c3l_&;9;ArJJ!YZjeBY8{0B6GH;9wtWpL2(g$8gCvKnd zZV%4fKUiT!ZPc~!d>xRnHq->FX6khew+tRR%^`3QW~Z<$bg(^ z#l;vjiZU4tg~p)Qmz0pWSyAWxUqUEbhcIkD0UjNYJDv2^k_=V_zr-Fz^D#`|BwOBb zmTeiUY>3j+zXf=~oj#X&J6(d)b5zCnR}r=gXcF-(Bcc^5GE<;r<>r1#_w_4ovqk-- zQC0-4NZGuA?eG~VIcj~#xHI!_m6dZNEC#<>ShKOk^f08O5X*$IXu1m?0+SgUj*=?a*cj990f$~xWe=6EWqFQ@bEgmT3i3; zkE=Ij8Xv&Ff1qsiuRZkO7yrE_&v?V|XCw4~55+$G|D3>rA#QKc=KmJF`uznIocRBH zw*RfTz@TzE5&mR_TYGyBl((O|q(J36U*je2>i>+SpW@kta{>3!2Qfj?Y1ynC?v#d= zld(}z%0DFhtU~+DVsN`3OOfJ5HwaNwaJ)M;wzGK_oK24#XZy|BE-GO|Stec~)*!uaEXk=)K|BEt>OPp|F|Utt|gDR?zGIuTJl3mAZI0T+4g4f|(1T zAPG&0?4h77bnhy&eL)T+V5cpMK9)yJNay#ow>RHdjtdF`xr!f#>A0Y5|2|f5MFhud zhM&SX^yUjXQ@)E}@|C4E2wT0yOi{CK!xBwjIy$fX!{ujiql?Adym?sPsYXv%nf>{c z)#0*qwKsexM149+C=f4p)Jh!SgMl zEb3(}p+Q*qCpI&8cWj-{yz5yNnT^8j2ASd0ZzQEt)LR6NGOD%L+D984ImdU9i~U`e zJN-5~E$fb{p~3v|*AmLE2R;?zQh}0CJt#GZ_cmYujZ-|?hCc$pH|F>iXK#i-<2Pp& z2S^d+d+MtDfdPQR{lh9*Xp@)M@`@wiaSVrGNy-yTz5Mvp#*Gf3E9$UksgvU!L*d4| zOxsq?u#!AZGo^$Pi@K9vLj3&sJQ$SmS#JDVdzgZd1B>ItV|L#+-2CS7f!5d?v*Ir* z(|o^cwehjdSqznd8^iht2=1tNiC;IZ_=G+cf#F>JpDW`73vSS2&EM!F?z8wo6{^Og z&U5ftD@*}5lf+GPG-Opn%9oi0>%#u{;|~TPABz8(dT1g*#^21Vm{~{1=_nbCu$hAN zx+`(gtG&~a_mblzBpAbuoSf&^8siS4&mh8YSaY#H0yVOdlEtzI75SV_!8Af39?pcx0|Sx#>UT+S~JRJ|)VIaAqyN`J5;5Sbg!EKBBN zXfd6lHu6U2FNT{Rn&23n9_UhzIIVyd%(|R{HGzB_kAN+CV-^|P9$!*7p(fmLNo#Yl z!hF7iMGN0ecXuhXQUrRo##L?obDnBHbI>s1!!n6f>VQ}kG|n%A6<1@}h&g@n1F)=5 zo02G9*YkB>a||62H|2B$!IJ8A9n2&$!dt1wGcMjw)ov?MuhFem2U%r&*i}aK(~mO# zP+~uEDefnIB50$EhS)+5Pk)kw3@+nL^RJf{ zDy>(h-qL21aV6|QpKCa+)yph5H2+7X&wD`YpXGoH@_NNq@zQvhFoeS{7%e&WK<9gNzaCo0Bf7vN;r}e0$Tu8S+ z$Jt{q9*N-tLBCgE{(PGAl8_HMswCMku95h8tl=`QN0|2v|J%r{F?X}3LPp7JAS_f9 z20AxMM%@27YZg`gasY><5G--yAHU!QU_4Pv3fq;0B!C#8z^r@Z#nf)-(dNmt7JFT6 zGiL1_n4r3shv8LjpQ@3qLE!P*jGHZKxzP(m=RA(Fuf6OZ!zqZr$Gu+94tRk0;w68u z{V;31mNKDrPgy30${G7n-%?jX)$}|yM8a7{SKzDwKi#L)Kq-FwQ>6GvGoS0mR;KH^ zzd!k9$p2&qhth@^eJh&MfzG)c&DwZX|2Y9G8Q77fMs`#0iOj8`plZhv7Vp!&1RY1g zQ0L_D*NP@hKL?_1^UbR1)oWsFzZc#TrgDDe>2j8dE{?bA!8C{PZTD9fWOPmIfn0s| zgPHWqhfYbA3I^y|V`o{oR(t8uLw>g`e?({SDG?4YGnPB7u2G(hWO5VUczZVSwITC` zDZYEM(_v*f`07whF+*wfuXMW)zpIO{*AR7=iSQq zpJGTHmuYRZ_zfIePZYWwKSg)3Hr3w)6l&G2k=t7Ab{AkA=F%E5b&Aa9qNwZGLwj0wrX!@7SOCQG* z=`Y{5@52rk{G5fMCJ)nJyf4!QT&CM=x6Bjxq}{HX?cCtXKX#6vPS$Q2NR7QT{&_y` zXFQUWT$%XQlrcAC_KUQnsUcVuoum?&qUqi;Rwr(LX-lwRMPhpxT#W)`n37im zs#WC%Or7@eqMN5Xzr8bC8#kSsR(2q$je3rT}(2B4`#^eB6^@BO)buMbOXN3H^ zj#-?Ih{{Mlp$he7*mzRD9}5B$BMMWHCD% zxKgcLw{`gNQn#SGaiDu!Q?Xj-aL~q;5RnQK%XtN<+&?)SPVJElXKpGXYw4L1g(S@x zG^t#s)jbaKtwXs|W@4ES)txUJC=b58VQ;lbBNAlj$%&#lwsgQg(}ohS2i5A2&!pEN z?W~K~F1{A&RkkG6A~VL~X{$v?+Sjb~S|V#Dr8U{c$LyUEqdOkX5H%fm{5LbAicj>T zxpE5bpB@P}+SZSm3!KYo$kPy5i7UbmQH2EdBIsH2(5l6q?2v<}jM(U^pv5`#_Mk2& zA;<=j&vAzJHygN+Ev}^<5o(0>A}lj~jJJn(^WsLAhQ{OE%)-)i)1@Yu=CNrVCwrWQ z_2?3fmV*#+43d*tctiQQ$!)?^QK@Xon?*)DHxK)r$v}}!8HA1oLoZ8T89)qA#_kWzj5h)3>MWk8K&0&SvQ?$Et->^C$&{VfFD6Y|Ikw zq=&B&(e^v(5qRsFs$@4Bs5-)KW635=;BOX}4QuDV7(!QlDajjxUPJp)T=_z~~jw%ZHfGd)F#BaxLN7hg6 z4@g%BMXDS>u3Q$(41lY>qq)NRAUH4x-<#I1KVp_c##K4$}C?DC= zPJy1$Lb`hRbSg~!lBy07Xz*0Q_u-BZF40MTO=M0PpD2TLl?LbZ)8mKIwk4LLCuX^i z&J>Bme5I@uDPF!^C7^WMu>-HMPZDtqUw3WIoCg~w;SMnFi8SwxyGRYVDa9lQ7GEx_ zV9Z7?Ev)i#{q|dTw!iP+-W}Y5&B20NMe`0z!=_JT@+7Q5-!zp9jGuqB)KD5t=jpWC zXTGV&W3D$*t4}Lxt9FtAv9zmyUTqDQ9;;5~W(L8uvoC%BF9k*6+`=PewNGP5s zad8aYb_}#!$Sx%rGY+#&s?~QqHm~*$m~72*b~kg`Qx8v;F4q05t%$wHZcx+bO_B0M zxUA)Z?0j#PK>>3%m^(0cQmS+2OZ*nHDDN#=R(6&gHoQ(YzcEROlzT_I+R*HmZXYnU z9p>O}u$K2_ZJU5biF`DkZy z=W>*D`Ut=U=m9}Si@aBcF{iNdKPQEBuPbQDm{D`!#S^e8r(LB;F z>f=coi7CNT&vuM$dW?dJr=xccFDlfuKd|igCw_jB&N1VOTxbfF>>4W>B1&eE!fCsC>?q%o^PyDSfPPo|hIwUa#h(X5?S929> z8>=2!eckL3UVYZ1TAy!gjWXS&E5yUv{;1mxB|EbNtV8=L4wA>VWkO#FF8LtH=N~x{ zgJo3P40LK4^%WCA4KLmCO$5VM9a2YIb6dYhJUl-f%90~SgC7Z>F4gLguSNCfNN!Dk zFhBjOHF3@=J1~$4n^(-KJ7={U>{tf0etC|se@1>^131pNQ^ut)vDHWoGc)d=X0OEDlszi>cbuD$xfwD@_yY zC-HU0c1f7*Z{-Q_pXIgkU*cXDS?#$&;Yn!^KkUR17gA{>B*F~y$;H`$^la*_6N6cO;F$<3|qgExt8Zjw_BGndF z8eK0`hp%l3p`uJwULigjO|}-t_2g%#=~l>FY2=*imb+!Pd^!!=-cr-eRgJLd`;O&v z!7x!cQb;-LZ8g?f>hib8eU{p|l#N$2!yhXt+&3%S9p8$>gt6jI<-#w#Qycx#8(Ez< z{}Xw5uK4<$PqR}&{Slkoyc$3 zwv7R1uE6uaLH0rhK^4>^nb|~u?koq=-kvOQAcYn|%}#<~oC7AdV*1Z~dYh{A8SReM zVQD6{z%NnSrmV3s`9N;>>X9l?t3^_AJRd~Dz+EQL7>tXY_nSe7Jtw+{t79c*jVx_T zN$u_lP^ZIn3n6vw)r`CN$+?mdZ3eZPt2|}9)80VEt6Pc5dx2h&YYEU2bpw6{QeOd zcza$5O6p4o7~cZ~Cz6i>&Mv^sVGA5FzPH7WPLnAg=>xr`okp8%;H0S*U7_1`d3mc& zbE&e5@;K5xa5aq>bzYp8o`kW6Y`HjhUjd4?v_@9@-`!N|zDuF2w_M`)gjF8F1Z7dB z`Vz9x8v-o(4RQYAxidmBB%YYqtbH+E>4i^CO)IH@9S7vsmL9lVS|Tdp6C0Vfyeg5B zzoW*WJrt^BJ$#lRVDVKX4w2P`M@TiLWJCXCbT5J&QMV`3V6|wDIp(GvDAvCg>DrdJ zqC-6^ClJ7|TpMAibJB53sH7UP6&O+>s8(%rO0dN`5wrD3Fzyo#!|tBFE{6F*Or)3B z2*)c=)ryJ`b`qy~FoB4;9L{F>&EqNMaP*rU@+!K^k)<3!{1$6U*ES^+(8H(SOEULI zihVM#)tHX6PeZn!@NDT`sla+Yn*2_qfqEB$ffKUx$gG_U-qpoinwC;RlCK^+zO`~5 z#@evOk&-3kns7Yv&tP-A!ngC2^jwQi!(M#3txb?oh0amdn>mUxc?gkZ2J$);D*PIn zx6Yj~;7|N|RM62ya^~^Ma_oW8$(Izmbz_rTgld!W#C)kC;?A#$@=cC7VY~0-srA0+ zUMKzJeOh7njd~1b(46ZTG?ODTcd9T%6eBB84_<1F119I<1tgp$#FvQzf_fy;khl5I zDwkCnV}t{fSLA2QOeLrRKiG(b?AJ%jV`S}R&00f>9zoBY*&;)V?%T#ME069KJn=cv zPkAKlycoNw*z-tPCC=YrqU-+Ki3uPjzYDayKI&13{zaMiiHM4#<0p(l1BkGh=NOQ* zWC@klayRuvCVHs@o~SbckJi;fTx2@zXZ6zt>aymy{QyO{tiS*0AJp*$oSEiug*bE8 z=9KG0;=nf2im$Cs%SI?XNEKxrphcQ&`Id2QB-(WHX=!O?I+n5(tIcSKz`2BI9^hWE zBG3%~2ELi&V=?tg?d$j^EW*x);}XJ~Q6{COWD4h%?oZ!pbO?_Fo{gNaexu1|PjAYK zteIqpsVy2WVF)cJCU^?cO(-2TYy^&ZY>je!E7GB!dOEYIzMn2(+0l~~i94OMSi_EC zMgZLP@@v@rE9xT{VSzS?CxdK4{Z<ZzO9A#;oog{-kTOXIZ39dK^ z51UDGCEq@;-74Hxvm3RVdWlY|v9sbi0^G&Yd7mC>PC;TspWL)U?V`9jXf$ySmi?NZ z?{EO~U~qX}-iFGfmm$c=<-GW?_C-0k7XKm)KJCs?v(=xUCG2WT;Pp>jzB^+bR z?_5vI*B|4llu(P)!BwI{{$&1biQETk4|onaXx94EhNhLoGw5#~J(NobI?o}ZR)|(J z3#dV51d4YOK>>9!uaA2$@6)~KDNBXl#EdM%h_Y=p*g1`fdzRr(AC8_ef!UpQi_)23=HvlMMudl%)0^HwA_)b~ul%YyZ?1`u3F z*`v$;I$Q-lto?yVwAf-DEC%Xl6NNDk#L52nT7b$n)eZ4_u0;l}65a(RKM=V%=)&wcay8((`K*QlRb2xx(2yBVR(c z({JOdu!1-{pVM;_vUJC}A~CNj+ov}1kMa)>P+PK*dn88$ zZxv$MV0A6jeb9Wurju!s+QnwZSti|D+>8wf{li-f1n4$^k|d-QNe+=Ocdx}f!=0+| zZ@e5bXg$xWmTLvQoWVCvfIn4C_PLPUqn_?^$pMk-EB_-(mt#S~I|>>V zBhuO?h9SWq_PnNik?TGq!*Ltc7SlA;5kROU%|0=#RFR$uIkq9XTtzz;Xb|et`M%h1 z(qN@nLk+#j)NPl?a&%%SMULiqi`8ex+DCTIfYrh=^LhLC$b^=B#-Zs0Wb=~7YZUCs zdubTH#1gVN$S9mgjL&NIkJ1T`<;%&&os*}iv&bb_;;gzV9o@B;JM2!kn#pgIeRd_0 zk{YP=oU>mWa6!!?GtGCJ-xClF7az{uLpFbSUI1w1X_dII%Aaf^5dLmwZ7I6zx|vzN zSBuTD$owf$*G%T<+pz#v>6!LE8_BQ2Uvjw8KWA;uscLYQ_{%>$xR+4f66u2Q;KsBI zSe)*yo$>n8dq$YPxgmWwc`)i5M>E9)e7Q^HvR|nS&ay~`<+on^i14dhznHmPliGCm zW||)HE1;we@SGQqz^HswC89N12s04H4F$1+2Xm+I@SD?fJYU`1J{`d`6BS~_f?md| z=-F^{-_Z#_BZmFi+=G3Pu!mh35zL|*Hl6Sm_0d)HyA!$;D!wqX;?AvKxNqY=YA>GW zSlHiqCr)sym)_;c@7D$E&>M0k=?H4`$sMe_`H(G}$g!E(I|~Q*VpLTbg`$`GpL|By zTnaIxG5JEV4q@kAN<4;O?pA8iG;@g5XB&Mllbp3-$8SvTy&FyZpYfGk3T3?_Jx?H! zp8JsKn(&>A3yOZ`*F3z!^DJLhyTg3ljS&4 zC!aGjhqVEK?`vgI8_xRFql6iv39T}DZu|S|&$#Y+j?-4)$|v0L+YpZ5K=-D{lg ziq=bk3x7#C*6V|_>ZMu9_84_lSyEXg1;HHXW^T+{^-S0<^cD0k@@Fq^p14Cv}b=kAh?59C|cql zbFyQuIgD%}dv)BBpaLe}{SISx*nf^(vMjfn@%=ROmf?67{YY$wqwZp~6XLc=yEM7P z)u>|e(`qewju!omY;nB*Yc&@1n*>6Uquq{*=90nxW zT2G@5GkI?$jfa>bE!stoq2<- z&**I2II)~QB-z$M^8Hticiw(+I}wXhp!T|@z^_hL-~`lyBDbnbrO%#v3uc{a6@Okf zvZVH|u&vwzo z-)BJ=FlJT>GJxFNLYb90&)bP-97sf3JbLjXf&CA0M?dps`J z?rkk)3yLi&mTis1zqSYc_|A0%nffyKom*TZ(Xo7GW1K={*>^^ZIf9Ou$h>WTTq`k# zRF+E9pQTe#+^+7l<=T)e8i;J24*X4uYc1UMBgsS~;y!}Y1BLS9!}{qaVZ>{xG(bslp&HM_$*47;v@ znxuN@IQy6Ql=kV(KiyXonzr3ccvG==OnNFnVfwV2^$p+kXp_J1$~8Eid=bCkUlbld zJc(0PF{?ScL%yn|w@s=j)_B<_9MFpaopUvYKYRR)1E@ zgkXI(xH1~7uECK4Z$q|zHa_Uw97mhjenU6lO4 z9PH!AZv2c_{@^iogIC2wz_ifYTEdXLwX8o}tmnF;{cjeKX`WOk!;qNwC6SULHu9hJrT#%h6LBkQ&*1G6-6lK z&J(sLy^hWi*+Ina9Q!OQb_@PsYq-&P&HU-YQthetEXx35jVn2}@N$*z#xQdsJ3HlA zo`y98$nW|ya6VAza||JTjcc#bUVhr^5BR~-znAlU{yLc`HPl;3(bAG7IyyQnRH{kU z=N^C}j=DYy@ZUZvz*rw?;=ytEcMrRIUs&Sh6Ru)uS#;%n0OKO7m6v&E?7y#M`gQFq z$AuyV{gWpbDq^g^-+JQ9%jo__2gY^(Uu2^X0wZy<4&eXSx3B)lUB3K8LVL6EVcP9~ zdE~2CvOSkv0C6Ihe-XQPPw1F;Lh9dN@28^N{2%gbgoOX|IF6Ycjlak1)%$LDN&o)| zish!vuN?oT=`c6=hWy_w2|?a|{;wQxMKeX<|CLR}0esWGXLpLazTLm~|M2#fQEj%( z+Ava}MN4s~P^>t?wb0^L9E!VZaHq7m6etd%Ee^rm-L<#}cMqNrKAwHwd#%0SZ>{&| z`y>CZtjWxEX6BfgW9B3anbtcEFTFD0AbB1Lqf}ApuXmi7W%xsyL-X^7Nbw>iN|X9t z`G2X}%6i*USH;c!BJ4#CaKgxdBX#dkg0gU0-v3(H%-l@S{jPHF@Qqr`1fBvcD&JdC z`h7f{@qa0?mJG9xp`)i4a^L^qgl!FMGN2T6PkWw`pU`3`_`gf;;!r6}Qc7J0UeIKW z?7W}W`NiD7hnFAFr{0=Rm+TQp@V^Xm=B}gi>C-lf6)F0xxmjdH%%lnB|9Bt)>)Xf< z9UotE&(P39J&xvaz+2~m3b`FWkLRE3rqb8n`f?^$*744ZDSIVuh5!F^p-xwS z(v%0^!M$Kn-P;^S*br_>aQv5L{`XNGXBqo{dQLC0)sju0G6$Zg9n+r2Ay7o;qX*I6 zGXEB#2L*<@CKc3pUsSMx?&%@z*Y8s2h92)tWa>=zdpIxd?}pe61atC%Oxzn=sbqiO zV$)BwBVJ$5#7;j=9dwsaXr1Xe$p~gYUA?W@joB-s$b7xuWYmi{-ivW>J4C0={_sQO zFk5z2nn+JI*(1H>$8vnNdcwiK9%GNFaPMoB#as)hVXZZ}U!@Y@bvZ^5w7cqY0LmmH zT#0_7fV~hy0qDVYS4FS3B-th$ds{l~c+ZwH+YOig{xPMp>;I;~Fc>28NcfC%EMdFX zZ1*0-fRy9)Z(n_pxn35}fQ{OU;jJK*x(4}Bo4>pf>$C#rkyjOBoBsqF97(XX)_)*!kCsP0jl@*y;OZm3B zpS`JWi#F2{#(gICX^)uzm0}s4Zqs(A7L$xcuh`;~=kCQVqR-2C zMdru;mY*gMn+He(fPQAE(85M~-mhtsFU{VNPnW|?oSK1TPfd?BN(wA4_6q*_-msy( zFY(Clw1#}mcz;O;JuoS4M;n&7z9*2)4aBxP?)5CQ9F8%x!&BIY$L1!XKRW#hx>IN; z>j;~XDrGZn7^ygK{OJ(1b7qjEgGL33_;qVY-^e`ND_$MJ9pn>Ip_6YSGn;4Hnh8-w zN#kv`BGj43`W90bIyo`1SI;rqSsMn_g|asm`aW z>-pqkjg6AL_vK*i@rU}&@{X1NVX9=SN-WYBa~)9<#sWDoiDjvRJv)}~wB$zDgq*R* za$3_!%VQUYrMi_ie3_n9jMp&~fOm;^!m+l?`K%}Q;rK=!oOtjSd>q8R0768fDbf8$ znY8Ua7~ge))RY0LXF$_pIV2R*ch!p7T)3;&+d~_89t>o#P$?$QF2!dg>B# z0^PVRZ0zl>sXlD(W$OJtEO2wFH~HKlEO?BaqMSK~knjevS3w2i;vVGPi*2P!_A=oA zr?vcZ6+AY(l`7+)u-$+)4AIQ0-T`4GftEnXFxkX4C`!(mB|B=EM14`u!lKAT%Zf-_ zo7FZz-*n#CRCD*===wesd@Gw}f7+&W=fdN+!Y}igz^U~K^H3|!RB*3jU3)r5$R_@<*#OFePi=yj{l9zl%Q=gOqsmq&dP;(l2mE$rh_oYsK(E&sh8 zhB28>5+E4dwE4v{W%`|f6M4-u4GQfiU+6P?g{M(wPWg@=0NH9|81Ub3uNLGv6I(N$ z31MmuBbYjLE4LAk6qw)3b{vol)i>J8);~N39HpGf)pr^4_(-`}@Nv)o3)h+|gE@H7vp;bD9OV z(CkDu-T%~C8#|zo+VEb8{#_a^YUkMB9u|iE?NO_+#K{7Rwr0;?%F!~sV71uF*BG8l zuDGXb-6i)LqymBXEmPINWWDfAqbC|KUQaU`(BM`NgxM_xm%fB%BH)tCP-=ZNk$Xkd z_q{CCYVyrq7ZmG7^qmlx<~- zSg!8GSKiE@2liOD?JpFet93c4P_GR=FaYjPYtGVYSjV8|LMUc$$lQ9k&^;VKCS_>7 z!gFzjuY1mMfQD|311DAttugEMWVFKC#6f>a7@&QF_ILBmcJ9=^00D!g*!pYpR{#~D z3+zka;{nzhMMI*6z-xo((~lK#TGp z!CHHQ=)$0h0pkfv>+u;%##!N&-dw!Z-rxc?J!3-sSTlH{nh>l;y&rHmmAa6%KjQgh zVHz^@(Aw8GzeT)a962?JT`2!l+O#o6?e1WddWheZmR>02>mtxmVLT2`*GS_H!WuAO zkf@+bp1;VB6n%JHUNM+9+sbTknGRoWtCzPr$-KL3!I0yGaR)mq`)1!z1F6s<-Y}m1D5+&v1g(2~fqBKjpQbl+)?Go#!3ENDzh zhmpgXW@Oh`kF)D~>x>)It;yi^YuP<}r@i`-=BW}VJ}I!qyR)^y?jiI0eSOaBENgNS zE$yiHK%bv^M$nR?n_SI%hD^O^{WVxd__Cmo*qKn6sA$4Zsqqo8kJwp!z>gc`bhf7n zkCp4|K(>j6WZ*r~KWW5JsT;N@_s5qw;(gWeYgTrJ9YELX&tD+EoT=;ximf*6cNgFB zry_m_-Lram#L-U<*3hwq`Ifb4RCwrcw76qFAz=EW;`=Bo4tiB7Go|)wvx^b+WhGpv zoslS1K5re9Y$y`zKK3j|9wd0tmMDC*8uHBRA<2EOSUr~rI2~h%^X^~4b^F3># zi&nt|k1+V41jswbvY21jFHLAmz{z$dvD40QfB7arn~lXGg&=gFqs^AYAvhqBVVcC1 z?d-9FXNZ94B~v6Zb87(Nhjp2+_Ur3# z(Qz#Lq=*r(KkF}}3#@c``6%iOV85t)C3vH}1bmKsQ_Q~CntwjiRe}*l7a+duujlgW zi1r|^1*lKdsH{QT5#_U4r#gIvN5Mv|uujz0wmE3rH~H&RymQE2d9JkXT5%6b@s}2c zHoJzry&tUU@F{aqF;fg9V4YfQGY&!1LEN7AyJ9<#8-aY;?rKxHo^>-H&Di<8sw*^& zq$%GgS#)|4?F}Rk@R7pnkM%MM8DimuCkZLC?VITn)z+Jpy4sf$4|$Hu>tKb|Uh$Qw zW|CA~?{Eo;8y0&N;y1L$o4Vukrk`*&`_4cG&bl{oj#v#N-7n+*SWUkxxAVn+Y;GNj zfJs;b(Szm3a93@~JfnUlnf8W>yroYL4OiJ+8LWz@Vi>#eXgPk`-r?h5STue$&0I;X z^900Jy@?qaZ{V-T5$q{8sz94Ps{3URVYI;Zi>L}$a5L%?oFBLymdrlY;c5)fikU7P zjEJCnDZrG3=fc~9^aVrp^^D!?kAA#;2f}@}tZ7^rc{F03zcm&;JY{&SpVE8mef^5u zcREAyrR(;QHeq7JA`?bZt64WpNgpwAN$#jV2jeRoi5PG8nO?sdUFmO76+7jg?1Qu# zbo-miB!2F|nTK5Q#(P9}B`}R&C?}FGmW*{)BJL6!i@3ZPMD)I13%dYsMko_oY8!0wrnP);AldE!C2jH{Y1;1dvz5F+uR{#7AZ06QsBKiiE2yf9sto>-j#JtF6^_hHOydsYpd?ADKA*F|v51q4LZ|I4(jk!=o+hh|^vf zTtl9H)}HfrB*((w6^4eE=iCMn+ggfzX#w)5>*i2cs>5DK4c?tVjdm7t&(qkUMzFZ0iYhQ1B- z?n88Es1l=g?q{n}w5VWn#kBfuZ>R78vfaq2U*51TuuMe=)hmDlkHDx&|0$Tq+XA7K zvN{`g`kS3}MIa=neQl=>un6`dQjJlfx^#m^K7OZQqM8v%Rx$$Nyqfz$$0A+7=f zo<(Epg@~SXdav_ie@=lbY^IY_zl3O%IG(N8)O+ux_ny>sFDvHLk7#_q=`TqqxE$oR z{vDOf^<~mMM~t*e*plfdO}{Gt8}>GrdaIrKqSw76yrpH#CAV zNIZ_Dbp|vGDC?0%&YEj-|J%GhT8zr8ieruc130r?DG%or;r5_xx5`yDuJ7Hh!ZQ zi5C#lS@UkVQ28{<9Q4F*~@RIOJKla?9 zHl83v$PgChJlX4x80^*}K8z5jNcmKBbfpAv`wAO6;g#{n$5d`#yRLK%Ol$SJ3B#2DHNpaqv;$7D?r0#?AJG}; z>GY*<7*!Rz`$!d06vRN!0UFJfpzal}0TE^L?9XyX3~HCz?&}Wsw`PlmupcamQ%(yH zeKk(`dlS|EsqXO8^84wu5imr)w0Fvylw~=ZKuAVV&j66=X(sTJ|3^s5**FWll^52CO2%Jyn4I_14BG4kf*g*-JkEtu4ZOI1u`V`2^7T`6Uk_oQ(Ee<(1VNa_Yg1r`YY^s`Wc65KwdY4y0p{KIBzQK%Q8avhP&xE{Ovq zDVx@cJq&RmlYtg$KOjimc1uLOSDVDNP;G%y0sbO;d31L1IXuJQVv-%+cohU@nM9;% zzVfQRGsc5%H~0Zhhq6|wIy?+Q0y*jwb0*Y37h|?g(q{p0% zcMk8E6PxR4O-`p)?77THMGyIxzI7jHopBxhomk9(ZnUvIZAeqsn%|!mbM)f0huVv0 zPQaE$0a<6RYz;?9l^S>V#hLd)XFRk34~iN{VAx?<#|~$k&rPfV#wO4t(@n3)Cvtc7#6dSMW zI*a49&fMF!(c_QpfyMlhCy#;^Vso*i>U!`cb9lg1JN)*CVpghR_dDLvu1lS#(VUKz zblBte3^^m>Oszi4CrS0xR$dpT-&h7!6|LzU8KqeJ$=hzF9478fKNi~6=KMx=?LxFB zZrf;iZB<_n5Tri-6ml7_lYR`zQ}E_Gf>8IN(!fC?clTG?#Qspq7Aih6*k}E(m$mV8 zA&W|1xT9|5f4d(-V)uXaBWgbA2j3x?&+ z3~;@~95va9#=A&$g#iOAEGU;okK><)Q?{NqMwpT!_FY&TJP_&DB))UNzMsjP|CMq! z-sINaGf2SpE8x7G$)HerTR;(BU4NkT4d9i~XolDUWF^ux$Livz523%Jwor=kKj|im zz{yhmZ>V&(C<$t%!#!pShyH0(qxz6Yp01tRiommh#HrQC_=L{U`T&%YADs5U#CCG#OfUKhNLIrsnzs zx=n5(PMtCK%4P+u%vQHO7iJdC|F@5`-tEzWRFJMV$kU=w9FR4AuHBvQ*nBK;U78X{fj&?&hZ=HWuT zPyl}#eil=MU{eA6$IF5cakDHOT&15Y_LO4~5LthrU3nRUCD6CeoIAr%PWo8h)YP5& z*psE6L`%Oaq?#}6c3H|gtjTE8sczjUfL8hdPE6E^i6wNt=G#1;5G3PvR|3bQ~KL$&vLy6bZLW1T7YN3%6SxX|O$DK<_^ z(c6g=PZC{i{2&q(`af8qEixuwWYYnbwh02$#~N67m*FdMhX%y3-BHs}ESGnmIlB^S z`oXL5iUgtD$GpUW5BQ3$I4{Q*`UTFEEGjJ5i-6oZp67w{eZt)F&Vl16N)jU~dc7;x zdJV28Nm%y}15{`e7gz5C4P7xQk_Nxul0xW!s#+0MTY=Ln|Edk~H&SUoXN?b>$M89W;RCj<})*>(r4Dzg2`^b9?mem zwPczu+TyaJ9{RjV%(}N7L4qB`WX@OJnWg zed*(JA<6l@mwxN$rFE6pjl*0El5E+^&0htpxu2F<^*B-@*M-(v6H3Rw)Sd!)-M)I* z@OQ95N9Dzt>F`o5myd7j{Fp16*R%4=CKTqy33VXCciz}XcNP9n#nTU|22M9{I7q4vgTf=KP3JdDv$tl%htPM@jen!>Ffq?`PDoG{@ zCsTf9`}Y_}hm}(l?5u0@&l9gqs)BaxZkmu~#g^)EC)$fK*Yo64<9gH9*Vs!!Rm2&^8?y$ zhc_p$&9S(j-@~c@fNsSxn1R-f?JRTj;N#?*^1iLLa-!0AV;CjdPiX443i^wJi>s&S z75jD~2R5;6N?>n~msoE!gu`r4UZ5WTlM)oPa<^XN5ARzR4U*+N)M2rG?Vth@Oka&8 zmHRxo__&Z|ARKBOuV?aYs>;inP7KeKak9qCJPW+`3Zd94rAVQ4+j z!^Ona0l`b`BkG#b?ulN5t83CfX>Z~u1ua9X6l^>YNMz?iS>`so%DyVjyfr*i_eED* z#hBt7?Nk7bY+Hga2)vZ7q1K z|ImETCS(;tCcW%=ec?GW*yh82)V6w7qv~>{%gDdJ)(*lkn)o~RH&;&sPVx5lw`~@I zw`EIz={h^dS30NozW35PigcV+Az^q>%v=jfJZAZWIYN<{|ou3Asmb(&cw#@*)rzUSE=NXNR z+}`B!-uJZtMgmO_k+FIfzjdJ=?mfj?&gH2>tORkQXYMty0%E`TB>#8BlUPG<&EiBg z{593uKbX|l#o~M+SwSqi@EcRhZ*{B+rUZfE(j2n#f<_z|Y?AFIg?FT-o ziZ|^KH@qE$kYNhFqHl3O+(=2d37U2Cit-8`+R!;<}68cI|(!&P{( zbjLH4f{`-n9p#IVwGZu5o{Y|$hA@*rk}{s1C@83x70~baA37KR@^~_mS$pjc2@jS( zN*fkNQ*}5qO_xjl!2dXQhcwOQb2dHn zdm5-!HMgB@qX|XF$y3ermMWboIKok#tWw2WgAa6&=G+o#3Mon1KQE>QQhebBE61iW zcYj5F>5{ha;lu3GVsMW=bP1tE{= z-r`g!+l@$Ylzp@)HH``MdfmX8K7JRek=E{xF)*>X-;MQ6EqN_e;bm zZsurDIP+DA*2r+V(U@rV4tf<|$re|qa8s(7EEbGweQ9J|j9Am-wJ|F-My4ow{E`Kw z_$Skr$}(_ni$=T~IL(nOMl^po&$rAQ1&8aa@A=B8v}kJ0c+2|x--2%^O5ebv&F>8c z^w6~qJxvF99uL;qg<{`qM#Q~joaE)cbTH6lHL`+7DXJ-?%Gk25Z6>6aUY>S84+A34-7WRT2}{M;B5khG5!1_WiGS&y~C8dx81LSx*?3Dr0d5lqBI^;Hjm z-wIXux$~aLb~NLE$tAqc=OVLD7xW>Shp5HNpu(oNbITltIo7SDD!@9VdMu;q>I?QW!=>=3|IpPU zAC0ZvYpu69>?a7F!DPj~#yD0Q(bCV(JE{I~@@rDVcl` zL`;#fz!Zt!0^WbgSJ>3*Oln$2V0&!P`-MdC(6a!@j-iX8+iJt=v~q0F91|cgSLmrE zn@BFKTQh_cw^XYb)8D&$)tn55Laki%s?{~Bh4CpF-)fb=!qtj<6f3TCQS$Tk8UCuOni8X$^}uX@1Q7ku{C{v#sS zEv_foUT!DSt}pt%c0#OAcP0ZCcUUv==YF!D1^w6vIK+2)Sf2ga)l3Fl^jn;r!L?KF zaGFhnYq;GcIpUIEpUR72ERbcU@!PAmGp!Aas%FtgHDJ(xC)cG#qB z^!tQt1rSC?fV&q&H>F^@VUGvx49jeU%_;7`rjg0cWA&juz?5NhwzyG+K(D`jcaYGN z!z&>iiaF_9zv&{K6E9HJQw;HAxL?RCw4B{(2fW0@96W4QQKT;`!dte@lCMEVm34WI z>>XE8Jv2DTjJR`Z$N_-KUWA94Ak`<27Zcd_1&VLQ46qwWZ0U;6Bfpk{Qh;`5F`DuJ zlMYi`pVdS3n#7Ye$ebLoyN|r`G#Nmo>O; z{o}sjqinm739`zUt21RPj7EM{>tW}<>|_DyoedtROhxw->tr26m-6X39R_=vs0wEs zlu#7l@NzmGN2dy_LxB8qv1xddls{d1_xB3#)idyW?hif};MqBYmhhNu16i`7m6MpD z%VqSoY7I1@nL(We9vq$TetXemh~R*GfcKWRA+p5P$vXcw1{0zx?XJn!0&fF?p;o`J zGz&xu9 zCnqulqekTUg|exAKB_-lU7F}Oj*H{G`(7zn6+lfBV>EUMGur*mdidsZ8>ay7U0B~% zHN=tnbB=wE52!_7r>j<_CSV-TU&M#ozTsr+`~qOn%;unUXmE>36Jv8&M>n)0nv~vB zzFGeeQhPWZdq^;lG;0h=6Bo1J=wx)fRr6qtVrNGcmN3!* zSLd}K;AJdtN!oQJ*q5kea0cru7wAQc2V`vWvf++q^hbToEp{XFO#Fvn=4PZ@@Be-8 zk3z+{c(6iOUmOi&eFQR9g@eJz(Vi-@^v!JHAdiGcTE2gXK#z(zEObBO!_-8cYe8d2 zZH%aD$^xZvTO!0TIF~cX(=C~;LRDlcWfMKe z>qfr5HXb!AJ8|M1Fi))QJnCyV6l1HphrZ^NK*CXE$@JzUPA8qus_zZaT$NoIzFPi1 zD64ayxf{E)UeIGxQ^i0b$4K4m#x*7A0=1OKkt>VWVJ;Y)YDo6Uy(1y>i&j^y;W7Ne z7I6jNQ!=^{@zYRA*ci^%8yW({Nqly{cO#58XNQ(u7txVpAGjOU@UK%~g8F;$ z=A)3)jf`c`_AJf3iy$hc+8Ei*j0EYL=pd9pov;QS6}^sb(xoO~iI?BEEmZ3Zarg~2 zZ4Y{l0*Z%O)E)Vz(yu^eg6HI^f)0a2k8&yKWdn|tH;M=5D9Yy;%*b5Mulu|fv~`r| zb0AkySoe!~3K=AHNo(i3pA9^*iY(KEp&o7|SOakzs`G|D5dy>s4rHI|JCb1NGBA?N z(LPZ?C99(dqYvD}Tz4GIftI{@fm~Tt(@~Lbwc+a8+po6zlnpCanr`78mlmoN5_*EH zJl?(1x~9rAgpdM( zab{0=QcbxSnE2J-@7bD0`4OqAJ2iwbPS%6cJIj7#wjTMTcCiRR*J3MPn|;PY`cayw zqu1Pr10E0Y+Od4CS5x&b{OxG`OPn3!C{?;pMk~GTzLBscSPMPR+^|(P^IERzSbAWG z1|Pa=vhqfv7OSxm6Fkem`3-`~${*IX!fhomFIhSW2bLykBS++Glc;fBu7f-x9->nF2@cOD zvd2i2B+ z+6+d1`URxh_E|8qySp4(m1>p4shi4DFntJes@EX7%O+Ot`?fH5rll9)$Ip5)epo@#_1#$tPH-Q#$= zgvT?qmPbzfTZQU8i8`7bTcNBqaZ7w4el4QQS6;^IeKX*3EuwqQe`HGcKUw?#*mue1g-g%N2 zjxPkuYtD8rVKXTUGrl`qkwZW+n;M2Mu7d%_#MfyQQp^+K_DGbqC4#cMzxk z6b_?4*0V&lU5-%)}gW`<(3R7%08oOzY3k#6Mh=jZ7CB!B8$ld}HPh@H4} zEnfR<1AlR5kaZ5lv;II>x0Q_RWTgib3}Ns|E&+$C&Kn<^Z@ck3DVn{#rtET*Q^4-- z+}yXKITY&n2{szpF@~uX(OoKDu;ETTeE(kPFxq%}7l$_suR(XC&`A=PZMd5Id}jZ%Pg>y%O< z{`I@O?ldv4(^}MS2>M(k(Wr4!$NbJ{1_M~s-24S^u6YY%trPzDNa^9jWC!Tlv}TAy z+{9CY@l9hDcjSSIlKKrr2uK#bQOnQP3=hK7*~E74Be6tO;c8n{lWw$+&zFjE)VTMf#Q9dV z19ig#Ef0s?9hA)caDHhN?Gb;kk~0J(*eq7znDhZOTZ^M^+xP(+cK?S?=24i*P?q0=jxY&F7$%^rFB4Jj|k zo$8fy#+~%<(Gf- z3K6`jTwTI_89SNp2d>J=DDE~-SdM{HOO2KKpx2^H>;;^r0 zYgA*`?4{dhascxKp+jT;i?KcbyJHVD5HVn@8M31sQfacm-{J*%9CW57)6Bhdlh zhAKJ+rnYXLYP=wS)rcNx1|VKu(;weFQ=P8XL==+an4{1%KM+dd6JmJ=IK)f57Gc)@ zOh`n55+6k;jfQ+MJLz|ZocIGYwg#aI`N1YH$KUd*G-qB&h)D$CwYSy;@OlefB?D_Y zZ(if&n12oz{*-btz{!<$$X>CP;I+2#dpBfVu)l(!-NX=-Js(Orkj`g{N%4kCci3a| z`-J#*)3V5P?H9D}k3A6)V1-a^!-J>wr;CFt?kgb)D}`z*PL}V=NA*cgU&}UVK@@Xw z?@{whzKjFmX&16|1{4SqjL z;y(rnOZl(QFv=nH{x;A%Yk&R+ai^1&Z-*O*Jp{J{yEU|yqI)H1 z-$g4FFWny_!A7+y?+DnEVLUg%^r)f$xIgVRPX8#VsiFabFzb+zNV`$bw3zEBEo?kNv zRwIkawhw)4Iohxml+(ROGcIQz4Q)s}Ia(O0#S1K&DzKK*c5J+{m3Ia4 zOfjLng{I{p@5zUpx2imdE?g4CnL7C9{R`EOAXAG|vr~BX!bR?V?8gIxv8eRML}L;k zmuLg$I|q((^|prZWThPb;)FXsnN{DN3)$$$P1oo5sn@6kz8b~8f3tZeYhoi!?nyql zk7u;Lv~H2e;hSR?cP(WY`L=<>oVGy7}s3b13P`%A1* zsPFW29l#Rs}y zy)WOT@hnEtHzF)uYDgUDH_krL8tqTnkES5}4#%+yV?&vMKc8pT(73yo+#FlLL=|SK zh=jdE9uk1O?mfoHrihF3;)n9aX8IkH(cN!7Qrokf=Nqw%rKxPz*AV?h*Yy|HiBsJ0 zp8s%)jZiVB>cD8zu2~XKgH?ra2`hiUu(Ci^U+o4nt6nbWuD{@QR=nXAiO@pOOG~)@ zM_au!Ur?5dn5u9x_cR{&SsfEu&3Ww}<1OZosv`>Op!X31#?(q9=Zq^43r8ytY0t~@ z1IQ$@VRd=SRVKK&V;O@D^YMG-&6c(RxT6(LO;Unw*ML=5=XfN;7MT!V)I1YzK@@c3 z!_v~(or4D+$caEIyWKp^2Wq3#IjB1xJuf;A{stBS7Q1z5vwUeWID8zRKN=Q8;e!9M zS@V0z?uUo0M0tbFQ@LSZXF_Tsym=3su2Nb{gEi?bK${6C=A7S%JWuPiHNTyx#bP=v zfqCzhz}(v6)0@K&I92*?uCT7yGg(L25w=^M?4vJIIz&>O^;<`%`0N39`53x<7L=?} zi>bdWA2&rYFs$Otolfv$T5m0daV8QxI3#S3ctMCWRm%4>v8+z8j4VU$5LqKU%kHGr zB7qbpeqXKlz$QMlf2>op{p^q^TNH(G|+t2OfLjPw8XXo1UBXB!YaB~jYWnNP(a_Zx| zvy|W1Xx_#(Zwwbka_Qx^z5-G| z`;TaymG=ZLfm$>@&rHGA&}Q}dv5kgY0j?q=tPIn{std2(GpJnXzet-f`u0VONn-1U z;##&JL&bGmZ{qFKP>lt(SQZvrB)+t#dPq&^1-a%Izj=psY< z#SYYba3Pd~!PAc!1CxT$h%z7_Qye!hywChnpZVf)I>#dr4I zY1@ga@AZ-F**LqcrdVPn5^Fk(wUCDcjsARv#Rgmm?m3s|zEovmwduuC$QM8S$$gw?*f~cPNO~Jk$7}r2f&!f6X}Nfu_9x>sOm29g=3a1Ax-F?1+xM86B)#b~N$w@h;XT`2g6cAzEAGDCct2kpM zLwUMRx;UOXUDp|{rhLUoABl97$fX|N2lyOZJO@5o{6Zy{GR_>0g+SzB$sbiYoH96X zcjw-&cm!Z%XvfobCVV;$VQ0&RiD?wDZ+-qP0bc#vZhMT_@Oh{>8e~U(m~2y~x6@)% z44zfFET%t>(Hn2IwI6CTRpDML{Ve*3NZl2LV|4V#{E}xi#vULe9y3g*`gJ6fR?uwm9m$F_7i^W-fjkL#e1TzJgX6L$7Z$N@_4JqP@t z`+z{gvW_gjiW=6tz_Qs=Y3?z0|OhCFaOQHHc>nQZK zII016bn}{(NMybK-kk9W7ttJN?)%T>rcC86yYH9y%axM{xlkNUR28>JFFqbGz3CaY zjMlBSl6Xb(NCS}?6M>jdt!Mmy?7j708(Y^lPK%WmDQ$6zlmf-wt;L<?ddCQ#g+;0{U9H|L!De(rOg`~7~t|G=9ch8;4qXZD)C*34S_TGyK9 zRx%a&_=am}&BLtBrs!9Px0E%SG~dE*Dusy8a%a&W%A#`9>^a@+oB^y>dFZefg_Ixp zW~JZU;QXd*R`=&KV(BkAp+n==tLlGb#t)a8RDZxOxd7IGd(@#k+oF!0MP_aI7 zdk2xeV=`H~v-LBZ`9et&Txt6faM`Cmc`Fb{A$8renAb|l#jJm*4+YM2AUk0vz{#P` z9`+=1Bvdv`s4~841=A(ylFYKEVobWHoap%Xjp@&?)oF)|{z(-=8xJn3biNIC!A{>c zDCaq&XkDXk!U#leA2>wrbz9xF<+zL%Ii>St^O(E7tN_O+cegcQ$&a-L;G+5HWEUJp zb=b{gM_x<$J6UK%!q?+(oZ<`zf1tp}Q`w*VFN>vg(RqR$RHCEJE{wl0Ii?e#Zttg- z*e{R8+ReRE`HdN9kk^WskS=pDaZx(vF5$D-hg%z6y{&K2 zokY$w64TPs!b_!rj7<4DA*Q#(^CI*{qRyFo9o7=AM1iq}DAiUKm&KsNwy0TS5ZYdIKcTJ+p|9yDzIP4#8vV6}fl2&z&Xl?! z$4Zs&^?0N#setXW*nbn0tXJF0dTfTp(i;rPCc_N4i#J}ZmwroFAC4+&q^7#a?y_->T#X6x)Tu=&qb^@zR=jZV(hAF3DrzETqH z9_nPo@q>{IE)a+o!M4|Kl9+B=yVn(QaBd+qEYY&v}Iu}ejzDH z3upgp6n|}xwb1|i!75KoMw^qRmvAaAvMYoSH-U`}{BfCg7R**w=$DIce&-I;PM6bv zr>#LTSI+Hs_duRfQDyvjBz#xO>+BV2?)sGB@!kabD8(XPwZueb4fm6ErGK6kh07A- zOJ5Qm;&8Hde3X6)lJ3VoSZq*s-jnb+R7w70Vzpdl{5AT2ZP$m_IyntN(sIdt*>4v+ zAe%DQIxhhL0Mw9En+k-xaFvjMk({s|dHYYQ8ehKjItMFJX3?nsF|GJrbT3{6SB|`m zJH*={*z*#zTU`|n+)JHHKGppH?&-vJSy}ZnSf3{{a|INO$D)6Vx`p-^(wEo|Y|CY!9T|8Zznag-yEm`Y%FID0A#PJE1 z_rric9_`>;R%a`JxY_(tbc{{&B}fAe@2t#SSR{rTqRdg(4Ac8w zrFv{IsVjE13_$>tl%C0!feU={FfA?ZGV=+G+$G}g<^a(ji-(8LKH4N0=W6ve^Q+D( z8RH9gGk2|o`=)uX(LJo7>~a`ISo%f&6`lRpba`k|GxGo+pZyqppu)FQYtzgKMSJd# zRTb?!nI^ARNM1Dg9z8Jf+6o?qFpJ%+k1`Bppag=3uPDaGah&g-H7EXKU~+afGs^zu zYMQTJyzu=w*C@hZ?vwQ4n+2SGKtFmj7B?qPvqVre@P={k0w4a5BVW8&rKefyRg~?X z`=p@LCp5xXNV+cy*sa9PO8h6=Q+LQ8^Kx}POe}2Up+}@tM)yt`$bh;gWdDi?{t7S4 zZ%I}szqsl5KNX`JSQ`@`p-8Bg5tID9#Tu-xth`cK*OGRN;K7i-@9$gC62eqhjA2n_ z@P4654D8Rxct!qC-8rU4+oV3QdPzyMyIdiSPO;I`5)OpbNTt!yDN$cw+f|>EZLc+U zGserjyc!DyC$Gv!9TP%Cc>##UnF^SSYJ}BPatvB}1jmI|SvCJ_OxO>-(5ji#E_0Zx z4}JsfM=2|-LEdeui)Cjj`T60rw@YFmv9XrP+~{9#wz|h_>Xc~b)GvUJcNh@vC)33L zTb5d~fAyCwMC75)`Xy33?~z41Mi|h&Jvdlq%NvHNN_~|HO!oOsc~1Fzzjy8d!6R=d zD{pvLXR;?7%4*Vsci#){^pElPhXkA6_D8#2wjrK!)z-OhLLiNo8zk1kDe;3Tnqh)O zYRh$j8`FZ@O7a0UAs%qvl&4%G=21NfH&^kw3Q8JmK04E-dhnOL&j~FxAPLz8@9qE~xIePX|V%|#{9oioxt4XWfMK?#Wh zYGoyIov0ESdsV8ub&JqG$X}PRRULa{>&J^%7+VtrXVT+L?}`HoxeaC57PVDYWKQi) zip^7Qxi6Ar`Bi$}P$u6<&WV(KIXU3MDCkl*8ZcC+73qi_c0@ULnrxN|zfMT0ZSslu z-y^4+?ulc~3O~t#;Er(4-u;Mqn&QDV1PzQp>>N&OffJ5=@)@|^0{FcsJ@fWTB zFVO_s9_mmV(2%Hlj`%^QiE!A*9!SoY6J2|Qc2#HCJ?gUkzckIhGMz`@PNUD6_zXvEL%uZrk6IS{waL02E=^ z8Rpz8qn)1=rhdr5smT2y7105!0=Be`PLnPysbm*Pr!Uxahi`9oi56FpE0`kgQRNUd z%=dmaAdE{Q+8*dIm9TH^GDhhSUUtFjkbx(rh3uoA>7yIH^y0Nvgokli9nlt^7yV;~ET&7P4#Vr>=A-Z;R;-wi8dRmyU)bdYX( zLkrHv$)`=qXWL=SK8%6?sQt}~?39!2mE#p)PL*94fcOB`Nq$0k;9^F zG}&vEG{PIoqK3*j-1w>NLxDERN{UTG2n=5BNHO2wwV6WS=nznSP;fD~fbc?gm@f zJz~LlvU)kZNVV0S+e&^(CL_Y=j7lQx##^deAG9a(a1b2c`~7cER-eL0=9*mZl0Q$K zp2;}Ba^z83xFE@;@nMFcvt9P=A~h~z?dOBiU76dufL*womng5_V$hz?{m@SHf|Fey zTyjZ%rfY;+W+h zO+A)27Am#vEZv@|sAxM^cMx()&;2AeBhs|PM?-Or$J5W0yu2ChgEV@fvTu&LsCY;C zH}gl#;+$Vw9Yqx5N+mnTOF9&t<&QdHF4bVaU5__EOFC;=)AMU^l`iY!HQ-wnY2I}u zy*qhsK6IIZuI64&wQ>eJWHxK$O|DRwAIRXL=Wja@yhI$x?uwGIP+{~};Z9fk-CGJe zmI$Kh3kv#TIn}oKW~M-h&%K+&!_g?oEht3BJZ^c@ThJ2Me^BVhZk@!oyA6FdBO5dA@qUPgkBBt; zmrO_s)YSFRr#)!d*36Jre%Cmhw^jp`t`mh0kaZV@7#j+@;%FD#^mN`|E%$$s{@cz% z%CF8lABa=K<^a&z*KxAJZI1YNd|$76}zP#c2fUZSJ1V%+Ky zK;~^EZaL_DUQm;)(PL3=yU;iLu;;V?;kPYkeXP1-9qYFS6a%Jx#Et6O#*zpyRK!;7r*Y+cI>NUofoa*9gRHc|%i1N$F&$ zJ)md~ycu%{I^Os~iPg{+O64%LnYciP2!0W#FC^(`TG2utfQv!PTH7A^9kU|eDse|P z4EY7HNtdBNWVN$?Xy5|t2psL=ZTKzbeH7#LCTGs&hd!Dsvcx3zb%L~k zg};O=uASOLnsAY4D5DNG$hW_1Tgq=duVZ_~ii4yo%Y@b)Q2SE$)S0rTLB!S(_hGv~ z6~Ul&fW!j7T4ktqnZ5pj)9%U=OkuAlxE7zzSL?R9Mmdls z+1qqu2OUR549#Z7F6G{g3v&T|mAGKb@Nh4yKQ#RM_;kp`e&OoOY7erssmvz%XcEYV zpXvpodHT7>$yMc5k|V!W$F~%pY8fc#xw6he{aM*um|2_c(a_HZL-*glt5edUu|&tv z!5e$>Odti8`L7cGAHXDej~(Dspm|V2itYYj+d{Idr;D%WeVE7RZd;7hR3-~Hna~}A zqPK1I`z;fUZA-aB!Yd}O>ZCu6J@Yi(o)kU}VKMK;**>P0icghLvhU5J7nsT?TWf`} z$x5~HlO1Nw&2kRL#_UFx>xC?Tsobmm!rOWFUMDmcP&Bkek&#<_MIQDhj_PV`t@jok zRO8U@1*^`pc#qpyh}^yJ>!V|cb2+5A$KQBLAnEf{U0x`SZCd#I^=E`f!+u;{5G} zySwG9a%B`_Gs`fm!3TW7o4VjJ-yy`aP>r%V-_wa(e*8+H)3#mf`AQu7f+r=&LN5KH zF$zr)CDS&^;InotaYozr$p?OkPsKswlO_1kzBKKUHwS9gbCGKYz)~2?+ohucEgL!D z3auV6yS!T*DcT$65n79FW~gY56Y?`x$?xVEx^!Uz-vva-8b3(Gg<%tSSJ-w|FMP`5 zw3uvVES+!6SnDVBmv;R9Ze*=hIFDq7BkaVYLL~YUHQrMKYqS+;{zeMkTI%(jJYlzu1p%kRM6+6BwT#`YF`V!4hmyISmtdfH zFqLHesK>ZB8uM*KE!J+?y`Vjl1N&Z{<4qX4U6`^w+Xl3ov!OubgjX4`*X~V+eq^9w z6y|5!Vq~wy*B2`8`_X2nSOaf7rg;lCWXtwnlQ9GNW7(}ih3&}HVtIgmhqvOFt<2<~ zJbb$<=c$3+5X5tkT#G<4? zxM#CzN6WL^u7J^4t)d}VZV26x1B)bi5JA3!XWV|h$$igOw=>n7B9m$UzNhXuJ#iN{ zYdN*AwRDd=Vhe@uO5pnD=L((IzJ4^wn@Pnh`{jaAun`ByeJTXOeU>I_jYcTYJk9q$ zSe`m^>5bb~kqA;0YyIk4Fl6y&=$^VAQoGzi!pLNldhWN)OW~?5_Ch54twz6)+nBJr8j}wGcS3fehTOv@5oKPCueWD7U0e0A#-5jy+ z@WQ;PCrcticZm*EB-HCf<4IdVENtdC?LwcpB(4xmT zwRD_IVzAn*t`&>nRcz|{y2L_=#>-d2SRX`n8JgNhm27VVhPEF}A+OLw^U&i~QGCmN z8z?#BOB_!^!GD6s)P7>(Wi*OCvV769P2zG7qIql5xFMZ$@lr*=g#y4q!eOy=DiJ3o z{;>|O@1;0DTx>{N>2kxfc(n?cHFV>c?#YK&+g++C8J+Fky`OI;h%s)!T)w!XwLwgh ztLF$G==>(2RuFOHcbpSm`uX{5O~*Uj9`Xv2CS<9n_JZ7@*oQJ2%rH;-UzV0jryLrR zm-lvILEj2!?RHlye7qFycP>fFD1c90(`D?lTNu;Zb6pBQN?FsOlI#v>27hUjEnXdU zE_Acs2wa^rHu-ZbO8vtSiZwQZWsj!^u-07fQR8JsdS`F-TNX*CR_K>nbWy@{82tq+ zEiWRCe>A&W%~`O=j$L1%h8`vI%urKj+&v9q6y^5c87Y$S$R=}U;#w=&ZsAmAw*k5# zVNx?rxTQ%y&1TZG*2FD74A^zQ0@2$U;)NL|}!Wi(T zk$TG#`Q#a?{B%=JL?7!oxSGrx%pciLB*+}0#IuS6Y zoCDuvEkcx3=N!#xuQ*^9kgcglYzVMi(KbG_lE;>m9(C?Sq}Jz}oRJzIt4=xI{FaLj;4kr=#)vI;gjA?)CSIjKc`qznhkPn&o&#sn zaj`2}49)fo;2wIGtacOZ>FWfsloF28fM>gLKsPdfNTo>3nco7a`_ZLYje}U}K70W7 zm&Z-boA^yO7ajaSJg=NQke+hT`(rQ@Q%-#h?&AO_nx*SNQCOg9I^3mbK5I7}+ak57 zH1mWw${nk@@z=TIDEYJh_yX|>@l)ba5DL`w!RHUX9PhWRENq?Lc@CitiNur^2B9*9 z9m;j-6OG&w9v=g)L3MBb>hiw`jv!v+bMgO-}sB^zU8e|gby-b zgqm&f+KZk7OX$6-8k@z^!0#kqClK~)oQx@#7mSBP(kz$2nbVt|F;T=pMqBZt4k6lD z#85FOMi}5bktp>HV)Xnt-FP&o?x3V)D**CMb-~ZD1Ul1D<)j-38|1f~bf#yB8$!Po zKX4lVB&yfZ9>X|zLfFglaH^u`>YuhgTx+JcFFR8<9WOBXv9t{P7f5aNTAx!kZFBmE z)2A=%nWB9Vnxb$ck51`OWlbcd1=6%<@R8n;J9JMRiHmI+GC#Lwkr22lj0z+c1w9!_ zU=ZyK@GRV482)&@gVRCx(@5-cek3H8gX(RI`%4>{>*G2DceMfY>wRCY#HJiB1;Wk! z)KcsF=(G)=(2PTFZ$6b6gTBGvaY1?gbJ$z_;hbAEoG#ohibboQorbp`V(Zex~ zQ|(p|e7jynS(T1aB);PtF9s4d%T1RPd9cc(ChX6Y#+J$VdBEcfrFZJ{po;Z4!?Cm~ zYbiMC)~kCs8@U5^=OuZ;SGt$Sx!t04eImJUO?){)?O-1*j|s}NmaE&nDK;{w-TCSg z@T(gi!>8)+hTwENm^}>MR#O0KIGLa2~W9^**w20hf~`IeJ+vTkUU4tztxhZ@wJoaIJQP zK6jb#cn;4pU4DXomiDxHXFH40(wg7D&-uw}n(w*rLx&PeR;uN-Ob;d70n1)|pQwB^ zjByD6cfwPV3`?$Wv@J^6Y%p>p3T1O%@-_G>$+sv_pH4q}aC!T7l|_)2_8@Ro&fmYL zo;XS(@T)6xtT*e1ZGG{0sS`H!OBxC3Ow7+xW-#Es;cj_z)S@@O|BXNFeD~{p{g=Gj zrvqFIKm3^{`g7-2V@8CsadnD5s*YvQzhXb zG&V{=%1qN6O)Hr9$ghqY)J4kqp6c@fRxO*s&9o-0qDzEk!r;#)B{+2^~K!CuQ$oJsX**Z&`KlRsMQ(&uiW>)yn65cAew>1--6Ze*wf?i1>M`9!G z0&-ih@X)czXU*aAP!RcCLfeFh1g%Q0V?otuk?( zFBG6)1KbZGPs8KlU4j{Z^6H*SkXPy!$k$@Kxn1`i`-jL=N8%btTHPl?fRoiU+>a< zs&RR#jI583*X^z89Plfr64PdrjUT(n{eVovK?SXqAMyf`5`c%{c*)D3WmB4dz7|w@ zPyP;Nm-4{-f=t7HeykBCan z>aay4d%O)_(1t}pB(VoJLL!i3R1eM@npg|KoZDxbruG) zru)t%W0|&{z746w^Xaj}{yc7Oesf;2S&tql&NRlBQ7}#Kj8!@Nw0m9&>?&q(KN5Zt zF;j_1FqZn_o9=1e-U+ALw?JyQxR5*)dZwy67B3*;T(u68q!BxO;Xc(i*t1bT_=MOn zUZFRdx!8STuQmi?nbxpx9jn!on4PS=KcG2Y{6y(oIUad=X$!Z>E9CL~wJV~WLdTbs z_v~rqV^W%A*iEHogQxa@$ya-KuQ@$JVT>G{T6>aA*eOJMBkUZnWecgLHH5ZIZ)~I~ zPPTwEZxlfF&bAk|T$##E8KDtSqEqC=ih-QjLxYJOn{TOQ#Qnbi4@TkEr9O_7%}p z>X?`;${s7Bq7IVZY>~(`wk2s)G1s4*c9A6_ulMyIUZYl`l%U~FFP+D97H`h62)p9K zykma2Zp@SIm0t+npXFWN-0|I8+0Y1?JN#k%6PudZpw?}y$yuTU;B@cK*o!oLMI%G( zuwcK(d>41g2%kKVLzC2vIt^ATKvv(y^8OtEsB;Q}p_-6bUH`n9Ke79htZK&--K1i& zvQLTmjqrWWo+j@Dmlny8gU!yncIchjWjcD%(YDZTdcSlQ7@Uj8BBBhEM^nYOUadZ* zo^KfwDY3SuvAX;2q00W%bt=vF9u&Ld)l^bTISj-r3Pj|vPoop2gSY+R&f}**&U^B1 zY&i1Mw!JN=rJiL!KT?<=U!aDTpCS;mf++$L0xT{IIf*`j$K@W_*^yTFET zz^v!nZt{Hfour1ave;5bE&650 zvBue1M?Ee!J;gU~*oNc)H*2gH1TSbLWGvG$OMxcTwv?=tGoDv(uLY1Ba7``PkG`rh?NYZ6>1K&WBc>XFX^i<419)){p8 z$Wb@~9=5-^fd*G`j-v=*7Lq)E4*Ffcz-@YgzD`PBD zQ3z&3*zBlrEAf6a--j7<<5>@raQHsU&L!x{uIsy94Xlb?mc%4Tl$$_#0V5 z1dEr;3b(Vqlr2HR6X{--%QuM827gL>TMXasUp^66S5Y-<;Y4pGSt&ofArfEtYAik` z85o|Z5GTw`mbIc`fO;rvi$QLflN+!5b1qLH3v`}mHT z9y6f(vEgoVv+37AGj!H^$;w}pj!LwOK~ox-p_ZtFvFV#%MT@16Fb}DE>pJ^iiUi}i zOSbdF7OGP0X|IQ34(C;qScOh{AvQ?=6MRw^QEBM{B6^ZyO|T898Ha0a29e_4|3yBf zqUY4=?ccx?Sjv3U*xZSNJig-r)Kur<8uQ~HDyu!W0U%Sq`2&;Rh6nxMqfM8NklJrr zQ70BgVL~gD5Ht8B#GRx+p*=b$bL?|}ji;C}zvGJ~GpX#Bo#g!CqlPqrA$9ozY}yQL zOflxMbkuvJ1;Iu2dqw%NTql27ZaqODH5}%gC`{(7j|0nswquk5^ zDL2}Rcx-e*b3avhkHXrbYs#UMyThaV6j5lE)>?IBES+C=6ARNrEN=_ak8g{Gr3uCL zVns)9wE7IM4T%ax8fBh(p;5V6%(I+@+5o)L8Q-r;Y=o=aTqbRCJ--NI*hXG9<7>X7 zM`iGD2J}>|tnMa!|WE37O|GE^( zhHu~Ux?bw@I{+BvKbGh}TNnsEHN0&B-G3DGLA@2J%?w|EH1v#+6O}Hshzw>_ICa6* zhwNgPOF2fFHJP1>ctqcl=E*Ww6_>OL zZJSs_p60pYuluFe1(_S;RRK<>;Dpdq_|cr9x5fsj-h~e!@l+n)4sI&5wbVx9$r`qt z=$o92UM}{SBvZ|7|EPVtFq33^%MfhZ0WCjVw35$3G_^Ur43HE`2cOM@#w_~c6C_G+Pd~wl1nhd?kW*JKcyn;=rss8_GH7vIhsN*ep$w$lD@ZMH(-n22W@8eKZI@ za&4=ggBsfByI-E&(9-07C_auxaNdF}U{-vWNp#S8WyNrF_C~NG6V{+zP}Lp8t#7k$ zpd~FnXO4kh!psoLZq9KLT9kip&x-@~W=F;oIPHh6emC8H8ZWPu(i^dwOF1g|U@80 zoHHg(q_BU^Ka5<%62X*A=l^69dW-ga;TTUDp)z^_OxVIhE|z48i_9gF!i6?az&2&Qpm!4pr`QZN>Pm zr!WKK{;bk>Hh2OUe4*AFT+}a9o=Z6XZIMg1TU$AZiUEy`?p{t#`l-pndgWQL0F5&b z911q%tDNI1)gac*r}U1wBof#ay5HeYHPWmuN4YQ3wTbq42X9(XZ!0{trP-Gw#D=~% z4uW+54s|9*M?n5Wn3ds>4Dw#ie%PBz8cZ3Ef0P53NY;%CgeBp)?JWoPN{M}DHV?{i z@Z7C5uBy`{0S-_=2P%tr)V8Wz8lR`;MHhEBSdZc8z`m6i#W zE+kZSDKURr8jgr)j6@^e*Ud}xHXfBU3eVNQQ_KFy`NwWxZ??0q$aM;cCkDpK>6=pWIUWzTt6b+1ak4NDSV+d0d2BwS7 zh|CNcJ}C9WzBzD}k%E^3hoaZmDevw-wYoJdnf=Eg6t}g|c<1X9|LdKoc{jL3?fz`k z@)vISo|Bz=wwwCE*mfccw)`A3}Yhq?zOWB0MBmATtO)t_jweEgJt{X|ibA?5^I`q4dY z={gR?BB-;sw{4)>rlia^FsQFOKgp{uJuOM^0`5r&U(Pb!&jRIK&9`_TLVw1rs}>-W z6&~W%IqSgoK2U^pQLc48+76((%m&Xm;BF zeBys54RZ>#%}1jV_0D4kjQ{xsjSE$EzWb*8-`Mkbzg$wmmg!ESf7}f8mp+PIFGSe* zFIzGOs}<3A}G{~B4|;)v}(RR`U3kx=c- z-*xrReRuv}m;aG}{2#J(h>C|Yf>E@51p&PvsVxnYqvOlc`6e~g=r_LI`PL_cp4NHX zN1!0f0foEGhNW#;|06)rmQ!hk+cDKaYJ|_Aa}eTG z|CB89tGn+)QI9wy&#UA)spLVuq)WZUnm7EjvTI2Z5ucWc0_iTu`P-3Gt><00`IxCm zgS8OX)yNr0NR9zxP0z;l%7)nXQ&$X91xepeY&oXVfTO2!P`&n8eA>A*c>>i-4RYBi zM8i=G$@NPSxpUn|>hPP!YbTnlGyIyU;2Z{lCsUtX7ey)KKWxr@$vue^D{`P* z6?XzPFXlA-HrZx|e`wf^@Rkrsi1E{p@>iBg6S^8hKKDdT8$P)X9>5>dkPeZr-I|Ud zeGcMT{pHx`Jg9SfKEH%|zsAFHUp~n_H)5Q}QLM(+6@ICnrAQ&1-q~N%UvAqF6)&2~ zbMu4;P4Q6L)P05k^N4UI8`{_o_;b0R3_TQ zJHNb^Q`h2*dqU){sydP`?Ifzbs*;EEFDbpRiBi*qzI*sPeZ*}0tkX?H0SBa5FAKUSyjR_n^G zL`io`%6DZg6Gy*D3W@hVojPY4=C6z*tagF&SCf@(l$hd*7`^}UB~$*iK5J{Xgi8ho z!DPQ#$UgF8+v=ZUY+){wSQQN zD|}<5J!^Ym-M4j`%KeS8C=Gtx1s6?3t;<}$yQM!vi7S7llFNe{I^{@2l}&m6P#M7J z#aFiNjc(;WRS2o2&)v#-|9aWc7CJ*SXC=!Hjmr1x@w9mhex`cg$>$Jz(af`w-xlaq z&B=`H=jn~|l@5>$isv2J7+sNzEpjx{jxe>8_KzI@+RH{vjQ5?!+3Ox??Ea=_+LhGwOH+8 z5=g$N7kyJWq5C&~xr2q_`WUvf8?d*JO~-^d@^qJcIuDaf3P~q+a3^v%L;4C~ef$|c zx4Q4|W;6}W`bn5JzvO#=_FBspx^D23s7jvI(CRYY`nAQNlkG&*t~+G1)xaTT^c%}? zf?8#4mFM8%^kODS_rE0Z`RicYCR!54Xi3KTZo2{=BwH%I5Y{0gV=)2)s}9>F^guq?h<$EG20rbve?I}%C_Q&gnu z#CTQEC>hYQJu3cvF&i8qo1!36z-g~WA2#9cZ@>RXuA`-CTXS_3vE7mG1-qA-mw+=U z*2bge?%3sL#%T{?b$)c1rz~J7vz-{^z9lF30m-yL?t5S$kH4kXpkCJZJ~e{t3#2m( zoyvS_wdm(cBla-Z%sLO)Uttbcz$839z!W-#Pmsp=1){MstzY9M=DuWGR9-FMHXgg~ z{=5*HlV_+txZ;R2_ag)_PaY4zXx8h_Q6$NEtH$`t32fluCKJtMbarS)akaZILQCcy-Nl$_$HRR09i6d;Eqd@MkJBh(04tBvd4>IrDmYu<*jIxS# z7}tV25s>KcdRgzbSrCbJ&3^zSo-!4QFFn}rQ>+&OxZ&=S+VE{i(bo6`0h#VlhyE2~ zq_==8gm3O%$`2d3U>_u2gJxyGF2(KSfGWw#-&Dp=wKaN>nK0KJLYl`YeY=w7WFi?w zw3z;DK1-MXN1AjYPYN%Z?fcTxUPZnOYv{FP)0KCX=h{P3XgYLU&ODLIUzB8=yI?TV z@ps}Wv+1u!`nIj{AH*!TPhy`>Lof4dP)IN>PmtZ4;p9N8g7(ab$hmd{bK(6vfnwSk ziK)Buiuu_YNL88!A1ZPLJT5qA(vx%N$tH1)8oC*d5kIjh@4BXm6mB;4V#L%|-CHed zz1b@%m8AJ$F@YDm{h(JwApq)36KxwC8~m$caYIA9_cX;3O7A<8Z!&W5$ZSq;f+C#s z0Tx|33no|A&;*?5J7~`1N!e5C#k$CzF-bHJ6%<+{AMj1pEmOEZU`3W&L3G&A1uMLY zDt4|hj4~Rp&|Ir`uGKv~*Y9C$`~&yMHD5KX`JSd0@wKhCK>#mvJ^Lg7m@OW_lO>TL z;TutYW`WLCM%w{`0qswA9-pJuFi*QH>{u+)N1Wf5^QW~ol+vm8ChdXYVtoChr z6DNX!oQ4Z?qqX02ULSA@vZq1CD%xNPuRkOxCz)ujAKQ%lyz*6T_Mx^4Lll@&zs6Y# zya@8YTIW-)2lp&AfV+DWeg}ya3vu<1Drdr;s+V-4j0N^We8$ZM^Z1TdOH%oHqRim@ z^fP_%jtft8xd~IVoA)H)Djz;2TbqhUszA_kY+=ev4W*u`iK5p5@cQ<|cG?^aMI87faWKR23cC>-xD~fygX!r8xKf+UQ+M(Coon$Gj~eby zeaj_qy;^T%TrMFv19xdghbo;_t1r}L0OMgU5b1`BiqA6%C4qNb2Rj?gLANy~S5aJj zc=1L0F`LGKaf^31)^&QQn3%f{`}tc|Kb z>Dzs%XvI;3-?#v(ly(7eb~Me=RTgf?+BKe$ev(1*qKtOiT6G|gSE@qhMY(RXyh7Z@Tb>pzrOmFf9-vl><)1- zG8cH9FY3+}a&d1-zz&g1l~xBQcyDFwh#KTM5$*fB2X_1GpMCoP6W-dKGAQG397 z$h=hTwXckSlxmnsYX7&zdXMyK@ac(ML`AqezB7QD07@mL>j1uwDLLF!>JOPalo)8!6mEF_Jm$#BedBsYb z-4ib=jBv-31)8miLQU5xybt%S)lG`&Mlz#<&aDn8(gD25$^s5Ep{1^#?~bO4=`U?+ zEsMTpxHrYhk?n7Nssj<$2rj)w(DdU|N<@66;A0I^a>z>%DBw~GQ?nRzvOT=0G*|eI zpoV9>Ao7A6suc9oj6*Zqf*aKUC3E>cRG>fjg&IMFt;Yg{PgTN2Mm zr6^*CZBjc6vND_5Qq1^@lqQGptuh&ORKp{5=KhlqRjKv_XI0p3x}$4<-XLY$Y=eFn=*~jUxF{ALfQZ90ni>@2+Q4;YgWGNm!ZF4fTYTl^V;inITHs^mtM1KAIMd*xrR$A+4FjYnA*0gpHqU0uy!RBg z^+ijh`C?7hT%cG^uGa_8I|RnmO->Gt_jQz%`NTuV!64-5jcW~q(>s4OB_$6|H@s^7 z-2C)#n{CFc62pA$0>60~=b*8gmLiLDgN$f@6`G^|PT|Oj7fa}zYU$i4+h@y?_vyFy zFzLmBHJQ!QIVE+#i*0A#?J+P}duS9ZJLyzwyE?euZ?uTP8=um4p=YfD!LU%FM358UwfrbnxNHYGf1 zK7l5;e7W2hmM`Nj#Iyut89M}p|5h8uiGc*giG>UF=+|a(-QJR!YB#EF!ovwkOoWihNa>J;2$8v{|w#SQ)JqlJGk-)E5z|3%A;rk+x|ejmxuCNcE-3 z=)0At>+pF<&7(ms=_VbvbDN1q_4%`&%U^1D6}~qHd)Xpcod3`+ivlgCw|{mHk2)%B$i3@!Y`O{~u08Nz z0sFWydtaZ0M7V}%o=QIM);xGrcqyV~bMDmops2v=m;GoT+p?yF+!vJ}5*2{waL$wH z41^aiGiRdYir0a%aOdwJsjd=p_O+5W-|7D0ZOKcAgO=0#yfSBl?|ZZ;3O7z(lA6}$ zGN3(3*z8c*0_cml8-IwlEw9ASs_0tw-ptm}(SjM^EAUj0r?Ji)BJ&S}W6uVIBx|W( ze$9}?m)$nOr;NL~7q>JLuG6)8G~kUKl#;aUoRoP65hw`A0r(^8cN;fxvmPM7{}z%K zj;z3NG)LW=YP)Yc=6X8sh!}yTbd49ft|8c1gXnjf7sYi?eWh&#gzu^km5TR6Xf9HW zX>x<+iP0V|^J02c`f~+#tyzNgla_;(;zj$~bRVL-ikdh==Tn30Sz2G`orm?$Szmtl z<${9uC0!_Hqk9d709{|w#QE-IkHp3)HFmnjOlUE4Zi-`aYq(M%W;2;^^1{;>Q-J@& z-djb*)h$t@Nk||BcZcBa?!jGxySuwLB)Ah?8cERL?(Xh^#@*dr?#?;qJLmt$xUcu^ z?g!}61A6ybyK2^~S|zF<$|2}F$&+Gujee&G4+M(Vn>wSL!_U}9#|t8zO&BGNgc52# z6wh817o8&)n~^cmngN!ETKJ=bq~xtQBG6ggf;yYCR~FO??PPb2@(jg3n8ezY;tx^a^p zpsK%Y_~eGD&*urF|DIpR#|6(>|K88!$|H>EN+ElEjgZV&Amr)it`L4JV{2r#y})K= z)>CXFOn3Cbb_yGgBay-?Sj;%O>WV1l;*jxHO~;QVjp?QCbcz-B0`f#82s$FDODxUW zIyT&X&DEym;U!$SIXls)|Wu5vU3Pq6xuBfA*ls7>KJ;I` zNCr2>F748k5#HgnYooV3vcE65wys;-;4S+p^Dg1&Ij;ZIFPb|tHCwWKR{q+N z0n&C@&rm-fyzr|myD%pUF{)`xzX34A_SIccaQ3B9R@W5|1Wi8aCyN=Cuh#ayVBU_* znD?QRrzd@1hWq;Kimj)}S*?wXHClz!-NPa2Sd$O=Or*2x3cyATq7i$6kwYNz36kgr zGkOb~uFO!p;m^cnDZS%@Bk@GXyfb}bF!fBgqXl;lb7)V`j{z2Qw^qR3a*s1apYah~ zeGgCHYEvXhA@w9SGvZ9?W+s;Q>}~ccqDcO7waZS})40jEdDWUR5~jc`B^_qG+)lV2 zTVI#)FheQfUVX8->&e!}&bYc961e7zQ>ww!YuLya@t2tZ4b-`-=RIWHz1a80Q-r8Z z%!z30v2A~Fn3(L-M}~7U8;|WToycjcKyEkEw*joMp*`(Oici0xE&$ynP^Cu*#!Eq> zepXtd&AsRodf$nuCAT_GzU3J83!$vXC%w;FrKD}^qLuMP)t_P5}H8aa-i68;P(6(<}DfDYvsPTJ24FOTmF$O}G2<{)WmmhB(DE$AcxqZCgz8#hXnC%h5r0`uedT zlebypf)bXW7Uh3giAvCu4KU<- zxjLn-4SNw1UAf5`;C6(ai$v7FWI%h4qd&UXQU6|v63m&K2FH$H!cuV4QcoL zbs%M*2(RR|+B1!msetE4jJN9Pum9q1ou}^#9u;?5?=X?24Z*SZ_3+Ae4exz9Qqc5R z>Iyv^I3uRlVJ}ML%(@kz=XB)G`%(V#NWmJdVZdQ_7n-S3tEOgbcmT0sPYdHmV?Gj2 zYCC7S9HRdctb}*1dg!WxP`&)I&n>*W0#4&;OuM9LLn-{bZr1s!CCZW#Ej+Iu%Ip2w zAq~T$Ri*if4#)d9z}U(x1{dusN{X_$ zv1~V=)!PhWOxLWP8L+P9KKcgJUKh4~s{mEDg<8ELsR{xey=C>~+iZXQ@q_Q43UF6@ z*kdwdBX}|(NFT1jD5&`x3yo6xa8Od3jCs$&wZs@Mg{5{W`By0;b0IR`z{V5!f^JtGw7@-M*a0(;b@QmPu*<#kM)$k9GM% zxvDbOes8VOaPgjl0ztd(Gx=SP-22Ety0+JGEYIuhv)9(E>T@>4$rU|Fh@y#Q?J!R`Gr+s zSP0(ww3}gWWN2KyvT&{s;`lLuWr%+elG)Ze#YAnm7_O?q9#jnI5t+PhSPg>izx3!U zVMP8IX+KNoAx9E(X#kw_ZI2HE`F|d28xA zPz?@i(uw1CbgCRS`!Av}^h&P|YD+fxx$tQ64W8Mksr#Fa=9K~G@#i0> z@K#bvXI?*c;p3XGb90bB+L(04(J;{aC`|?j(GAyj$mY18y0J$GIUFc}5@DCI4kPw% zUKOv6olW#OB4QS?VL{luCCnIUBarWo#tZA+M&l#bm>AwpmFnBKUOjtbJ0ObGlul!rA z)Fm!flBX;RsMbz^8u;wTdq3wXQ41o{y6UYYxCn+ znGWHwsdN6$CCTXqO-i!$C%wc;DLl`c6~jkeS0m5#h!UHXGX8|K>u}XAtu<>%h+fnX z$q1RT17@l()j~tujJJB#Rq-2f9rY^c+>CIMYD-41`it+b-!N$1)VV|cE#b>y75|oS zq7s8%wyIlg>=*e+B5(O#MygTFNcy$4omPQHS8TFM`t-gGV$2zN18O@>m4j^eM`Q$6{J>|o&=$xjcpr$=t}#$&{Ojc>Uf=#4H({In z$0NgCJGdzjoAo?C5t#P*-B_wdDI+CdB+jy5d5ei2=ScGD`G$T21{jYwGEzZsr(-bx z!Zg~@1&=7fhSK|?&*^kq%(GZ6&d;9&4|OCsmxJwBcXu48}uh9ft1T(P%Ll-1GiMWUWoQK}_|XPzz$uej?~b{pC|Z*{(j^wv@^Gi_wUieG~gpV< z_)jiCnyv#-4=dU8CNkmIlGEiEOu_cRoWz%JLPkpamo~*e&^&`?d@Gf7kiD#w`N11s zzNTDKwUQMfV4t7&h_SIcYqdj%!Jg;ENBh6~B!X3xzVN%;;?LK>p>YERX30>-;)1S< zYZG;6K0a`E_S9ujs&Jj}6I(sQOF~5X3&SdRIb-R9IrIJrv5woc{Lbqwxt@nJ1Fy)l za0g02pogDj2D+N_m>cnZ5Ql*QMc-x!4TIyJDBW!GG!Ry8IDWM|*yV~SU|bt$xRg3& z4@SYsVlr+2aJSE6_P!K^JjW8hub;>myLb_dIoF*0Og=FI33ao@Gb$M?#E%dQxi_0$ zpMH(D7PXVgGfzabOE2yfP&Xx{D@Sy8k-J}Xkf$XwaP(Q#6V@T%c@N&$INQ}!QSsut zxOAC@8R8lRnOd<(TnN+m*>MqXHsu=&*Ia}rU!yZ5f7$mI1A?k@>Ab_N@~ex3=?#3~ zt}X{xy+k0K;W;+6ZA!;uE#Y1Qb(vau;`VT3-O=$iz>*8ZBOzrhIZq!sJ7!`RMBuAe zE9MG9vdVPsI%6E~o}#5(EhGFpr?J!-Cl zqJMz@rLY0Nv(rD>s^E?aLX~0YyfK)v>XGDmL?{utOs%8)vu)A^P@qY@5M-2Ci{g5)Zbb}>-vjDJa1;gT zP6N8FBG6Op7)MY5tsNApsf-ni*Vz$2cdJI&%o<^4#=PotkCpj!h-Jg0ti@{pOajHMziy2oX2bHatAM@-44BPkYnOEnSfl z$u34fU|`_X_f~0&u&}U{H)28PVzs`u;Sth|mDXfrKaiUgxBrNPJoP1FSvHD`V8GcM zQ_dV4XrbjUPi)=0-R55q%)JY^K?I65_S~n>j@-(6Hr*Ytt434XSaCCT^rU64A6g$< z2A~9Ak@P)pN`J}u&Xe&nGe6}eM~TM8Nz?YyP<^U~TltP%%(x3!00+qH@~py3)&2-K zU#txH%3x_A-{)>cprnBzl3?ajmhMQ?KI=T@)$m8oZG`@X+SsUmI-b18eU6`42m-02 z=WCRnMK=#RGoBSKO~aGy7!cDpplR6(xcL@e>)Q6R;(^Zs0!yB_WE7cvgzKJ7$4~{L zXL`S8Orp1f79y4%iXsjN{-S;2LP^2im~~5-v$<#A{a>d5rcj6=FTn#Rc2=itCw*@Fa}&>28yo)=WX7l#u=@^LE9tU>(9{Q|I4( zrlEQ|p7r@_hB(H*eTRyp9LK2bhjyM9pxh8?)ocn(zL=-o97)MIBZNGdO>#~GG>HT= zvxQF5VA?2YM`w(D|9RkmuzxA>cyE~&VH&Z*^4>~#DKFp7IIr)NAXD9T&+c#Vt4MQo zWNjD$GMT4N+ZTD*CvylMB}H!OpNP9y(lM7^Kcb+739#OMf9T$s z>%yVqvog#_FzxzjvcVH${=_X%vh=~Hkt`1H9ofXIzhli6jz+WKhWj`Om(B1EQ>b8L zGX#&LAL}Iu#`l@p`SlXtPdg#P)Qsun@z&Wl4~(mYzvTXA7@9SYy%g^Q(QVrIa!a_h zKrcMf*jZavrf+c~Fx)!F%G!wy*C+LYDc#NfG19UaDf!)=-HYO>`vCtSnZF^;uTzV&`@eJoyX)L(2VX5{=Us?)Fhzq7L0 zWix7thR>!!f0)wJ)=pXCQ0Rff@oU+vO4_}ycDo_%sBG5}Z6|oR_+U*e=3ftBismh` zEa!Nb;Rx~Q=y#-vzmg+!@?hO2d3NZEHj-V3uAjdQPi%&X}+PZca(ty@$La;F4*NEsZp zAmlLTAgP^Nx9Cq^^tyDzkJ7DN(m(J|zDCK@A(8d!U*xdD8Z{mp_TW51fTQ)XU0gK3;mIdYDyO18f@<1%yR<{qM^_+ zUw9xaUj^}YXJ57wbN+iuY$fvBu*jFIGO+N{xpE}fL=IbMHgNK9c1{{^M&5m=LYe>k z4>P%Vrtcf2c=IYVAFVjDl|%YwWO1#!^3OU}rXHcSyzjSe8JP}$1f>cjc>DUm9{ZQo zIvXwHwtbpgJ01FsB4<5kz>%;VG7)*?`{PBvbuU%tnl)+*$kE3M`Q95l3ZB(z5U|19Vj*ybeE{*WjOfci&nk;Wh2;4FXo-=*x zsEa+p$t}vC3iNSL{UcpoPD;*Q;`JEQ(#Y^e{2c*{_9mRKd?HE2zP~H&yoyagJDg^~ zl*k|Io?HB(4mPwB;}YF!em5-su37c>t{X*+vqaI4?UdKbBTbg9^O{D;5L;{!y#82j zz6i{Gxyb_?GqqTF{N#GAe$A`%|`O`GgpO()r(XIO^8+=lGy&ak7*cw}QVQYN+`%rqn=kcjqK01*S_SkU| z_PKsA?E4F$zh{*{d`*XVVDGYzv6ihY&Zp0nTJ*+g>-8B$El!fo{`xSYqZ(+-_Vctu z;EG@_0y209*(enu>#>kw|Ohteo@A<7H#EF zJ)B~!>svS8F>XvDA5RSq1qh-1CmX%agB(n8A1p6d-jJ2nDIi!ur&ZCoG?V;Ev(*FR zLtTv8^TX6HbH=6~91R%t3Lo=8d-Pww`@_-n>V6IX%i5bcT8yb+W>qkQ5lvO<-?LN& zPxaa>RvBYXb8@w|M5BGx`D^60zK$z9za7pW->fkGk?snIBx@6Fd2BvgGZTCKR3rbx zJ=?`;Z`eXyJa2(X5-9#y-S@r_nEPr#FtT&MTTr>mVlnrs=IiT9xiL(%${L`czGaLD zd)0g+&tQR}eq!Nja}iC@4?SXLYY~s^)51dPh#cQGQx^WHO+K;B3t?iJd4Kr%a>wTP zOA;KzVg1(Oyoo(^9|tNn-#v6NThW0gMq_dLfQOdE8}i5b%4Tf5c!~gt30CGiSOYe~ z!I@pvR_w1;wusg3um*U8@a+dIEWPXy2JwD;Q;&t> znA5W_^FA$HNW+o_YpM{I-xuT9#BEUVc6`ZZ6dK;u_corQoTbq;=GPcP84X7fW4)7J zf1>#A<^qmtOgcvO0EfM(*<8la}#{z}y;cO{m=gF-?UmEEgGnrRZV2 z@7cBXm-U4(RF!hLF%4O(FGs>GB0fyl{)Ym)EJ#Vap3ygPslvMvzCEWznUXR@8X-Gp z5G*Vwx~lgY-zN>2;u&m|dp#d4Z%d1DRvWJPcE|MepFO?)z_h3>|4*dF@2-0Q|rna5ni zg`kr3+R$#*NSKoa5-0h8M+G5PO9eVN>lQTgJjtHk(jBs9TZze2g+=M}7TD_Pko=)a zilX!Fx)q)1oOLk{h2Ql5!Qpi}h&p4Ez+<922XJN&0P%K;MPH)2^`}WXW7q7L6}x`! zev(i|q`%=jk<<-WI&J+x+x*yhKepC|`wFKd7C+E^yMeRKz0oZC;vLV;`qSG~G91i) zwNex1#9LBlhJ(tDz+~G!r@!1l@n|W?N8pqyDYbL0#McC2U%cgO*G($xU6Gp`MJ8(P zUqVobkr+JqkZ$;i5rr&^Zx{0$v#_Q5T!EOAJo z42O_~u>>qZbN4qsrHot28CoJBG8rJ0*DTFCo85&_@Q_^BCy{x-@BX(7wW3NZ}qF96NmkF)19#}5g^v8rL zi^B7PSDy(7aVOh3CHt@EpAq-#uik+&tl=bW_W7I}*dDi8cbnt(J5%fY7Ri|oEbDht zc9Q{@r!TM&mmA~cBg4r!dy*$txj<%HBC`iUebakpJbiG4$5lO&gP58`T0R+aR)T!9 zz^-GzvVx;_Ia$RG>-DKUcRSK=^YmGDGS`hNMxI2r1Z_W-)Jut&&G5&Q-Nj>kcy2Qh zEq9>HQW^2f;Z#_XX>zj5zw|J!JT<8`@y+>FlLJfl;$1}y40Jh#5glpFY9oaXabkK-qQNM!=e4J&GDDUT+$2 z90@28C6$2ui2b4!51(dcGQpNZO~2ss)B816$LF|}?|EGPZV?KNoAPZ*I>yr_);LRR z(af3EJUWJO3^;2`oikd%GZU7KbJXNdZOqx>;^Ra|1y|h@{fZ{a;9o7~Qy;~rE|L7V zd9vGBSpTmUyXm1h9i7vRWo+Rj|4jrsN&;(qnujJlqr=RoAtlTJ%Z>SKmeAEOFTxu+ z;Gs1;V6bB1mp$KiQ6oCbb7j`5qW@`7XgunkRB4I5UC|INGeurK=E?MYqUdwCmhTRH zAEyMKcAay-yMKLTMvJ@T{%To5JoHzgmm+g!!W=RcwT&9v|9luf=r$~i5v2p&@NUx$ zZ&&KnEetVFM$(qgqGxON9f&@+E=N1di=pcOi(Q4pA8nTC)P;RJ&e`m_+}p3`ZnAk> z9PscPWP%gH0sXm*7frmrt0qFD+Q!yI(5Wo!uc;!e`?q7-%{{hJ=*(?%Z^6DN&9Fxh zgEBXCmAXiRm(zm&Z%sx}wHGZ>2%lxOz0qT6uEL-o_lf5Zh(b9%shxYCr)_b6iT9~j zCWT%(Loe6I`q|J!HfC>xytd}wei2^}zMQL8pQgFn)~k%EydxSv*E=bLs+xcxpyRHOp=kUi~C||K5iKj^N z1@jePPpi36jI6H>QAk;yFssjkI~(E{h;KPU%%8*h^{o4*A-B2nKMwC_ejHZX;xRG7 zS47)ymA03etbx=g+3&W$nvk*OKzgkASkG}g`aYp6M`n3sg&BUcB``fc96$H!!TUoJ zvmZx5bWtp!?71;Hcs0nE<((yv3vkXC9!)l{P5AA&Me&orU{$V6SRe^Mv6y^Xqi1}2Gxjn8? zY_kI{Ty$_WgZXw;B*=)rT=0(cX7!x(r13YLWfTwd4sQnbWyYF0G@R~=!_qZ(y=O&a zKlg&o;BRo*=7vz~{(K=@$|lU}X!{FKw5p8Y`m0{1vRCS~Q)JKj)7|wt1`*vjg8}5} z^{ha!wbvgMyW94uL?{2{M#|0a5o^imnKZJ2_zsqXlB0DTZQMtx&`0&M2uW0k-8t8x zXgq3?ka4NEcAA-3%ah#e8hvEBh2m;%Q#GA;kkxMWFH@v1s6=luu5 zfbw#0ZE!n!QKPZg^E{Su@2V#TTfetlB?n92?r?OOODjWi7q*t%?NMg=EMFjf`(dDG z*1Vm?T%952xN1f%I?PPRvo;@jltqoQ>Gaqw-MQ@H?&7yiW;uUCC0BzJ25*Ugi_H@D z5nt7AIZ68z;9q;3b4Yu+=YOS{>$TRbE4nJ;(2KAu;adNS*F*@n+$PY{rK+4-dHSww z;7CNlCLA(q(#MJT^22&k>n}xIP<-WVRvZaF(mYDP(p^~4PUYA<#0A)4O!)>8($lxn z)r^ttoX4q3Pmw1z!pAxrlSy;?^C6gG?sTTKQZcs_sQ~YrFx8g3=GTeWM(e$$2P0pv zai^1~(WUt0s=5Kqn@@r*u85lqje%j^k5jd}%2TMI1oW-g>Q_9DQmvu%qr#B^xU`eR zqpbk_m%yjP^36q3@99cQD5?R|)t#s#YQ#)jTs9`RiyM*Kij%29pW7!ouNqs~Y>^M^<%msWles^K+ug z66aBNThTU%;H_dy01{zqaz?UFZ|-@(-bx#Fp+H1SH}7192}f4jEpfG5u469-x#A2- zW=8*ky5CT#HN*OX6dLwa4m}RFKzPiNQTLS1iuWc6lguaC5V|vqJLh)_M!Dc%bx0qp zl_Dcgy`{L86aLGWw-Ps}Mwe;5vafqk`DMez8_$-C0V#FdO$Y3R4Iq?VJzwtKm_3nX zwJ6CNI4-X>yjl9x?$?#qlzU#dq1Jqc#^2>14|+iQCEUFBu*w1pqL2u!`1-SUpSC=T z`FU#d=hfne%A1j`VOP$nR(rl+*FaBTG%??u6b2Wqea}Vxc`s4h_|h#5&?1W}`1)A9 zziw1gCc0k%_PamY7NI~-o9^PB)wH-;xyH~&?W5yO<&i%?Y6B1 zGTj-$3|S+pXfV^Qt~{_eu!yH~9bNlGe~$Rh%aBAx?zok(QMUS&7>qgb`yG#sWJ9&| z!i@MoI5U^Sa^85L?T%eUKK?!Ta2wX73$li?_dtn2T%0U+u8yfN*!gr(9X$2zUDCLY zWJ)Uomu)INoV9J%iOCx)v8k!#r?w$5H zti9Fr`H8@JLjB#@Umt!lk`Z#fIn1 zetLxif-zI&<=NfYiAzetd~y(7YEiQa`&*3Zn?Zzd;dtkVlY>$h|RTABN*&MJX|5|iF*fG*?_Bxs z&^d$~8U1~6IxXpfOJ|>n@Ix=my|Ju7K(r$_)2W)XXVAK}WvVv)t*l70MzK7olvG~} zw-DL@%OQKpl~_!44E~y3B0_TX&vuKr=g!DaH*^&4OKM0&=)nBgvBuub^?DwY$JHBL zY>psWGbUau^^F4$7Z*abD3O!TbBjqd;X{HToPo) zhST{$1kY%pUz5*PkGZs!~V52x>~h%>B-wDsw&KYt};k zccZ_rauJVt6Y!pXkOmu0(B)7US{B|tGe6JN4&cxufBXRk4}TAUskG(2bC6Z)L;hdg zH}EP}3&KVkaF;7uce*6@8Tq3C9Z7A^>Fsp3rZV6&RlIh5U+ZR;0!sYf;BwmHJpB+I zOjU%KcX1EQOI6a6{M1ndt3dt{15|k}E!@Z3Q;0ZLEDunUHP`(5#?tb7_kLZN zsds|ngm|wj0S-sIoggf)%m zL18;ik}bF&2bHG{XKiN<7(d6|k38+!I^CQi2yDSp>u0-|4+64 z*{>hKBA5)WL?5ED`{RzrQyxx=(RUyxSWCX`Sv56m@ZBE;wls8orR=exsi~Z=d2e@f5e%kpf^+*j_p(a^ClpoyZn&k1;A-Fj!x{i-vTUR#0)){k$W z=(UY{deuEjwmROHJfWpXA)K+>YOSZ}>WCVQXMTzS<~ROx0jmm6NI>@y&_C<09jc;x zw$i7eZmt#e_4Pd?9(O&M$;$Tkar3Et`|W1gYx-9sPD@I`ak3>5`7w=jZ zk|=SG4UIAgWX0Uwd2DQMDu7~@b#!D64S#Ji&Ub|cF*XZ>h$+p>fm2_gaZlJza5C-5 z6Ei3{iv01J^F`46mVi=S_tfvnHUHE`h6AL`={k+~12L@TO)!ZhY_`EIWwu@~^e4=% zY&{f=509$$->|=bOHdS%DbKytKsh?#x_`a5vul_UcCrg{h3Fi0|=WZVXowfuqg{N#cFSN)EFIY~{Ik*-{ z$z#Q=7K(^LANRSL`s87(d+YkZ*j7FQ&TM=e5aaY(Zqppb^jNmND)URP*|zGy3_Qr% zZLj*p!04g;`j(|^^9Ij_*G)8d=iJP3k^lA_@N4YdkP9joyeV6Ux1}4(;~g7yCTVCG z)O}pPKVS!=)Y}-7e`@M+;=(sEH&<3tGRpY#xf~J!IjrTVAE;!74>&qHg1*g|-p_4m zY0>q8wg?{?k=0?q+TPx_EZmz$?HA@r=EQs^_!hCdJW{HE&!E76gG|bpGRB^D_fCQD zj6M2f)mAgxR@9%NbGm>^^9*UJ8*Z@COi%hd7U`gC_f8o?nfObsbY1#CiWNF=Pv=># zOqrON7}Sp@m>UcXb=`N_xb`Y6Ec{hfRn_e#AC}vN>jEr<9@7nn#f)S#f3%LHV7bAv zTJ!Yv(Mv%o!CKnQpt8zChZ>iG1%6gn#Y0x4C0h&d3%O6=nbOH+hTPyetnX z(=8o!j4SQe;wD!mjG<)MQ_|GLK^XPmBV=J^{l3r<(Z6Y_@{?lTEuT~;)@HfTp-~4m zBshGz-nRGfTAcPlMO_`@$qx*1oE(>)pPx@iO5!N)ijXWaf?}*+de*%;owG?L&FtRa z$Y)%ZdFdc_JRVM_GrPBr*j$+E92f{ybD;({a^%3uileOGp?R?FNxCI@V^{x- z3|MpxFfW0-Y^^`Au?-HoTc?t1y~l0^_-;~|;+9C?Zs4j>kJ~O0?4zxf^oplLLD%7Esf2k0z;}_SbSIYbuMZt-aL=2w5Z4)4+2X z9Oz(m!#Df<&F_}s@c%G{Q^I553K?;6@r<7`T=@A#Md6W=@JGx9eewnIz$@1TsRA@@ zp|@5640(BZ^teYnHQwGXd)XR~_4eV2=hLXiQHeJE^vf$Mz#AJ;Vt%{f+9y@=R!M*+ zv<{X#&&>_OtEOx)*S#M zq+Q@7=X~cQFf=?|I+`JEqna!#gqbytrM^s#@u?{{i+vBZ&@I_6;~HdAzgW3=JZHlJ z-`&9`=im8x-JwD3ok)~v^?b#=4Htg&-XUB_ccAbuOq{-I>I<)H!>1bVKz||W2!&WM zWSIv}5zpnmtG>Ns0G6~g{tXok>}09BzP0mZDn;I_SK3m{s`ME9CDW1}pK<^C-fYH{ z*f=tmM@JKotoF}U^W%?K0?&6*0;7COC1qu0a}Cnp2>rjSWqIQ3J~l}Xd%bS^P1_HA z6xU^1<|&k_E7R0L!|_Q`4T=$F*nd0FeF!rC zzOe31qAFsvh(|l`_4lXlp;Ug}?CTK`QJ#7GcbC)U7X6AW9^XLo*Sp_BF1yr&S`&7p;dAoY)ST9dhThmACM@f#E$mJ>czdHHO!2FD$eP@vOQ^h0a#U5pQe?%|+ZEHzQ+a<}7(R1GM z{&c}654N>gVvEOa&0P#r#G*Wpzyk6uQ9r)V&X}>qad}Hch3|c$zA#Q7 z8qBw`@UJ}we*SyUPssvbM&fEvveT#6Gvs$ z#N;Z|Q5K4^7PbWrhdT=vmg>SXn`T3qw8hE8Ypl(^!M<3!>t*> z%%`hz@O>kH%DiHSmG zP0!9pPY&z_F+{Z^^DbsoqP^Po8sKx;6w$spM@L)3te7gSESS&cE7!2J&3|k()K9DO z$;tlPL(Krsg|_{5nGz>SDaJj8G~#5tOwc9=}%3>TlR`SKohlB+|{4;=Y^AU1g7Doy-sho}CJhCIs+6u#aBN49|y~=a{l=0i1!;5Z+*`Q`LU|WK!>DQ%*e<{ z1F{}n{h}NddXaOxMe$D=b4ZdBfnnyIcztyR_4u+RavFAv9V-YzNMfv*ghu$Go|fT=Y^7Z3QL z*kZWM*Mrdb>erT5VUJeZ!a$3t3K3M;+(|;P!Ti#u&xIBi{J?`5taV?BGQ`HlZaJ%8 z?Q}s{m-lc5&h1X%O7rpicpSD`7y{%nMdf9G~ z(c6Sf8Y{It?BaL{L@n^Z!PLwG*|EkJ4+d|b9LwxC6O%hE+7G%@l=z6oX=WMECC}ar zXMmm#3=LJuMwzEk037emr_JlM9E92cxB=F{2*|M5U` zNnxF@Mg`Bdyv4{~)ewtf@P$|LYhmO+mEXf>wJ`*cFJjRik;u(D#3)lD|I2Pn{*Wm# z!O+D$$hC;PyjP!^{TWdURbAWLmYJTOo&d!NFscR}27m)kZ~#YpPJh+)n97YOW0Dvd z0N$<+8Br>9tN5RAf1ovSajVQ%>*QLVeQc4*8t-Ad8461TF%U`%>^m#=YK<cV2n4p7t>(qW<2bcFPSAoXKs>TiUfSX{dbH(cM89-YE-n%1)IrTi zAML%QlbBcAJ=$9ZZIcUv3ldI9NLV}faA;nhwAQ3TCqe%-(^N3vE!N+fI4t9%1iw7yL)fBHZA$Md&!d^bZespIS7CWHws?Okrlq{*^S) zKHCmq&_zY)tf_OL>gnnyT9*;@iacU)Ew`;4k_p$myCV&pR+M}589nkeRQA>Z<>oy> z<-XVPRFjpJ)$hW>N)EJ7K?h5$MyFV@-ocPV)d{f$g7($bwcRjLfS-O0={7MjVLMEZ zR`HR!S}9Th^sT0*Mo#dMEqC?Dx=MODQPr3o+>dpdf~jN)`99b#LtfPvhAory_c{B& zi2utMEG?l^a~KW1h?-sfC37-34U-+XWC70sZ~^9y2Uq!G@0IRV?PQ#}@VPSNfr0QG z;3!3^z|~U)t)w=7fK!l&2#fJ3Ezq2yE^2;4fYB?-5G)-kL(0~IuYGysPJ3jE-Rweg3y7wcoored` zTW!p4hUP>CJeo+qh7$*JF&MXsn~c}9D>!Se9T=uF z#FQ>}h|bs%T*!30Iq(M<1&GHc$5U9IR_6!Rm+Z0Y6n;~tK35m1I!so`pvx);l%LsK z*f6(82G19qp65~Y>Cw+tD?53scQ`sMAeK!D1XIZ@I}_76X6qp?M+;6o0gbM9tnxJj zx!m!Q&&~t*cI}%KWtl8L@Oi%=s`J;R6dS4GEnOndO~KS+PncSVD;<5h+r4dn*|kwWrvs1Heu3pHP)^&Axjd}vHy7;1m&V|zU_pri z|2K3;OiBtB(~pJ)9SZLX81%%7oF?}9V>iHXqb4Pc1Cu?m;g!CAowVb9ME#&kVi-4f zCh3jTQe!&t!HReM0Io?i7ci(i8Mdfy)KvJx>3BO30S`N&1rfr1EkBw=DL_+yGw!`B z1Y`>FXsOE@?sZ7@QqVl(eaGLI-!snJiH}M+3DQu zZ2zStox|LlVWvTsto)XIEDm844|&a93$$%UhWsLlm^HrB_fWyCZQ=62 zf8XfMPgMOQVsUoR(Mt>_yxuG)#e(a+$+z7Y$7yg*7aAy)>^o5-C`)(8r)TrjtwuXg z1G$UezK-BCh2yB}kEi+Zb%~7I{G!{31Vfj#JyT=5qGfrX$y2ygI@-B5ZpAc&KA~Va z4A!)tmpPOGLmC7E$mNW$$Z`(hNrSV6GB(8m@2a&2X(7 zl(!py*LOo_pwj+Ht*tU>I##OgWCV2P*v3tc2d<@MWsP|W!kTP96J`Kk@*(*=DwI&O zzr}lIXiJTeI}U+jdJBcdYJ=Jg?#d^ZpUT~}N_Qbpm&lr5dYn*iEXm^C@o3uPw!lwD zz#Wz-Ym5AV^qiFagwIAH;gzm#i1quKMG#f1B3O3;3Mk38v$JdM9s}ANJ2^W8Jk{D= zRS%GZHvnmJ4egN8hSB}Wab%Qcw(yQInoLz7*IBF0#Br)(_<}s5RBqJGK*GnPj|pB} zHoa?z^92pEqC!fk5aoRYFz~xyAV=G&#@d-@;aq|5Uq0Jr^`_x|u{v;4i?x+Pud^#Z z5? zF666-Q`gt-O%f?6tTUZ-?ojNLO_5v)uAf7BWH)I@xwgJh;--s_I&JN*a@C%5JR{2! zz?*NCV7ly6aO{utVS(1~SGU*hE6AD?{)Wu^@*uYJf}x|_-r4T!K|OEAUGDpe=-b9K zua_M*KJ(F%r!3f=F6;Fi0z7xL?kh)&`%Avd1Ff6%i}jEet2c6IOa9J&1)5E>Swmj%-D?ZHr)A1BAI4O@q|}zl z6R+J(9^Gy7^NZfaaMCVt91k68UfvW33XdL!9!>KZ?`>Q~Kmm z_nbLk=&pzgeTH8k;id5K`UEygY{PKCl?Da2^kXgNBQ>AvXapx<*J!U9xS<_Ef zJ2Xw$@XxGWIvSy@WnK|&C>z8-)Z-H#vb$= zXGBwn#qA;%HI8pOAvYLrqvKT_|2Aljj05z5)tSISxptL(2E7NhDEN)&#^AlszNX(v z`VlsWSBmzd-akeb(N+cagb!}Ipejvfj`x&m8abjl(`%9`)Mxr(*iRt=UtKOn*c*Zv zo7}|Ef;Mb|W#Ch_2`k~wcBPp?KTS5Q;RLA~3)bfIt_Tf}R}6+_?iA)?!h_<#e`8qq zXxS5`N=VXHH2U;Nrq}F`Novitd3m`y_MN?Y`5-sE(nczj{c#72FwTg~wiK6@cUE4# z0mJ34ow-VO`j>axB5wSLp9!vWS(4M0{Bax;jBtDjBwT=7p29 zYp?ei%BhNCfQ0}?W2#h9=kzAxd9gU(euRnA7hHRcz3&7P-PI0BhK;jWvT~ zZV)tNEm2wqUnBS`*M5iqUPB!48V;KE4mdzO@=5PD;c#}y(Enj+uFhdQVKQ3Pkk*(e zdg?akZu)T`CCrEvOMMV+k@`^Dd@gVHbj(#_m$tWJ{Q6g8Ur$ddFa5aM>D_{h@KnTh z*Mf~Q5K^K9r=PnDKL4-eg3F6 zP8gs0FnP2bRcmlwNNON->B@RgqFTQ4)3yKaWo8aoVb{7Wi!+A2Z!ROiT@_8TwD&)W-VmUVkQNH04tKXOwXa7xT^>CkY3$uam&ZljS29+!SfGw* zZYk889e8_cQ;c5w`s~`tNS^oy{H1#vQR6vL$m!*h|Nh+vsTzH9=A!MGP%h2~w)1|? z2kAaRtM1A1>Ja~sRpUic{=mCV(V0O|9>*!%8n?MAOTlaW=F4LQ<-S&W#`7C;vqH-! zt?h+h?0uC;@Z08!*ga<$k`3Q;mvswe?@A_LX_s9h3a|CH?6Ws(1pRGSR(x#99<#ZH zAkmhz*^U!NpURF+(_CD6BfJWgwmGE0)s5ao@os+<)Er(o)i-{8_bm=c8^*@GjURo< z`XzF6!Tb1u@|Q1Wmc^L>Ysj`YrdH@34?npOT>c{diU_a~d>b<|&srmi4geE)4eQBPUS87VXWipo2_ z3K00z@A=PKxB=Ur&+C3{iv$@Y@Z(Wisbdm13EK%X7C}S)%~@n}!L;Zx_WgFbqHR>d zxSZ>JjyBgK(I9lmJ z@_i+ar5!6OBji=KlJ1k3aq^GaDP0nUE?C)zh;6ifoyH zOaRZQ{uQEXYRUxUu=jmhdABPnoPJjY{FIYWRaMPwWBb7m$nBrBLBl{VYJ&ljw)@^8 zKz5j+@|a_fbAM$VQv%E18?PN?Ksx$Uj_xfHPU9_PkYj4+vO5Hq^!A@blBEc^rtnxd zw#D?LBoP))Le;bO)FEkCn25=u(8PK#|G_R|K4kAvEuRKs+46extA_Erw{a*Gy7`#{ zNPZlrf9^PHc*l3-7i@Z&In~cP`b$`tPb|gD)7>#A#j35XbsX|J$*0BE75p-S*+SAs z)2%TPKWO_`G>k)fFB>n7Vr(d#MXAm?RW0Ki`GRoIAnr=2poK1^@YRbF@C^#}Yx9JL`|be|VvS2%*xeZ8rU~dMiAt zbBte?cIe{k<6=e^7qI}J5vVP2d5y&E9K9)5S!y+q)qeRfhdMM!0v*}@Qfxi>nV0%8 z45zyy3qFbbV`++$p&STAz%fD(X@N~u^+}mOPJl1vQ8_><8uS<`FTe%Ig+9ghU8szX zxY39|JEjnB7~+u3F`dBD#p7>q20P4YJSu92x*SeH-nbmycUwM(e0xI ztq7g`23_j_vWefcSh|9SBbYDR6W2taGB9TLO#c^WMESiCLSL9PRm|%*X2klonGi8P z%WE<*#gPr}^QJ5{iB7hB`|CJ){BzF1c$KDj7<=o%;POCkm%USR z-v?$2c#ezI#Dn7I%Yqpm@Z+hfE=+my0>G(>bdR^BraD@Qn5Z5XcNhNt`D;!fi}TZ_ zW0cwx3Yoy`Yk2*SG0E~3>Ln*SQKamSu7@dVP!KM?% z(F33o@rSl+GzCfdAD#)H7>S~N&@XAZgr==Xu~gVDUlD>le2dKEq4w>s6)C5cBsFpH zb3?XfijOGXe2*lNH|kjnB9%HIV2LziFA+Tk_Y;|x2tQW>aKrNQsHCLnC%huh32v!B zQ_*zxg-Srr{Y^k1DW5Xs%kvCYA9iA5;^o!ViAyi5lB*jcb590rzr0BO z9oYc?dGp)tZ!JI|84anTW#glU1_n-`3YLqa+6#P_554wMRE(EUt0vfUSGc=PUA^3N z_hWEhKFsfnPW6jsHf4j9;w_jW>fVtqUEB7!%`kA?|h;XCDC?k=hO*tRrI) zJXT3U?fo5z@o#KFA{gMDpV=7f3hP&~%QKu*^?;eO72lP(3BRwqL6N599lu=oEZpWJo=_7RiOq{JQNcE z5s?Hf{EJpqJc5`qjT_iZr7S!3cKpmrOYjXV)`6NY5iHpC^+gX)#a*eY-dC_8W3#j8 z;&|`}s_+C$fD2`RnILZg`hhVl)+3^1@r$PQyOap>I5%hIKYH1ru1Pi9X-zP7B_@oU@cE%}gD$&bE|=S|3Z{^$H9&OQt?Hzg3d#-oJGwB) z(->{l)R_Lu8+<(|2T?%M2>%7I1k(NRw@`0;j8g`Oek@?}>uM^ES+i|>l8JVN-1SwW zUVi(_K}zVcuvB2UbKXA|4|EujS@KE$TXEYy!$Bl6+uD|8l#}iNWb>z=PyLH5AFH_uFp(PEo_V zenpNrM*+xFfGX~$hpNY7LS>$6?6dSm0u} z1915taSB}O^B-Zk?cc(7U?>hIu5;eb17jDng5-pim^k`%ABRT^ZL&JiSWgC&150s8 z@wJDRhm*rm`AT)+=4X2hyy6z`V5XBMy<^qG(BGk@Io zwlY&oWTPupfRlAD(F*&dumRdypyqq_;Yc*$k=lfp}W{k;~;BW)VT(d3&T}$Fi zW}i96*Mii?J(bITLThxt8e;nVdRzbEbbm2~I!Bo`JM4bd{sFUl;%Qz+O`T3(d~;3k zYy{iV=U?(cgW;@{H1Y|HDxJRjhR%2fM-K?(Cca!0hRJsgpr1~jD$Nkwf6T_T8j4fP z%h%qG*IH?z_5C^~4VAABEWJL^%iJ}=wHmKw?$oTwW=U)2@{exe5)@uHIL}2*9mZ^$ z(rdva@sjs_AuwAAJ{EzZ&VOglgi^p365i zEg_~=gF1uiI-R!?Y%=B~n`3c%^y)>uoO-!k-P4DdIA>=3USGu+@pl<1A8L|BU}+M$ ztS109Y}{K<$%N?LEiUkzf7J5nb`RWrjtBMM9=`GipH!fBv)*rco}98I9jjPTEao6%kt@C4 za;^sdL2u~44!@|DhWJOM4pdyR3Lg!kjhtU~q!AYg?C*OmBkF9A`I?p1sY&)O0=j>f znvA-yxv(WV(@rXFw2f|Gu5teQHvQb&B?E(E%I4x3)^P<4U58#2%1twF4Ho|_1YIA6 zbuCm12@op|+mEyBbn~>FNJ17W1(0B?61=XNbB>4;SN~jHt?oG$9yruZnZxSYVr|vMw>gZ-I^d%cFUDx#WbgNAdm;({MWB(0;;zwj8V3)h(2{k(A~o8 z07bK62jo19f<_3r<8+ba$-{+%?9gOhgdkJVZ9N(Aj#jdY(?!QebCnR&K~y=G?uTGS z4X~->xGJ&2!^>BDQ5svyCafZ%N-6=81pu)FpgRSzxABKKdl|5SGfQ-iF?9>y1?S`! z7Si$YRrkI`$h_rDZCl^~FnoYYT{^uaEEb!xQKF&hB_!||oTmG)z%SZzT{gj|3lBXa zO0)%k=th^I(t0PgP;Ge6pf`Ex`%93WpSDP+YVVDrtCgDo+pGEJnmmqxhRAqZR8N1Q z{gY|PPWS2!>+l|Y5l7g?^Dfye<9^Vt;vymE;nQNnQ(W|*XNcS0Z1as6Lx*C>p7mm0 zvq#H-J9un%JVHS4g44d~vk;TVs%n${rJ|xA>`42OEXDkLelkg7@Pf>~|DG3opR2I_P!cG0`A>BaQ(k^P4JE!bb4Ion2kG)aB3F%e zv6PrJ0M+fDR`-D8^f_cqO-(}z>nkhbPa|dW2k0hS_ojw*A|XXltk{EEYJba)zeJ*6 zl!)39Z0gp=Y!=u0<{4qZ_}B@h0p5fVd#cJnprrBa;qGq1&rA<<3c<=KB;@+A!F69% z`!JG8o^&F8PN#uiUW~Z28(!~7wae<7>JvGQ2VyGlI@R+qSUR3@+V0fmXkd5MrD*Nr zqMU1tbWVdL`Spj-+lPXjZ4+>CaCrj+&R2(P>m3-YksQe(QYW;-7~>|Alyjv%(Waio zL|N-K7X%Fh7<%xoEsA2JodF!Y;bB??SsRta^7U( zN%quH(Oer0{Y7$XSi3!7ZZ(gd>#R@uVi9q{qQuTD#@F%00Kee|Pc8=%6tO&6>N?u2 zIoDeNTr|JLsAOuxEGH+|J2+U$o0}!jf3h)Av68ia;C7TzvzAb)`Q3nVkR<09e1G=x?j(^*VJ9vg8wA!^g(PK#%N~Z1@3c&Ma~gt1<&7T{75=6H?tTO) zCf3#ci18ht)&G)XV`(Y;I%bw;QIURr7RcKEX_heolYv#~kfuQv^+2Ct4<9A8DfYHy zXnfm3JG{!XzEXgGu-Bj4Wa{XY8whzTN+pPO$${E3aiCZn>JOFeKpke!yi1qoAO-5J zJEmvY#{c|z1-DBxFWIGy{5(z~ileUnMAW5ansPkFo<6|S4 zA*K_`BH1rRojiNwO>Ubq+E~7FYEX-4q+kelR2v%&%~(d`<>Gtu=)a-vOLP6&70?bH6} z7~>rd9aZaNFbm9x{Z!1j5}I zr)l$1>x5+L{0Uy?B5QG}-rWX_l)sk;_QkiR8~n3N8rl$u;l~xlZ<8bpNbdf;RYKV> zGXE&y@>Q0-y2RVb?-N;`tpA-;YMN$ynS%BHQBJkXw4lP5(81~d>qN|$Zslelo2$r$ zM)F@<@Xu@3qtsiadiumvbz5-j-gfnot8Rqo_DQAe=BVonn)RH`zep(XYbwC6HD1tc zd;4?#|KhxrYorlhVS zL6h4qTQb)OIJq)KvudK~znRBBsuHQD?yx~LTki~>Z@J8SIGuthy z@Xn0{>5$0{UX`>i;|$LPJC4 z|Ns7j?SODn6C!)z=SWlX#|^ z!uLIHoKI~{N!kT5p;wmA&)ar2sPA+1G+tc_-_(}z7ab+ELdh6REx9 zxd#g!iu~ZYgb%$ z368r<9_RN6GOmaBW_MW@_1!%$b8K|}mpTSzm&#FMpI=|<^D*<=)tqUsb<73a01ezc zeSLDtVHl{KNlfY`n6qchzKHgpb*pM{bbPvk?#<&aZ3nVRUQ~HRq?~xz#i816cs<$O-y*g5A|q@!Z=78=2q36I z5#l0pmh$7Ip~CkhSXkk$(1eLy$(z)PIWV?o?vRn$DzC1)xzI`wFPlTcAcd0My0jgC zg%z`-BA7M=*SapTOaLp!LccY$85K)q0=IJ;Yt{j3_^4fsQ;XMTLM{d`vBvf&2$7fMj`ad#GEsn2z{lF9;?jjR1y znpj|~UuGhQ0bLq^US}w@-QWIvcE2F)f~O$ufMaP+%zoI9?cU~13*U3sfDfAu;KZi! ztNmn%;q}y#FtAvz~I6HW7Hh&xbwTAm0Z?srWYA{ z1s)~{G>YLveVz3#f7niHzu#SllAe^zTFCLd9lzs#UWt zWeGWnN9ez%zo_*h)wd}fIC&U3k<-VqeE;|lJ!@?y$V;kp3az$&g1L6I6+tA|)kCXVS2mK+HSyy9 z`DHmIs`;jgi@eR&fps~mphSPVBNA^b(r5BX&cV@3CrHhAK0U86M``m7E1%3CN;ew; z+Aywxrrg~X_hE+T2W=CVU%Za`g-Ag{t&rzu6azx)57QX}$E=4}uK2+8)=uI=k?4=^iw3YR(pRe>M6nHzZ_~ zL@6_1u%p_NH93UO$SU8k>!?_p-~JvNUK(t+N%LcIAAMI$n=1+-#uLHhV`qjOX}3a+ z=2}M-cd@ue2cVIJ7I4p-mUFFv?%?(cZUlDpP|Khb#kl)b4j z?CGZa>umFn1C2dB#`6`m1C3|zr5+72viJM3eiom~GoqY^CLS}-E%`jcW(pBjYTNvz zqfpnZsdrh-;y+jy%*6SoJ9f!|C&`tf~02tzogHplX8Z0UKEJVFXDn**;xdMqLG08w<^4H=&i6l{}d6(;=ZP^x8I_?Gbp)H%%Dw z+bY0j+J*7WW?L~S=uvWfN#;zU@zTNZXT@aMljV@an8qZ6zD=*Qi2T#D_z}w^IxP1B zrhC<%6B>mm@H-Svc1kFD*VQH(VW|uUbp!Z3~ zx*{x$5bD5kr|=MpWf~j5bV3zen-i?dUVQ18-I1v zUb|RVVu#9tUlQ`WKjT=S#SBe%yBp$lVf1XfP=K%O5#7ZbnSaB&tW2mEDr4_9ci>jf z#i`c@V4Q(eA-)U#*p`rm?cQ(R7-jf$OB>Vi-a4#dHNAt>GHiEV&Ir*wNpz`7YbQ$s zV|?GzZH_E=IMO7;Kj@n6n`BE<7|x$%@pQsru1^2i7b$rLCzEgC*;?}0Y%b1d!Hm6} zTSemPnH=vBe)bh{py2kNqOMP@&Ai~awnt{<9Mxah>bTD8weThTv}x^_gcd{*ps&r- z(E7LmA?BsdWGyuUd|c>EqaF(Gc=sKFAx|+^0nqQ?6C|Q#K2+c~ymf3*f3zC&_9f!86K)RdeHdQxv`SZiZKoui+x%b)wB6`0VOYW-pa1ZM7mKAe}V~$u{{T`K(JsoudcyhH%qm z8}ap_g|JA&GCpI4MBfu6H&uLob$-;B>}n`ss~;|HY>iwcvyOoU%Y5s|vi7!s0!!XakiJ)R2-+ z-_OzNgJU6r!);_qjv`jcocSo3JYL;EgO8H@j=zXa!s*REI8CQ1#K^>JYfjjWfU+w= zRwY3n5@7-^WL9EhJ>_ecU9dcT)3s!@8PdFT?#x@>{QDsc0enI63SqU5JY<)nxcTry z+-!5rcrn)myX)VSVTdHCiR9y*+eQ!MnJT_I0FNfe-bnP7e{WIm1b0Wn>BQUf)gckMLUfsFrqZQ0>{{;k6&Vx!!bB?Xi#Am4Zm7Pi78JVJ=O%9cRZ=J&3ni(>I;P zuV%1ScIh0yAKuWJDRx6^9?Z)0B$Fh5&WqJY`>}AjuQcR{gjZ7NEpy)V5d#`t7R`lp z4^#@>=-m=3UfNbb8>^EC4|Q|x#Iv9J-x00 zIXhC%{m*r*p0O&j>CN6t$mxNnbM9Ld4PaCJIBLT|uI884XGR`wp#g3Cv^MNIvK3O_ zN24QVI3wSJ8w8>ZPcvh0q?-{y#X0 zEa;y!tD;6fL~I{s&SHUV_?Xqwh4}{8`a%&_`o7p^Rbqqf%^Cv>J(6_?_Yref7-G2; zVwYDE2cWqg6ZXQD+V+VKY4J%KYz%3KcDXWi{QR$RH<|C5w8~gX9l`6K91xDiq{sup& z`W|P7hmC-3k$ElX0q-Pt2$JF1dup&u#8DFvHqz8c85#%X=pq07)>$hs)15#$^*u61 z1Qvq0^L`~pRYT~Z`P7B(u#%UTkod;d^$P^riGZL<`!gRMq2SOaGCN8FkLM z*Yfj4^pX%S&Xn$J2N;=ing7lgboUTWn>LEmujYv#^?VJLs^=WAb<+tfjeSBB9-b7%fsrwnOWA*g-&oAJ56e`0qN1! zoKMOOC1to^YA(jH|Pa2%B=RZtbBJEQBk#w=A1RPGo7)wl1&$>zTWW4JQ~pX^ML zak$)3G~=&ff0wIw4<%|x#tGrm+uN&eXw0-iQIQ(sQN4o*J)Y)Cy6gS77NGrtAX+^d zXG^zxwY*?$oE~Uq-vsB|qPKN6fdRy?zIsJWfaD-(Vt0>glZHJ)`~ zQh~^qp@2Ut3;vZ5Jtks7Vx;Pr{mYTiPy`KE_qF%jt zxno5g2JT_?K)0p|*Y63;-RwzlA5HMDH#Ym7Ser=yD#g=}OUvNKgLC!R(N1kywa0w=L{(?r%r8-*A{f(xS&+4xjWt}C(X zF2G;mpn`tp>HNJnIHj(;t@c#LRXcd(2|iDzd*?7l?bweWs;U!mw3_tOFvGAM>mI)J zuw#lqHsdHQ+b4S7=kwZCWN=>sg%~^)b_ne76T_=JS@R#f1Kr^7?%!C~z)hQn_da$g zgB5`ZEdFfcSv-$^yKmYT-E?1!F(Q>gUbKo$r>AVx$$+H1XGqZf&THnp4;M+vt#j#Q z(1$jp46(pA9(8~0vk3aVI-mA>0Qb#0pAmykx>(DO@9Ew}I7EwMZ&_(MN&uF~ZTH~X z&6$xA76t=7zC@DmCmV(cC@I+#R?s`Sn4A0A%Vgn4s{qlr`HhTJDplXtsY~Jn(q;LC zzE{qcKTXc_RXAH8Q@A#|&2zNa==97&u1TD`3pt;}^I-^0oZ7Ze(x4|WuMXIC&MtCu zqQ$m8?Oe@Shv60Wxmuob99aj)F~GAA7RnPJI5^ zEi!JYy9NY)x)Or9z(D}~=c4i)33Iw~PfSzvIePY^CGoZ<)eYiLhB$9ju8xLe`G>t2 z4jk6~s7P=2srUO`BWtynPb!S2acfR)^lUNjFsK&X^pxnbhYt`jes=h-^0KD_^#jR= zYve9FtM?201Alq-@{Ex*+sY&D=4(;C+2cF<^LB!q0DYHvBNLuZo{mEb7iQb~q0b-S zmbG{H&0{<|*VH=&}yIiS>?a#{HwH9fkuFk4?2{6?mVb*h^K|6{VTpF#t;+OEI`tM0^EgcE1k!7Ll zUdiz- zxX8;#GtZs3FWI*;>&B4!Bb*x19Io+gl|93)d|sW^d=0(Q#r56=>}2A@UeO8eD2d{R z6;gA(3$dH?tJmS#4o_ruuLpOfyA<_$#4OFwdU_%r!025r}5nuqq^{krhvRxY=v z7T>-jiF5)^%R2pD=nx!YR^V!fg^8Y@SGE^+?5(aCZRZ5w9UO2C-B^Aa?F?hJx)4}c za))b~zTuec9pUsdZm9kKdQ;xiWKjrl{?*>qMvJlg&5W@NUJIQz%m$nryC5vYq98H@ z#&{GoW#evkn!0{ExgKbt5Z-D;7Hj!!-3VEH9k+qGK5y7DKz39-SjRmu;gd%a0cx#! z^vGeYiuLsOxyN?6tV1;>|HY2p*)f{UL{IxuzhWz^7%D^1fFxS~C+`Cj``QgLC85AL zu>grE4kf7DIld^T84DRYz3~!1Vo~r?^d{AELr3PD#4Z)g9oxs<*|58@BZ#V+zl;#2 zkiysq528ld?%IY?k<7Hhj|@4mjNEqb-H-a=JH0b>8K6-{4pJ`&e%n0k$U0rClvtiw z4z?az=lgzR8=|pA+EOa|krX6A5zmH_sk9}C4qie+h}h;wsYN>TrJ4--?I-uv?aj}& zj;oHSx%}3-a%|KPRd}^qqHZT%e#mQE1|hR6gUOa=Bn>HU{^qxjItZTFRWFZ!V*xv} zac-v(?dT6NN5DH{<&|*b_+XO=o59%F;jj)_;k`4e+2+~z_U7{9VP#d0N(fwS$ut$Vu=`?z+7>6w*C2dl=Hgw>SDhl*ug16@HL_$&XSmczn;V9?T4O3RpD7|7<=m- zXy71)b2>jG^yut>K=COd;rkgPHo>DES?%9L5%x}7lBbVjL*Y#+6wTso^f!| zGpt_m;+3S2vZM*i?B~9ckGx)B*>`*1dLrVxI81P-`H#A$qqvN`V5t&eb{YfFHjLv62;=*ARIW!}^EP!C;NmZFJ&N+5Yh$-gm+yuv zQ;&|PySm`$6|!}43m?_bzrmt|Z}r2{*40B92k+ka;3i(`j0l|DO~o&DcD!(%=cq#z z5*yGFpc?jhApE8hkMu8=S(2H2gdIdrpZYV9&Wp7LmsD|Im$OSzrZOOhN_NSW{0XmI z<<3txnO|A0HABMgV}(&jG#Gp;Ghhp`Ya8aAN7R19L^LKyv0!xJ(T}dK6eP;p+Tt+G z%UjD)L{v81P3V5bmM1T4o0S#qHl{@2 zZFL=&QkfN};o&^gD084%$$95d!X&>Q`^_K@>NWM@z;Z_#?JYTQT}%Yq8$m^FCjM|e zP+Irb_m%s=HB&QlhasCjn`dC-Q{L^8x8_kcm|9`T{LLv^liJ~(c{8`MEO$}YdBtYM zVwUA4OG-?c^JE6095p{;^d$n*q#mBA(vPOK0&e6bxoOoZg0#kpESU@m@~cs%Y*NjuiG3{{qM^j$`cOcYTbJHOOs!w~xC_7Ki~;kKMrY{0>%yK#2D@&89edy#S3*{lWt?>NoxH9d#I&>#ORk zotJe@e9^T9RW_v~xM?n*xDcbB^EOiWwtJl=)Fxh$mP!USYmiy$8agXt+_+-n+12f3 zqL`&_Ns9tDJb_(7wymwUqiv({d>bxZ%)HaxYJbPqSRWKSMHl{TtN)8mkgKb(9TN&S zjl^8~^?C9givkQpmMPOzXCNapGg*K&WBrNh;O6(p1ciEI>?SH9xJm$%%s`Yv!)3Q# zwEN(;woo2dP*5tVmldObx_ObQYBfQ;$EE1fXfvbTu1Ney0ZgLUU7u!Bb0c9zfW>u( zUHCfoxLrB=yJX4U^zY&sevZVWRwN4S)2!Dhb#4Vh@4E9_H~I7ijR$`}>rK2C4w;5T zFtgPMyo=ZBSNKrn*^?Oo8S>tXPW^0W{AMe-KT-H6$*f?_T^oX$$mT0kJc_34lxn25 zS}lv>V_LIU)uOx=ZX5}kUEU?&gEsr!1BIQS$@&FS<4{sL_G)jTQ1FgeqziFIup{;UoO5PP21Ix}cW$s!xGG!@RxYX_@urBX+A7caYi={*?j@odtTU*2DCB zhZIsj5=EkzcPM*_t?z!@!a>(*IQF#DpaBz46-H zN$RB~=(ZV7B^l+a#a1aslc^NO-g&L|W|BPQ$AWBbca7Ydz|PZ_jw3Z?Z`^8_x52k{ zc4L^3(!tzn52S2j_f)Ihv~M}0Yfjzh^lxXkL3O&Ndts4ucCVl6#q818kq6C#fzplG zD4i6`o*_HKxGe+cogk&g)G4Z7rzA=QG+DfIQ1HR4*}?B%uhz-*luo!UE!m%X=50h3 z&C3ZNTxw#I?pJ-oOCvY4TktBsFmv_8?XDR?FJA|U`!FZce!uk3Ke2I(Z9jYQSep5<} zXr(Jovl>Iwag!J8WUef3o68b@X7YqEbw$~acWVXe;Z+M-aqPMs`Bc&r);RRiSeadp z?IwUjPVde)G{H;y93VC2bKPLF$&)_mQF?k*mk_@j62l2900SpW$X> zE?Xhnyo0BmK*PdSag&hC7xnB7F;MBF3{N*FRV9|;Zcl)gj>R70*~hlU#+YyTw5Ub9?5|qeQgTol~*@;sNHI;$GtC< zJ$brB$upGz8uE4s9Qu)~eEr=KnIrG-xc4>iW)mUpiTJlHsAv7<80WWX249WK zBFjsC@1_lyG=JFaZ6ghC5qh8+DlqVV8U7#ctcw$!$rDFQ#(y0yYryQ;JIg5X?}*79 zozgDF51b0D=0JsuU5;}3?W1LAp%g5^pDhs+RbD#WoudC**Q^tA!N_(iycbcPfB5#Z z%c6m9%o58-s8X!k4}774aa&^BY!noGO1TMpyG2d}L?iy305=!^XADLki+EU4NB*`< zmf4)jGq1PVum|GUrx`V}0J{+Z+_4gHbvdEynC_jKaS_QCwSx`FC{jupI3k@i{pYh) zE}NxU0n>jU$7sHmsI)b=G+7ZLgSbBlWhS5>Ddx2V*fL>S14{I6b~@L~xt|`#(b~>v zY|1??^B`_(U^Q>&DO~?9@#427WZ_2o<4=~)wW>DPz$2hl5zBw)n(Kco;zk!SoiBHp zv=P9Jn_YEmJ~nb46qq7PnH84W7s!vTKffd5$29eU;s-1O

?qb$EV7puS(r0~C7M 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

x2v0fvJN04|2EsN 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

`Fa0TM8$dg?=)f+4s6d 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

rwHPH(ngwy#|Hhp!& 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 Fe*qns&LRK+ literal 0 HcmV?d00001 diff --git a/docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-hopgui-toolbar-icon.png b/docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-hopgui-toolbar-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e082a32440d6d0f3bb37c11e37b088e842dc1c24 GIT binary patch literal 7430 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
0uxb9+c>j9#VZ8q@EOc8)um1}l+&Kc` zKN!RQRbBYc^Y&Y>TR>&Be&I zw$$=b{p}SkbO(AxQqm@gg`>XYEke`5Zq|rZQHP4l^TbyEy@n?MM>g4bJ&op9x(j3c zSQgH|!t=ND{7sb9+~of@Z_Za!847XnR6pSDbb?KKhp(BRdI!PLE>o_~LYr_IO~kuD z!56?#2w2$sVoMC!ruz}Yy(n|D_4|LGgHWmAKY)8TK%@38+=z=M0qVPlS=k*E(`-R` z2BBVe`LHUH#?;$fQMu}d^0#5cy_1KnBxNKfkz6%=tb}zbc*RENaQ^hxJp_x$tr;|L z{<4MXU+j| zVLOX*0NmXr_;B5E>947#H+KfMbSP45&sT`0z2))0fLm5)He8aN(RAJDDZr+kDQ5OS zZT?1*mGOlg?uS4iHM5c9?z;nTVdI6^=Nd*qmlto}VoP@MznU)7!#Y%BlJ)$WP&as8 z3jn?7ynCSc<8_1wUu@y)#yE9Ir#0&U3@<;l_V+7sEo}U@$ZNT37}u52H|#gRB=mXH zvBdeY(VF)&?_demAaAV$QrYhKMqLZPwDV%zAOOjb#PsRmSm5^$R_xZxe5j3$X7*NV z?7vNUJ`C?owqgy>Z>kjW z7+g&342>imaT2Oj>B=q*@M(4q>(&2V@TG?HU_<79VZA;)%Dkcw_?G%yR(NCG!MAr> z4~0jR9uv4tG7xhtX*)XAez`zm@9&NhR$22hIMCdLYMPHDh%-lS>>3q^L?$!cVp=`9%67dn)GDhBNT*rUPhkv1IGi z<((Mx1{Q4zZ#YkU@tB=bGAJ&^6Sn4k#2}Ob+jmbX=yE1vtdmq<)Q3-t4x`5(o}id(N7bO_)42 zUz|lDs@E_dSSWls2NoL~$*H-C1>Zrd)r@`_ob0q3I-X<# zySYPn%GM}ub{9iDz+Lt{T38;~O!3t`@Kr*q0}iY@?z@O+i~9+buN7rdZ$3%?2OO4wUr?zD;pUy8~- z18rImSm1Q#PA=`<1sLg>f)bx=cy!<-^dI6q=C#m?WqSHPG%K5pfV5$|)qiUFrqf_~ zOx%xA=~Ewm{gPQ8IF!fLwXkSzPFcrD`^colE?UNo_z{WcKW!r9-PLS-bmpq$SnfHA&s+`3hGVAbW;Jn)_)n9Ej9kAGvO zJKhWh@s1+Y|6+n-)AR+7A-zVlb1>NF?;18}oW|Qc)ycx4(W&EN32<)7_~BC?Zi;ry`gG|gBYq(NC|D{VtYHHa~o zVEwH^Rn7S41+S2#nzec(Jk?+{5rhYMyDuyOANp23sMPFYQ4z-- z471Hk%>pl-sWYh{+mUlOWE!v zN$1SSjxo8n%(+(+X{h~lfN5Vzu+b`2!?ulkHdjj_N1i(0EAgAEN8VG+&@MQ#HO`VS zRdScrW?URdSxMsygq6RP>tzeD;(icXN^z?XUvJ^n>sZsyv3AS zzT%CEV(uTsIw=G!4y;`7i`je6y3u}s#SphD(7!miw_tfXN7nas;u$w_FkZ>ez}u^h zO!5kCVUFHz2}03ig1jCev+AcHNyF>TcUmphuH(lLSkFSzO_tHBrX)!3z^k+;Sk&QG(Le(Uv_ zEh<3sdsF1wM2|)~*HbOh5F_V1V2&o>>4JgY3US8VwrG=aj;HO?rE@*a4^a4bK|nE7 zjVRG4a)^Caq7#>N;SgGLbFQf^55V@;9|fh`Yw=3x4E?vRI-bZ!2DTBi%0yFmG*ZJQ zBoCE@M<3U9mZv(}Ik&$)Py`pgEI;4uJic9nCni$G_mlen z6f+8w)ZvW}*C*>C?DAdCf3dxuBT0S@l)Z8C!M`wK}h@qnZND-+Y^U@jlWF+X3M)#=Pa@< zgHjXV%c%c@lZ^j8e6)DsZ`MDJA~EPbFg~}{k$kI!fYPyuX2QNqcJ^xsPgsCTLFERp zoCErhMOEORp@Ply{3{w@nRJNofl~VzxP)1dMAY3_9iVV9XJID4-eD z5EBcRD6yBj_2YW8>pMxEcep*oIwR3?jd5{(nKtHmMUo!$xOu|#hQXrq52w@+X{yNV zS76$sX&Jq6Iome$;Yp;ue&T?y$Z`?P+n|4-DGT##92k!?<-= zDrA@8-i(f<+LIWJUkDo26U}_HHiFmeXq(z!kI+g?H@UKjslXu@eo93$F7dW}X2vz%`C}M6b&Qkc zsRCD}{y>jGljEgvCA~|W07z?ag^gFhgs69YG1@<8?bXatFv)BfavyS6TsE4J#bYT4 zFz8=U)2O@bDA#uS{+>N8tE+M^l%zUI3EkSQE96U4ALgdr*Y+>zl{Zm8)T{`1OR(Fy zN`>uonu^?t2oLx#1iA8Img|LlChH7Oqb)E0gLjA)*&^7rNJ9@P*@fT5U+4$Yt$wQ) zq~^zQ>5oxRqDQA^Q%8@+%AlIqJ-5sZs54HN)T(#n@D2a;Q*ieRWWzL>0%4)pcNy>1 z9P;Rb#f+0C7SCCBx%H%z);XUM9Um33tIsk_dS&{Q;guE1V^59y(+2yq zyJGniY^b)^aG!fdluIOhwcU;99ter30L5&mD`_OJzpG8_eZdIek%kcZ= zaO-DyG|S~_d4p8Puj43bqYHGuTixV|f``+fr)P)lf|&?Bgp(6d=UN%93^^A#>+jV% zV&i3jr5Yh*Hf5CcU5vGtxbO|Un6#MFyd0-p?KK;k^K~e_I8u(DT6AhvlB4LvR$nUK z!-ELecS_DF1a7&_NfU-+u)BbLlGfT5}akFQ4-3;B*XI89@5GFzj1>40piipsJ(J?J{Z|DF|i0$ zbeUP-b>WJ!h-gf0yLCLo+alW2x}5wLndSQmJngp(tGqg%x58qCsI~o}nPkQ*fz7Gu z;@7^2YeYn@ZFP6J?!P;8{dkk72z-3caSW*FDj=#rTInbDU7o2o2lPZj zU`3VF47%i)K2DVfyr)q)De!u(X2qPsX7(*QY5%Ui?ba{)CpZO-&09c!VBR>SfTXm zeb=?Fx_7YLK75`ntZVPvNZ@umEtd#KTP}N&EzX|CbKg&u7Hi5_Xza3naC4_<^LF7x zeYr~5(1vTg;*kZo6jAQklrI89*Hw=(!eB{Mx@?knCm}{WHTu^D+JTpeVyo_YqQq6H za;GbDbUj5h=|cAi)ZlzGrK?)FY?;QgEq!RBIe=lW^08$!CE$en=DMAZT!-h%3w0~H zlh{hDiw|1{$wZca^1uWM>I>FRW=b7BDrn=`zIgLw#m~>N&dxzo%ux| z2IM3e!h6>o05rn@i>vd!OXJ#Ae`*klPi{i9@a%Hus3Z{&1w^a-S=$rTLb=DJK!C?G z;DXM-4yAk{(l5{MXx3G?m&p>JXP&*QP=ppPeI8|EDzCy2fv$NVap=Ly5D`!(HH|I z+;p0@u%i{V&9MRI=R2f?vrovmi)K*Zv8{ZUJ62p&_zBdQC1Kr5fOXGj0@gj3naP%9 zCqFyNF0Pa)?#FZ;XqK=~DRY{w8s7CuiojA|H)6^efW5B~zEva3 z;Wb{*>LdSjz89|yVow_B^Kk5Q`S{`_ez&UKT*MQ1eIC>e#x2+Q-W~EH?EHSQ(+}UJ zD`WHmVXt;IWT8aZnXL+=GCl^8iP3L z{mjnOJ1APgxKT>ROV?(Gr|ujvQMo<`aOH0-cv?M>%5a{40bRJ9aP z?QSb$n^gN9DU~8;VX|@VO&af&=82F5f0_8^F1cy6hbrs@jtGEMNZcJ;;Gh9ZQDV^|>BPAcTBNs}ET0 zqS^(}$3|dEx3IyBdH82G<$y)6e#s&w4V>R%rEzC-(Ybnt0;ym(8P!LD{fNqq+M;|K zHc~}?O)M5$JlSatF^RUarso{Tm66V>Rm6k8F|j<$<+W_Jz>-P@en|FRm7K?5;qf!> z2`6AaF1~t~YNOHdi?B*yI=q|CRLMaEDk*nFV2jY5C3)$ifv0beA;EWxaw{zyo)Kli zO8Q;`k3xsZCV=V6pskF1LK{iZqyz|u*b>h@`uh&cNC^K2&N!37ggTP9nidK!Q{$CP zbyzdG!X4?!{X8jh)}9n1`3XL3*)wTDh9t5SjO%vqzsCSnWs+I9eNoC$fw59=l#hXS4){Ab%#kALm4jPDhOc3V9mT_E%#yvB9#CgNtZxTFz zs`QU}*%)bkCC_}#NuZP~fw1IOCVBX)W{l@#+(}Qw>2$p!va{L)Qj51Y8K=FZXOJqU zl&6onj~CGkh=!Q67`aRF5>KAHq$xHjD>@(e*EKUb;8Io+H`DwE2$4$AL_KrF;Udjb zu-IYDWD}jf`?_hRcU`N$Kn6RaLlF%Y>TSMWoUFqX1KRX{^{P0Svw5W`@IacJ*=$@| zdz;+l{(9(0wrq+`9AgFErajmxE3cOr(Emtk>HD=-jY8de&iR;Lu7io&X*J zB$irKlEkI1B{|?MMPZE}jn0&7mo|W*(}ztP-YV6BCDmyh+i2x3q9e5*|)twkQAfXgvSo`_I#mu zSuUdv3`y9QRE+K5B`7e)zXej`Ew&mrg5YGnFcrcR8^f~sCmGA3reu?ftLgZf=@XT1 z8PY_mLAB9*9CoVVY3I@{l_sCl8*{A&&hqi1`Rc8-lGExGb`QM~4hO#o|Aqq-5dxo* z@xNk@H&Y9@H|q?MhLA>sZt*ip@~yAQG#`E%gznJoh z?|0oe(p|oj%MO!(feF^^9H6*hIc(ATp;}DTO?2M7$Iu?D^S`zL4w?#|J60C(@h4~>1`&r zc)4mB;lA>GFief|%1-W9Mx>2g`-MsdPS$J%`k$TLl-(Xny;IkuByj7>IFGp`=Zd-8 zZ@N~B2eTuN4SrS#Nor0<9CcT@+j?O>uGcd%-p1>`M)Bb%&T)v)fbfZ($f9{Kpc)t> z@UTkDAYchoDHB2WKIevAY3=mnfyHb7Mz%%a3o6$akNFy&r$ysLJPE;q^0E#Do zGeuPYpG;QhL+1mG343;{36~aUKBSelV(SmMBrGv!Glb7uy)EEHU$&sH&YV_r7B6E~ zfoax%x?6|T>@wzx-b^A1zciBMIaAe=vJUONxpPh%J`WPE-P%-lMX{TR(xbl^ufJWf zYEb(rd-Lig9uDsOgh?*g{Y}ds#q*+gtqv&)0S-dZ#jucwUmlym$d>NzAv~U%tyWEW zVm>w5Rqf>PqNE!$-*yzo5&LcLSAT)g$MK#Ttr8*w;h3u3O4H>{_IyM!r4oA=`~CHl z`J_Bcw^Mdl9&gfM(aA?NspXnz`91F`N`|j@@|EO?~WzeQH5qF^Cz^k)1vO{S=Jre#j_{=}=n;oorf+?h8ZCBil4H>?wdyfkWD z>FG65mQ$r@j0n5uy$UH7g4dSz56g8AE%Fo+OVacH!bxdewr1-k?_ZG7&lLAoptd#O zV_RRt0(SXF&qIWbGnOq?;aSL*&xRl-`?}rHMtX+pTlhXg7L09*`h6t&-3UD#zUd^Ygtsi4>u5R6RGxIe{Tn-lxz0c3mzV`6cs zT1hgH^P+!-NGQ(twnx@B@im4yc!yQs^650iVQJ$3IT|1gzbkYRJn*|+o~FX9z6h3- z5Te;IcO)~}iq4`~>o`Ft;Jt(OsZJzNdX+n3kkm6wd{8f2d#RLVgW1DbkA>%EeCJ%a zYhaoR|(jwLKBcIgKO~1l z&kq?-{OL8MW&)bvM zB6zDXZ%q!U79B_Sz`AzObh{nV$92Y?_EG02jo&^kFRDg|L~IjYeaFKYenSm;xa8Em zV{ApM)7@ExsNZ=bE+@J zUYmRsxR%@Yd+?&xeU7B(4&*UKIM>-8OZef&$z9JgBId+FN)uwVGIPhDt+#8Q|H7kv z+(5_dm4FZRRp7_RA=_-cbAdOCdJ4;b#bV5_f9siK?y_Bn{KFDa4)qmbO|t8Tdigbf z_6LWW4Gl4gEiz`c^s_dS0}9N=6INNciN#S%L0{XoN# z1Y(W`Ik3l=ugVsZtPlUh$T0>kYTQ1AaV6S2ao^NGW$z`oUAt&l(rawVckRw6O^|lZ zr(~ATbX}~*i}77W|B$Y#R82caMA9p*s&Jo-_tYQGW*zuB0`;6yRxjgD3mdC~-9V5sG6 z>eBU`?c`ejE3SM!h@-7JjAK++bmnO_)OI$!u)xpQ=z6zIh9`jSY z-DT8m-qCu^x2yBXv-v};1N&ZW z_%>WyW2MpNv~T<6lH=BA0kodC8jFJ~|F|xJ|Al<=D`Cd`Y!!I&>~m%7@bjWMzJ7vv zd*+~RMeIC-NWVU`LgANw5P{lpS^`X#PY5P-UgcJJ{VuVc$VKT^$Rb%S*@lDMlKJT- z+>BdgPh+q?8dSCTDp~wJrsl-&IbJ?=AbtBdABXt8qGneC$G-=lm&mbB!y_IyXHhN&bz z>G3sG9bHRw122=ro<=f$8YkMzp1K#*q!noic(`>k1Ik@SZy&&;7)s3SytSUJ%b8z0 ztfMb3EWBxkuND)07|LCB;{fp$I@_$Q$l-K~-)+cVf1`%Rlb((aZEf{O3JK8^QmF|N z+|81Pdq0bhCR{L`AAiV!w0pnW9G74}Sj-4@(luSC_BUDC>)Q4T+Vs`Cj!vup&fGbU z^EHk#Xub0`Hb)`DkY2Kg$tgPuH8aKM0;t}=@0;=6P!m^+7v#?{as88xIVj8EX{mD% z$lj_xuB_=RQj=u&4eIXKtn6=7H4{`hcWkI<3N6a1`RH-^!u&y3C@1GvlFm;;XuVq( z?S{};T^HNcAS}iyrNCwXJ|@kVAuk8K(ol2n$CUF=JHG{c=V4RFcbGBEtj>Qk(dzB* zYHGpK7W2v|I=$8@7FcYOc6SWG2fd_vscMKc&P)sN&{F?Bu=Pg4{HcABVdxGb=wjj9 zZQ&p|xR6nnP;bO^`T+U(baCzVP9Auy`{Wb2iQMPpgU%dmUs3X}Sbzr`s^$2xl~FC6 z`_}$?g=sJ=O@3wh{`GvX=zy$|sx*NH4kdd3S&qzyi7k|ELU6#+VY$3Hd zTq64FMWxO7m6@&PgrMz%6T-3zV`S_=y%kZa2`?GJ@BCocaqY&^6_M;@s(sTUyRf&B zaVv>;qwvAO0dEn$+P<5tY>yodF3`VwSymx7+eVN&WKRLKhed_=jpJxG`E@XuE$Df0 zUAM^}I$1!uGRK-Cye=%B^1~MVYIZNUGN}e(w@ zQD-L?@c$|33|Hn(hRh!%KgAMy8j z&GUhXJDqmX0MyqgJBW9DvnR(7T#c)iV)m%f^F%@u0@t5OW7=ERj(NfS{-$udCvn6lyQPo`YrYz-$A;1Tlk_dNpp>Kc!^vkCb%eSKkF}(Ju#F zfF2xSF7bzUeTF&PuP#WV>L9fNT3hX=D2^NUst>1)C&Gx!l6R*%3n!K6@cH&8SG#ZU zA9Yu~#M%z_F6`+wcICU0^|~iXJ7;lkn98AXfOD$gJdzIY`7x;Spn6*6YGtocDg{$k z%HCe=>oS-XiW>>{LbQk0fHFAT$eyq5sGOtGhdrvne%bt$4#=FN${0ybfyrQpEA=#f zHY-B2dJ<(J)Os|VYPi`3*fkYI zbB|4}hj7?_euP69ODNazXJOwT-C2lU=dlXFT!@TQd=9Ielf~W#)mQkqXaiAy{TiM~ zvXLGt+g4cZz3x!>_3KL>4(BBra?_C-!Bll58jG}M&Fw|8PD_5ZTR-2#PSU!vVQKgu zxW-4g`H{q2-6Fja@C&t#^LoGoJQWXdu#?g)Ij=ZsS)`nAPm8s}_FeHw1=ZVY`e-xz zUXtakley#A&Xg9HCeV}G1h!WG(Q4LxMh_fbVwEa<8@&025qg$;o6@U2qia&O-14k_ zx~YZ5%?o<6(`mmn@x!p~9XI6Uv>JD>tpfpv?@Ww==dc8L51%B^Hipl#9RrfSpA7+x#(MXMHtP23deUF@e1 z;LQ7{M@$K4=lIM7mk_agFQE%YdNpjT^qWeX9JNO=>x^C>z-%kUSz89LH|; zO}u|#h!F~MYwoJzbEb2cz$6z5l(&4wPNsgK?ia;TjnIyN{0 zB`(4bx0{yCW9sJGH?? z_ar`tFWAEdkR#|upZ+n^RhY+@%^eMvWA@A|T(uf7ex+K$#i395{=W8toPKn z>iwvuevkMzRnc3>PuD*!!;foYlm!$WsrI>p${J|$H5g;RY?S|cu9#i}T!2J6$G?mq zE-hVqZS{CZChGWd!#?%r0F(5^!Qk;XuU>|pr6N1w%*45$g=4MqvmEok3mJ4e^=ulh zi^>w?_rJ8wx`$`BwO6N*YPeh-Ybh4`EVWrTxMQ12+1!i(YtpPePD>iI=a!T{NRu=i zOy^c}N0(n|cRU^~e(>LB5PY=4eS~hkpF8A{!06=A#p={6j@ccX=}8hkO!dbVENWIx zr|YMbCMi(xmCsSU%E_Z3{~2s8CI#Qxe;0IawH~l{wW5($RO#@d8r?=G&c|`i!ILg_ zxhQMdBiX4l*~i;&mLw-pDK3I4bMra}4%SpND<0b0rybyAk}Awxx~AfcQi>H)atTyV zMaN~DC|c&80z_n-q}S};a5~t~dYGHlCgmjPjG&d}4oN9)isrBAf|47y-7B4)?WBWs zzrDGvw>Z@jKi-yJkvbY?Yy0>q{Lra!^fz$ZQC-U< zG++HjFvTbn++gr#ub`xl{lVB41j6x)!V?Ht7Uis%%-uBsJ)ld6tGC${9+WKK)AIJj z>N(2Y`z=&9teYK(bt*QZ&RNcj3TE^}nKfxYkEYaq*O6#hdU^_M^;)#mWA$sV>}YNy z;5;p|IXNn;QE>;CJqs1#S24|>C})339+?qu>bgs;q&a^-Ttxhwo?n);?qw}ZZ*`wb zb4OJc|6P4;u7fzyE&IlT20Fd$s$y$I%xRrjRnl}lJw2F=OUQnI*}gdkQd*>=p`p*Q z1A#K{Mg-VCXa6Xb7KZ?pR8>tkp&zJ=jv(FmMmrix$Lx_;xGGbBgo6H5Q)$kOusl4A zbVPWKAUrgZXJ*ZLbbJ~Jl7EGC6yTttUmo3QjWP0AN z4S}d`ejgk}YBm3m!C|swX02b;R=C2guj2raCX~shpa7>vzZCkNiK&$rOol4${;jsw zdBh5wTQV!sRhPj$xrTLY5h(L^geW!{!Ehy}QBjf2sE zq&OPUn1+o@;$-G(XFrV1Wr)vD*UYsu-~;A&co@Dd)XvBrcSZnrWG?xYr5UA0f$^6U zI!LB~C98#43Fk#bnT#eS{(!bR9AqDAtV=O7kRAoI+ z^5S*V*o3&yE9%yJRl)ORKN+q!^)3?zZtIb}OPOkyHBGX|_P%-!E1L78s70zD3}mqF z@v&hs<;u^#J_Y8289(*OnSh+zOlr?m@*MkxUBxy)3r^_uv!xBC->PcTGB;V?dzf~6 zqk}kdk2`}dCqC#^@4eA7K$0feLPn(zpZQzGThSP1o@l~0c znhH7q07fu=%F$(aHNL)h-B!r`^XGefRp0WX2WQ7eksZAcx@B|^AcWGpS~PLXy%59b zCJTh>$f2R06w3mZm24Ge#c;(cPaTYG_GMT~DZbW#(}a?$tE$ltvDm?u4Yi$SSP`VX zn7Yqp%w~0dx<7ac9aLeIQm)zQwtGCliXv6FJG*OlBofHSb&vX{Qt`P%Gt6Xk8F|om=J?Q>S`VAWHukHG8jXWOixm19 zHr2A_sB}ICq55`O&D@ZXE437oj>o6#nN;=;!^EA1Yf5b21+(;my@)dV_`{&iiw$1w zwawyicSCybVFOO6V%-&paOP@uI zscwCr&NkM1I8_&>TkC2Ha`yGO`=C-SPp?jzM46)O<*wnY5^l9F&A1x8vs}Un_NNnM z=<|@{Pi`+t!&v!QX5Xx#=-VuU4~;K#=Z|VRolIX~x)>{mE)KpyxIj(WvXP)+rqLf8e=LmovCJ~#6%1@d>Oat2gn{-s9~B27 zZhk){?Ot80Ak3(*EkU(YPxe)s*`257EnU7bwk((WpH4e?k@MeZR4o;n63+y?@%yWD zyHQWiTa^KmSB^PN4V6o}YMd8pk5$&qQn3jG+t}3X)?QA^;g@b6ud=oCbNF}PB&k39 zp&x(DWaHO>YBJRo#wQq?%Fr!zN@pPWoKdjrSLjeBU%)XgxMQ#QbnnSJg5MNH%7FNP zaz6Wgt||mjlFKmaa3_Q1j2-W>ai|*|_726O8HZJmzb_Sx?Wu!FN=h+#rZBrxJSg9^ z5vzW$SP4XOU5Gb528PV!Oz)*7k9~i-dki$0ovrFxI6HKXz50plQO0yggnJ7la1xyD za`}#`#aC-qHqycHnjVHYhsAuoWC{=Otabk8l<%7$4Je)WBWPQ@p;pyyF?dZqf_D4i z?aKMQ`h4T@(rLnueU<*I3|P9S04HmScD{=>cy7MnhoAq#GSBF0X@s&Y?*wgWomY{> zNNhn)BcfC08|nUN8;cUs{)^7w$59*QH2GzggYClL8&<~(BODA*r!bhxbju7 z0y?;4}MUI=0>KNj3U5 zH+L{da%E}L*Gf>k*&HMrnH?;HGF-1|5{l}vZQNGkbs1YrY<%*U@*C9>KSHmofa#Cj zM8E7n#4A4*C!fA>uRq7R<1Da|rSJcY%W~z@X!rK8X;O?|v7Rc)GXBi(*c;<^_7z<_ zen&Y0ht_N!i@oGqe4wyM?t5&9IT*mc_O|QbSUxG_pejmUozBPy-gC!~PRxw}BHUrq}q_|>&0@B`3ecq-r$TwA~y`BUfsfl2$=`d>E;~eIxQJWEd zIds}~aI?yrX{z4~s5mlNtffpFrj-f1P^{8c%i!*2n|la&GdrNiv-S{>l{AZY39-b$ zX0CHdi2>Cr9Nwbj*h*La5BA>rFRJcq7)DSKB}4?Il@ySWZWN@u8>G8C2T@U4x*58e zk?xi*>F#D|7>1geXY}&=-uDxK!1I2dcmFV-IcN6Sv-j$~_Bw0%%9iM_k1VQ`XA-(Q zcqucnKMZ!z?ieDGYrS99>O3H0arxw>&$G2RbaR3}IY0am;vI+D9LyfKt?q~OY3%w1 z`)z<3}mrQLizDz>zuDgc@zeAqD5^>XNoOiwO$Q-pup;Jp}I6k+w z%U_D?SkMNu5)jFyC$*nL1V)WNu{`_?~}wD4V9qgpxb-Ol%jt8q%lIC zAEEM|myZG(>mxuoT^7{Si&lu@gkJjwHMWV3(IqhCrbbOI@|9!{U6D;)ICP;6X;|kK z8dK&TAb4I=**jkzRrV=W$DB)yns)NGE}R0TH~O%LL)d~1vB&EGOwnxZavs&yX!E}=lo z3m77`wQruX^(5r`KvU(H1-$eRkiPXc$Qu4-f2p-cT8X!9~iSMRV4tO ziZp|o1B-oDP@~5ubj)USWa38ok)@I{Bg$eFrfwU!MR*dprqRVlT9fR zzu0HjX4cs}WNW2{G^<1mrQ_rTAT4K&a=+A4BhS=!O8fTS%-Y9^?JvY-qIP2HX7 zN0TJ7VFJc=aGM+{T*?B-QG>KLAMV9IgZ`i>TrDM0KGF{=-Qz*{yxm60+vhdv+Yc{u4I zpLxrc)l9AP`mO{^RM+QWuW3P{dXrrAx`IBNKU|f7^8QWSJMbw%M_DNiEX78cZ+@Z+ z?rI5vbv=`MKSsg+-V8F=%g9${L+}cB#&mir$XKixIpizBu1v0ui1i} zcJnp2$4VerQG;(eO?GyFHJ5eeX_iq3SsT3$I^otHf3oDRdyaN5uA?f7YD~G7j#jN) zs8*%;l&bCI44V-jwFf(SZ1EmCwd8aG1^Oo@fcTsm)RfDx`G2@Pe+{qy@R4_EQL4Du zP(wX2iY=uSTs7dIO2WGW^70rxwzKImBb+K9rf>Ayrf*zuq7njtw?#bb3Ibg6&ZsK2 zbApdoCJkXf_xq)LO7+DV4Lx=?8uyiu4Rl-VQ__fu&iJ|;)|Tcoba=M5VojrI>T=Va z$y{tiu*J>9w+s6^ zS+!*$jW{Lvs-v{Q{mM3%ibh0N3OUX0G zuY*k7Xr3pMA%B6Pho9SQe3CtMAJrPATiU?<027Oe>fF$6Y3>iMF?s5HjJ%`c)QG#7 zOH57YwQX?u#-P=HUG&WOP}A2U)vD~&n_U$}Xd27$AZ~Z-$s@+LVAVMYJM~OSLO%0g z?OiR|&GpObjq>~pWvVF=MMObc)Oy_Btt+OPV0JhNO{V7EUUZL1QxkzP)iX0^ABB{rE^$yFB2?1^Hz;+^PUkZ?NE zqgRr^KzWPzOoD3B9{VMA+MWn4Wc({qPf+cUuT+(1ynjIwY)Q{yh&rd0z`UuTMb2`)Kr zK}GW=Ges$a88gNhjeO%hjJ^A##>8`2+Jv}mj(LLgO?1$)&!wXii~xlATw(06l!W^d zJ>^t8Yw-+EW5KbNTpHj&qanrCb&cO}{Ee)mYyh}TEnwSzJeWqJUV~EIg~@QT%_)}? z^u~VcKz<_C@Qa9%tdCq8w1gPHUiuT{XVJ#b-V65uAzwR$;Gu9jEmtil)pH*_W)@PM zd;5*k^{EEm+vCWNlS4hQ$JgEx8<8Zk=vH-@Wor>%(y?k(VaWb8SB)2x*Fx{+L6Y*z zU=EbJRw>uH6`d(0FDO!nJtUo0))V&XP6sJ(j}a59Z`W9t>VFajiymu?ME%kEWMHAzl;yh7>YGnaBb-I5>n zgAS$HnbgeA%{9^c3xLIviqc-|^;v@b874`Ojl}_>X8je`TLmy;4`qbjbg$Mt5kaBHshtod7SY*+AX`Z&!yZw zKSK=VL@J#2@NZZS^r{jxnAYh{Y%W%=O&G6}L`Vg29!p22O&YK@y(Qmff5gd;-`=pH zHqh6^BUE9_3$6)!BBe@YI1|DN`B=(!Cd#2O5f4>iBhkRq+eud?S*LY8{QL+$sS(YGH7ofk& zKTUG%2(>^rjW2+alEHE)KiWkamiz7Zkb#AZ)=cjU#d4OX2R012zcK)=ni6E2wi``c z+=pT|kDfiAuk|RkRq4G;!0F^4j<75EsBHiWzwyw5+? zi*^jbkO~4G_pG0S!R0_Idg$|V2pe_Y`8 zS<&B)Fx%_=#B$m2=^M*6ieQeB2f-WW__{7J;{r&H8kXe0 z56e=~xSB2Cd*vTZClP`YP)zW1Qr|0hK;@kk78=?V=DX+rj*T`IrrpcQ<=&jtx*lOb zxm>3!FBYgc3b*<)9@>sp5;gqxZISt8h4KAAnh*6j(~D@+#V_7KOjkPE@|yA9+x(361sHgB=`~$qd1GL}!ZwN-+;}3fAUzCQr#(MJSoak?Fv{kf! z5%$j=insqj`tR>S82`}yzuo^I{_~&(z#ocRUF5`(fIcPEtkPm_SXwOji<|5--91<~`Zn55mC&P#yr9PZ2Pr|!+n!CDtMq7p zCBQ@Jk9BVy>+};Ht{F49{wFdBGR9fB1iBvm-;eyD{b7_w1^AbHlqT+nWBCql0F5%8 zlX^*GB5xoCUo)rtfNYatL@UN z58Ltr=!PckfJR6EYm0;HcPr%xDK{~MhB5Lx>mWciEA^baNsbG7Ed(ub82HY*kf_0> z%ewHB8TpWh?Dt@3Xy5+;|eIU%<&>kZ4rZX^t>dU`F?2 zz~sd!mj!8zZNP9j*;0`Fnab5`Bc%2NT4p)b5IUk)z-9fv@K783BRN%6r5teU?Z5A* z#(J2?7PxR2>ubpKj?Z9Rn=)-u_4lU3kJoN)(F;1TuwtzYLaKFO3n-V!^xf*N zRdPLBIW;wO>*g@z_)(hbLstv}1+Li{2H4`QjLf*h>vwAUy=;T&lub*d47sGbZauXi znAjz2r~9)V8FKm+GRJM#t*!GJxldi>5V!TyYX19Mse)T_xU!0>;_=xn$dsHxWM;vH z7&}dIsgz+rN(k(*j5l)sl@y~p|Hk)AWWD6d2tXT|Qm5Dp=Y8h7{Fi%P()>{*MMXs; z`zx$kA+ISBzMxhCt@SC_x6_$lQk!fl1wBrSB!SDeS76Hdjg^j1s?v(7UgJ|6g?spL z!Y$4b21#z~+}7NMBG|8U==fnBtNDJz$`j?YK|0hJ=N%_xV|I#Lu2tR7n0uUFD#*K!X<3v+8}Q^aWU8#TN2$qjH_BXkr!O zz5`}g8?47my|`uJaaxDWlbR2GEbOlFJ!3bU5}hx-pl64GM+1uJSEyt73R>0J>)*ld z9OLINl5-f3Zr+(uBlL6;$GKgz>_T?=#H>r%sSV-We#sC#ekSNY4t7wY{<2r2b)xZcT-dyAk`xu^Mdzj|ScZ&Z3-lOt78PdRwf zm}INVR`COFC@eWXg$w~>`O$W z=#O)2kAdUl9t@cAP7<{>XgTE49Y-JU!RkhSg>k7q>4n1Us(8$nq%1_wmEj;ij7Y>1 z^u~EhtUCMsW~{U!xLNO7Y-IYlP&AtzpNMqlee4is<9d|c6r0@HAyNaTg!@anYAK_*;x)=~&cP0+QI|Lud#g zC8&@B`O2t(TwP!WZae>AVGHn1A4pYAR~3bcca--Ksf+H+tjwIIeyhu5!PsvvtU*#J z)&Ik-=3oW9yYN=xd=r_a%RVwDI{2Msi^gzTWE>DB-rC}8b+aOm`9X%09CxZaBiCZK zLGN_nT+e_GEtgyAKcEqL$jt=Z)mTv7hyz+K zWP(1V$EFVm{exi*(A$sC#p=*-LjM@IL66Qeg^Pvt!?@QqXxW^dh(D5+sM2bM(9JO> z1aSUhvD3f)idQm;4`+o;hC6cg_1UUJ$rxBVzen_)L;G^Je18In#Z)WaxXLpxyS(MU zwRlx4OC8yGfet;MR$?WmXKJ;Kr%_Osia9vXgoCN|uTw~GimM$;-|pRVSukl?W;Dui z=P%`tum~hECJYzDaS9IxOp6@hzOJOP2`$Qg^6W4Ao0OX__0)pp`*Gv8#)*lJk2|%N zM=0~-(|kOI7%y#MF+p6{F3iXOtk0P(9q*@e!y~b{>xKs(Wd55!4|ns0=d@Hk4<%DF!^aWcfdb1$xx~8y2Yb zBqaM=UmvHh4aYMgO3kZSQFi6)t)s$EK5E4ji=(dRc{KK0o9Se741#)N77yB>Ou;GvXn%oM2MlB!!8@`n_Kr9oX}=Zg#*&v0Ja?dlW_264@WkGRT-D5(DRJHTT|`+b3+vek-{R z+|DZ>+eX)Sto0p7 zRpH+!U|M}*w;~=;y`N`KD<|T3SI*|Jc?!&T)nW9w`;0nd)o!7iVs#-gEz%mrZmex8 zTuj=RvZszD&v^R5K(a2?D6l1j5w%m0F=mrf=g3vk(9Qf@)OcK&&?#%7HeNG6@uTSh^g|}eJqDcm5yh>^9(>S$B(CvrFmP6#8@v*{0 zQR-IPDxOjlFKDjBABBiECD_WObflT0Y(WmBW^5IE;$k2!iTUV+;MyK(5nh>)#FD=( zC;`Y2)+olcV-ciLbCGr6HXnC~Z(KTt@w}$gzjkVAW$sHauN1~s^;l89{jrTw=jFnd zg9)xFRDh#E!x?ZwtnGUyPKI}iO@?JF2>5Yhi+qH6K4c;VY@_&HQX`^9y($x~D^++3>1qoAhdN?Rj$Sg1;PG##;UlW~|((D)x}P?ZaO``Z=vf=;W)RD^Sj zEg!iTsJI_jw&|E;Yg;D|w~C|teG&n?jPpIAHnvvgFy!GcTfOD;m=US)J&QTrPy8jT zy>wj=h?XRtw*~MT+ z$SFxrX$5kS0Zt0mFzR~{iyF${KR)ZUfiOk5ZC$9ou{k?pjh|vrDO$-2@4wPU_71y-A~!PSoK16fb<$TuTWa z=va2@KA-k-5_wpFi^_j7FvUOG0Pn;CG#TDTS{mJiKd~E*S)y$#&m*s-Vi2DlOxWvg zJqnwz-zOi2U#SPQoWFly{8p%AJjTg*a#$Nsyk^#8z1i-#|BG9;CfD$6i(+Q&g1W}% z@KL}UBo{0H(W24(oE?wbfVo4PNpKI|AxH~qH?ScD!Vt3`kDUYWees&!bDmTQ09qxH zeKzr{v+dfi@dcc|cOc_a-H^Ui?Tx=LsmmDO01;wMfkhdm)M)rg9GPVQ1&D)1`L&oL zRh$zHV_4$oP?i; zN;t|L@9E=lb`t2Y@#4iA6^3gI(1*%r>c`S0?z=>1SJ3Z$SeLgA355S`_T)zn>YP}zTEO5Ye3(llVYOZ zOV+4}7*e2TU?{PfU~rwF{p+)S!U>)!&DGVFQx)sP=at^DA1~F0tQw z6xH57G|;?@QJ?w(_~-hc&%5CN`~8gn&iDWKaQ_R5{|9{gS!bj?lMp_3NO(8(-nE@R zOD8I`R=EA7F`vjq+48M>wpQ7d6bo@cQ5~>No22lwi@u>&=5uVa^Js9502kC zu!4mAG7n-^rZ%iL9LfFVPO(dz)+0EDMztZFy?Dgu+2(1v-j%>%sro>PkVSq5#?hqE z#cADOjpOxT>SX*m1q$BGz`utHS&yEF7!)u~aL{#~DB}**TFlkH9*lKZKooxw4wa*P zBc+WC$pty6X@Irz;sI*C(GGIdx>M zHHt#4$dr<>;*eb6FLD@6{a}R8{rt04jp&YjN#UGk>h_cF%FdDx_o<9{&@aEB7nJ#Y_uf4bA$aiM*^_tg zRDXK$$72x)e82_vXN6(M#da6?LbGD-k0>vB+;&`B`))WOfF|~!?~b% z=PPac2v<#0>!}*{I;j5_$Z>N2N8vFn#+oMF9KTsi%YcT^pW?2!ymRVuh+PLeKXscpr~B|BK6{Xoww`A3r)X;!6Vg9bnYYI*M7u!A zomeQ&EkoacevDzqcQm#+^XUdKFflyiMt5Y*0J6}%nNwD}twUAFd%o=k9D}xD?0O?n z)uItbmOF4snLl~4?d1L@%Wi0=D3HySs-O@HOy{u!^lZ5{0M%X;PRM4=*H}MW_)hfu zHR?`|(qG6>Mp9SZ=OGF0(_kx3w>2rx-i%;WmCmC6W(muGV*!l54yGEuD^yaHMIZ|A z?$KCbfSUZCeR_%<3~mT~I6aGfcQvW#?%(mwQi`Fqm2wp*NETz@0ei@XUn6U9$2-Bd zIns`XZfdi@j6+DGZ>6*ihe}r+$49R8ZeKMQ66?!W_ctt8(SZx|u5y7}>xF@dZUQqm zo^KkSLrMe^mG?tnDVOT(nT?h7Udv07$H<278@7K+a-CxQ2d^IrOi&rVM^bAb!b0^!);2k`~fDX~tE z9i_{8tIO@ha~AFabJQK)Qw>|$3hjZeB?8Ga1QX3$}rYsjUm zWrjJWnX}x9$Rm93MycViNyMO4-UTPn!*w^8DNVOBG*96bzzI*TAbx>V(#u61r#BOx z<_*9<73b9K3vM6(eyf{?#x;`^Q%U-5#ZwL?w*~|L3?+LZr(ap_8I2kqXrS_;+kKcY z_H!Teg752rzg|hgk0^@{o&DgZ>q&x`V`m|D#gNZKhsNjE(+V&`j^Iz&yl9;Lea>RO zdkveQUUt;1M4(kN{WlAv6`gf;eX}=2#)y4%D?@}!fLrjQ@}I=$r@@|oN$2`;Wm)?7 zPZ?iWN>5fLj2O1`@YX-NeA-nN6TW@CVPSUVI-Ja9rE_Y`Sun~~HgrEi#?c!p&tO2% zE1m1O`30AlKoMkhQG_s<%M*<0z{CxQyB^?2MY^5QA^yNGEk8b~7Iu^yJqrnmCJ zKV=@KsiorcH>v4N*mKU4Hv7T;0PNQ*-$2^1tU;pT`qu@_TZ5lh zhZNR#Ta9&FcHJ!fD?hh5Dhmos1nyYJnKGS-gabr&o@!h_a(wPj+p@q@pw!JlkrGOA z11CxJhhrZP!@txUT)&q}@l?1vkpzKp7?VW1f=-QHX5rh;v=Ns`|7dM6>TaNU=PID0 zWPUgk=H}8vV|1ylx+n&a7tn)|4-E&*Pn2o-h(~Hf9n1|?f<@QMM|qzlJ-Dx(Ez$Pz z;&?8qhi8z`vVfosAjGmgx_PLqb!zoemeXizsRcDnAPp&jyZ5dK0~9RzcEGY=DS+L{ zL3WsM{leehyJ?$_({BhW-10JAix1CCX9bl)l|b@aLgy)bLAT-q-tmZD52BjOY2yue zo-fG_Y$7D%svj%j#Eu_tPA-sk(!MkC++fc179#PSJ3#qk(_Zov=9`TPKWkH}%})dv z$<_UE^z`>NS6FrU`-)$Cc#5Cc#<{w)r)l~3mf?$8ZLP`S08a_b%sfv9+6fepv^(mL z3|3t0qfZqrtjBj4FfWeYm-;4rd-!p(KEPhTDS7UAc)K^?fqM?AlmZN~xL8PAPBxt- zp7LR6NJEKYZgiv^qSNYqZ{;;I<34PVsZUaU#&o2DqICqr$w!O?z3A6IHBQsDtspl@ zwwv>wdFJfswC3Zh)k9^Sy@8*avtaS*Kw{SUk=@xIjotB2#O%l+IoPJgZ!HjGs`m7s z%hUbDt4s)*jk1EhVS@@)AIL>{P%4Yh>_*G4G2%9vNLLk+j!P}fM z{l&1zcazWRY&1c;j`$}%aV^CJ)|(W4o4Y2;q9pC_+-Gi6&W<6)#)7bd$hG&{_>7Id zhWmNo?TrUbEv07n(sA|NB=fMR*|b0c@uit~C0_MWMyxb%)YSW45h^{=rR$~Key{YQ zM=(~#a>VNSnuyQk1i;P0dc-6c@p!Dg9M*_#;#_Lq!P^W0|T!8o3C{;xF(?j-L3Z8v#lV2yH5l)1m zJ~tao@(Cf7&wpj{9Fi-2m@Q?($vk^4L6$gDBWd$u>`nQe_OYuVk6)q*{)k1JzFNen z2P`Wf%sf8l^lUg?6W8H4gK9Ne>X>*peE7A|oiU{uxn}df z*b8_>{6^Md{1~e)W(C0eI4kor6Fm0PAhT`S;&zob@FH*tnUkoUaVDFV(znkQ?n+=l9WR#~aHg9)Un z7Jya*eU|aVJO!vEp4(xqUSlP0Sj!oAT#T$Qw8?=Mr#t&o2Nh(5>LAoB=t8@I)w za-Mhm-?9#8B%AZC-yis4I{RgC%tr%%=7NwM*9(Su&q#aSDz1lB4Q>nK7+`^&5id0> zJpKEM)~J8f6(z^5<*gHWo%tV^7RNS6HURy5a*Xl5AH0^B4#Y=qdaH8aY~))>{W~Yv zs;g+A7hX8uA+0D^vg;IN;_l3nKMA~=cW6O*{-$`b`pp=FPA_j2;v!=jt^Uelp3*=F zcPNbSY@1}mX6xHd8a9T{&CZ>l=4_~)ZnG(g#W*pSSBILG({gu=MtD$Vjg6SKa5TPy ztT`$#+0wcG5q#g9AT1{;9z}|(==+PEk4JG{@c!&x+nVq>g|h1){DeVj3D)CqUMjMg zq?>Z7)4QuB9B)&mP~ITL^?_nxc=uNGJor&Y@3QnL4|08B;^T_iaQ%5UKxNp3u+I9? zC~F@Tml3pz(X4{*cF=j;|Dwu(z&RLoNHiMpg?!Ghlcvnl4l{~;^!xUj#^E`dIyrxl zK36D_li29O%H0sC-aVLwC;vDZi*)HtY7w3nXC)k_pc5Ora~MEnmszcxjb7vfCsd%C zOCG;8Ay)Da+R;w$J16a?rd}Sg!WusEO=Jm<)wv!)z6n4GdQ!@Fse*VNz%8HruSAqZSDwe)h(*c5s%gfnWoNm+CK=zx z(+fq#X$q#^l>5E0-+X)IeQKigAT8bOE%6X)aYJs^YzZTy)C!v!K6Y1!Do?enEy%nm zf5Oc`1&-FVA!5IP54uD@M5B@pP1(KP5Y+q`)A|)$sIY$cC2cP0dnj!+#grMDngc;y?}5LuA_!efIx!e>>&Gh<{;MzF6DDKgmN z=_49Y%}V5lyVHZ8cz$`59#|cxb3O0o@7ZncST_CT_82lS4+v0BrxdRuz~{^gArx{X zU~jH}xMG_Ak06X2H&N1Ra~6vp67^B%btFZ}t!w+vfN!arH?YZ=4dYqg!dhz6Wn zEqfQRZ{*G@$bAvi;ky<+y7fMulP=1$H(j>FKe;WQ@i`um`ds_G)1ka=J(P$_l&@pq z5^9Oda(c;(l7?S&KOu5K1+mzmr7BV}&qolYW83e|;XH1Im4RI*MgdO34vNk4o$Yz< zIvo0ik!zV=p03-##!17nWS$s!)W8twOhi_)l6%=5fgheuP~4588TK3dSU_@*IuJ3m zH~k|vy21`_>RE0)G&FI%#YbXe*ph*@d}hJM58-ltPm-fRK68{J%S%R%|=gV90M2P9&BYymT0G;;bk$#{;8h8-n_V={HK`Ddp6Hv{bh@b zZ^)DW0&fHUP-|}@FVSn_760>>alJ+oajtFccOXvB0$%MiK`a9Oeh@$}y2k|%M-oztU z2ln3&aKgJ*0{Sb>AJb-0p~_B}F6-Z=ei3%J3oGvKMUHKYgH5pV1tv+XGHmQ`SAoJ;r%L0CBWE7|&yo_V<5P^c<=FUX zGgd4|KCEFs9&&ZxAOHLorrxZI%8FDKk`a9=c~AbfZx0|Xy80~C_Y1m_hUlmdQIB?^$Xgcg3UqEB;6z;1qX2y{NF!+dFPxz5P#m~ z@uz&wN?Kt4v)?j+;QF!rQcIAPQ(FvTgMrKKn(Ap)JE>6;s7|yeV$|{kXa`XlX!%ZJ z(6oKtEp>d9$2L{;21*eG(M|;MOK1Hwj(EuYUJxzqsy_BkAx*v5W;Tf6xw{d120i^| z<@Qg^=d&pbI!(pjTa^~NMlgt1v!o6WGNeW-WsQU)LxG3A78+TwPs&_Aovf3Os|9YB zhZlWr2KClKKO`2&RvU;U#4>pDTqu@r<&Lqgx>&r}bXe@zK+a=W>q__}5$4wM;&p-O zltMd{g=L!V8E3)xTy-FM$^+^l69Q_IXx!wj0o9}Cn!?{qbfJ47byBhi+9(>P!T*(3}zS&BpQA+>DXdwfSl}xS9R+47mKB0B$^9FQ*<+|hU z_B`(JZ>iO`9w6P>X`92*LLXPof;E)%Eho$YPKzx=^m%zKuIDz|hdaOnOW zYTB;?CKA=RAGs>Mo>$!C z;{UvQ7Y_c744H~oe{1<|I?=&TFcEwf7%O*Rtmszmk9Kw;6Wbu6y^0gnR>c$EM~-nW z%)_}&ZRcDM@$d%lc!7eFsdbvKc;gQ6YdS8sBqXf8&*KzY3q{60VtQ`N;vFsbhm?or znVXxKJ<%#9N}74(!R{UU<{=wV@V!|rK_*$7YpS|6whfJrmx4kTTq}3=z>gAkYwhc^ zXV+z6uzY-1p&6amdnnlV_4Q$=6Tf7Eq#q^$#r6Y1m;J*pZswavRRxV?84=t~_lJh2u%WX+swW(%jEGI__tH+rMT=`3eTTQ*r)rs~Y{Knqv4I zR>L?yWIozV;&YMjW3N0!Den5~1cZNe;t6y7a6qfw{+QQEAd zw^WVAmLr~L3`8K(!9Jfhj=3&r^Q-mdix~m*fMr2;kI^o=Ja@EPV&P$VA<%k%lfLTV zjkJ$9l!HqD0I~ZV8Hqn?KDy8e%rbfU^l5B>ut)|D{>{(Z-#T1~`fv-$dlpad%%EKf z-HI?iBI^bEIi=X3Gr#k5Z?U9iR;)Z~y}_ZKX-+#^4?S38W*U}}{8uubUCwpVR6gK9 zpP%SD9{{256Eih+i`u3bZ+FhU&vlDpvO*hiizr_Go=%s2!95<%|3}yUB>Vy(`D4Tp z#GH54_PblGyAz8kFYmdp54fB7RisJGUzQ)Z-;;W{w$?G%@%4OUd$xkV(w;-2RE1|< zI6$%HsX*q3dkitE1OnLix`}>n1%PwHy4nR#NR>rJW>|GlX6ZB6?D=Wn>nJM0)FovT z&0?xO3$X{&ThqNE6M6B9o! zDFs8xbPJW*?!$;y=A586&L-Dj&~ID$nv=vniaNX(edw1pGtrv@iZz0G);o^X7o5yb z34c6Y5BH9U{zI2mVdrV(f4+T-M;oj~d6M)wa_emVW_zsPheU*)`VZ+b{Pyv5}`&7|b=8o-U-LnPMX22$H^h zU@YILv9dZj-AqdM`pJ;B9jWkqDR%stY@j!Aj`$8+>-GKQ5!WBfwt0a`eAuM-af+ z^^JJ3TElBhUed4lKFRTPzdfdE{G$Lc(I4Fx^VCF_SijCO*TDR~w#RW#O~9@9g_~xy z<9n%)s=Xvd9UoT?oPqZVEWY~wTwxb)}GCD@Sd_DG`& z`aHDhYKPbnpQJB+AX|1N*G}Z=5FAhzvtLVB<~ynQ%?bW??4wsTk!Y28Rj{|1ybN0l zo&`4FZm~baLk1jXo~0LkuYpJtAG?^4XS-9m5<=bZvnZsjChN$#J{8YxOYRAbRTt)o6-w3=X^sldNYDf|y_^j%vl@M2>#>QuNAoo^3sgd^djxj^vth{awk zeY%WH`&u8Rk@L9e0pshNyEb81yEEqHQ6G^a*;Dl*lFrZh2%@NQDb#dti6M~ zO+#XeQA(}KE4KwOMO}Nu?#L1hnx&MC!Ikw)b&8o#)ts*D@idjCB0LO(%~_)S8J_hVjJzM9)!uXnFkSE*6!>N@DXgYYa()Xi- zROnl;RCT_d4Iu}1u?i3*0o+_70nuN03+s{y+V0>_6KpH_Bt`ZUTQ(>uBqIc)m&Q{V zc$lB)@}?JsP1(#=vS1t`@Q?j(=mG{eA5A=%w%RqT8+-L!jkkH2%k46zrN2e-4j+87 zp2Kf%#dCu^XPe(-+i?@y@nnL{bgOu!T>*_yB?TydNZ#q8RB{ITuMQ^L29(}@(s&y2;{hBrL4pWF~1 z_UWo!&2FLq>DjpHv$|Ni6|Tx7^B&pW`r69d$h8%|cy&hmEzEjCv@Ua+w z<;z?0K4tXxV+8D17ZWw>uqjjT?hLMdf#vvlwXX(mQJO2lJZyD8Q*93~v(n5unLR(x~ zw73ufmxI3h1aCZv9-Q6WfZlLY=z2~fR*SUAyd;Yz9ElBd@ zdG?+?duH~`?8%Hrf3$Izk1EnT$temL2_3XH%|QI5>92rmw1+U{opYb_6h6(9nH(Lg zExYJ9K+~ar+5>LuvCvtljC-IFp42mi#mHJFeK&~;jWLYTBXE#Z_;9LRGiOET68qcv zMSBP+`z@1nZ8T0qXx0Ap>d$@8(=xA+m+merhJ7=jqANV#?D>o@=t-`jOx$yW=_eH)b(+oYW<~ag zK*Bp?Eey`ls)a$z5tR|bz}l!--kJE*kn(AF_!&AEY4SVh7rp?L#Kl=?gO80Eo3Zfo z)XC7fRwr`1>uok>jN(Yh{*2V7+0}ra!E|u!EAlr9CUpTrsiz+r+U$%Y1Ebyr1nPTP zQ66;j%I%++gr8v0$j^)(Pucgtes2M-^F=8OKM11Y94yFFC!a1>RW{oZLrSnYn2)br zTBPB){Ex>x?n~1`tc9%5)u>@*cHMrvhBx~_)e+5K1)PaGYGjxMS*)UZs8AhsV>DaZ z!3baSe*8~aN-WSv%*oLrz3W)rk~4_!=iQCoiT164wy!)3PSzU}A=NLXnse?wy{ZoN ziBCqW3nm9^BQ9`JM}glF4fPHd(_eU^$sTw>B%8fvs^C4@gvKzU3X{rVMMpim8@#C^w2`oe*{-KS>X zt$G{gHR5N81zmZv^K)Iyb;cI8ju-M>zBkA>fUAQix@Er^RP51g?s>MOi9=<4D)?c` zO8RGkfM9y*e8FmbRr~TuvL3N!%VWjD^krzxhh(4ryyUpj~{TBq?%B+C^%}l{S!H68uk+12J1gPq4nkN{4(1=Ix@?0IIT|q zq&_-qT<#Z_9IN_ipCKPUEQ)UOZHD0SN3!>*w$-wq7WO=u1f(}Dnhu`1%f%$@eubTx!Bf60k=~X z^NGngR=s<>I}9dHN#ZQ`-V*d~twR)o>uQ1R&!}v=Yyr3Bt*=cYpD&gM%5T5glFciRZu%MRc;DshJ^&h!j0~2xBC@n#OpuVjYL`Df>dCfQ7kQ@KdB@9ro4NB1 zR4!Kp9J=QH3K3FbAB6k??&R#D!ZA?3hHWovh?t8cp`{cGUg%%Bf7N@0X))xSo=-sj>6k<$v6r>oiBVUCO%(%Xt1 zSXC7Nyj?O*<`T%n8kV;lq5xBbAeyN;7or*tl1t2|CC$81I8Mo^>GOQu~A zufuNdj5e>Gq#G3r3swO5YG7bs?+qmF1~va^=akefcfK0m`%r1A4oMTqlc)AK4qnl( zCcRzp-~OcEn)QO>p99lBIK6rKAJA}v3S>QY%)jSb{~cuk{ckMFe>?ndxW<3`JM)fY z{@u%e|6jiQOCJC2&+|J4#(#VI{SI(Loc~k%7rg&}u(xDjB5c=eAvJz>_{j52mGJIV zxNcAgvqm_$4-??g39<=%J#ck)Zp-p({{7Fm_TkwIIf}$0!(rIL?=|yG{j**X!QT3F zwp28)dwQS^{KQwSQ&J7 zE=3$lRnH9f4YGZfG6a4vcmxzB>z^?*So8C5&3_>&pp=U^c^aCy-bL~Hbwq(CB;u>> z-O0*nxz6VNp-_R|yDZEPK8{7{Q~*{&XBke1FMA}mt$o%=D!tWpt;tH(XuD=bMoC8V z;ZcNzk4<5vPcGGmnu}lI3K3H<9pAXVk?r#SUxr?~Yad4yO3-R|dG={E{|Z00d)ZUc zJ4u$>(Hxd4Zz-gbujLX(fe|&q?>6}6+0gLNLySV1BAqABs})wxCuTZ!9COt*Vk~d= zq4aTi6d0ZQ)O(AHoP)?RN%8pcT1efU<(J@rLdx%9J9ND`oPImqs~V)6Uy+d|Y1f=O zCwbkOv#T1baKoI(njahGZi?r+Daauc%t$E5mBz`+B{p(q`8qOqJr zH39pF7LoKlYjo?wtYcS72o_0ss2jRD?-V8y)EA81LuDUtd3b3kqdnp`^q0%`hc`B? zl~}E0t^VCkNr*!~*K0wcvMPN8vwMaaLMR*#pC8xdVD2O#tHNnvmW+Hq1+Q@ z|FPT4IZ&ppXh185jWf5f6v1z)Qy13{xK5(HkUe(@aMwE*b*QUG*Dn0nX3U~Yqf2$q z)C61X^r~w^B!z7;igJs8S*7F4lD{g{sOe>34~ad$oXvx*kAf)uH9q^O5Zk!mXL5VOg$cP;;_j>bKsQtKg13_le$e{(%;bERVyRD));d0QV{Qg5v1=f`Uj}1sI#A`977Occ&Zmp9N+*`G z*~H%Piz)P8Guc#)OP@*f<4mE&1f>TR65Q3XGIaHZqX8*p2ey>{{byfFSa_X{=N@Dt z4{0*8^hQPN;JH9Bd_^W{9T+hEQXcD+mwF4>W{#BvPr z#}^6j-R<5iHz$3K=!i(`G`*Ya)bw!Zz&%~U@9F8@LCc*M|CO0?maiS=p=(+NSYY_I z&v`$82XysX(6x|_&)D~LXq7sqw&^61|1n%QJQBy4Qbgsr&PD#a@ZnjM}N_$-n_@eqzWl0W*}bF^)Nm zwD-Mgw7)_!rlVPmrkKOH#q0~)5?Pa(yX4cH46Un=B}jI@*7UzBw)2?KR!!lU<~dm5 zKV`Nma}(zF^%qJu-QX|y!Z+!BPdPNBTc*TeVpu*-F6f< zKDnnFq_!^Eo;A=M5Ti;pBW$VWG;KMFW=g@H;9xAi*mtzPk9Nv`CXg8USdG^`JGS3~ zfn#0N%Gzz2Midg%QFfxl!(ZvOxs?d;a^lcE6p-2W-08b3kUl zZhN7j8CTax=5__pc6Uxi>C1XQo7|4+K-~CNZ>+iY+cusis#-ja(FsGq9-ojMJQ<|`Ui|TEH!6A>Tj)zpH2JzV z)ACC~X1?uzolifHTm7g_3r+#V zb?_dJ?oIxn$RFr>yTkM4qFqa7dO#Ed^d0cn-=iU!&Bo?K<`oy!^l*^)FqQr=k&frK zV$2qotjhYw4aiPwaRh4BVru~ROUp>;BHw)f{u0ybe0AMMR3wsY)FHLi$@Y)4?H@Do zv3ZR>!wra)TWy6w_0D(qe@ZH+N}NtQf7H_5fDp7EE&|!+0yCDnn-72J)E8Ay4Z^~V z%a5ra>v|;MKjtW=V+4EIRs5_ywQZXnj5lYwa#;!Vm||T~JOLN|kth3KVe$WMfVXLxI{YmH}(b_c?N%3v)N{F)okG<;dlDN6k5+mCu zPJpc2XS26kCVR7AgSXw(I02a6&F8kChm?Ru*3``S@$nESavJWf36l-rH`Zi zVDPuq-26P#2s>~Yr;gbl84{)^_sZn2QONKTcuNONbrYiY2X}4Um*UpR|DGzb&P+|H zQi=6E1{SL;_9&i^wu&&2k^+CqtHO~GsAm4ebOZCpesl>w&ENFq| zj8;E4p8OGkJ)w-0;0BWo^NKe_{YaB2tCXHK>S^f?sNZf^Do?yrhW3P@FSO#3t1jur z@}Y*svlnrV8?o*C{im^|SK_Sr>hbAB(~aS5B#VU-dE93BzLm8jhb7ywf2ks*UjC2z z;ujxXZ6}kbhp|b~4b=qGH8=;cKaRz+!N13`-Knh1GzAkX)8K@^eb{yrLvdY`&#nIM z#alzpvYEJc!R`k6EA#6?){ZNTS+!4=)2?`reZFTOd}B!G&QH(ixwK95R4p;GI8h$!q&r^<2K4cnuY~*xrPoaP94awR8~vdBn9HYWJUt`h&a>M9 zkm(1`s%`d88;=AokAMdN_Qrq4iY)eEm6_nWw%pSj%Tn8KbjxR&8$>I-vUf4PmM`M) z;p&Ahb^=#7tAl5$uSvQZ#(e1 zR66(cX95+nmU)xiN>S$p*B8Z2oRX!Vepmxu0{j-*-zXlTRIlAk{Y-i-XU!OjrdVQjY=J-ab#b*50GDz$klU$VA_`g`=@yOyVc5< zn=~37#=U`0n2XsUB~FU3Q7No2c`?99P~fZH^(Olj?t)sEJRkw+ zG*8eN!Sve59ZHr*%o8EN@54hqHwYOMSa!<3>g=lxK<5)z3*(7ZU%U#C9A^ zQSQp%%Z(YOXQk9UIbeS9=usERa268dCsl3k5t0UcF4+y-pzFe#GmpF1#N+~nnl5sC z2d<9{pJ~zFLoF_FP>3Ar;|8$FzWnxd-m31hd=#hZB&i_L)NoSQ>bH+!0slYd0OkFm zt&JU}LkEB(TLOtHWGVVMZ|@CSd@$Av={;^AJ--reN1hKv*a}DFbRo~)OX7RUsA#xi z0p(Y5hwR?=&%%;FvPJP9>MRY$u9Wbz0P*?+n`;E-nkR!FVG!KAkB(~#J2j(v{rdHI z`|xmQ2d>~zg?nQ@0EgA4d;6`WO7xB@yTL|`ZpYiafeH(cB>&cVQk+tO>AG(LeEC8W z;(+p)`2GUp(O(bxDb7vVq8poGjlE3-V zK-N}1Z#&mPGNkh+et#+O^Xlb!wRJ610JQB(3XFlYkQ#6kuHsqz9B1!CN|yS(h&Az? za@}RcC>q-Rmn@Y}J_~&=i_+sGnDqRQ2L0mNL-eHtOB)e6U_+EhvcM^L<#b?ma#iol5EeEx~_-JGAPz_dOVNA8bB*yjnos%aJox z!7GE>nE%V0@ktUMGQvcwcznC>LMk}AHayxsli8^uG$gJ%h^za%W$+}vhqCaGt7RE{ zL`fj8D^WKZTRC=g^CN_CnI+e}AE`hM(!U$e3n{7luKl{_fx(6-n4I~+P51_Z#-6(9M>?LjPg)wt zu3@uWTJQ7*UQPH%ee&yO*+84ROEJ6o&ZAHS9~(za z!-Gs~Y4*OV!C+2fcax~2O{Wv}ckhHWAQ%irTJcJuR_~nkQD;y+N#z83&kupqp3BR4 zH2aR-=roC(2Z`Niru3>#g=!zCFZ=o}tfJnxaWu-94O2Wo4SvqcM>vU_e|r`nyksLW z%l(@y8JW9F$EqC(m&wR~=DKkfZcnzSrR2Ffkh8KT$v`cex}tpKWBTeQ<=e_7X3rQ7 zF<%h>=$feVa)Fu{5dJ9NoDQ_hTGUYw71OghE02!#H21Y&qBuxr3d@Fl<-8zD z*rdI>+~i7p@>wZ*ldCRr3jeg%Gq*5aY{`9d_>l+C6C+*&$(9nyB*!q z?zM>r7HJ9;hcN@YYAmHInY$egnvP&DTQPlabL71{O6P@@^JSZ3wDE0ELC&kg)a#ln zS~OV62eTT9$!Ib=u7S8>PTlyEg1##G{n5=SD-~`UA0~>qs!luv&c>TX>;6LkV&~7h zZch<~muk!YL{A(nKS9NqD%+Hy1@4Ljze1(^#I4IDvo}|09ZVivuRk))utqfGJHwyL zd~tQ9_P>e~$VvxSCd!c_P*$6tui-|lK0{gG6wrrH?C?!hV;sZzJ56B#?;>N>7Ycnll5%|42S^NqDOe&A1D_xlApq5v&!wlY=fL~*>K@vzz! zD;BJB67KjaaxEj1_Un< zo^P-T_@;z@LeO9Exjy4x$ZGfkqD>N??5Lz3w9&h;yg;+U-`BINfgOL=}I!dNDn|yR%!v2EF13&Dsn>Hs-Ys zMlS5;vH)Mld#5=iKzzxSCrPt7?RCcRMV28b6jIqYq3ceU0(VfoKE0o13YBnMlP6RWg$kKX`)B*ssD6HQ;uXWP_n)Ii{sw2)q zFKd}PCt9nv6iK@l6a~JX67y5LL0z&OfQ8*%$*t$G8tX1)#L@KB-dIa5;%YNeweD4- z(ez@~)-Y+mjljX|!A$c^JY?%vbiR6W7O4xDT*34nWv7$M)akMNQ8};OmRZ({uh2>F zq=|IbSUtP?b&sLTT4CZr9SE*t?cv^wc41k4l6!F&i?~WVKS%HH$PwF0;Rhyvjo4IK zS=SXvnuLNRuHn3xOXDnJOSnvxx)*+p?aTUi6j>{699>C3 zTo7G1b;kOmFuwByo1U48tJwxAL_!|uQcd<^FOe;^jssH%xM)&)CZLwzTQ|$aw0cSe zZeFb=ht^CUZE;x}@wma3swm}_BG7kwDq=y@0QZmTt`PGStM7HJr-<$L!x?nhzJOUy zfc1CrpAa!3=Jem;LP$i7x)ohoson+-}g~y^UjmnQKzB=$Ry#_wo%&glhM(BSpS5J%P-Gm!$lCL zz`+>3&e0m3n@z$?Iu#?~i)CP8NFrB82{HpualA&9-2tMGHYJgbtlx7tsRz2ZV+nU# zE<3)k@h@!d@2}7mpk35~uWB8o03y0Q>!y|Qn!CP?n=T&&%k}SU2OP#`c~amq&G@Fk zINbS;V;Oj?k<>bdroyl*5t(lhDh&hz4Udm|la5EHoUYhI^G0t{_Y~!%jhKgVbdT;J z;BBkl$!DSqRd|`EE~2K+LU1e5Yp|XJrGa!3ZZe)__i?4xX4@4J;}eU>G&f$2(zj{Q zh2B|oz2@GZd$|6ws0$3JX79gl$K@~@z>A+fuk&F2LB6heu9U1Lpp_aw?>dDX5d)X( zCiBkNOht9+>^f=3?(Tr(EF0&_fo6=2L$`QkoqSZLiGis-TocSD+d&F`OHMx2mwU0( zDKt6BFQU_I%YQSkGhoqS`Au$pyd)l0r}wIGl>*7#r!^*hZvCCBa*6SMCtXvH`+%js z*|!kWNps_-A1S>+z}G3;-X~SZGbt;k;r!rLmHN1ov7GV4@6QiP%H;ZYfxz^-lh~?D z&Bq6qU$ag8H$NehAvM?p-jt%zs~L_ahuX^2pY23QXqZ(*mcxuYpXm1D7CF;e?=j;! z7zIo}?dT-sWv1qg)fv>e*qk~T>0d4)buXzZCnhXxe}e3U>A61ge}hvNXa6aEZ&wAc zsn(_+-^H({seK=*g9@7&Fy*5V!S7&WmBsCW|jFEa8d@&lItIqih0|PnmavHPI_Tsb(-r^ zQ#W|!u1XLaR%l@E>;+g26exIUdD5AR(N39m0b%~UTj5D_ictA?^%`uUVZF!jw~m{ahL1s6d7qOgRldaaq`J?WO#4pO>ei6J zM<@H6Kqw)1aYU7@` zl1)>?wvgV-=dxW-wY3Q?|Kv4BVRnA<(U-;iXpP9@QUV{~`QDypv0biXus!9Qe3}?% z?BDLtz;}X~MMLl+$X7{YJEOAR#*QZPxk!d3fwYiU2etktn8s5=qi9-NTkH5C*4Lfr zG+t44L~Ao)3?p(~s&#O{=(x>eebZ^N1X{W!m+ekXS$jTz;v%dZ`NFn3hxkSGchNBj zCi$AiOlPmkU^BZP!)6DzAiGf>C(}@Fq+{#0;k~GI@h#ciB_1HMDlHiQ>*@FousVFO zI4FjbSyWWS?J4Bp;o))=;n&OZ=dp(G1LH(T5MJD=NaWwpe+IOKRh~!Rc#&?KKN;5F zao*ke?_2M_mG4breLOYX|C#d8KMD0eMGC)r{hxpPPTjWzSuJnnV*^HJ(I37*!6WG+ z3z@X3f1Rg_>3&&!L*t%@PyRFechC*Xrq2uIGOu8@ z>iUKxEm_m7tac2Ky1Kd>w^Pi?QTntsXKcXRRo>=aTY=d-D0<&rMvstr` zFI8}gJ1z3|USm8v9$sEHkBMK>U{=b0dhH1z(s~?E;FMj-g@qk3~}aNFLz`rp6R`)ba9 zTXv(^QG<8oEV!^M6s8TP>l+7ao&JmOpFf(pKwzgVgi^i z`jexzvm8yQ*20bo)#H!c*`}G%E?I4}m4Jz3B#WE5MNZ|a#u%c!o5O#gsE{HqB ztht{AoBKXRm2PTM8^a(wiOq<;a=rtfqUF>grj960Ea~#&qLYZHfZPICH|jA{ z?R&2~gd0hbs53yPK5j>ZG-yPkN{C7}F+OnE#N?#rX+ON(;PMy&N~S>j{xJtAMSH2O!fB67F{T1Sj{|TfkXME$p1e?RSazcC&k?(|B!o z*V)d4*B9+~?gM%jHL+zK>S@~DSLEy`lGBEDoPgIGk3oqb9md0eW6|D@5|Evs05{N_ zM{_%0v*Zm#8>DEBh!t^xk1MNBjz@Ra^mI+0CPoQ8b+z|AzS=ynxr^NAz3j*^;C^&E zNGLJ%iHGf{s#1C`@zWw5`KuOf>f?e7;UX$FN5Z!9I06oGh0uebt<%QCgL6ew(;;uu zm9kyUZ-`Hw{iW)}q89H@5NoFPC*Dy*uJfzsqvyJv>~hB(kk9&-mL~#>a`q=vIqT9k zF*C=&^Cs2$6u*8>>$~N9jZ-dHrw5@d&xb}%FE^*ikXxGPXk19k>M>|cI;=mlM{aEB>7ZNFbrgBsK%$k0NRZrZRJE)UD40=fO7ok>7HG7)zZ&wY^bxn5?ck;VXaZ^$N&OnXbS4%Sc~+l?5jE{9R;TDpIpC17{l z?cv>zBRVOpW3^Zf#7|^bpBav#loLp}u&(EcojvN#H^1!txFmbA;;SgzfrVbn;3j>A z*qR19YmK|Cp3mlZC9#QrMiIPsSC1<3N6mQe4i0a2Mud@@QTHc$O>&D-3605c2D3Ih zwTpQ5qB_q}!%df3&$bxS@a^dQk_;77$ERD?E7Hv9UMPahuL5$bFU0OEO;;;t-+koW zaC-Pvc=|NS-e#ngzcrV~2CVoh*5+LuuACVn50MMM3ePtix_On>&GUkuOgJjHO6BKf3qHV7t;a{8}hJY7tyrhZI|E2#8p@b4XISWT8mfe<4_ z8@sZTY}`}1u4}PJ0nqc1go9MmuKip)@b=^LTU|OdG zl*nfgdcKDip9a7ux`7MSEbJr&i1Q)~shyu;o~wvaK&_oPuB-oxjw1QVWYQ5PkLynb zoi-z@^+yluPBv!;E3&mB@<;pEPeB)p=3OyV*6!J$^Q_gQz8uDBaF6_YuBg@6)a%m# z(pEkWo96H}LS%MM4LkSh^LfAq6XHa~!+AaIvP#+9ZK({t%p{PJDFeu}abM4^-ve#K z-c1qTP=;5PAT}CKQMQfr4aQJ#(19Y+xmuC=ZX4As1b}CWUv>GX>kiEPO8KI5Y3wDY z`)0>DUAE!phyx4P{H}s`rVhbq8Vy ziK4NlC{)#>9muut%WY7B?sQV#lgY{G!-E=vijgR-F1n77L26n@U|Ls~!jFUfb8%yKPj>i=I+~;d=oQ zRuYjk!;2}1{0aMv!6;DC>~-Dln%x<q)6 z=_yu|Xm3POMaxrOCm@9`OA*h3DlWJI+qi0tj?E$>NB#iH&1e0n^X-|0+LBg;ZX z6_=_@NNlm)!F8m5Z;nM*RHsCl^jXljrUaps|&Pz>42J3YodZe+3^dG2R%G>19@Pl>I0 zS=&A6$e^yWG=8gru#&k(i0D}}r`;-m^!O~z(e})CW~HO+KZr93>YSCbcF~MVH;&VE z&oL(w`V*xZ#+7E{d>HW!%p4rFVkj0n6=LeRT7dIEWifbXgBzwjrzgST*#2HPe(JEX+>2PCY3;^+Lt;HxCQa`Y zMA_U?Q|y|*(cN$+3eFuwM|K+nP4`mXtAdsXX_rm4b21i6&1ny39&6m07C3^y`$2n5 z8{;R5@D(hG10gB66%@nMDDL2N${rCR&Tp*gm3Kz%v0`0d_&!0axBbj_d%}W;-#ln%f|BZlfc?B(&uJrCA0X~7M zt$tJsRXcW8*bUC#Wk&dVpGR9R1RELOeD)G)oOP7N^+z?QKge}7%&RRT8t|=)e6CtG z3Q_K&G&?ZJ>Z3F_lIg-Fk*`2IYUD&n&u*Rxc~lolUU(kImLs+hIh@!OwkX|$N+}L` zj`jfu$spC{6UpI@@uNdHlkU_HT3C8v9XuA^40TloqYmagv97obKomkRbBrYLBJ&*p zV$Dr$Mh!ZNWVj;~8B%KZxlGO| zCgWNY^0Jsh_4?5WPKMnqYW0X4-7k|2m6-IQ+kJKgb627G9V?>pwgwzCX8xUR&_40> zBk{sWes~pVHr3LNm{&2g4sbz(`V8}th>C?;HTvk;^iFzs1k@dGyp?Sigp&9mjW?>og z_TXxguS;fwh1--g#D+^p65vzy$Se^|0A7;*tth~GJd>sumVOZ9!V^Dsd*#)zr~sV$ z>Z(!jeu%0C;DQ$pHif<69Mt4e&8fVcQa#>u>sl&pbKIFk2r->xMty!QvAA)W1sFka zag%i`r-OAb**)wsCUqXFRf;~nOsjX)dv~Ww>3A&mSWI^+hqkCr<*ql@lhAuc5_Zw5 zw4P*7(oz`!g{0GK;3zrs%h=h`ODsQz=e&jj9Y^X3-p?iXCE>}pw^v#i3l?y2 zJlzDt`qp%&>Y2eo2X@odj@=|WLox0kh`;0YM@X*Ij*6m0A?+l|U|D!Y9xaS6yghGg z>V35GsJWwkjT0ZdT;M`6McHCDk>?lT*Cm+qIfsXxW_0axs5!H$!+};f8g-~$7t9=% zRi9mS)ur?D>6D_1b)my%@%47AB0=%{c8)6Zt1;7ZH$N%ERb3cl7CO&29O_naa@|61 zZhPT)USPA?oA*Ow)Qj=t+vZ?hFD;|lP;<@3GC_6L4;Cn&3uUg^$Kfz)fr6Atv!j`L z#&gO}g29a7J6104W#&Pfi9vF5fhjevI@IR;)fx8IJXI3BOwe&3inL zFQ8Bdm1?oux~T@*@ScW-4pt$xx>SOT!e&h2Hw&U(RAS;-QM%o0i{tLWXNOa+S2%xN zMC-!j_&;RihRSUo5~ftDMp3BO^YZN1AqoN4iNFzlGbR}@bkpUklM}LDR9`BERH#&- z$A)4@(V%LItdZwl%T!a;HrH*j$5E5C(Ga^tf#Y*4__w-Liu-6smr!92hs9Q#b={Mz zdQStZz{=|$(zRVsSC#}+N+(=ORA3rDmk2Ka6%OrQcbX~_)}@3LzjfFvIzC2Zi6hz( zC&eoHGim*ZJ`#@^6^n&BMHWT4tPZ@;^YrxKD745^g-~+xxRa@3GfFoo_Zi22gidk$ z4f*LkMT%DLC{J1u_>Jw1g7Ub17Nj-{p8);pPCVI&r*^Wia7$BBeMtwH?BHb0uHWhA zv0p;1I~mHG069{i?w;M<@K|O#!ktV!uBcl!N31h#+M|OMk#TQRI#_BkmsbJDKZb`us;d=RxvkIJ{T)_U*d0j# z>A=~uA2WCfS7n$tC`j-6RZzI9-9eOBkTV#XOycG&sIC$Ob?TNpd#yetu;rKrA%_&~ zr7V>U^arFki>fj@+!VA!VJ)zl<^iwsnPQ?!%~Z#jfCcQ^knFX#t5z6e2)dDAIFeTr zICU4ztA-}~s6_Z~dMc?WF_!IAE`PmwH{Aq3k-+Qz#zK?HMUjK6`pt4u2L~HB?5}tB z<_=rXtB0tE{WOD3G=IH%$g2$=ErysV_O0TjTY?fNk#i~w6E`=1Wx?6y^)mLkzOk}U z;?R41y)jDVOj)K~DRSCwF8yh0m#nPM{kxYH1YN2Qf`XTvOpRjMR!%S8+S$Aly1IIF z@9v3#krJ9oUPlAt-)E4oY8WP97I`(DLjT^x=%^GMCXEk<&CS*BOJC3~F1AJDgiewk zT{y)l@-eoh|MkuxAM?8KWifH;j(8Chn`eBwBNFTNT7vuh+6dtPU@6Fk{}VhE=Uzu#9sM80{Y*RJZb3z6q+I=rTOiI5O7lBAoQWEowgMFVN4 zi|x)p0_C_+0W(rRalvIqEUZ+2dC8cZN$?N&g9k&Rm><#6lCkNXc|`G?uV@mGl2ndp z;PJ0AWh4ErODE3AX%#gEJ$iCsf*gvBvSfy?$N93 zgsavYJNFLHmJl((ZV^sjj?W|(sjBp%%A+RFZID7weCTYi*c#|4R++X-$J%X{fgSKc zICVsV$okgsOR5I$CYzh*E+0E@i!?+o9Xl&)D;CrMcP4^k_~5)TiOW++PbG?%AID-m z^Hg$9W|W~}#3Um`Y9ur?GJPf(_vIeCLYT3_kw;K{QC$45)lBh4H{V6O6iY}k8{G8=}LO&+wZ6&A1A52V*UHEcX^s)B=AJ2{5O}~y!A-68 z##{oM9AB!mqv`Kx$k!<`wXl2kNKLiT zeeAwquM6RYaR%&I;jvt<$}h>U$+=$sgX>UEL%F4z-e^`SglbkwMn3AMb66ge$7YE^ zXYs1!yyxLjlULdP%_+?@#sP(6A_if)hsP>gafiH`1 zppa<17qXTzC>4blD?i>9-PPHR$sw(0X{3gnn%a=jQ#?bX)p?n6b?pjrUJ09_t;q zqtKrh#)zR(=fOsdB5~KE#8NUDA)|TYDF4&EE*g^he6eCaiiR{^YgSK>P)g7+iG9A1 zo;t!4ZBvtfO-@cXZ;2PF1g)gRz9HOV2V@fY`**!NDvi}ysm^2@bpD`e3Uh_>A(F)P zN?JOus2EGgs?IV*EF;!rZdU(2=LvM*F8j@q%}<>*(IaSSY9;w=H}#L?JMBtlTfNz# zIeK@)DsI51_?i-1gshU$QE4+o9nN{i!46>3C6~W7Igo5qz8C9)EupmY0@9ue*)|?z zaf@d$@r+~+>CX0C%wzh5mqaDSFw#GC+xKH2~;F~B`5PEki$NPLeALp1r>x6foE0G{Iuo{JI zvzN!aa$AE?e{TU^%QWErz{n9tS}ArM26-1QfmI2-Ky2nhB3@d$2Ct(b!=-N@pW#-Z z8&sxorp7X{BuEZ?UBG5}--*TYkm!dM4efqYWE1Ie8-=!Tt59NuhcNnf4o<{5lR@)C zVdc{88{w#C{drd^ONSg?*8&~#yf*gM7)Nd}jPlsc(&?o|!j4<}>y_Ij!jRRs4}I>1 zP||-xnWw1l_(*GSK+C~?;n!SQ(D_Ti=RQjyUQhzJP!KItslMyIP~!w0XMTPH3|s?X%l&>+k`92rkqRJ(MtB=djE?k1WoEe~wQ^Lx&e zx+&gB+Bnfz{38EFh%mKQ3lYD$eJ(2ZNX6q-M`6ef%P_a%O-kb_7)@UL-`XW8DBaD{ z09?roup(H=;Ka&}9)2^_)XqjwmCW6?A){|^o-}sg(Fuq(=XjSeNnuO2e33Qyl6*{- z>3N1ap{GxQBiZ+$?LDr$68%}TZ-Ur1jkA~DeTkU-wcamA4{`cLPSBs+%o4A)-a2f8 zLp03B`nP28QUY*Fs`TerQn9$5BZpMGBXtEUoNQKG3hA7Rr07$S>-+K;zm>}1jYO*G zQk3SZQHXfxhoRPA)~R71B~EOX?@JYQ?0|)Xwtyta0p4L4Zn5c0TTRZ^-nwN_^jzY$ zSKoI|P$StwV7l^cfCQczRfrW%Fy2FK#ut*`i`xx02)L<~eHCb$N|xC4d<_(&wSwfT zi~B9Ha&hWkV&&t`MxEi}wvwJ&EdUP~z%?%ViGYQJ`M#g9kS;r)UNc$<0$2L*E z-s5bYCe0tXY??@vFD>!x#$x5Uu!J5_(&3SJzUC&U!l|CKV$+tcz_e12NcbWCQ#+fF z0`E!m_|DNUk1t{WS5a3T*JSth@!}>am>$=XB-+NPdOBVOp_QpSD$L^TsG^2~LxB6=j zCAoP{w^-EDT$jeWc)rI7$g+mad z5yOIbUAqUe4n8i6Rcc$KbTN%$01@A@ZpMGf{$9<9 zX$(odqGMW=!mr0$$SlsE64p=)9{k+sj!HJYne(T=mC{L;JVUj8I7wT~UwycrIJ7P| zhE&$hEM(X7g@eiIv9V)jE!lK7;HL+G8yQ(#g9Y3a?NYbvN$41$Ro*mO9KB{W0a6rxELdfCPn9w&NB%pYxeGWg<3A5(CIDFHzMY?)+ z^6*sPKWZjSJCDqAiNItXly4U+8-J&Yq62n?9vtB!lYdEcRLeNp{5{_({_gRGkQ`6l z9A}>!S|nPc_G9R89D2?qMTaOIts_E=4FT)DI~zbZikZa3orFo_BL$<9p8V9rzY<|? ztOO4QIb})ODAEe=6XDW>AZE?q?t){s2-CjrSXl%O0#tZ^o_a}WbGW&C!hJ&&K&Az1 zF2h-nm_Br#0sk_?T`=X=uFm@TZi(rE)#}RnY}ljmsb7_xv_d%@SN=ZtAKo%wd0r#? z8C>~qNIaB1S@VADH)@3RqxO*g>d!KrX?tqtZCmy^-NzuR^~5p$n?srS<)_^vjIJw1 zMf{(QMyI-pE2ft3*dbmge0+*S3Q}piYQ{(OC+HY5H26%kq?5HT6vX&oQ=)fup4_W^ zM6V1VFaeW*xkIdK?^@?2sU`RBv=@-v3@EKRq60!s~4o*60lq$W>S-rlf!S zc4_G5NU;laOm1sb!~`}-UGI-l-0T+%3y(oDK%OCie+&uE6Q!ph{U9lc?dM0iv03xT z6i>HT<}L-}^h=vnb*G}(%0`(mc?moY<)zA+SIuzEC#DObB^1M^*T67e_btqfMS_hx zg9UyMi&bf%ob>&<0cuMkp?M66m-Lze4_p4tL*uQ!qxZZhFi`IOotvee*@`bs)BDHKgFXj!F8GOt(?H}rc155e_LmqRb6C5AGd(-?utMWHJ zKt$M_;-46=(xQou{rI8Qg6_VwLVV-B!QPMg`SQMvnsFeg(~l=?o;>4Ej@(D`^<{T$ z^R1?Dyy8YKMxWu-(!a>Oenr+k;-b{PHg#*#a%mFWwIon1nNmQq_}&xG7|J+1?Yqy? zSz`3LgC6u1f4=x^&+F&&Y*etr%52ET!*0j$=8xiarOcA(@#K~q|H$pns~CmOPTw?? zpF$nPRV?;-biLkS(9>rZ3H6#u%rQ!Z;Nm`V^+vN%^!-J-#j;my!EmB%-nYpx*3+*r=Q9rQ%jd6HClVH{1T}HTnKRk~yS1{*CILZz z-L4)R48Q*{L-W4fJ;dsFO$JDaNCFhv9g}k7wY|6G65WJoGE@&L{S69}sdz5uo+Y>g zwbaE=zyPkKbn1|N27OnlAO^jWCJNAFDGF}Co*Vf}4E(w2b-ua$(;a{J^-*Bb3pJ7LG=7f6Wip-Y7UR zc}VG47Farm@1CVF1^p#V_MJIr#x!UvM_9wKJyhX)@=SW&-R+y38!NhD7k^`yoB>`C z9d(TuF5s`EhvN;(fZ{9wtv3yVrVK{Md@k$Co4bys6i%@yNhc&vgH<7EikQ-9s1FimMI>9Z_fzVVS1!#D^6Cx?FD zgOx0uqSXBP;XD_Zytgo%Q<>!9%HBgHl!0x+P4FT*Z zng(&FhTrF?A7j{&4v7-gA^vSo{>+kCY=K8az>#nczyQ|9)0xcVH2`r`n&^5=Gs5(i zSuy+ix7ehDn06v;J!gylo|9xpl)oH6_O-cmX0wm7kc&kMZs@5}@6DjksW8ViT3X1e zKm5fqp+qq$Gw{Uu0Vz+f`)z{jj1$(*k09cpAl&V2OM7ur+O>nCNW;w91p|o;aQkOJb~pZgL*xM{eAU<}=s-V7(t; zVPUDgiK%`!-B*~s#iqy1R!n!<8-I1fqH8pvqa6?Tul`PQ^QEOc?g^1B;2`Hzk;j5! z_3SbpVZHATz2^DvJN;yUh`Q$7c6ewj^>^RD2OkLs0SE3a{Zni}%M!$y{O$xUiKORS z-x*AQw!M(TO$?iB743_ad--xp7R!nD3BezK7cd*O(?B2-^YLxg+a|-AO3O6L34S(a zfk`8FFeMemNFKqu>r(GioPTcl?8Tb27lILA)nBz#t5B!$m(;dO#f~p{XfQ|7XzxZi z7${@udWVB-tc@$0&-hr`Sx0|DXk|j{KdZ?P`=3-c}D&JUGTH2bKb<(KVKzeY?tR1R?8F8|(FU4s?-u#{S zeRx$A?Q3WDlvVj1o+dA^nAz(Kk9VY6+^aqBb{;WwPso;{gozjGyA4^Nv5lQ6&(`LY z4;jU4ZWjw9%S!=NMA8l635n)vbZ)&rA1yxPi@8oyeJox$#8WU{T@Kl7unUXN67mvl z2H!Og*B9ac#$oAoKwjZ4af;_wTK;OdN!oiSB2b^T z>oLk5(TR}rLzDU>0M`GP&%$KF)nUG=ap5gG^VXTVUA?l3it&gc>9dYBmtzrLc$wQQ z%_t_)8zNY3d>)ml@zv-V;m9%UeCvhS^+dK%%WjIgu4d^`T77Z3X+-=yBY(HN8=-Bj zjawk6v1moyOJZ9K&t4;2xwQjt-L25#3HTwZzX5kk>tWvM1@&mb^5FVu78`-v_M?P& z83&I{A;yIjsPJ%lD1+$(vPUlw+u@)YV2nxP{XXDbQrraF79-$GU3A@e+8H0GJ9LYA3qvu za~O1BlP$cU{!Is?-E($iscs&8P1{G1K76(;5p&c$;s${UG;eoXH)Rc>40BZrOel^~ zGKt^Jzi(As{#sV;StVGnHQjUvj|P>^(l>OK8;a7_P;+=ci(3vR+L)UjvvIHw+cIy? zQ%VfKdkp@&nXd!UAFDo>E>tUTPB_*EugjMXZ0Y4?^Rq>QVN}MX5fUcivDMAvUeIpr2s^7b zdUxujtfVv*R&{5j;MQyZELBGsraF>VoSam`|K!WO_qOG!Ut6+g?a1O{@AldRzgMdf zUqijD8NJ$S|E>QQ%ZCqn02Tv^0P{WF;IlcMEIe-}$a~d$E;VYAezPr&_xftg@3Ppz z6`}#@qI9#HDelan^GS%mI|nNPv>xgV*^i-Pw>q?b@~nNhV5}#~rYq4tW(u|ZGS@~h zZBU)*FZHo3C;^w^j$&eXe+kmoV0>bx6tPcY*#x1ardD@6=F1TDHiUTuZw=B_AB5JG z=SmZn=oB|TF{Wu4+4vRh-CThh4~av=c-}bPXo1TW=5ZsP(qm(Pm4XW5H_8UV!un~N z+J-E-?}Ko6(1=ee)Dm9Wxp6h8R)uO_gEsb4-^*vv_^Vc4d_v+mRFf4O8!^k2HUHr2 zCO$BX6<2XLs+uUZ*ZhG>?sr0^h$*t3~zdyQ1nDQz(JRC(QUuBEP5U_Z-mYpDzX)EppUb;cE~9#Z&7h_P`I zRmSb3KmlSQqWkMBNyT*l>_)pn9jx}jkm*az;(fw7SQ*@ z2ph4BZ{mPbAKUA?jr7Si0D^RMURbmHYBgYYi_E(ou9B_HrU_G0J|6GO4F<>}tEaa9 zrP=)xzuk0xXO0={vMb50WYxzY-wct%#Cg#vlxLeunD&N-#C|;f+%4E;C-7UDBA$`?13NRu;lip}O0Dr=$NfB| zQPW-8b#L6d{5s`L{fXk%T3s4*>z@woobH(uAv}-x7KwXT`_#<)h3k0vfKTOVl6ZNY zUM3A^A@}0edDmS0X@Kd87bFVAt=o4q#ITEP?IxNNnY0p<3oqdJXr~G*r*dC~H9)8I!vCHYgxiwbZqX;Q6?)v!%^u zK3>Wnyo~ThWUX})&CCRo<9MLUI+=}fzc&&&x%vHN!74GK{&Y`SwKLn{R+O*dYSVNq zLw_tg+mj?V#k^G{D@TR4A0#64-698}>KOw?!eqIoX}!TRX&j;tgVX`nzXk?kl4+5mtn<3Nb9UOpk ziqx6=<+5KVi+dkL^qQ3QXOvJ!iDgFy71<)I1MEW;5Sp6m`OQHIl$SflNWSOXb;A^e z#1v-sh?K(pi~n-by%r!l!`LzU=>L9u3ty zj{2oq;1{f%FkLc;nK3TC@Nb{@J(9KeHz`P!>W}`{S3E=bto! z5oB)=c*!8gLQy&ygtLg?b4^hme-~-yRiDjd8X$p96cJsLyyhx9rS24j4{hn zQ(e0(a?qgGO7;`~_I&PMl^S*XIH}wC^V~HKkyUpCVUI2P3}Fv2c2_O}!STvmF__=+ zjhZP+K@2m+DRz8e0P0bdMW!BkzcEM?m1`dJ(L0wAgw7jyFgEBU@VU*LedV`bfGImS zJrFQsvUc9eEH~OkehG5D>XiMlff}2Fs?MkT@_E=HBL~Y^%k^`Ql-G|sP$jYK86x}T zL)0J}zn`G(=~nG7kMhk0yLC?evz|(xV!c_;T)Yg?lT4MY7U+i3hwgD@Xl2fesO=v`o$OI^ zw;eZ6M$FM@)YwO3Ru)dR?NEI}*9_Ig*)=&g4uiv=^={63al&U;2Etxm=;k5^I}IP{ z2=?p3NSc#Z1w+Oo-!~dX^@LbCO1>8(OSD#i_{8Ka@Z6oVLBy)1xL*5Q{A$hXy0>E3zLH)KObC4d>No z4j7yLzSp%5TA%pEDz%a-+Dl&qqmE%lQA3YCHFjx)Xoar6eY2-N-+&OR{#$$efuBrg zvZScou!pNaT=9K>MnOc{WZxz?W!r3?j*++YF&%(71e)8P0;ia)f1@yuJ-Dxmr((&qg0_@iHl<(M;t8{1!NL-nxBPG9FKNWK8qf|L0QeZ=BT`xn_U3b~seE-~6*zckcu$h{&mI>_r>hBhm zPjhjh;|rWTE%4bPAuJuL+EC6u3Ew_M z$#B2Ddv>^W=E_7H7(aalB28(;JgTWDOsn-C94C>0OpYn4$R`Q(muS$om0$L7s))V( zfu0blfR)7#i{|dP+9kv{23AB6Wu+Cntmgw&`9uZrgHr7W>$X~uvPj5QNOL~V*mc~V zm6zLMZ;SWA*Oa1#gB9pdhA8x{SDoYWS>yji2)*Y1fVe-%aVb-!`)>FrJv7W)OIo}= zoXtR1R->O|<$;#9n_Gwlj_b}zRdPpR<$FiX9wM5_Mu{(TOO$-2>@_+uAi1lM7GW1m zYS$iivo9KY7Sv-Au5(0KGTOXxpir!-mCn_VztI^&s)4Po1`j@S-BGXTsw#M`Cw_GF zBZk3pb+v!_x!;Lho_BcPUJF`uVfB|FyPL6K?)-J|m=W3xl$!Q#3oZ;2B*CIUYCAMRz9667SFbM1rCOvkYS@ar^5GpLsY^i2gC3}D% zg)#N=s&8NSoiN{a-9KDyY-7-C_F4^HKKKuj^27~*n}w4%%~pJDu7DF{=@#IM# zz2i8Ro|^2ZeNhL!52lb^1yR`Lt9KO+QQ@|-rjf}SlKIH`Jd=F zW}fKFf1|y_(om=$B|&32vj+c^>wO*=N2K_#F1p!S)_l7}>y=SO)Vn1xwYaBzQu$H- zrSg)}o`n~($~r7ne*!g?jos|JXsG1nx2$hJgL&`ld|v=vFD5G>}LM!`lt@h-~3sg$zuB?+ijye3q=%D0!}#_SA`@dFS(Qb zog{7RLE=9jP96j*Q8rEPPPGFeOjQ+FFIMjM&YSOhUgM)vy3dPxR`+@t>GSpsRPwHw zd3+m;kL5CUl6X^op8l6}jTQz<0QX6|y0T>mn6)k5nA((nWoiE+$t~9wqDB}cL|m_+ z{#By9qeHFexy~mXoJeW1WqSJT7ud{+xVLc`k-cegY!&@)#&^|?UbHPYs4_Fdd4>6( z_5og^D%^5~igxT(z%2qGi${|<9NUVAE4?4ah8&$KO{hb%K4VpPcTY5g%Vb1-Tn2N) z8Q8=4XU&x&!K|#RVE7}@Ql*x#i_5vRAvi;;k7v| z!&RzO=DaadS^W8OdWY684^b9=!gaQm?ol0WyGlnKW&&~qwkB;%CVoF zIYJl&Q@8PPfp0;?eB>8U&80_F0@jdz%GD%Io7r*&`k}Yjtyecx_>|e?j!emB5mx2C@y|6uzmnG(TOM z#QF-x_{)3ar>?+R%U|R?E7{u^dYAWPaI;8|Z%OX_dpiKa=`ni##*nkeF*9+z6xr1x zz&dL=?snBU?|&VQE7y~2L(b>uCF9etpKFHd8wZJI-)fdwXZ9s3dw`ocN=7r_+!U9! zE+cBx;9w|Pe$Wt3GdGg0HJDbLU7`~_>@i&;7f$$N;={4gWDGWKp}&32ghy>jaqTO6 z1NV~rdUdYWUx`6X%LS=fwj=$K1IHu`Agf=B`KpRVm<9`Ox8LUV(2h0`!gT(UJEVMj z+UT5MP(Y}tB#Eo|e1?y3uB9X<#`M&$=vthI6K1T4;6`4@rRJXhM~*vmc-RCCjp^?# z_4X}Ri=S{QdN8LKy!L2v*3?Xkm=$U z&Og}RJG9sH+G9hby}h3q`Z5x7=j5#@Ko$+T|AS}X=(Ax?zVPc3>@2CB(aIM z#pb77y9TJ~MI`ow;=}O?2pGVmx%8=@_3KSA>_C7hpU9}How@Hq0#MDtBLm4+@$L(r zm!`T_HleLet@W|P(IM;$)p5`^()@%;&UNun4I=8JU_0qJ)+I7g0&P~?R$f0`MA>4{ z@}I@26BXVmvbzA59#x428 z3qFd#Da7P3GPzvR{*{?ZCqoR@b7Ne`BkMP#%*%+e;si3x(&tWuO~R^WfAs}=8@4KF zlBT1dy)?&uW3>8Mwe7X4!l56ouKvZ29l~{77-<~lN)j=y<731u-OCLvR%o&hG=n#4 zMQ5?mTd(Zc_c)qREvs4UIX$0NJE8iHhdamZ93DLv>rA#Pm?hm%Ajya9a1r!8ch_Hk zP8Qg3&W9#e^5J0M78flIk(AUnkqTb$G4>0*39-hceP~`eY)}FD$$#RSoi3s|=Ns9~ z4O!W^5)SlU(jB56oKg7+GlpfW4r4%5gU#=BZz-Q$#D+UNJLl-j@Dvx9;W4RA4Xn)= z%U}8l91T%bZ~}6K^(z}MXi>| zO*2c)>gpzh#(DISqxtAgL%k1pkTzejGMD7gm=+kijgN&QNuS?d+si-a7915pe2n_x zL2Nrm`^wrr&fUQw(kn+1L+DJAWat1$JG84ID(11D_t}+Pmdb+E5lTrM*BWz4e=qs_ zSD2b!EP#noSF86ZHkH>lYMRkss(@I#PhR=H^%1pMXcS`NcRDT~2>6kEn$UOk`@sN! zV!DDrt*b+K0;=*@uuvp-8NpGGYuBlnsvnt84s-yXF4As|;@5fi#`1V1% zImzVS;BLcst7QX?zez44lwjp;OG27)=@C%RkTx(_<(6x3G#vj_?(Z`O{pZRQ$dJm# z-BSESM(FLlK(DU_;RFEYrRkz&x<8md_hKT`)e< zD#s}M3BkppX?cVXWQxnhL_BULv^)FU3Ht@dFE*{!X>@@2cRcihPU@NMwl~4 zgE(f*mTXfEYLEL0R^5A;IXJ{pHg7O5H|_l=(rZ3>6Pk#*%?V;-ua~N#d(jI0Ivaqi zFjdmKOEp$?>A1OZ>fodHIj?-koRUMg$SuvI$iAP`2ZwO3xmaNS;+6T;VZmJc+r>sq z(gU00L~X5do6#N}zV3L{$RA^~6|F^)Fdt2awA1$Ui)RoAy)r&6M*W7>7j+KvW$!Kf zEDdAXk027c$B~B{MXzZ>?8%)gjzfoxZ8d!S60|F3i-+qR5*TnU09BlItp)2cuMr2( z3yG@13;xowgK6XSUP&|5!;5^dEBI|5;ozdiAIKts`M$CF;QGQZP<>*t`e7s4OC43* z_9O8@tZd6ux3jOei_4zr_{ql5Ow||&v>%7=gsb#!_f4Slt&jqB;Mjj|0ZwG^s`Il( z+pHmKu|fiY9UxuY#+Jlc+*C$?DsaTZ@{@RDzxx35t2IZJdDrm}r5grQeZ3Eoui2#) z;L4al!G(cpothRTOk8i0L}TYT0{zusw{Yh}M)6>js($idoy4U6tgxmYP#RZ^Wi7EC zpQ(CL5J_G2h(jo4iDxY_=O+P20@IEO4XU?OJ4i*cvi53x704E8aIhJ8!m}cHvcqFc*!qp!}2ka?qx<=B}<+E zG(kqEHaV2sowAGhRwW!*|{s6(_KA zJX3d1)WJXD6BYcD2K#Y#J=@Zd*;xEMe0lhL%0y>)f^>`-fxNtstK_o?xeBFPc-VXl z9BQ3*=CAR>LJE`4Z=Pad_}BggwiqUGI$)Byz_e{0!(wRts}-UHoZRG&l*CAGV) zzt9)+2zy~QGXYiA&G`k}x}!9lr{y2SmBS-8Ts6YZ9C_v#Px_o` zJhs5bOgt^oiWpSk6Ed(AX}$cqmO5OJ)$AY50NJ=OWW+qWtxozW;6=n;LK|m087eBD znw$>*rv)D_Od3R14!j0`)eCb$Vvv}NF)GNyyApXp_L9N;Aw?YqaE!bRWWg`a^9C39 zyXl1_Jg@HE&w06;kYMGh%E9G5@JeMSD@qKjC`68q@+~2{Vl7)R(TSrS@@-UL%TmRgl=1F%kYthA}5tQ$clsw)&vN0Pko4^nu$C1oM{PL|?=3H|N zRk})1G#6!y9k)&=C+llh2@Xy>i0eR}yEAl2rKhdv%iNdC4oNdZ znPX{4$L`sjkwMi^1_#B_+Vj|O|o-wppSQqHTB%2c3oQw1Q3Y&0Ze9Erg~hB zG9aLr$akul1=mdJ8Si?npGZK}Wyr$14`(X`#y#`3_}q@11t0Hw!&1EtUoAf{`O7aX z=R30GSWaIvha^S@Hz!?BdhdS<=5q2$gaEk( z@Sab&rniYseT{hjLYuH8UrZqt$RFtaH^t2>LsIRXK(iYjK!er+$f0}A&^O>s0$ApS z=FR6=l8e>qPF2Sn=D;K@W}r;J-@U-)6B|l_T*Ru?WZezO&PbXboVMP~`n$aksPemy zEBlb5!|v7JuA7(rtfQk*d>(D5p?CXL6rKDI?h7;3s@K~@mq|2dTw;gD-W%&LiRNZd^ySXM=*T*@Ti{{YD&Vg~>K literal 0 HcmV?d00001 diff --git a/docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-welcome-dialog.png b/docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-welcome-dialog.png new file mode 100644 index 0000000000000000000000000000000000000000..33b4e010f91fdb59e05aec172e35e07a008070d2 GIT binary patch literal 176980 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
P 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. + +=== Environment tab + +image::marketplace/marketplace-dialog-environment.png[Marketplace dialog Environment tab,75%,align="left"] + +This tab embeds the full environment editor (no separate “Edit…” window). It is the GUI equivalent of `hop marketplace validate` / `apply` and of editing `hop-env.yaml` by hand. + +==== File toolbar + +* *New* — empty environment specification +* *Open…* — open a `hop-env.yaml` / `.yml` / `.json` file +* *Save* / *Save As…* — write YAML or JSON (by extension) +* Filename *combo* — current path plus recently used environment files (remembered via the Hop audit list for this namespace). Selecting an entry loads that file. +* On open, Hop prefers the last file you edited in this dialog; otherwise it may pre-select `full-client-env.yaml` at the install root when that file exists. + +==== Nested editor tabs + +[cols="1,3"] +|=== +| Tab | Contents + +| *General* +| Spec `version`, `hopVersion`, and `enforceOnRun` (when true, hop-run can fail if the install drifts from this file; also controlled by `-Dhop.env.enforce=true`). + +| *Repositories* +| Ordered list of Maven repositories for *this environment file* (first row is primary). Optional username/password. *Import from hop-config…* copies enabled repositories from hop-config (one-shot; env-file repos stay independent of the main *Repositories* tab). + +| *Plugins* +| Plugin GAVs to install. *From catalog…* multi-selects from the optional-plugin catalog. Leave Group ID blank to use `org.apache.hop`. Version can default from *Hop version* on General when applying. + +| *Dependencies* +| Optional jars (for example JDBC) with target directory under Hop home (default `lib/jdbc`). +|=== + +==== Validate and Apply + +At the bottom of the Environment tab: + +* *Validate* — compare the local install to the saved environment file without downloading. +* *Apply* — install missing plugins and dependencies declared in the file. +* *Prune extras on apply* — same as CLI `apply --prune` (confirm before running). +* *Strict validate* — also fail when extra marketplace-installed plugins (receipts under `plugins/.marketplace/`) are not listed in the file. + +If validation finds drift, Hop shows a report. Use *Apply* to fix, then restart Hop. + +image::marketplace/marketplace-environment-drift.png[Marketplace environment drift report,75%,align="left"] + +[[marketplace-gui-repositories]] +=== Repositories tab + +image::marketplace/marketplace-dialog-repositories.png[Marketplace dialog Repositories tab,75%,align="left"] + +Configure the global marketplace repository list (stored under `marketplace` in `${HOP_CONFIG_FOLDER}/hop-config.json` — the same config the CLI uses): + +* Table columns: *Primary*, *Enabled*, *Id*, *Name*, *URL*, *Auth* +* *Add* / *Edit* / *Remove* — maintain repository entries +* *Set primary* — install tries this repository first +* *Up* / *Down* — order fallbacks after the primary +* *Reset defaults* — Apache Repository (primary) + Maven Central +* *Save* — write hop-config (required to keep changes) + +Add or edit a repository with id, name, URL, optional credentials, and primary/enabled flags: + +image::marketplace/marketplace-dialog-repository-editor.png[Add or edit marketplace repository,60%,align="left"] + +=== Projects lifecycle environments + +When the *Projects* plugin is installed, each lifecycle environment can store marketplace-specific *attributes* (namespaced under the `marketplace` group). On the environment properties dialog, open the *Marketplace plugins* tab: + +image::marketplace/marketplace-lifecycle-enviromnent-enforce-configuration.png[Lifecycle environment Marketplace plugins configuration,75%,align="left"] -=== Environment file (Apply / Validate) +Typical options: -The dialog also exposes declarative environments (same as the CLI): +* *Environment file* — path to a `hop-env.yaml` (variables allowed, for example under the project home) +* *On enable* — `off` (no check), `warn` (log or dialog on drift), or `enforce` (fail enabling the environment if the install does not match) +* *Strict* — treat extra marketplace plugins as drift +* *Auto-apply missing plugins on enable* — optional; off by default (use only on controlled machines) -* **Environment file** — path to `hop-env.yaml` / `.yml` / `.json`. If present, `full-client-env.yaml` at the install root is pre-filled. -* **Browse…** — choose a file. -* **Validate** — compare the local install to the file without downloading. Use **Strict validate** to also fail when extra marketplace plugins are installed. -* **Apply** — install missing plugins and dependencies. Optionally enable **Prune extras on apply** (same as `apply --prune`; confirm before running). +If *On enable* is unset, purpose-based defaults apply: *Production* → enforce, *Testing* / *Acceptance* → warn, *Development* / CI-style purposes → off. -After Apply, restart Hop so plugins load. +This complements hop-env `enforceOnRun` (checked at hop-run) and the Environment tab *Validate* / *Apply* actions (manual checks from the marketplace dialog). == Declarative environments (`hop-env.yaml`) diff --git a/plugins/misc/marketplace/README.md b/plugins/misc/marketplace/README.md index bea7d138b38..42713eb13bd 100644 --- a/plugins/misc/marketplace/README.md +++ b/plugins/misc/marketplace/README.md @@ -93,6 +93,27 @@ dependencies: `hop-run` checks the env file only when `enforceOnRun: true` or `-Dhop.env.enforce=true`. Discovery order: `-f` / `HOP_ENV_FILE` / `PROJECT_HOME/hop-env.yaml` / install-root `hop-env.yaml`. +### Projects lifecycle environments + +When the **Projects** plugin enables a lifecycle environment, Marketplace can +check the same hop-env file using settings stored as **namespaced attributes** +on that environment (`IAttributes` group `marketplace`). No compile-time +dependency exists between the two plugins; they share core `AttributesContext`. + +| Attribute key (`marketplace` group) | Values | Meaning | +|-------------------------------------|--------|---------| +| `envFile` | path (variables OK) | hop-env / full-client-env file | +| `onEnable` | `off` / `warn` / `enforce` | Action when the environment is enabled | +| `strict` | `true` / `false` | Extra marketplace plugins count as drift | +| `autoApply` | `true` / `false` | Apply missing plugins on enable (default off) | + +If `onEnable` is unset, purpose defaults apply: **Production** → `enforce`, +**Testing/Acceptance** → `warn`, **Development/CI/CB** → `off`. + +Configure these on the environment dialog **Marketplace plugins** tab (only +visible when this plugin is installed). At enable time extension point +`HopProjectEnvironmentAfterEnabled` runs the check. + ## Config (`hop-config.json`) Marketplace settings live under the `marketplace` key in **`${HOP_CONFIG_FOLDER}/hop-config.json`** @@ -150,38 +171,170 @@ export HOP_MARKETPLACE_PASSWORD='…' ## GUI -Hop GUI → **Tools → Marketplace…** lists Wave 1 optional plugins. Choose the -**primary repository**, or **Manage…** to add/edit/remove/reorder repositories -(same hop-config.json as the CLI). Install uses the primary first, then fallbacks. -Restart after install or uninstall. +Hop GUI → **Tools → Marketplace…**, or the main toolbar icon after **Save As…** +(separator before it), opens the marketplace. The startup **Welcome** dialog also has a +**Marketplace** topic (docs link, open dialog, install-all via `full-client-env.yaml`). +The dialog lists optional plugins from the registry. Choose the **primary repository**, +or **Manage…** to add/edit/remove/reorder repositories (same hop-config.json as the CLI). +Install uses the primary first, then fallbacks. + +**Environment file** path + **Browse…** / **Edit…** / **Validate** / **Apply** manage +declarative `hop-env.yaml` files. **Edit…** opens a tabbed editor (General, +Repositories, Plugins, Dependencies) with New/Open/Save/Save As, catalog multi-add, +and optional import of repositories from hop-config. + +Restart after install, apply, or uninstall. + +## Optional plugin registry (source of truth) + +All marketplace-optional plugins are declared in **one file only**: + +```text +plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml +``` + +Do not hardcode plugin lists elsewhere. Everything below reads this registry: + +| Consumer | How it uses the registry | +|----------|--------------------------| +| GUI catalog / `hop marketplace query` | Loads YAML at runtime | +| `full-client-env.yaml` | Generated by `tools/generate-full-client-env.sh` (Maven `generate-resources`) | +| Local publish to Nexus/Artifactory | `docker/marketplace-nexus/publish-marketplace-plugins.sh` | +| Unpack zips into an install (IT images) | `tools/install-wave1-plugins.sh` via `tools/list-marketplace-plugins.sh` | + +Each entry needs at least: + +```yaml + - artifactId: hop-tech-parquet + name: Parquet + category: Technology + description: Parquet file format support. + installPath: plugins/tech/parquet # path under Hop home after install + modulePath: plugins/tech/parquet # Maven module in this repo (for package/publish) +``` + +Top-level `groupId` (default `org.apache.hop`) is used when publishing. + +### Making a plugin optional (checklist) + +1. Exclude it from the fat hop-client assembly. +2. **Add one entry** to `optional-plugins.yaml` (`artifactId`, `installPath`, `modulePath`, …). +3. Rebuild marketplace / client so `full-client-env.yaml` regenerates. +4. For local testing: package + publish the zip (see next section), point Hop at that repo, + then `./hop marketplace apply -f full-client-env.yaml` (or install a single GAV). +5. Restart Hop. + +## Publishing plugin zips (local Nexus / Artifactory) + +Marketplace installs **Maven GAV zips**, not jars alone. Layout: + +```text +{repoBase}/org/apache/hop/{artifactId}/{version}/{artifactId}-{version}.zip +``` + +Plugin modules already produce that zip via the reactor assembly +(`appendAssemblyId=false` → `modulePath/target/{artifactId}-{version}.zip`). + +### Script: `publish-marketplace-plugins.sh` + +From the **Hop repo root**: + +```bash +# List what the registry will publish (no network) +./tools/list-marketplace-plugins.sh +./tools/list-marketplace-plugins.sh --zips +``` + +#### Local Sonatype Nexus (Docker) + +```bash +./docker/marketplace-nexus/start.sh +# UI http://localhost:8081/ — admin / hop-nexus-dev +# Repo http://127.0.0.1:8081/repository/hop-plugins/ + +export NEXUS_PASSWORD=hop-nexus-dev -## Optional plugin registry & full-client-env.yaml +# Build every registry modulePath, then deploy all zips: +./docker/marketplace-nexus/publish-marketplace-plugins.sh --package -Source of truth for marketplace-optional plugins: +# Or deploy only zips that already exist under target/: +./docker/marketplace-nexus/publish-marketplace-plugins.sh + +# Preview without uploading: +./docker/marketplace-nexus/publish-marketplace-plugins.sh --dry-run +``` -`src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml` +Prefer **`127.0.0.1`** over `localhost` in Hop config (IPv6 vs Docker IPv4). -- GUI catalog loads this file at runtime. -- `tools/generate-full-client-env.sh` builds `full-client-env.yaml` (Maven `generate-resources`). -- The marketplace plugin zip places `full-client-env.yaml` at the **Hop install root** (and under samples). +More detail: `docker/marketplace-nexus/README.md`. -When moving another plugin out of the fat client: exclude it from assemblies, **add one entry** -to `optional-plugins.yaml`, rebuild. Then: +#### Your Artifactory (or any Maven 2 repo) ```bash +export ARTIFACTORY_URL='https://artifactory.example.com/artifactory/hop-plugins-local' +export ARTIFACTORY_USER='deploy-user' +export ARTIFACTORY_PASSWORD='…' +export NEXUS_REPO_ID=artifactory # must match used for deploy auth +export HOP_VERSION=2.19.0-SNAPSHOT # optional; default 2.19.0-SNAPSHOT + +./docker/marketplace-nexus/publish-marketplace-plugins.sh --package +``` + +Equivalent env names also accepted: `NEXUS_REPO_URL`, `NEXUS_USER`, `NEXUS_PASSWORD`, +`NEXUS_ADMIN_PASSWORD`. + +| Flag / env | Meaning | +|------------|---------| +| `--package` | `mvn -pl -am package -DskipTests`, then deploy | +| `--dry-run` | Print deploy targets; no Maven deploy (and no password required) | +| `HOP_VERSION` | Version coordinate and zip filename (default `2.19.0-SNAPSHOT`) | +| `GROUP_ID` | Override group (default: `groupId` from the YAML, else `org.apache.hop`) | +| `NEXUS_REPO_ID` | Maven `settings.xml` server id for credentials (default `hop-plugins`) | + +Missing zips are **skipped** with a message (`SKIP (not built)`), not a hard failure—so you +can publish a subset after a partial package. + +`publish-wave1-plugins.sh` is a **deprecated alias** of `publish-marketplace-plugins.sh`. + +### Point Hop at the local repo and install + +```bash +cd /path/to/hop-client # install root (hop launcher cd's here) + +./hop marketplace repo add --id local-nexus \ + --url http://127.0.0.1:8081/repository/hop-plugins/ --primary + +./hop marketplace install hop-tech-parquet +# or restore everything listed in the registry / full-client env: ./hop marketplace apply -f full-client-env.yaml ``` +Anonymous **read** on the repo is ideal for installs. Deploy credentials stay only on the +publish side (admin / CI user). + +### Related helper scripts + +```bash +# artifactId|modulePath (or --zips / --modules) +./tools/list-marketplace-plugins.sh + +# Unzip all built registry zips into a Hop install (no Maven repo) +./tools/install-wave1-plugins.sh [HOP_INSTALL_DIR] + +# Regenerate full-client-env.yaml (also run by marketplace module generate-resources) +./tools/generate-full-client-env.sh [HOP_VERSION] [OUTPUT_PATH] +``` + ## Packaging & size -Optional plugin modules already produce installable zips via the reactor `assembly` -profile (`appendAssemblyId=false` → `artifactId-version.zip` next to the jar). A -normal Maven deploy publishes that zip so marketplace can download it from ASF / -Central. For local SNAPSHOTs use `docker/marketplace-nexus/publish-wave1-plugins.sh`. +Optional plugins are **not** bundled in the default hop-client zip so the download stays +under the ASF packaging limit. Production releases publish the same GAV zips to +Apache Repository / Maven Central; day-to-day SNAPSHOT testing uses local Nexus or +Artifactory as above. -Lean client size (after Wave 1 optional split) is checked with: +Lean client size check: ```bash ./tools/check-assembly-size.sh -# typically hop-client ~590 MB (limit 850 MB) +# typically hop-client well under the 850 MB limit ``` diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java index 2f5cd7b94c0..e62767e0d45 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginCatalog.java @@ -88,7 +88,6 @@ public static boolean isInstalledOnDisk(Path hopHome, OptionalPluginInfo info) { return Files.isDirectory(path); } - @SuppressWarnings("unchecked") private static List loadRegistry() { try (InputStream in = OptionalPluginCatalog.class.getResourceAsStream(REGISTRY_RESOURCE)) { if (in == null) { diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java index 0c5381fd17b..1d2925c1303 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java @@ -97,7 +97,6 @@ public static MarketplaceConfig load() { } } - @SuppressWarnings("unchecked") public void save() { ensureValidPrimary(); Map asMap = HopJson.newMapper().convertValue(this, Map.class); @@ -199,9 +198,6 @@ public List orderedRepositories() { if (primary != null && Objects.equals(primary.getId(), repo.getId()) && primary == repo) { continue; } - if (primary != null && primary == repo) { - continue; - } // skip duplicate of primary by id if (primary != null && StringUtils.isNotBlank(primary.getId()) diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentLoader.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentLoader.java index 2228af6ca2f..ee6cfa22a6f 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentLoader.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentLoader.java @@ -19,17 +19,24 @@ import java.io.IOException; import java.io.InputStream; +import java.io.Writer; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; import java.util.Locale; import java.util.Map; +import org.apache.commons.lang3.StringUtils; import org.apache.hop.core.exception.HopException; import org.apache.hop.core.json.HopJson; +import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.SafeConstructor; -/** Loads {@link HopEnvironmentSpec} from YAML or JSON. */ +/** Loads and saves {@link HopEnvironmentSpec} as YAML or JSON. */ public final class HopEnvironmentLoader { private HopEnvironmentLoader() {} @@ -61,4 +68,123 @@ public static HopEnvironmentSpec load(Path file) throws HopException { throw new HopException("Unable to parse environment file: " + file, e); } } + + /** + * Writes {@code spec} to {@code file}. Format is JSON when the path ends with {@code .json}; + * otherwise YAML. + */ + public static void save(Path file, HopEnvironmentSpec spec) throws HopException { + if (file == null) { + throw new HopException("Environment file path is required"); + } + if (spec == null) { + throw new HopException("Environment specification is required"); + } + try { + Path parent = file.getParent(); + if (parent != null) { + Files.createDirectories(parent); + } + String name = file.getFileName().toString().toLowerCase(Locale.ROOT); + if (name.endsWith(".json")) { + HopJson.newMapper().writerWithDefaultPrettyPrinter().writeValue(file.toFile(), spec); + return; + } + Map map = toYamlMap(spec); + DumperOptions options = new DumperOptions(); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + options.setPrettyFlow(true); + options.setIndent(2); + options.setIndicatorIndent(0); + Yaml yaml = new Yaml(options); + try (Writer writer = Files.newBufferedWriter(file, StandardCharsets.UTF_8)) { + yaml.dump(map, writer); + } + } catch (Exception e) { + throw new HopException("Unable to write environment file: " + file, e); + } + } + + /** + * Builds a LinkedHashMap with stable field order and omits blank optional fields / empty lists. + */ + static Map toYamlMap(HopEnvironmentSpec spec) { + Map root = new LinkedHashMap<>(); + root.put("version", StringUtils.defaultIfBlank(spec.getVersion(), "1.0")); + if (StringUtils.isNotBlank(spec.getHopVersion())) { + root.put("hopVersion", spec.getHopVersion()); + } + root.put("enforceOnRun", spec.isEnforceOnRun()); + + List> repos = new ArrayList<>(); + for (HopEnvironmentSpec.RepositoryRef ref : nullSafe(spec.getRepositories())) { + if (ref == null || (StringUtils.isBlank(ref.getId()) && StringUtils.isBlank(ref.getUrl()))) { + continue; + } + Map m = new LinkedHashMap<>(); + if (StringUtils.isNotBlank(ref.getId())) { + m.put("id", ref.getId()); + } + if (StringUtils.isNotBlank(ref.getUrl())) { + m.put("url", ref.getUrl()); + } + if (StringUtils.isNotBlank(ref.getUsername())) { + m.put("username", ref.getUsername()); + } + if (StringUtils.isNotBlank(ref.getPassword())) { + m.put("password", ref.getPassword()); + } + repos.add(m); + } + if (!repos.isEmpty()) { + root.put("repositories", repos); + } + + List> plugins = new ArrayList<>(); + for (HopEnvironmentSpec.PluginRef ref : nullSafe(spec.getPlugins())) { + if (ref == null || StringUtils.isBlank(ref.getArtifactId())) { + continue; + } + Map m = new LinkedHashMap<>(); + if (StringUtils.isNotBlank(ref.getGroupId())) { + m.put("groupId", ref.getGroupId()); + } + m.put("artifactId", ref.getArtifactId()); + if (StringUtils.isNotBlank(ref.getVersion())) { + m.put("version", ref.getVersion()); + } + plugins.add(m); + } + if (!plugins.isEmpty()) { + root.put("plugins", plugins); + } + + List> deps = new ArrayList<>(); + for (HopEnvironmentSpec.DependencyRef ref : nullSafe(spec.getDependencies())) { + if (ref == null + || StringUtils.isAnyBlank(ref.getGroupId(), ref.getArtifactId(), ref.getVersion())) { + continue; + } + Map m = new LinkedHashMap<>(); + m.put("groupId", ref.getGroupId()); + m.put("artifactId", ref.getArtifactId()); + m.put("version", ref.getVersion()); + String target = StringUtils.defaultIfBlank(ref.getTarget(), "lib/jdbc"); + if (!"lib/jdbc".equals(target)) { + m.put("target", target); + } else if (StringUtils.isNotBlank(ref.getTarget())) { + // keep explicit default if user set it + m.put("target", target); + } + deps.add(m); + } + if (!deps.isEmpty()) { + root.put("dependencies", deps); + } + return root; + } + + private static List nullSafe(List list) { + return list == null ? List.of() : list; + } } diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentSpec.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentSpec.java index 66d0e474529..1efee5f64c7 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentSpec.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/HopEnvironmentSpec.java @@ -31,7 +31,7 @@ * enforceOnRun: false * repositories: * - id: central - * url: https://repo1.maven.org/maven2/ + * url: Maven central * plugins: * - artifactId: hop-tech-parquet * version: "2.19.0" diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/MarketplaceAttributes.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/MarketplaceAttributes.java new file mode 100644 index 00000000000..faef714c38e --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/env/MarketplaceAttributes.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.env; + +import org.apache.commons.lang3.StringUtils; +import org.apache.hop.core.IAttributes; + +/** + * Attribute group/key constants for marketplace settings stored via {@link IAttributes} (e.g. on + * lifecycle environments). Group name is {@link #GROUP}; keys are short and stable for JSON. + */ +public final class MarketplaceAttributes { + + /** IAttributes group for marketplace settings. */ + public static final String GROUP = "marketplace"; + + /** Path to hop-env.yaml / full-client-env.yaml (may contain variables). */ + public static final String KEY_ENV_FILE = "envFile"; + + /** + * When environment is enabled: {@link #ON_ENABLE_OFF}, {@link #ON_ENABLE_WARN}, {@link + * #ON_ENABLE_ENFORCE}. + */ + public static final String KEY_ON_ENABLE = "onEnable"; + + /** When true, extra marketplace plugins (receipts not in env file) count as drift. */ + public static final String KEY_STRICT = "strict"; + + /** When true, apply missing installs on enable (default false). */ + public static final String KEY_AUTO_APPLY = "autoApply"; + + public static final String ON_ENABLE_OFF = "off"; + public static final String ON_ENABLE_WARN = "warn"; + public static final String ON_ENABLE_ENFORCE = "enforce"; + + private MarketplaceAttributes() {} + + /** + * Resolve on-enable policy from attributes, falling back to purpose-based defaults when unset. + * + *

    + *
  • Production → enforce + *
  • Testing / Acceptance → warn + *
  • Development / CI / CB / other → off + *
+ */ + public static String resolveOnEnable(IAttributes attributes, String purpose) { + String explicit = attributes != null ? attributes.getAttribute(GROUP, KEY_ON_ENABLE) : null; + if (StringUtils.isNotBlank(explicit)) { + return explicit.trim().toLowerCase(); + } + return defaultOnEnableForPurpose(purpose); + } + + public static String defaultOnEnableForPurpose(String purpose) { + if (StringUtils.isBlank(purpose)) { + return ON_ENABLE_OFF; + } + String p = purpose.trim().toLowerCase(); + if (p.contains("production") || p.contains("prod")) { + return ON_ENABLE_ENFORCE; + } + if (p.contains("test") || p.contains("accept")) { + return ON_ENABLE_WARN; + } + return ON_ENABLE_OFF; + } + + public static boolean isStrict(IAttributes attributes) { + if (attributes == null) { + return false; + } + String v = attributes.getAttribute(GROUP, KEY_STRICT); + return "true".equalsIgnoreCase(v) || "Y".equalsIgnoreCase(v); + } + + public static boolean isAutoApply(IAttributes attributes) { + if (attributes == null) { + return false; + } + String v = attributes.getAttribute(GROUP, KEY_AUTO_APPLY); + return "true".equalsIgnoreCase(v) || "Y".equalsIgnoreCase(v); + } + + public static String envFile(IAttributes attributes) { + return attributes != null ? attributes.getAttribute(GROUP, KEY_ENV_FILE) : null; + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/AddPluginsFromCatalogDialog.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/AddPluginsFromCatalogDialog.java new file mode 100644 index 00000000000..4eea0c40103 --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/AddPluginsFromCatalogDialog.java @@ -0,0 +1,195 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.gui; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.apache.commons.lang3.StringUtils; +import org.apache.hop.core.Const; +import org.apache.hop.core.variables.Variables; +import org.apache.hop.i18n.BaseMessages; +import org.apache.hop.marketplace.catalog.OptionalPluginCatalog; +import org.apache.hop.marketplace.catalog.OptionalPluginInfo; +import org.apache.hop.ui.core.PropsUi; +import org.apache.hop.ui.core.gui.GuiResource; +import org.apache.hop.ui.core.widget.ColumnInfo; +import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Dialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; + +/** Multi-select optional plugins from the marketplace catalog. */ +public class AddPluginsFromCatalogDialog extends Dialog { + + private static final Class PKG = MarketplaceGuiPlugin.class; + + private final PropsUi props; + private final Set alreadyListed; + private final List selected = new ArrayList<>(); + + private Shell shell; + private TableView wTable; + private Text wFilter; + + public AddPluginsFromCatalogDialog(Shell parent, Set alreadyListedArtifactIds) { + super(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX); + this.props = PropsUi.getInstance(); + this.alreadyListed = + alreadyListedArtifactIds == null ? Set.of() : new HashSet<>(alreadyListedArtifactIds); + } + + /** + * @return selected catalog entries, or empty if cancelled + */ + public List open() { + Shell parent = getParent(); + shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX); + PropsUi.setLook(shell); + shell.setImage(GuiResource.getInstance().getImageHopUi()); + shell.setText(BaseMessages.getString(PKG, "AddPluginsFromCatalogDialog.Shell.Title")); + + FormLayout formLayout = new FormLayout(); + formLayout.marginWidth = PropsUi.getFormMargin(); + formLayout.marginHeight = PropsUi.getFormMargin(); + shell.setLayout(formLayout); + + Label wlFilter = new Label(shell, SWT.RIGHT); + PropsUi.setLook(wlFilter); + wlFilter.setText(BaseMessages.getString(PKG, "AddPluginsFromCatalogDialog.Filter.Label")); + FormData fdlFilter = new FormData(); + fdlFilter.left = new FormAttachment(0, 0); + fdlFilter.top = new FormAttachment(0, 0); + wlFilter.setLayoutData(fdlFilter); + + wFilter = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + PropsUi.setLook(wFilter); + FormData fdFilter = new FormData(); + fdFilter.left = new FormAttachment(wlFilter, PropsUi.getMargin()); + fdFilter.top = new FormAttachment(wlFilter, 0, SWT.CENTER); + fdFilter.right = new FormAttachment(100, 0); + wFilter.setLayoutData(fdFilter); + wFilter.addListener(SWT.Modify, e -> refreshTable()); + + Button wCancel = new Button(shell, SWT.PUSH); + wCancel.setText(BaseMessages.getString(PKG, "AddPluginsFromCatalogDialog.Button.Cancel")); + wCancel.addListener(SWT.Selection, e -> shell.dispose()); + + Button wOk = new Button(shell, SWT.PUSH); + wOk.setText(BaseMessages.getString(PKG, "AddPluginsFromCatalogDialog.Button.Add")); + wOk.addListener(SWT.Selection, e -> ok()); + + BaseTransformDialog.positionBottomButtons( + shell, new Button[] {wOk, wCancel}, PropsUi.getMargin(), null); + + ColumnInfo[] columns = { + new ColumnInfo( + BaseMessages.getString(PKG, "AddPluginsFromCatalogDialog.Column.Name"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "AddPluginsFromCatalogDialog.Column.Artifact"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "AddPluginsFromCatalogDialog.Column.Category"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "AddPluginsFromCatalogDialog.Column.Description"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + }; + wTable = + new TableView( + Variables.getADefaultVariableSpace(), + shell, + SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI | SWT.V_SCROLL, + columns, + 1, + true, + null, + props, + false); + PropsUi.setLook(wTable); + + FormData fdTable = new FormData(); + fdTable.left = new FormAttachment(0, 0); + fdTable.top = new FormAttachment(wFilter, PropsUi.getMargin() * 2); + fdTable.right = new FormAttachment(100, 0); + fdTable.bottom = new FormAttachment(wOk, -PropsUi.getMargin() * 2); + wTable.setLayoutData(fdTable); + + refreshTable(); + + BaseTransformDialog.setSize(shell); + shell.setSize(Math.max(shell.getSize().x, 720), Math.max(shell.getSize().y, 480)); + shell.open(); + Display display = parent.getDisplay(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + return selected; + } + + private void refreshTable() { + wTable.table.removeAll(); + String filter = wFilter != null ? wFilter.getText() : ""; + for (OptionalPluginInfo info : OptionalPluginCatalog.query(filter)) { + if (info == null || StringUtils.isBlank(info.getArtifactId())) { + continue; + } + if (alreadyListed.contains(info.getArtifactId())) { + continue; + } + TableItem item = new TableItem(wTable.table, SWT.NONE); + item.setText(1, Const.NVL(info.getName(), info.getArtifactId())); + item.setText(2, Const.NVL(info.getArtifactId(), "")); + item.setText(3, Const.NVL(info.getCategory(), "")); + item.setText(4, Const.NVL(info.getDescription(), "")); + item.setData(info); + } + wTable.optimizeTableView(); + } + + private void ok() { + selected.clear(); + for (TableItem item : wTable.table.getSelection()) { + if (item.getData() instanceof OptionalPluginInfo info) { + selected.add(info); + } + } + shell.dispose(); + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/HopEnvironmentDialog.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/HopEnvironmentDialog.java new file mode 100644 index 00000000000..08c9df8c61a --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/HopEnvironmentDialog.java @@ -0,0 +1,1516 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.gui; + +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.StringUtils; +import org.apache.hop.core.Const; +import org.apache.hop.core.logging.ILogChannel; +import org.apache.hop.core.logging.LogChannel; +import org.apache.hop.core.variables.Variables; +import org.apache.hop.history.AuditList; +import org.apache.hop.history.AuditManager; +import org.apache.hop.i18n.BaseMessages; +import org.apache.hop.marketplace.catalog.OptionalPluginInfo; +import org.apache.hop.marketplace.config.MarketplaceConfig; +import org.apache.hop.marketplace.config.MarketplaceRepository; +import org.apache.hop.marketplace.env.EnvironmentApplier; +import org.apache.hop.marketplace.env.EnvironmentDrift; +import org.apache.hop.marketplace.env.HopEnvironmentLoader; +import org.apache.hop.marketplace.env.HopEnvironmentSpec; +import org.apache.hop.marketplace.install.HopHome; +import org.apache.hop.marketplace.install.PluginInstaller; +import org.apache.hop.ui.core.PropsUi; +import org.apache.hop.ui.core.dialog.BaseDialog; +import org.apache.hop.ui.core.dialog.ErrorDialog; +import org.apache.hop.ui.core.dialog.MessageBox; +import org.apache.hop.ui.core.gui.GuiResource; +import org.apache.hop.ui.core.gui.HopNamespace; +import org.apache.hop.ui.core.gui.WindowProperty; +import org.apache.hop.ui.core.widget.ColumnInfo; +import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.shared.AuditManagerGuiUtil; +import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Dialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; + +/** + * Graphical editor for marketplace environment files ({@code hop-env.yaml} / {@code .json}). + * + *

Covers all {@link HopEnvironmentSpec} fields: general settings, repositories, plugins, and jar + * dependencies. + */ +@Getter +@Setter +public class HopEnvironmentDialog extends Dialog { + + private static final Class PKG = MarketplaceGuiPlugin.class; + + /** Audit list type for recently opened/saved marketplace environment files. */ + public static final String AUDIT_TYPE_ENV_FILES = "MarketplaceEnvFiles"; + + private final PropsUi props; + private final ILogChannel log = new LogChannel("MarketplaceEnvironment"); + private final Path hopHome; + private final MarketplaceConfig config; + + private Shell shell; + private Combo wFileCombo; + private Text wVersion; + private Text wHopVersion; + private Button wEnforceOnRun; + private Button wPrune; + private Button wStrict; + private TableView wRepos; + private TableView wPlugins; + private TableView wDependencies; + + private Path currentPath; + private boolean dirty; + private boolean ignoreDirtyEvents; + private boolean saved; + private Path resultPath; + private boolean embedded; + private java.util.function.Consumer statusListener; + + public HopEnvironmentDialog(Shell parent, Path initialPath) { + super(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX); + this.props = PropsUi.getInstance(); + Path home; + MarketplaceConfig cfg; + try { + home = HopHome.resolve(); + cfg = MarketplaceConfig.load(); + } catch (Exception e) { + home = Path.of(System.getProperty("user.dir", ".")).toAbsolutePath().normalize(); + cfg = new MarketplaceConfig(); + } + this.hopHome = home; + this.config = cfg; + this.currentPath = initialPath; + } + + /** + * Embed the environment editor into an existing composite (e.g. Marketplace Environment tab). + * + * @param parent composite with FormLayout + * @param initialPath optional hop-env path to load + * @param statusListener optional status line callback (may be null) + */ + public static void embed(Composite parent, Path initialPath, Consumer statusListener) { + HopEnvironmentDialog editor = new HopEnvironmentDialog(parent.getShell(), initialPath); + editor.embedded = true; + editor.statusListener = statusListener; + editor.shell = parent.getShell(); + editor.createControls(parent, false); + if (initialPath != null && Files.isRegularFile(initialPath)) { + editor.loadFromPath(initialPath); + } else { + editor.loadSpec(newEmptySpec(), null); + } + } + + public Path open() { + Shell parent = getParent(); + shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX); + PropsUi.setLook(shell); + shell.setImage(GuiResource.getInstance().getImageHopUi()); + updateTitle(); + + FormLayout formLayout = new FormLayout(); + formLayout.marginWidth = PropsUi.getFormMargin(); + formLayout.marginHeight = PropsUi.getFormMargin(); + shell.setLayout(formLayout); + + createControls(shell, true); + + shell.addListener( + SWT.Close, + e -> { + e.doit = false; + close(); + }); + + BaseTransformDialog.setSize(shell); + shell.setSize(Math.max(shell.getSize().x, 820), Math.max(shell.getSize().y, 560)); + shell.open(); + Display display = parent.getDisplay(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + return resultPath; + } + + private void createControls(Composite parent, boolean includeClose) { + // File toolbar + Button wNew = new Button(parent, SWT.PUSH); + wNew.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Button.New")); + wNew.addListener(SWT.Selection, e -> newFile()); + FormData fdNew = new FormData(); + fdNew.left = new FormAttachment(0, 0); + fdNew.top = new FormAttachment(0, 0); + wNew.setLayoutData(fdNew); + + Button wOpen = new Button(parent, SWT.PUSH); + wOpen.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Button.Open")); + wOpen.addListener(SWT.Selection, e -> openFile()); + FormData fdOpen = new FormData(); + fdOpen.left = new FormAttachment(wNew, PropsUi.getMargin()); + fdOpen.top = new FormAttachment(0, 0); + wOpen.setLayoutData(fdOpen); + + Button wSave = new Button(parent, SWT.PUSH); + wSave.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Button.Save")); + wSave.addListener(SWT.Selection, e -> save()); + FormData fdSave = new FormData(); + fdSave.left = new FormAttachment(wOpen, PropsUi.getMargin()); + fdSave.top = new FormAttachment(0, 0); + wSave.setLayoutData(fdSave); + + Button wSaveAs = new Button(parent, SWT.PUSH); + wSaveAs.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Button.SaveAs")); + wSaveAs.addListener(SWT.Selection, e -> saveAs()); + FormData fdSaveAs = new FormData(); + fdSaveAs.left = new FormAttachment(wSave, PropsUi.getMargin()); + fdSaveAs.top = new FormAttachment(0, 0); + wSaveAs.setLayoutData(fdSaveAs); + + wFileCombo = new Combo(parent, SWT.DROP_DOWN | SWT.BORDER); + PropsUi.setLook(wFileCombo); + FormData fdFile = new FormData(); + fdFile.left = new FormAttachment(wSaveAs, PropsUi.getMargin() * 2); + fdFile.right = new FormAttachment(100, 0); + fdFile.top = new FormAttachment(wNew, 0, SWT.CENTER); + wFileCombo.setLayoutData(fdFile); + refreshFileComboItems(currentPath != null ? currentPath.toString() : ""); + wFileCombo.addListener(SWT.Selection, e -> onFileComboSelected()); + wFileCombo.addListener(SWT.DefaultSelection, e -> onFileComboSelected()); + + Label wToolbarSep = new Label(parent, SWT.HORIZONTAL | SWT.SEPARATOR); + FormData fdToolbarSep = new FormData(); + fdToolbarSep.left = new FormAttachment(0, 0); + fdToolbarSep.right = new FormAttachment(100, 0); + fdToolbarSep.top = new FormAttachment(wNew, PropsUi.getMargin()); + wToolbarSep.setLayoutData(fdToolbarSep); + + // Bottom buttons + Button wApply = new Button(parent, SWT.PUSH); + wApply.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Button.Apply")); + wApply.setToolTipText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Button.Apply.Tooltip")); + wApply.addListener(SWT.Selection, e -> apply()); + + Button wValidate = new Button(parent, SWT.PUSH); + wValidate.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Button.Validate")); + wValidate.setToolTipText( + BaseMessages.getString(PKG, "HopEnvironmentDialog.Button.Validate.Tooltip")); + wValidate.addListener(SWT.Selection, e -> validate()); + + Button wClose = null; + if (includeClose) { + wClose = new Button(parent, SWT.PUSH); + wClose.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Button.Close")); + wClose.addListener(SWT.Selection, e -> close()); + BaseTransformDialog.positionBottomButtons( + parent, new Button[] {wValidate, wApply, wClose}, PropsUi.getMargin(), null); + } else { + BaseTransformDialog.positionBottomButtons( + parent, new Button[] {wValidate, wApply}, PropsUi.getMargin(), null); + } + + wPrune = new Button(parent, SWT.CHECK); + PropsUi.setLook(wPrune); + wPrune.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Prune")); + wPrune.setToolTipText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Prune.Tooltip")); + FormData fdPrune = new FormData(); + fdPrune.left = new FormAttachment(0, 0); + fdPrune.bottom = new FormAttachment(wValidate, -PropsUi.getMargin()); + wPrune.setLayoutData(fdPrune); + + wStrict = new Button(parent, SWT.CHECK); + PropsUi.setLook(wStrict); + wStrict.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Strict")); + wStrict.setToolTipText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Strict.Tooltip")); + FormData fdStrict = new FormData(); + fdStrict.left = new FormAttachment(wPrune, PropsUi.getMargin() * 3); + fdStrict.bottom = new FormAttachment(wValidate, -PropsUi.getMargin()); + wStrict.setLayoutData(fdStrict); + + CTabFolder wTabFolder = new CTabFolder(parent, SWT.BORDER); + PropsUi.setLook(wTabFolder); + FormData fdTabs = new FormData(); + fdTabs.left = new FormAttachment(0, 0); + fdTabs.top = new FormAttachment(wToolbarSep, PropsUi.getMargin()); + fdTabs.right = new FormAttachment(100, 0); + fdTabs.bottom = new FormAttachment(wPrune, -PropsUi.getMargin()); + wTabFolder.setLayoutData(fdTabs); + + createGeneralTab(wTabFolder); + createRepositoriesTab(wTabFolder); + createPluginsTab(wTabFolder); + createDependenciesTab(wTabFolder); + wTabFolder.setSelection(0); + + // Load initial content (dialog mode only; embed() loads after createControls) + if (!embedded) { + if (currentPath != null && Files.isRegularFile(currentPath)) { + loadFromPath(currentPath); + } else { + loadSpec(newEmptySpec(), null); + } + } + } + + private void createGeneralTab(CTabFolder folder) { + CTabItem tab = new CTabItem(folder, SWT.NONE); + tab.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Tab.General")); + Composite comp = new Composite(folder, SWT.NONE); + PropsUi.setLook(comp); + FormLayout layout = new FormLayout(); + layout.marginWidth = PropsUi.getFormMargin(); + layout.marginHeight = PropsUi.getFormMargin(); + comp.setLayout(layout); + tab.setControl(comp); + + Label wlHelp = new Label(comp, SWT.LEFT | SWT.WRAP); + PropsUi.setLook(wlHelp); + wlHelp.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.General.Help")); + FormData fdlHelp = new FormData(); + fdlHelp.left = new FormAttachment(0, 0); + fdlHelp.top = new FormAttachment(0, 0); + fdlHelp.right = new FormAttachment(100, 0); + wlHelp.setLayoutData(fdlHelp); + + int middle = 30; + Label wlVersion = new Label(comp, SWT.RIGHT); + PropsUi.setLook(wlVersion); + wlVersion.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.General.Version")); + FormData fdlVersion = new FormData(); + fdlVersion.left = new FormAttachment(0, 0); + fdlVersion.top = new FormAttachment(wlHelp, PropsUi.getMargin() * 2); + fdlVersion.right = new FormAttachment(middle, -PropsUi.getMargin()); + wlVersion.setLayoutData(fdlVersion); + wVersion = new Text(comp, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + PropsUi.setLook(wVersion); + FormData fdVersion = new FormData(); + fdVersion.left = new FormAttachment(middle, 0); + fdVersion.top = new FormAttachment(wlVersion, 0, SWT.CENTER); + fdVersion.right = new FormAttachment(100, 0); + wVersion.setLayoutData(fdVersion); + wVersion.addListener(SWT.Modify, e -> markDirty()); + + Label wlHopVersion = new Label(comp, SWT.RIGHT); + PropsUi.setLook(wlHopVersion); + wlHopVersion.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.General.HopVersion")); + FormData fdlHopVersion = new FormData(); + fdlHopVersion.left = new FormAttachment(0, 0); + fdlHopVersion.top = new FormAttachment(wVersion, PropsUi.getMargin()); + fdlHopVersion.right = new FormAttachment(middle, -PropsUi.getMargin()); + wlHopVersion.setLayoutData(fdlHopVersion); + wHopVersion = new Text(comp, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + PropsUi.setLook(wHopVersion); + FormData fdHopVersion = new FormData(); + fdHopVersion.left = new FormAttachment(middle, 0); + fdHopVersion.top = new FormAttachment(wlHopVersion, 0, SWT.CENTER); + fdHopVersion.right = new FormAttachment(100, 0); + wHopVersion.setLayoutData(fdHopVersion); + wHopVersion.addListener(SWT.Modify, e -> markDirty()); + + wEnforceOnRun = new Button(comp, SWT.CHECK); + PropsUi.setLook(wEnforceOnRun); + wEnforceOnRun.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.General.EnforceOnRun")); + wEnforceOnRun.setToolTipText( + BaseMessages.getString(PKG, "HopEnvironmentDialog.General.EnforceOnRun.Tooltip")); + FormData fdEnforce = new FormData(); + fdEnforce.left = new FormAttachment(middle, 0); + fdEnforce.top = new FormAttachment(wHopVersion, PropsUi.getMargin() * 2); + wEnforceOnRun.setLayoutData(fdEnforce); + wEnforceOnRun.addListener(SWT.Selection, e -> markDirty()); + } + + private void createRepositoriesTab(CTabFolder folder) { + CTabItem tab = new CTabItem(folder, SWT.NONE); + tab.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Tab.Repositories")); + tab.setImage(GuiResource.getInstance().getImageServer()); + Composite comp = new Composite(folder, SWT.NONE); + PropsUi.setLook(comp); + FormLayout layout = new FormLayout(); + layout.marginWidth = PropsUi.getFormMargin(); + layout.marginHeight = PropsUi.getFormMargin(); + comp.setLayout(layout); + tab.setControl(comp); + + Label wlHelp = new Label(comp, SWT.LEFT | SWT.WRAP); + PropsUi.setLook(wlHelp); + wlHelp.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Repositories.Help")); + FormData fdlHelp = new FormData(); + fdlHelp.left = new FormAttachment(0, 0); + fdlHelp.top = new FormAttachment(0, 0); + fdlHelp.right = new FormAttachment(100, 0); + wlHelp.setLayoutData(fdlHelp); + + Button wAdd = sideButton(comp, "HopEnvironmentDialog.Button.Add", wlHelp); + Button wEdit = sideButton(comp, "HopEnvironmentDialog.Button.Edit", wAdd); + Button wRemove = sideButton(comp, "HopEnvironmentDialog.Button.Remove", wEdit); + Button wUp = sideButton(comp, "HopEnvironmentDialog.Button.MoveUp", wRemove); + Button wDown = sideButton(comp, "HopEnvironmentDialog.Button.MoveDown", wUp); + Button wImport = sideButton(comp, "HopEnvironmentDialog.Button.ImportRepos", wDown); + + wAdd.addListener(SWT.Selection, e -> addRepository()); + wEdit.addListener(SWT.Selection, e -> editRepository()); + wRemove.addListener(SWT.Selection, e -> removeSelected(wRepos)); + wUp.addListener(SWT.Selection, e -> moveSelected(wRepos, -1)); + wDown.addListener(SWT.Selection, e -> moveSelected(wRepos, 1)); + wImport.addListener(SWT.Selection, e -> importReposFromConfig()); + + wRepos = + createTableView( + comp, + wlHelp, + wAdd, + new ColumnInfo[] { + new ColumnInfo( + BaseMessages.getString(PKG, "HopEnvironmentDialog.Repo.Column.Id"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "HopEnvironmentDialog.Repo.Column.Url"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "HopEnvironmentDialog.Repo.Column.Username"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "HopEnvironmentDialog.Repo.Column.Auth"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + }); + wRepos.table.addListener(SWT.DefaultSelection, e -> editRepository()); + } + + private void createPluginsTab(CTabFolder folder) { + CTabItem tab = new CTabItem(folder, SWT.NONE); + tab.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Tab.Plugins")); + tab.setImage(GuiResource.getInstance().getImagePlugin()); + Composite comp = new Composite(folder, SWT.NONE); + PropsUi.setLook(comp); + FormLayout layout = new FormLayout(); + layout.marginWidth = PropsUi.getFormMargin(); + layout.marginHeight = PropsUi.getFormMargin(); + comp.setLayout(layout); + tab.setControl(comp); + + Label wlHelp = new Label(comp, SWT.LEFT | SWT.WRAP); + PropsUi.setLook(wlHelp); + wlHelp.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Plugins.Help")); + FormData fdlHelp = new FormData(); + fdlHelp.left = new FormAttachment(0, 0); + fdlHelp.top = new FormAttachment(0, 0); + fdlHelp.right = new FormAttachment(100, 0); + wlHelp.setLayoutData(fdlHelp); + + Button wCatalog = sideButton(comp, "HopEnvironmentDialog.Button.AddFromCatalog", wlHelp, null); + Button wAdd = sideButton(comp, "HopEnvironmentDialog.Button.Add", wCatalog, wCatalog); + Button wEdit = sideButton(comp, "HopEnvironmentDialog.Button.Edit", wAdd, wCatalog); + Button wRemove = sideButton(comp, "HopEnvironmentDialog.Button.Remove", wEdit, wCatalog); + Button wUp = sideButton(comp, "HopEnvironmentDialog.Button.MoveUp", wRemove, wCatalog); + Button wDown = sideButton(comp, "HopEnvironmentDialog.Button.MoveDown", wUp, wCatalog); + + wCatalog.addListener(SWT.Selection, e -> addPluginsFromCatalog()); + wAdd.addListener(SWT.Selection, e -> addPlugin()); + wEdit.addListener(SWT.Selection, e -> editPlugin()); + wRemove.addListener(SWT.Selection, e -> removeSelected(wPlugins)); + wUp.addListener(SWT.Selection, e -> moveSelected(wPlugins, -1)); + wDown.addListener(SWT.Selection, e -> moveSelected(wPlugins, 1)); + + wPlugins = + createTableView( + comp, + wlHelp, + wCatalog, + new ColumnInfo[] { + new ColumnInfo( + BaseMessages.getString(PKG, "HopEnvironmentDialog.Plugin.Column.GroupId"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "HopEnvironmentDialog.Plugin.Column.ArtifactId"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "HopEnvironmentDialog.Plugin.Column.Version"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + }); + wPlugins.table.addListener(SWT.DefaultSelection, e -> editPlugin()); + } + + private void createDependenciesTab(CTabFolder folder) { + CTabItem tab = new CTabItem(folder, SWT.NONE); + tab.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Tab.Dependencies")); + tab.setImage(GuiResource.getInstance().getImageLabel()); + Composite comp = new Composite(folder, SWT.NONE); + PropsUi.setLook(comp); + FormLayout layout = new FormLayout(); + layout.marginWidth = PropsUi.getFormMargin(); + layout.marginHeight = PropsUi.getFormMargin(); + comp.setLayout(layout); + tab.setControl(comp); + + Label wlHelp = new Label(comp, SWT.LEFT | SWT.WRAP); + PropsUi.setLook(wlHelp); + wlHelp.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Dependencies.Help")); + FormData fdlHelp = new FormData(); + fdlHelp.left = new FormAttachment(0, 0); + fdlHelp.top = new FormAttachment(0, 0); + fdlHelp.right = new FormAttachment(100, 0); + wlHelp.setLayoutData(fdlHelp); + + Button wAdd = sideButton(comp, "HopEnvironmentDialog.Button.Add", wlHelp); + Button wEdit = sideButton(comp, "HopEnvironmentDialog.Button.Edit", wAdd); + Button wRemove = sideButton(comp, "HopEnvironmentDialog.Button.Remove", wEdit); + Button wUp = sideButton(comp, "HopEnvironmentDialog.Button.MoveUp", wRemove); + Button wDown = sideButton(comp, "HopEnvironmentDialog.Button.MoveDown", wUp); + + wAdd.addListener(SWT.Selection, e -> addDependency()); + wEdit.addListener(SWT.Selection, e -> editDependency()); + wRemove.addListener(SWT.Selection, e -> removeSelected(wDependencies)); + wUp.addListener(SWT.Selection, e -> moveSelected(wDependencies, -1)); + wDown.addListener(SWT.Selection, e -> moveSelected(wDependencies, 1)); + + wDependencies = + createTableView( + comp, + wlHelp, + wAdd, + new ColumnInfo[] { + new ColumnInfo( + BaseMessages.getString(PKG, "HopEnvironmentDialog.Dep.Column.GroupId"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "HopEnvironmentDialog.Dep.Column.ArtifactId"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "HopEnvironmentDialog.Dep.Column.Version"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "HopEnvironmentDialog.Dep.Column.Target"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + }); + wDependencies.table.addListener(SWT.DefaultSelection, e -> editDependency()); + } + + private Button sideButton(Composite parent, String key, Control above) { + return sideButton(parent, key, above, null); + } + + private Button sideButton(Composite parent, String key, Control above, Control left) { + Button b = new Button(parent, SWT.PUSH); + b.setText(BaseMessages.getString(PKG, key)); + FormData fd = new FormData(); + fd.right = new FormAttachment(100, 0); + fd.top = new FormAttachment(above, PropsUi.getMargin()); + if (left == null) { + fd.left = new FormAttachment(100, (int) (-100 * PropsUi.getNativeZoomFactor())); + } else { + fd.left = new FormAttachment(left, 0, SWT.LEFT); + } + b.setLayoutData(fd); + return b; + } + + private TableView createTableView( + Composite parent, Label help, Button sideTop, ColumnInfo[] columns) { + TableView view = + new TableView( + Variables.getADefaultVariableSpace(), + parent, + SWT.BORDER | SWT.FULL_SELECTION | SWT.SINGLE | SWT.V_SCROLL, + columns, + 1, + true, + null, + props, + false); + PropsUi.setLook(view); + FormData fd = new FormData(); + fd.left = new FormAttachment(0, 0); + fd.top = new FormAttachment(help, PropsUi.getMargin()); + fd.right = new FormAttachment(sideTop, -PropsUi.getMargin()); + fd.bottom = new FormAttachment(100, 0); + view.setLayoutData(fd); + return view; + } + + // --- load / save / dirty --- + + private static HopEnvironmentSpec newEmptySpec() { + HopEnvironmentSpec spec = new HopEnvironmentSpec(); + spec.setVersion("1.0"); + return spec; + } + + private void loadFromPath(Path path) { + try { + HopEnvironmentSpec spec = HopEnvironmentLoader.load(path); + loadSpec(spec, path); + rememberEnvFile(path); + } catch (Exception e) { + new ErrorDialog( + shell, + BaseMessages.getString(PKG, "HopEnvironmentDialog.Error.Header"), + BaseMessages.getString(PKG, "HopEnvironmentDialog.Error.Load", path.toString()), + e); + } + } + + private void loadSpec(HopEnvironmentSpec spec, Path path) { + ignoreDirtyEvents = true; + try { + currentPath = path; + wVersion.setText(Const.NVL(spec.getVersion(), "1.0")); + wHopVersion.setText(Const.NVL(spec.getHopVersion(), "")); + wEnforceOnRun.setSelection(spec.isEnforceOnRun()); + fillRepos(spec.getRepositories()); + fillPlugins(spec.getPlugins()); + fillDependencies(spec.getDependencies()); + wRepos.optimizeTableView(); + wPlugins.optimizeTableView(); + wDependencies.optimizeTableView(); + dirty = false; + updateFileLabel(); + updateTitle(); + } finally { + ignoreDirtyEvents = false; + } + } + + private void fillRepos(List list) { + wRepos.table.removeAll(); + if (list == null) { + return; + } + for (HopEnvironmentSpec.RepositoryRef ref : list) { + if (ref == null) { + continue; + } + addRepoItem(ref); + } + } + + private void addRepoItem(HopEnvironmentSpec.RepositoryRef ref) { + TableItem item = new TableItem(wRepos.table, SWT.NONE); + item.setText(1, Const.NVL(ref.getId(), "")); + item.setText(2, Const.NVL(ref.getUrl(), "")); + item.setText(3, Const.NVL(ref.getUsername(), "")); + item.setText(4, StringUtils.isNotBlank(ref.getPassword()) ? "Y" : ""); + item.setData(ref); + } + + private void fillPlugins(List list) { + wPlugins.table.removeAll(); + if (list == null) { + return; + } + for (HopEnvironmentSpec.PluginRef ref : list) { + if (ref == null) { + continue; + } + addPluginItem(ref); + } + } + + private void addPluginItem(HopEnvironmentSpec.PluginRef ref) { + TableItem item = new TableItem(wPlugins.table, SWT.NONE); + item.setText(1, Const.NVL(ref.getGroupId(), "")); + item.setText(2, Const.NVL(ref.getArtifactId(), "")); + item.setText(3, Const.NVL(ref.getVersion(), "")); + item.setData(ref); + } + + private void fillDependencies(List list) { + wDependencies.table.removeAll(); + if (list == null) { + return; + } + for (HopEnvironmentSpec.DependencyRef ref : list) { + if (ref == null) { + continue; + } + addDepItem(ref); + } + } + + private void addDepItem(HopEnvironmentSpec.DependencyRef ref) { + TableItem item = new TableItem(wDependencies.table, SWT.NONE); + item.setText(1, Const.NVL(ref.getGroupId(), "")); + item.setText(2, Const.NVL(ref.getArtifactId(), "")); + item.setText(3, Const.NVL(ref.getVersion(), "")); + item.setText(4, Const.NVL(ref.getTarget(), "lib/jdbc")); + item.setData(ref); + } + + private HopEnvironmentSpec collectSpec() { + HopEnvironmentSpec spec = new HopEnvironmentSpec(); + spec.setVersion(StringUtils.defaultIfBlank(wVersion.getText(), "1.0").trim()); + String hopVer = wHopVersion.getText(); + spec.setHopVersion(StringUtils.isBlank(hopVer) ? null : hopVer.trim()); + spec.setEnforceOnRun(wEnforceOnRun.getSelection()); + + List repos = new ArrayList<>(); + for (TableItem item : wRepos.table.getItems()) { + if (item.getData() instanceof HopEnvironmentSpec.RepositoryRef ref) { + repos.add(ref); + } + } + spec.setRepositories(repos); + + List plugins = new ArrayList<>(); + for (TableItem item : wPlugins.table.getItems()) { + if (item.getData() instanceof HopEnvironmentSpec.PluginRef ref) { + plugins.add(ref); + } + } + spec.setPlugins(plugins); + + List deps = new ArrayList<>(); + for (TableItem item : wDependencies.table.getItems()) { + if (item.getData() instanceof HopEnvironmentSpec.DependencyRef ref) { + deps.add(ref); + } + } + spec.setDependencies(deps); + return spec; + } + + private void markDirty() { + if (ignoreDirtyEvents) { + return; + } + if (!dirty) { + dirty = true; + updateTitle(); + } + } + + private void updateTitle() { + if (embedded) { + return; + } + String name = + currentPath != null + ? currentPath.getFileName().toString() + : BaseMessages.getString(PKG, "HopEnvironmentDialog.Untitled"); + String title = + BaseMessages.getString(PKG, "HopEnvironmentDialog.Shell.Title", name) + (dirty ? " *" : ""); + if (shell != null && !shell.isDisposed()) { + shell.setText(title); + } + } + + private void updateFileLabel() { + if (wFileCombo == null || wFileCombo.isDisposed()) { + return; + } + if (currentPath != null) { + refreshFileComboItems(currentPath.toString()); + } else { + refreshFileComboItems(""); + wFileCombo.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Untitled")); + } + } + + /** + * Load recent filenames from {@link AuditManager#getActive()}{@code .retrieveList(...)} into the + * combo and select {@code selectedPath} when non-blank. + */ + private void refreshFileComboItems(String selectedPath) { + if (wFileCombo == null || wFileCombo.isDisposed()) { + return; + } + try { + AuditList list = + AuditManager.getActive().retrieveList(HopNamespace.getNamespace(), AUDIT_TYPE_ENV_FILES); + if (list != null && list.getNames() != null && !list.getNames().isEmpty()) { + wFileCombo.setItems(list.getNames().toArray(new String[0])); + } else { + wFileCombo.setItems(new String[0]); + } + } catch (Exception e) { + log.logError("Unable to load marketplace environment file audit list", e); + wFileCombo.setItems(AuditManagerGuiUtil.getLastUsedValues(AUDIT_TYPE_ENV_FILES)); + } + if (StringUtils.isNotBlank(selectedPath)) { + wFileCombo.setText(selectedPath); + } + } + + /** Remember path in the audit list (most-recent first) and refresh the combo. */ + private void rememberEnvFile(Path path) { + if (path == null) { + return; + } + String absolute = path.toAbsolutePath().normalize().toString(); + AuditManagerGuiUtil.addLastUsedValue(AUDIT_TYPE_ENV_FILES, absolute); + refreshFileComboItems(absolute); + } + + private void onFileComboSelected() { + if (wFileCombo == null || wFileCombo.isDisposed()) { + return; + } + String text = wFileCombo.getText(); + if (StringUtils.isBlank(text)) { + return; + } + Path p = Path.of(text.trim()).toAbsolutePath().normalize(); + if (currentPath != null && currentPath.equals(p)) { + return; + } + if (!Files.isRegularFile(p)) { + return; + } + if (confirmDiscardIfDirty()) { + updateFileLabel(); + return; + } + loadFromPath(p); + } + + private boolean confirmDiscardIfDirty() { + if (!dirty) { + return false; + } + MessageBox box = new MessageBox(shell, SWT.YES | SWT.NO | SWT.CANCEL | SWT.ICON_WARNING); + box.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Dirty.Header")); + box.setMessage(BaseMessages.getString(PKG, "HopEnvironmentDialog.Dirty.Message")); + int answer = box.open(); + if (answer == SWT.CANCEL) { + return true; + } + if (answer == SWT.YES) { + return !save(); + } + return false; + } + + private void newFile() { + if (confirmDiscardIfDirty()) { + return; + } + loadSpec(newEmptySpec(), null); + } + + private void openFile() { + if (confirmDiscardIfDirty()) { + return; + } + String path = + BaseDialog.presentFileDialog( + false, + shell, + new String[] {"*.yaml;*.yml;*.json", "*.*"}, + new String[] { + BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Filter.Env"), + BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Filter.All") + }, + false); + if (StringUtils.isBlank(path)) { + return; + } + Path p = Path.of(path.trim()).toAbsolutePath().normalize(); + if (!Files.isRegularFile(p)) { + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_WARNING); + box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.NotFound.Header")); + box.setMessage( + BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.NotFound.Message", p.toString())); + box.open(); + return; + } + loadFromPath(p); + rememberEnvFile(p); + } + + private boolean save() { + if (currentPath == null) { + return saveAs(); + } + return writeTo(currentPath); + } + + private boolean saveAs() { + String path = + BaseDialog.presentFileDialog( + true, + shell, + new String[] {"*.yaml;*.yml", "*.json", "*.*"}, + new String[] { + BaseMessages.getString(PKG, "HopEnvironmentDialog.Filter.Yaml"), + BaseMessages.getString(PKG, "HopEnvironmentDialog.Filter.Json"), + BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Filter.All") + }, + false); + if (StringUtils.isBlank(path)) { + return false; + } + Path p = Path.of(path.trim()).toAbsolutePath().normalize(); + String name = p.getFileName().toString().toLowerCase(); + if (!name.endsWith(".yaml") && !name.endsWith(".yml") && !name.endsWith(".json")) { + p = p.resolveSibling(p.getFileName().toString() + ".yaml"); + } + return writeTo(p); + } + + private boolean writeTo(Path path) { + try { + HopEnvironmentSpec spec = collectSpec(); + String validationError = validateSpec(spec); + if (validationError != null) { + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_WARNING); + box.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Validation.Header")); + box.setMessage(validationError); + box.open(); + return false; + } + HopEnvironmentLoader.save(path, spec); + currentPath = path; + resultPath = path; + saved = true; + dirty = false; + rememberEnvFile(path); + updateFileLabel(); + updateTitle(); + return true; + } catch (Exception e) { + new ErrorDialog( + shell, + BaseMessages.getString(PKG, "HopEnvironmentDialog.Error.Header"), + BaseMessages.getString(PKG, "HopEnvironmentDialog.Error.Save", path.toString()), + e); + return false; + } + } + + private String validateSpec(HopEnvironmentSpec spec) { + for (HopEnvironmentSpec.RepositoryRef ref : spec.getRepositories()) { + if (StringUtils.isBlank(ref.getId()) || StringUtils.isBlank(ref.getUrl())) { + return BaseMessages.getString(PKG, "HopEnvironmentDialog.Validation.RepoIdUrl"); + } + } + for (HopEnvironmentSpec.PluginRef ref : spec.getPlugins()) { + if (StringUtils.isBlank(ref.getArtifactId())) { + return BaseMessages.getString(PKG, "HopEnvironmentDialog.Validation.PluginArtifact"); + } + } + for (HopEnvironmentSpec.DependencyRef ref : spec.getDependencies()) { + if (StringUtils.isAnyBlank(ref.getGroupId(), ref.getArtifactId(), ref.getVersion())) { + return BaseMessages.getString(PKG, "HopEnvironmentDialog.Validation.DepGav"); + } + } + return null; + } + + private boolean ensureSavedForAction() { + if (dirty || currentPath == null) { + MessageBox box = new MessageBox(shell, SWT.YES | SWT.NO | SWT.ICON_QUESTION); + box.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.SaveFirst.Header")); + box.setMessage(BaseMessages.getString(PKG, "HopEnvironmentDialog.SaveFirst.Message")); + if (box.open() != SWT.YES) { + return true; + } + if (!save()) { + return true; + } + } + return currentPath == null || !Files.isRegularFile(currentPath); + } + + private void validate() { + if (ensureSavedForAction()) { + return; + } + try { + HopEnvironmentSpec env = HopEnvironmentLoader.load(currentPath); + EnvironmentApplier applier = new EnvironmentApplier(log, hopHome, MarketplaceConfig.load()); + EnvironmentDrift drift = applier.validate(env); + if (wStrict.getSelection()) { + populateExtraPlugins(env, drift); + } + boolean hard = + !drift.getMissingPlugins().isEmpty() + || !drift.getVersionMismatches().isEmpty() + || !drift.getMissingDependencies().isEmpty() + || (wStrict.getSelection() && !drift.getExtraMarketplacePlugins().isEmpty()); + if (!hard) { + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION); + box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Validate.Ok.Header")); + box.setMessage( + BaseMessages.getString( + PKG, "MarketplaceDialog.Validate.Ok.Message", currentPath.toString())); + box.open(); + notifyStatus(BaseMessages.getString(PKG, "MarketplaceDialog.Status.RestartHint")); + return; + } + notifyStatus(BaseMessages.getString(PKG, "MarketplaceDialog.Status.Drift")); + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_WARNING); + box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Validate.Drift.Header")); + box.setMessage( + BaseMessages.getString(PKG, "MarketplaceDialog.Validate.Drift.Message") + + "\n\n" + + drift.formatReport() + + "\n" + + BaseMessages.getString(PKG, "MarketplaceDialog.Validate.Drift.Hint")); + box.open(); + } catch (Exception e) { + new ErrorDialog( + shell, + BaseMessages.getString(PKG, "HopEnvironmentDialog.Error.Header"), + BaseMessages.getString(PKG, "MarketplaceDialog.Validate.Error"), + e); + } + } + + private void apply() { + if (ensureSavedForAction()) { + return; + } + boolean prune = wPrune.getSelection(); + if (prune) { + MessageBox confirm = new MessageBox(shell, SWT.YES | SWT.NO | SWT.ICON_QUESTION); + confirm.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Apply.PruneConfirm.Header")); + confirm.setMessage( + BaseMessages.getString(PKG, "MarketplaceDialog.Apply.PruneConfirm.Message")); + if (confirm.open() != SWT.YES) { + return; + } + } + try { + MarketplaceConfig live = MarketplaceConfig.load(); + if (!live.isEnabled()) { + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_WARNING); + box.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Error.Header")); + box.setMessage(BaseMessages.getString(PKG, "MarketplaceDialog.Apply.Disabled")); + box.open(); + return; + } + HopEnvironmentSpec env = HopEnvironmentLoader.load(currentPath); + new EnvironmentApplier(log, hopHome, live).apply(env, prune); + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION); + box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Apply.Done.Header")); + box.setMessage( + BaseMessages.getString( + PKG, "MarketplaceDialog.Apply.Done.Message", currentPath.toString())); + box.open(); + } catch (Exception e) { + new ErrorDialog( + shell, + BaseMessages.getString(PKG, "HopEnvironmentDialog.Error.Header"), + BaseMessages.getString(PKG, "MarketplaceDialog.Apply.Error"), + e); + } + } + + private void populateExtraPlugins(HopEnvironmentSpec env, EnvironmentDrift drift) + throws Exception { + Set desired = new HashSet<>(); + if (env.getPlugins() != null) { + for (HopEnvironmentSpec.PluginRef ref : env.getPlugins()) { + if (ref.getArtifactId() != null) { + desired.add(ref.getArtifactId()); + } + } + } + Path receipts = hopHome.resolve(PluginInstaller.RECEIPTS_DIR); + if (!Files.isDirectory(receipts)) { + return; + } + try (DirectoryStream stream = Files.newDirectoryStream(receipts, "*.json")) { + for (Path f : stream) { + String name = f.getFileName().toString(); + String id = name.substring(0, name.length() - ".json".length()); + if (!desired.contains(id)) { + drift.getExtraMarketplacePlugins().add(id); + } + } + } + } + + private void close() { + if (embedded) { + return; + } + if (confirmDiscardIfDirty()) { + return; + } + props.setScreen(new WindowProperty(shell)); + shell.dispose(); + } + + // --- repository CRUD --- + + private void addRepository() { + HopEnvironmentSpec.RepositoryRef ref = new HopEnvironmentSpec.RepositoryRef(); + if (editRepositoryDialog(ref, true)) { + addRepoItem(ref); + markDirty(); + } + } + + private void editRepository() { + TableItem[] sel = wRepos.table.getSelection(); + if (sel == null || sel.length == 0) { + return; + } + HopEnvironmentSpec.RepositoryRef ref = (HopEnvironmentSpec.RepositoryRef) sel[0].getData(); + if (ref == null) { + return; + } + if (editRepositoryDialog(ref, false)) { + sel[0].setText(1, Const.NVL(ref.getId(), "")); + sel[0].setText(2, Const.NVL(ref.getUrl(), "")); + sel[0].setText(3, Const.NVL(ref.getUsername(), "")); + sel[0].setText(4, StringUtils.isNotBlank(ref.getPassword()) ? "Y" : ""); + markDirty(); + } + } + + private boolean editRepositoryDialog(HopEnvironmentSpec.RepositoryRef ref, boolean isNew) { + Shell dialog = new Shell(shell, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE); + PropsUi.setLook(dialog); + dialog.setText( + BaseMessages.getString( + PKG, + isNew ? "HopEnvironmentDialog.Repo.Edit.Add" : "HopEnvironmentDialog.Repo.Edit.Edit")); + FormLayout layout = new FormLayout(); + layout.marginWidth = PropsUi.getFormMargin(); + layout.marginHeight = PropsUi.getFormMargin(); + dialog.setLayout(layout); + int middle = 30; + int margin = PropsUi.getMargin(); + + Label wlId = labeled(dialog, "HopEnvironmentDialog.Repo.Column.Id", 0, middle, margin); + Text wId = textField(dialog, wlId, middle, Const.NVL(ref.getId(), "")); + Label wlUrl = labeled(dialog, "HopEnvironmentDialog.Repo.Column.Url", wId, middle, margin); + Text wUrl = textField(dialog, wlUrl, middle, Const.NVL(ref.getUrl(), "")); + Label wlUser = + labeled(dialog, "HopEnvironmentDialog.Repo.Column.Username", wUrl, middle, margin); + Text wUser = textField(dialog, wlUser, middle, Const.NVL(ref.getUsername(), "")); + Label wlPass = + labeled(dialog, "HopEnvironmentDialog.Repo.Column.Password", wUser, middle, margin); + Text wPass = new Text(dialog, SWT.SINGLE | SWT.LEFT | SWT.BORDER | SWT.PASSWORD); + PropsUi.setLook(wPass); + wPass.setText(Const.NVL(ref.getPassword(), "")); + FormData fdPass = new FormData(); + fdPass.left = new FormAttachment(middle, 0); + fdPass.top = new FormAttachment(wlPass, 0, SWT.CENTER); + fdPass.right = new FormAttachment(100, 0); + wPass.setLayoutData(fdPass); + + final boolean[] ok = {false}; + Button wOk = new Button(dialog, SWT.PUSH); + wOk.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Button.Ok")); + Button wCancel = new Button(dialog, SWT.PUSH); + wCancel.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Button.Cancel")); + wCancel.addListener(SWT.Selection, e -> dialog.dispose()); + wOk.addListener( + SWT.Selection, + e -> { + if (StringUtils.isBlank(wId.getText()) || StringUtils.isBlank(wUrl.getText())) { + MessageBox box = new MessageBox(dialog, SWT.OK | SWT.ICON_WARNING); + box.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Validation.Header")); + box.setMessage( + BaseMessages.getString(PKG, "HopEnvironmentDialog.Validation.RepoIdUrl")); + box.open(); + return; + } + ref.setId(wId.getText().trim()); + ref.setUrl(wUrl.getText().trim()); + ref.setUsername(blankToNull(wUser.getText())); + ref.setPassword(blankToNull(wPass.getText())); + ok[0] = true; + dialog.dispose(); + }); + BaseTransformDialog.positionBottomButtons(dialog, new Button[] {wOk, wCancel}, margin, wPass); + BaseTransformDialog.setSize(dialog); + dialog.open(); + Display display = shell.getDisplay(); + while (!dialog.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + return ok[0]; + } + + private void importReposFromConfig() { + try { + MarketplaceConfig live = config != null ? config : MarketplaceConfig.load(); + if (live.getRepositories() == null || live.getRepositories().isEmpty()) { + return; + } + MessageBox confirm = new MessageBox(shell, SWT.YES | SWT.NO | SWT.ICON_QUESTION); + confirm.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.ImportRepos.Header")); + confirm.setMessage(BaseMessages.getString(PKG, "HopEnvironmentDialog.ImportRepos.Message")); + if (confirm.open() != SWT.YES) { + return; + } + wRepos.table.removeAll(); + for (MarketplaceRepository repo : live.getRepositories()) { + if (repo == null || !repo.isEnabled()) { + continue; + } + HopEnvironmentSpec.RepositoryRef ref = new HopEnvironmentSpec.RepositoryRef(); + ref.setId(repo.getId()); + ref.setUrl(repo.getUrl()); + ref.setUsername(repo.getUsername()); + ref.setPassword(repo.getPassword()); + addRepoItem(ref); + } + markDirty(); + } catch (Exception e) { + new ErrorDialog( + shell, + BaseMessages.getString(PKG, "HopEnvironmentDialog.Error.Header"), + BaseMessages.getString(PKG, "HopEnvironmentDialog.Error.ImportRepos"), + e); + } + } + + // --- plugin CRUD --- + + private void addPlugin() { + HopEnvironmentSpec.PluginRef ref = new HopEnvironmentSpec.PluginRef(); + ref.setVersion(StringUtils.trimToNull(wHopVersion.getText())); + if (editPluginDialog(ref, true)) { + addPluginItem(ref); + markDirty(); + } + } + + private void editPlugin() { + TableItem[] sel = wPlugins.table.getSelection(); + if (sel == null || sel.length == 0) { + return; + } + HopEnvironmentSpec.PluginRef ref = (HopEnvironmentSpec.PluginRef) sel[0].getData(); + if (ref == null) { + return; + } + if (editPluginDialog(ref, false)) { + sel[0].setText(1, Const.NVL(ref.getGroupId(), "")); + sel[0].setText(2, Const.NVL(ref.getArtifactId(), "")); + sel[0].setText(3, Const.NVL(ref.getVersion(), "")); + markDirty(); + } + } + + private boolean editPluginDialog(HopEnvironmentSpec.PluginRef ref, boolean isNew) { + Shell dialog = new Shell(shell, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE); + PropsUi.setLook(dialog); + dialog.setText( + BaseMessages.getString( + PKG, + isNew + ? "HopEnvironmentDialog.Plugin.Edit.Add" + : "HopEnvironmentDialog.Plugin.Edit.Edit")); + FormLayout layout = new FormLayout(); + layout.marginWidth = PropsUi.getFormMargin(); + layout.marginHeight = PropsUi.getFormMargin(); + dialog.setLayout(layout); + int middle = 30; + int margin = PropsUi.getMargin(); + + Label wlGroup = + labeled(dialog, "HopEnvironmentDialog.Plugin.Column.GroupId", 0, middle, margin); + Text wGroup = textField(dialog, wlGroup, middle, Const.NVL(ref.getGroupId(), "")); + Label wlArt = + labeled(dialog, "HopEnvironmentDialog.Plugin.Column.ArtifactId", wGroup, middle, margin); + Text wArt = textField(dialog, wlArt, middle, Const.NVL(ref.getArtifactId(), "")); + Label wlVer = + labeled(dialog, "HopEnvironmentDialog.Plugin.Column.Version", wArt, middle, margin); + Text wVer = textField(dialog, wlVer, middle, Const.NVL(ref.getVersion(), "")); + + final boolean[] ok = {false}; + Button wOk = new Button(dialog, SWT.PUSH); + wOk.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Button.Ok")); + Button wCancel = new Button(dialog, SWT.PUSH); + wCancel.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Button.Cancel")); + wCancel.addListener(SWT.Selection, e -> dialog.dispose()); + wOk.addListener( + SWT.Selection, + e -> { + if (StringUtils.isBlank(wArt.getText())) { + MessageBox box = new MessageBox(dialog, SWT.OK | SWT.ICON_WARNING); + box.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Validation.Header")); + box.setMessage( + BaseMessages.getString(PKG, "HopEnvironmentDialog.Validation.PluginArtifact")); + box.open(); + return; + } + ref.setGroupId(blankToNull(wGroup.getText())); + ref.setArtifactId(wArt.getText().trim()); + ref.setVersion(blankToNull(wVer.getText())); + ok[0] = true; + dialog.dispose(); + }); + BaseTransformDialog.positionBottomButtons(dialog, new Button[] {wOk, wCancel}, margin, wVer); + BaseTransformDialog.setSize(dialog); + dialog.open(); + Display display = shell.getDisplay(); + while (!dialog.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + return ok[0]; + } + + private void addPluginsFromCatalog() { + Set existing = new HashSet<>(); + for (TableItem item : wPlugins.table.getItems()) { + if (item.getData() instanceof HopEnvironmentSpec.PluginRef ref + && StringUtils.isNotBlank(ref.getArtifactId())) { + existing.add(ref.getArtifactId()); + } + } + List chosen = new AddPluginsFromCatalogDialog(shell, existing).open(); + if (chosen == null || chosen.isEmpty()) { + return; + } + String defaultVersion = StringUtils.trimToNull(wHopVersion.getText()); + for (OptionalPluginInfo info : chosen) { + HopEnvironmentSpec.PluginRef ref = new HopEnvironmentSpec.PluginRef(); + ref.setArtifactId(info.getArtifactId()); + ref.setVersion(defaultVersion); + addPluginItem(ref); + } + markDirty(); + } + + // --- dependency CRUD --- + + private void addDependency() { + HopEnvironmentSpec.DependencyRef ref = new HopEnvironmentSpec.DependencyRef(); + ref.setTarget("lib/jdbc"); + if (editDependencyDialog(ref, true)) { + addDepItem(ref); + markDirty(); + } + } + + private void editDependency() { + TableItem[] sel = wDependencies.table.getSelection(); + if (sel == null || sel.length == 0) { + return; + } + HopEnvironmentSpec.DependencyRef ref = (HopEnvironmentSpec.DependencyRef) sel[0].getData(); + if (ref == null) { + return; + } + if (editDependencyDialog(ref, false)) { + sel[0].setText(1, Const.NVL(ref.getGroupId(), "")); + sel[0].setText(2, Const.NVL(ref.getArtifactId(), "")); + sel[0].setText(3, Const.NVL(ref.getVersion(), "")); + sel[0].setText(4, Const.NVL(ref.getTarget(), "lib/jdbc")); + markDirty(); + } + } + + private boolean editDependencyDialog(HopEnvironmentSpec.DependencyRef ref, boolean isNew) { + Shell dialog = new Shell(shell, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE); + PropsUi.setLook(dialog); + dialog.setText( + BaseMessages.getString( + PKG, + isNew ? "HopEnvironmentDialog.Dep.Edit.Add" : "HopEnvironmentDialog.Dep.Edit.Edit")); + FormLayout layout = new FormLayout(); + layout.marginWidth = PropsUi.getFormMargin(); + layout.marginHeight = PropsUi.getFormMargin(); + dialog.setLayout(layout); + int middle = 30; + int margin = PropsUi.getMargin(); + + Label wlGroup = labeled(dialog, "HopEnvironmentDialog.Dep.Column.GroupId", 0, middle, margin); + Text wGroup = textField(dialog, wlGroup, middle, Const.NVL(ref.getGroupId(), "")); + Label wlArt = + labeled(dialog, "HopEnvironmentDialog.Dep.Column.ArtifactId", wGroup, middle, margin); + Text wArt = textField(dialog, wlArt, middle, Const.NVL(ref.getArtifactId(), "")); + Label wlVer = labeled(dialog, "HopEnvironmentDialog.Dep.Column.Version", wArt, middle, margin); + Text wVer = textField(dialog, wlVer, middle, Const.NVL(ref.getVersion(), "")); + Label wlTarget = + labeled(dialog, "HopEnvironmentDialog.Dep.Column.Target", wVer, middle, margin); + Text wTarget = textField(dialog, wlTarget, middle, Const.NVL(ref.getTarget(), "lib/jdbc")); + + final boolean[] ok = {false}; + Button wOk = new Button(dialog, SWT.PUSH); + wOk.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Button.Ok")); + Button wCancel = new Button(dialog, SWT.PUSH); + wCancel.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Button.Cancel")); + wCancel.addListener(SWT.Selection, e -> dialog.dispose()); + wOk.addListener( + SWT.Selection, + e -> { + if (StringUtils.isAnyBlank(wGroup.getText(), wArt.getText(), wVer.getText())) { + MessageBox box = new MessageBox(dialog, SWT.OK | SWT.ICON_WARNING); + box.setText(BaseMessages.getString(PKG, "HopEnvironmentDialog.Validation.Header")); + box.setMessage(BaseMessages.getString(PKG, "HopEnvironmentDialog.Validation.DepGav")); + box.open(); + return; + } + ref.setGroupId(wGroup.getText().trim()); + ref.setArtifactId(wArt.getText().trim()); + ref.setVersion(wVer.getText().trim()); + ref.setTarget(StringUtils.defaultIfBlank(wTarget.getText(), "lib/jdbc").trim()); + ok[0] = true; + dialog.dispose(); + }); + BaseTransformDialog.positionBottomButtons(dialog, new Button[] {wOk, wCancel}, margin, wTarget); + BaseTransformDialog.setSize(dialog); + dialog.open(); + Display display = shell.getDisplay(); + while (!dialog.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + return ok[0]; + } + + // --- table helpers --- + + private void removeSelected(TableView view) { + int idx = view.table.getSelectionIndex(); + if (idx < 0) { + return; + } + view.table.remove(idx); + markDirty(); + } + + private void moveSelected(TableView view, int delta) { + int idx = view.table.getSelectionIndex(); + if (idx < 0) { + return; + } + int target = idx + delta; + if (target < 0 || target >= view.table.getItemCount()) { + return; + } + TableItem a = view.table.getItem(idx); + TableItem b = view.table.getItem(target); + Object dataA = a.getData(); + Object dataB = b.getData(); + int cols = view.table.getColumnCount(); + String[] textsA = new String[cols]; + String[] textsB = new String[cols]; + for (int c = 0; c < cols; c++) { + textsA[c] = a.getText(c); + textsB[c] = b.getText(c); + } + for (int c = 0; c < cols; c++) { + a.setText(c, textsB[c]); + b.setText(c, textsA[c]); + } + a.setData(dataB); + b.setData(dataA); + view.table.setSelection(target); + markDirty(); + } + + private Label labeled(Shell dialog, String key, Object above, int middle, int margin) { + Label label = new Label(dialog, SWT.RIGHT); + PropsUi.setLook(label); + label.setText(BaseMessages.getString(PKG, key)); + FormData fd = new FormData(); + fd.left = new FormAttachment(0, 0); + fd.right = new FormAttachment(middle, -margin); + if (above instanceof Integer) { + fd.top = new FormAttachment(0, margin); + } else { + fd.top = new FormAttachment((Control) above, margin); + } + label.setLayoutData(fd); + return label; + } + + private Text textField(Shell dialog, Label label, int middle, String value) { + Text text = new Text(dialog, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + PropsUi.setLook(text); + text.setText(value); + FormData fd = new FormData(); + fd.left = new FormAttachment(middle, 0); + fd.top = new FormAttachment(label, 0, SWT.CENTER); + fd.right = new FormAttachment(100, 0); + text.setLayoutData(fd); + return text; + } + + private void notifyStatus(String message) { + if (statusListener != null && message != null) { + statusListener.accept(message); + } + } + + private static String blankToNull(String value) { + return StringUtils.isBlank(value) ? null : value.trim(); + } + + public boolean wasSaved() { + return saved; + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java index a5e274f0d9d..a0e1b2b41a7 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java @@ -17,50 +17,45 @@ package org.apache.hop.marketplace.gui; -import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; -import java.util.HashSet; import java.util.List; -import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.apache.hop.core.Const; import org.apache.hop.core.logging.ILogChannel; import org.apache.hop.core.logging.LogChannel; +import org.apache.hop.core.variables.Variables; import org.apache.hop.i18n.BaseMessages; import org.apache.hop.marketplace.catalog.OptionalPluginCatalog; import org.apache.hop.marketplace.catalog.OptionalPluginInfo; import org.apache.hop.marketplace.command.MarketplaceCommand; import org.apache.hop.marketplace.config.MarketplaceConfig; -import org.apache.hop.marketplace.config.MarketplaceRepository; import org.apache.hop.marketplace.env.EnvironmentApplier; -import org.apache.hop.marketplace.env.EnvironmentDrift; -import org.apache.hop.marketplace.env.HopEnvironmentLoader; -import org.apache.hop.marketplace.env.HopEnvironmentSpec; import org.apache.hop.marketplace.install.HopHome; import org.apache.hop.marketplace.install.InstallReceipt; import org.apache.hop.marketplace.install.PluginInstaller; import org.apache.hop.marketplace.install.PluginUninstaller; import org.apache.hop.marketplace.resolve.MavenCoordinates; import org.apache.hop.ui.core.PropsUi; -import org.apache.hop.ui.core.dialog.BaseDialog; import org.apache.hop.ui.core.dialog.ErrorDialog; import org.apache.hop.ui.core.dialog.MessageBox; import org.apache.hop.ui.core.gui.GuiResource; import org.apache.hop.ui.core.gui.WindowProperty; +import org.apache.hop.ui.core.widget.ColumnInfo; +import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Dialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; @@ -73,15 +68,12 @@ public class MarketplaceDialog extends Dialog { private final ILogChannel log = new LogChannel("Marketplace"); private Shell shell; - private Table wTable; - private Combo wRepo; - private final java.util.List repoComboIds = new java.util.ArrayList<>(); - private Text wEnvFile; - private Button wPrune; - private Button wStrict; + private TableView wTable; + private Text wSearch; private Label wStatus; private Path hopHome; private MarketplaceConfig config; + private boolean tableOptimized; public MarketplaceDialog(Shell parent) { super(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX); @@ -91,13 +83,13 @@ public MarketplaceDialog(Shell parent) { public void open() { Shell parent = getParent(); shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX); - props.setLook(shell); + PropsUi.setLook(shell); shell.setImage(GuiResource.getInstance().getImageHopUi()); shell.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Shell.Title")); FormLayout formLayout = new FormLayout(); - formLayout.marginWidth = Const.FORM_MARGIN; - formLayout.marginHeight = Const.FORM_MARGIN; + formLayout.marginWidth = PropsUi.getFormMargin(); + formLayout.marginHeight = PropsUi.getFormMargin(); shell.setLayout(formLayout); try { @@ -112,155 +104,35 @@ public void open() { return; } - // Primary repository (install still uses full fallback chain with this first) - Label wlRepo = new Label(shell, SWT.RIGHT); - props.setLook(wlRepo); - wlRepo.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Repository.Label")); - FormData fdlRepo = new FormData(); - fdlRepo.left = new FormAttachment(0, 0); - fdlRepo.top = new FormAttachment(0, 0); - wlRepo.setLayoutData(fdlRepo); - - Button wManageRepos = new Button(shell, SWT.PUSH); - wManageRepos.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.ManageRepos")); - wManageRepos.addListener(SWT.Selection, e -> manageRepositories()); - FormData fdManage = new FormData(); - fdManage.right = new FormAttachment(100, 0); - fdManage.top = new FormAttachment(0, 0); - wManageRepos.setLayoutData(fdManage); - - wRepo = new Combo(shell, SWT.READ_ONLY | SWT.BORDER); - props.setLook(wRepo); - FormData fdRepo = new FormData(); - fdRepo.left = new FormAttachment(wlRepo, Const.MARGIN); - fdRepo.top = new FormAttachment(wlRepo, 0, SWT.CENTER); - fdRepo.right = new FormAttachment(wManageRepos, -Const.MARGIN); - wRepo.setLayoutData(fdRepo); - wRepo.addListener(SWT.Selection, e -> onPrimaryRepoSelected()); - fillRepoCombo(); - - // Environment file (hop-env / full-client-env) — Validate / Apply - Label wlEnv = new Label(shell, SWT.RIGHT); - props.setLook(wlEnv); - wlEnv.setText(BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Label")); - FormData fdlEnv = new FormData(); - fdlEnv.left = new FormAttachment(0, 0); - fdlEnv.top = new FormAttachment(wRepo, Const.MARGIN * 2); - wlEnv.setLayoutData(fdlEnv); - - Button wApplyEnv = new Button(shell, SWT.PUSH); - wApplyEnv.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.ApplyEnv")); - wApplyEnv.setToolTipText( - BaseMessages.getString(PKG, "MarketplaceDialog.Button.ApplyEnv.Tooltip")); - wApplyEnv.addListener(SWT.Selection, e -> applyEnvironment()); - FormData fdApplyEnv = new FormData(); - fdApplyEnv.right = new FormAttachment(100, 0); - fdApplyEnv.top = new FormAttachment(wlEnv, 0, SWT.CENTER); - wApplyEnv.setLayoutData(fdApplyEnv); - - Button wValidateEnv = new Button(shell, SWT.PUSH); - wValidateEnv.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.ValidateEnv")); - wValidateEnv.setToolTipText( - BaseMessages.getString(PKG, "MarketplaceDialog.Button.ValidateEnv.Tooltip")); - wValidateEnv.addListener(SWT.Selection, e -> validateEnvironment()); - FormData fdValidateEnv = new FormData(); - fdValidateEnv.right = new FormAttachment(wApplyEnv, -Const.MARGIN); - fdValidateEnv.top = new FormAttachment(wlEnv, 0, SWT.CENTER); - wValidateEnv.setLayoutData(fdValidateEnv); - - Button wBrowseEnv = new Button(shell, SWT.PUSH); - wBrowseEnv.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.BrowseEnv")); - wBrowseEnv.addListener(SWT.Selection, e -> browseEnvironmentFile()); - FormData fdBrowseEnv = new FormData(); - fdBrowseEnv.right = new FormAttachment(wValidateEnv, -Const.MARGIN); - fdBrowseEnv.top = new FormAttachment(wlEnv, 0, SWT.CENTER); - wBrowseEnv.setLayoutData(fdBrowseEnv); - - wEnvFile = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER); - props.setLook(wEnvFile); - FormData fdEnvFile = new FormData(); - fdEnvFile.left = new FormAttachment(wlEnv, Const.MARGIN); - fdEnvFile.top = new FormAttachment(wlEnv, 0, SWT.CENTER); - fdEnvFile.right = new FormAttachment(wBrowseEnv, -Const.MARGIN); - wEnvFile.setLayoutData(fdEnvFile); - suggestDefaultEnvFile(); - - wPrune = new Button(shell, SWT.CHECK); - props.setLook(wPrune); - wPrune.setText(BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Prune")); - wPrune.setToolTipText(BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Prune.Tooltip")); - FormData fdPrune = new FormData(); - fdPrune.left = new FormAttachment(wlEnv, Const.MARGIN); - fdPrune.top = new FormAttachment(wEnvFile, Const.MARGIN); - wPrune.setLayoutData(fdPrune); - - wStrict = new Button(shell, SWT.CHECK); - props.setLook(wStrict); - wStrict.setText(BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Strict")); - wStrict.setToolTipText(BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Strict.Tooltip")); - FormData fdStrict = new FormData(); - fdStrict.left = new FormAttachment(wPrune, Const.MARGIN * 3); - fdStrict.top = new FormAttachment(wEnvFile, Const.MARGIN); - wStrict.setLayoutData(fdStrict); - - // Buttons (bottom) + // Shell-level Close only; Install/Uninstall/Refresh live on the Plugins tab. Button wClose = new Button(shell, SWT.PUSH); wClose.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.Close")); wClose.addListener(SWT.Selection, e -> close()); + BaseTransformDialog.positionBottomButtons(shell, new Button[] {wClose}, PropsUi.getMargin(), null); - Button wUninstall = new Button(shell, SWT.PUSH); - wUninstall.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.Uninstall")); - wUninstall.addListener(SWT.Selection, e -> uninstallSelected()); - - Button wInstall = new Button(shell, SWT.PUSH); - wInstall.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.Install")); - wInstall.addListener(SWT.Selection, e -> installSelected()); - - Button wRefresh = new Button(shell, SWT.PUSH); - wRefresh.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.Refresh")); - wRefresh.addListener(SWT.Selection, e -> refreshTable()); - - BaseTransformDialog.positionBottomButtons( - shell, new Button[] {wInstall, wUninstall, wRefresh, wClose}, Const.MARGIN, null); - - // Status + // Status (shared across tabs) wStatus = new Label(shell, SWT.LEFT); - props.setLook(wStatus); + PropsUi.setLook(wStatus); wStatus.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Status.RestartHint")); FormData fdStatus = new FormData(); fdStatus.left = new FormAttachment(0, 0); fdStatus.right = new FormAttachment(100, 0); - fdStatus.bottom = new FormAttachment(wClose, -Const.MARGIN * 2); + fdStatus.bottom = new FormAttachment(wClose, -PropsUi.getMargin() * 2); wStatus.setLayoutData(fdStatus); - // Table - wTable = new Table(shell, SWT.BORDER | SWT.FULL_SELECTION | SWT.SINGLE | SWT.V_SCROLL); - props.setLook(wTable); - wTable.setHeaderVisible(true); - wTable.setLinesVisible(true); - - TableColumn colName = new TableColumn(wTable, SWT.LEFT); - colName.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Column.Name")); - colName.setWidth(180); - TableColumn colArtifact = new TableColumn(wTable, SWT.LEFT); - colArtifact.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Column.Artifact")); - colArtifact.setWidth(200); - TableColumn colCategory = new TableColumn(wTable, SWT.LEFT); - colCategory.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Column.Category")); - colCategory.setWidth(100); - TableColumn colStatus = new TableColumn(wTable, SWT.LEFT); - colStatus.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Column.Status")); - colStatus.setWidth(100); - TableColumn colDesc = new TableColumn(wTable, SWT.LEFT); - colDesc.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Column.Description")); - colDesc.setWidth(320); + CTabFolder wTabFolder = new CTabFolder(shell, SWT.BORDER); + PropsUi.setLook(wTabFolder); + FormData fdTabs = new FormData(); + fdTabs.left = new FormAttachment(0, 0); + fdTabs.top = new FormAttachment(0, 0); + fdTabs.right = new FormAttachment(100, 0); + fdTabs.bottom = new FormAttachment(wStatus, -PropsUi.getMargin()); + wTabFolder.setLayoutData(fdTabs); - FormData fdTable = new FormData(); - fdTable.left = new FormAttachment(0, 0); - fdTable.top = new FormAttachment(wPrune, Const.MARGIN * 2); - fdTable.right = new FormAttachment(100, 0); - fdTable.bottom = new FormAttachment(wStatus, -Const.MARGIN); - wTable.setLayoutData(fdTable); + createPluginsTab(wTabFolder); + createEnvironmentTab(wTabFolder); + createRepositoriesTab(wTabFolder); + wTabFolder.setSelection(0); refreshTable(); @@ -274,61 +146,194 @@ public void open() { } } - private void fillRepoCombo() { - wRepo.removeAll(); - repoComboIds.clear(); - MarketplaceRepository primary = config.primaryRepository(); - int select = 0; - int i = 0; - for (MarketplaceRepository repo : config.getRepositories()) { - if (repo == null || !repo.isEnabled()) { - continue; - } - wRepo.add(repo.displayName() + " — " + repo.normalizedUrl()); - repoComboIds.add(repo.getId()); - if (primary != null && primary.getId() != null && primary.getId().equals(repo.getId())) { - select = i; + private void createPluginsTab(CTabFolder folder) { + CTabItem tab = new CTabItem(folder, SWT.NONE); + tab.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Tab.Plugins")); + tab.setImage(GuiResource.getInstance().getImagePlugin()); + Composite comp = new Composite(folder, SWT.NONE); + PropsUi.setLook(comp); + FormLayout layout = new FormLayout(); + layout.marginWidth = PropsUi.getFormMargin(); + layout.marginHeight = PropsUi.getFormMargin(); + comp.setLayout(layout); + tab.setControl(comp); + + Button wUninstall = new Button(comp, SWT.PUSH); + wUninstall.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.Uninstall")); + wUninstall.addListener(SWT.Selection, e -> uninstallSelected()); + + Button wInstall = new Button(comp, SWT.PUSH); + wInstall.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.Install")); + wInstall.addListener(SWT.Selection, e -> installSelected()); + + Button wRefresh = new Button(comp, SWT.PUSH); + wRefresh.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.Refresh")); + wRefresh.addListener(SWT.Selection, e -> refreshTable()); + + BaseTransformDialog.positionBottomButtons( + comp, new Button[] {wInstall, wUninstall, wRefresh}, PropsUi.getMargin(), null); + + // Search / filter above the plugin list + Label wlSearch = new Label(comp, SWT.RIGHT); + PropsUi.setLook(wlSearch); + wlSearch.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Search.Label")); + FormData fdlSearch = new FormData(); + fdlSearch.left = new FormAttachment(0, 0); + fdlSearch.top = new FormAttachment(0, 0); + wlSearch.setLayoutData(fdlSearch); + + Button wClearSearch = new Button(comp, SWT.PUSH); + wClearSearch.setImage(GuiResource.getInstance().getImageClear()); + wClearSearch.setToolTipText(BaseMessages.getString(PKG, "MarketplaceDialog.Search.Clear")); + wClearSearch.addListener(SWT.Selection, e -> clearSearch()); + FormData fdClearSearch = new FormData(); + fdClearSearch.right = new FormAttachment(100, 0); + fdClearSearch.top = new FormAttachment(wlSearch, 0, SWT.CENTER); + wClearSearch.setLayoutData(fdClearSearch); + + wSearch = new Text(comp, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + PropsUi.setLook(wSearch); + wSearch.setMessage(BaseMessages.getString(PKG, "MarketplaceDialog.Search.Placeholder")); + FormData fdSearch = new FormData(); + fdSearch.left = new FormAttachment(wlSearch, PropsUi.getMargin()); + fdSearch.top = new FormAttachment(wlSearch, 0, SWT.CENTER); + fdSearch.right = new FormAttachment(wClearSearch, -PropsUi.getMargin()); + wSearch.setLayoutData(fdSearch); + wSearch.addListener(SWT.Modify, e -> refreshTable()); + + Label wSearchSep = new Label(comp, SWT.HORIZONTAL | SWT.SEPARATOR); + FormData fdSearchSep = new FormData(); + fdSearchSep.left = new FormAttachment(0, 0); + fdSearchSep.right = new FormAttachment(100, 0); + fdSearchSep.top = new FormAttachment(wSearch, PropsUi.getMargin()); + wSearchSep.setLayoutData(fdSearchSep); + + ColumnInfo[] columns = { + new ColumnInfo( + BaseMessages.getString(PKG, "MarketplaceDialog.Column.Name"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "MarketplaceDialog.Column.Artifact"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "MarketplaceDialog.Column.Category"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "MarketplaceDialog.Column.Status"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "MarketplaceDialog.Column.Description"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + }; + wTable = + new TableView( + Variables.getADefaultVariableSpace(), + comp, + SWT.BORDER | SWT.FULL_SELECTION | SWT.SINGLE | SWT.V_SCROLL, + columns, + 1, + true, + null, + props, + false); + PropsUi.setLook(wTable); + + FormData fdTable = new FormData(); + fdTable.left = new FormAttachment(0, 0); + fdTable.top = new FormAttachment(wSearchSep, PropsUi.getMargin()); + fdTable.right = new FormAttachment(100, 0); + fdTable.bottom = new FormAttachment(wInstall, -PropsUi.getMargin() * 2); + wTable.setLayoutData(fdTable); + } + + private void createEnvironmentTab(CTabFolder folder) { + CTabItem tab = new CTabItem(folder, SWT.NONE); + tab.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Tab.Environment")); + tab.setImage(GuiResource.getInstance().getImageFile()); + Composite comp = new Composite(folder, SWT.NONE); + PropsUi.setLook(comp); + FormLayout layout = new FormLayout(); + layout.marginWidth = PropsUi.getFormMargin(); + layout.marginHeight = PropsUi.getFormMargin(); + comp.setLayout(layout); + tab.setControl(comp); + + // Full hop-env editor (formerly HopEnvironmentDialog modal) + HopEnvironmentDialog.embed( + comp, + resolveDefaultEnvPath(), + msg -> { + if (wStatus != null && !wStatus.isDisposed()) { + wStatus.setText(msg); + } + }); + } + + private Path resolveDefaultEnvPath() { + // Last file edited in the marketplace environment editor (audit list, most-recent first) + String last = + org.apache.hop.ui.hopgui.shared.AuditManagerGuiUtil.getLastUsedValue( + HopEnvironmentDialog.AUDIT_TYPE_ENV_FILES); + if (StringUtils.isNotBlank(last)) { + Path lastPath = Path.of(last.trim()).toAbsolutePath().normalize(); + if (Files.isRegularFile(lastPath)) { + return lastPath; } - i++; } - if (i > 0) { - wRepo.select(select); + Path fullClient = hopHome.resolve("full-client-env.yaml"); + if (Files.isRegularFile(fullClient)) { + return fullClient; } + return EnvironmentApplier.resolveEnvironmentFile(hopHome, null); } - private void onPrimaryRepoSelected() { - int idx = wRepo.getSelectionIndex(); - if (idx < 0 || idx >= repoComboIds.size()) { - return; - } - try { - config.setPrimary(repoComboIds.get(idx)); - config.save(); - } catch (Exception e) { - new ErrorDialog( - shell, - BaseMessages.getString(PKG, "MarketplaceDialog.Error.Header"), - BaseMessages.getString(PKG, "MarketplaceDialog.Repository.SetPrimary.Error"), - e); - } + private void createRepositoriesTab(CTabFolder folder) { + CTabItem tab = new CTabItem(folder, SWT.NONE); + tab.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Tab.Repositories")); + tab.setImage(GuiResource.getInstance().getImageServer()); + Composite comp = new Composite(folder, SWT.NONE); + PropsUi.setLook(comp); + FormLayout layout = new FormLayout(); + layout.marginWidth = PropsUi.getFormMargin(); + layout.marginHeight = PropsUi.getFormMargin(); + comp.setLayout(layout); + tab.setControl(comp); + + // Full repository management UI (formerly a nested ManageRepositoriesDialog) + new MarketplaceRepositoriesPanel(comp, config); } - private void manageRepositories() { - ManageRepositoriesDialog dialog = new ManageRepositoriesDialog(shell, config); - if (dialog.open()) { - config = MarketplaceConfig.load(); - fillRepoCombo(); + private void clearSearch() { + if (wSearch != null && !wSearch.isDisposed()) { + wSearch.setText(""); + wSearch.setFocus(); } } private void refreshTable() { - wTable.removeAll(); - List plugins = OptionalPluginCatalog.listWave1(); + wTable.table.removeAll(); + // Filter only when more than 2 characters are typed (same as explorer/metadata search). + String searchText = wSearch != null ? wSearch.getText() : ""; + List plugins = + searchText != null && searchText.trim().length() > 2 + ? OptionalPluginCatalog.query(searchText) + : OptionalPluginCatalog.listWave1(); for (OptionalPluginInfo info : plugins) { - TableItem item = new TableItem(wTable, SWT.NONE); - item.setText(0, Const.NVL(info.getName(), "")); - item.setText(1, Const.NVL(info.getArtifactId(), "")); - item.setText(2, Const.NVL(info.getCategory(), "")); + // Column 0 is the (hidden) index column; data columns are 1-based. + TableItem item = new TableItem(wTable.table, SWT.NONE); + item.setText(1, Const.NVL(info.getName(), "")); + item.setText(2, Const.NVL(info.getArtifactId(), "")); + item.setText(3, Const.NVL(info.getCategory(), "")); boolean onDisk = OptionalPluginCatalog.isInstalledOnDisk(hopHome, info); InstallReceipt receipt = null; try { @@ -348,14 +353,18 @@ private void refreshTable() { } else { status = BaseMessages.getString(PKG, "MarketplaceDialog.Status.NotInstalled"); } - item.setText(3, status); - item.setText(4, Const.NVL(info.getDescription(), "")); + item.setText(4, status); + item.setText(5, Const.NVL(info.getDescription(), "")); item.setData(info); } + if (!tableOptimized) { + wTable.optimizeTableView(); + tableOptimized = true; + } } private OptionalPluginInfo selected() { - TableItem[] items = wTable.getSelection(); + TableItem[] items = wTable.table.getSelection(); if (items == null || items.length == 0) { return null; } @@ -429,173 +438,6 @@ private void uninstallSelected() { } } - private void suggestDefaultEnvFile() { - Path fullClient = hopHome.resolve("full-client-env.yaml"); - if (Files.isRegularFile(fullClient)) { - wEnvFile.setText(fullClient.toString()); - return; - } - Path discovered = EnvironmentApplier.resolveEnvironmentFile(hopHome, null); - if (discovered != null) { - wEnvFile.setText(discovered.toString()); - } - } - - private void browseEnvironmentFile() { - String path = - BaseDialog.presentFileDialog( - false, - shell, - new String[] {"*.yaml;*.yml;*.json", "*.*"}, - new String[] { - BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Filter.Env"), - BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Filter.All") - }, - false); - if (StringUtils.isNotBlank(path)) { - wEnvFile.setText(path); - } - } - - private Path requireEnvFilePath() { - String text = wEnvFile.getText(); - if (StringUtils.isBlank(text)) { - MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_WARNING); - box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Missing.Header")); - box.setMessage(BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Missing.Message")); - box.open(); - return null; - } - Path path = Path.of(text.trim()).toAbsolutePath().normalize(); - if (!Files.isRegularFile(path)) { - MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_WARNING); - box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.NotFound.Header")); - box.setMessage( - BaseMessages.getString( - PKG, "MarketplaceDialog.EnvFile.NotFound.Message", path.toString())); - box.open(); - return null; - } - return path; - } - - private void validateEnvironment() { - Path envPath = requireEnvFilePath(); - if (envPath == null) { - return; - } - try { - wStatus.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Status.Validating")); - shell.update(); - HopEnvironmentSpec env = HopEnvironmentLoader.load(envPath); - EnvironmentApplier applier = new EnvironmentApplier(log, hopHome, MarketplaceConfig.load()); - EnvironmentDrift drift = applier.validate(env); - if (wStrict.getSelection()) { - populateExtraPlugins(env, drift); - } - boolean hard = - !drift.getMissingPlugins().isEmpty() - || !drift.getVersionMismatches().isEmpty() - || !drift.getMissingDependencies().isEmpty() - || (wStrict.getSelection() && !drift.getExtraMarketplacePlugins().isEmpty()); - if (!hard) { - MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION); - box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Validate.Ok.Header")); - box.setMessage( - BaseMessages.getString( - PKG, "MarketplaceDialog.Validate.Ok.Message", envPath.toString())); - box.open(); - wStatus.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Status.RestartHint")); - return; - } - MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_WARNING); - box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Validate.Drift.Header")); - box.setMessage( - BaseMessages.getString(PKG, "MarketplaceDialog.Validate.Drift.Message") - + "\n\n" - + drift.formatReport() - + "\n" - + BaseMessages.getString(PKG, "MarketplaceDialog.Validate.Drift.Hint")); - box.open(); - wStatus.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Status.Drift")); - } catch (Exception e) { - new ErrorDialog( - shell, - BaseMessages.getString(PKG, "MarketplaceDialog.Error.Header"), - BaseMessages.getString(PKG, "MarketplaceDialog.Validate.Error"), - e); - } - } - - private void applyEnvironment() { - Path envPath = requireEnvFilePath(); - if (envPath == null) { - return; - } - boolean prune = wPrune.getSelection(); - if (prune) { - MessageBox confirm = new MessageBox(shell, SWT.YES | SWT.NO | SWT.ICON_QUESTION); - confirm.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Apply.PruneConfirm.Header")); - confirm.setMessage( - BaseMessages.getString(PKG, "MarketplaceDialog.Apply.PruneConfirm.Message")); - if (confirm.open() != SWT.YES) { - return; - } - } - try { - config = MarketplaceConfig.load(); - if (!config.isEnabled()) { - MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_WARNING); - box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Error.Header")); - box.setMessage(BaseMessages.getString(PKG, "MarketplaceDialog.Apply.Disabled")); - box.open(); - return; - } - wStatus.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Status.Applying")); - shell.update(); - HopEnvironmentSpec env = HopEnvironmentLoader.load(envPath); - new EnvironmentApplier(log, hopHome, config).apply(env, prune); - MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION); - box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Apply.Done.Header")); - box.setMessage( - BaseMessages.getString(PKG, "MarketplaceDialog.Apply.Done.Message", envPath.toString())); - box.open(); - refreshTable(); - wStatus.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Status.RestartHint")); - } catch (Exception e) { - new ErrorDialog( - shell, - BaseMessages.getString(PKG, "MarketplaceDialog.Error.Header"), - BaseMessages.getString(PKG, "MarketplaceDialog.Apply.Error"), - e); - } - } - - private void populateExtraPlugins(HopEnvironmentSpec env, EnvironmentDrift drift) - throws Exception { - Set desired = new HashSet<>(); - if (env.getPlugins() != null) { - for (HopEnvironmentSpec.PluginRef ref : env.getPlugins()) { - if (ref.getArtifactId() != null) { - desired.add(ref.getArtifactId()); - } - } - } - Path receipts = hopHome.resolve(PluginInstaller.RECEIPTS_DIR); - if (!Files.isDirectory(receipts)) { - return; - } - try (DirectoryStream stream = Files.newDirectoryStream(receipts, "*.json")) { - for (Path f : stream) { - String name = f.getFileName().toString(); - String id = name.substring(0, name.length() - ".json".length()); - if (!desired.contains(id)) { - drift.getExtraMarketplacePlugins().add(id); - } - } - } - } - private void close() { props.setScreen(new WindowProperty(shell)); shell.dispose(); diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceGuiPlugin.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceGuiPlugin.java index 0a272035153..7ca82d0ce92 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceGuiPlugin.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceGuiPlugin.java @@ -19,6 +19,7 @@ import org.apache.hop.core.gui.plugin.GuiPlugin; import org.apache.hop.core.gui.plugin.menu.GuiMenuElement; +import org.apache.hop.core.gui.plugin.toolbar.GuiToolbarElement; import org.apache.hop.ui.core.dialog.ErrorDialog; import org.apache.hop.ui.hopgui.HopGui; @@ -30,6 +31,9 @@ public class MarketplaceGuiPlugin { public static final String ID_MAIN_MENU_TOOLS_MARKETPLACE = "40200-menu-tools-marketplace"; + /** After Save As ({@code toolbar-10050-save-as}) on the main toolbar. */ + public static final String ID_MAIN_TOOLBAR_MARKETPLACE = "toolbar-10060-marketplace"; + private static MarketplaceGuiPlugin instance; public MarketplaceGuiPlugin() { @@ -50,6 +54,12 @@ public static MarketplaceGuiPlugin getInstance() { parentId = HopGui.ID_MAIN_MENU_TOOLS_PARENT_ID, image = "ui/images/plugin.svg", separator = true) + @GuiToolbarElement( + root = HopGui.ID_MAIN_TOOLBAR, + id = ID_MAIN_TOOLBAR_MARKETPLACE, + image = "ui/images/plugin.svg", + toolTip = "i18n::MarketplaceGuiPlugin.Toolbar.Marketplace.Tooltip", + separator = true) public void menuToolsMarketplace() { HopGui hopGui = HopGui.getInstance(); try { diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/ManageRepositoriesDialog.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceRepositoriesPanel.java similarity index 71% rename from plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/ManageRepositoriesDialog.java rename to plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceRepositoriesPanel.java index 2dd7c330a67..c4960d3063f 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/ManageRepositoriesDialog.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceRepositoriesPanel.java @@ -21,63 +21,54 @@ import java.util.List; import org.apache.commons.lang3.StringUtils; import org.apache.hop.core.Const; +import org.apache.hop.core.variables.Variables; import org.apache.hop.i18n.BaseMessages; import org.apache.hop.marketplace.config.MarketplaceConfig; import org.apache.hop.marketplace.config.MarketplaceRepository; import org.apache.hop.ui.core.PropsUi; import org.apache.hop.ui.core.dialog.ErrorDialog; import org.apache.hop.ui.core.dialog.MessageBox; -import org.apache.hop.ui.core.gui.GuiResource; +import org.apache.hop.ui.core.gui.WindowProperty; +import org.apache.hop.ui.core.widget.ColumnInfo; +import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Dialog; +import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; -/** Edit marketplace repository list (saved to hop-config.json). */ -public class ManageRepositoriesDialog extends Dialog { +/** + * Marketplace repository list editor hosted as a panel (e.g. Marketplace dialog Repositories tab). + * Settings are saved to hop-config.json via {@link MarketplaceConfig#save()}. + */ +public class MarketplaceRepositoriesPanel { private static final Class PKG = MarketplaceGuiPlugin.class; - private final PropsUi props; private final MarketplaceConfig config; - private boolean saved; - - private Shell shell; - private Table wTable; - - public ManageRepositoriesDialog(Shell parent, MarketplaceConfig config) { - super(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX); - this.props = PropsUi.getInstance(); - this.config = config; - } + private final Shell shell; + private final TableView wTable; /** - * @return true if the user saved changes + * Build the repositories UI into {@code parent} (must use {@link FormLayout}). + * + * @param parent tab composite + * @param config shared marketplace config (mutated in place; call Save to persist) */ - public boolean open() { - Shell parent = getParent(); - shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX); - props.setLook(shell); - shell.setImage(GuiResource.getInstance().getImageHopUi()); - shell.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Shell.Title")); - - FormLayout formLayout = new FormLayout(); - formLayout.marginWidth = Const.FORM_MARGIN; - formLayout.marginHeight = Const.FORM_MARGIN; - shell.setLayout(formLayout); - - Label wlHelp = new Label(shell, SWT.LEFT | SWT.WRAP); - props.setLook(wlHelp); + public MarketplaceRepositoriesPanel(Composite parent, MarketplaceConfig config) { + PropsUi props = PropsUi.getInstance(); + this.config = config; + this.shell = parent.getShell(); + + Label wlHelp = new Label(parent, SWT.LEFT | SWT.WRAP); + PropsUi.setLook(wlHelp); wlHelp.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Help")); FormData fdlHelp = new FormData(); fdlHelp.left = new FormAttachment(0, 0); @@ -85,108 +76,131 @@ public boolean open() { fdlHelp.right = new FormAttachment(100, 0); wlHelp.setLayoutData(fdlHelp); - Button wCancel = new Button(shell, SWT.PUSH); - wCancel.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Cancel")); - wCancel.addListener(SWT.Selection, e -> shell.dispose()); + Label wHelpSep = new Label(parent, SWT.HORIZONTAL | SWT.SEPARATOR); + FormData fdHelpSep = new FormData(); + fdHelpSep.left = new FormAttachment(0, 0); + fdHelpSep.right = new FormAttachment(100, 0); + fdHelpSep.top = new FormAttachment(wlHelp, PropsUi.getMargin()); + wHelpSep.setLayoutData(fdHelpSep); - Button wSave = new Button(shell, SWT.PUSH); + Button wSave = new Button(parent, SWT.PUSH); wSave.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Save")); wSave.addListener(SWT.Selection, e -> save()); - Button wReset = new Button(shell, SWT.PUSH); + Button wReset = new Button(parent, SWT.PUSH); wReset.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.ResetDefaults")); wReset.addListener(SWT.Selection, e -> resetDefaults()); - Button wRemove = new Button(shell, SWT.PUSH); + Button wRemove = new Button(parent, SWT.PUSH); wRemove.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Remove")); wRemove.addListener(SWT.Selection, e -> removeSelected()); - Button wEdit = new Button(shell, SWT.PUSH); + Button wEdit = new Button(parent, SWT.PUSH); wEdit.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Edit")); wEdit.addListener(SWT.Selection, e -> editSelected()); - Button wAdd = new Button(shell, SWT.PUSH); + Button wAdd = new Button(parent, SWT.PUSH); wAdd.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Add")); wAdd.addListener(SWT.Selection, e -> addRepository()); - Button wPrimary = new Button(shell, SWT.PUSH); + Button wPrimary = new Button(parent, SWT.PUSH); wPrimary.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.SetPrimary")); wPrimary.addListener(SWT.Selection, e -> setPrimarySelected()); - Button wUp = new Button(shell, SWT.PUSH); + Button wUp = new Button(parent, SWT.PUSH); wUp.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.MoveUp")); wUp.addListener(SWT.Selection, e -> moveSelected(-1)); - Button wDown = new Button(shell, SWT.PUSH); + Button wDown = new Button(parent, SWT.PUSH); wDown.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.MoveDown")); wDown.addListener(SWT.Selection, e -> moveSelected(1)); BaseTransformDialog.positionBottomButtons( - shell, - new Button[] {wAdd, wEdit, wRemove, wPrimary, wUp, wDown, wReset, wSave, wCancel}, - Const.MARGIN, - null); - - wTable = new Table(shell, SWT.BORDER | SWT.FULL_SELECTION | SWT.SINGLE | SWT.V_SCROLL); - props.setLook(wTable); - wTable.setHeaderVisible(true); - wTable.setLinesVisible(true); - addColumn(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Primary"), 60); - addColumn(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Enabled"), 60); - addColumn(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Id"), 100); - addColumn(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Name"), 160); - addColumn(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Url"), 360); - addColumn(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Auth"), 50); + parent, + new Button[] {wAdd, wEdit, wRemove, wPrimary, wUp, wDown, wReset, wSave}, + PropsUi.getMargin(), + wlHelp); + + ColumnInfo[] columns = { + new ColumnInfo( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Primary"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Enabled"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Id"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Name"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Url"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + new ColumnInfo( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Auth"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), + }; + wTable = + new TableView( + Variables.getADefaultVariableSpace(), + parent, + SWT.BORDER | SWT.FULL_SELECTION | SWT.SINGLE | SWT.V_SCROLL, + columns, + 1, + true, + null, + props, + false); + PropsUi.setLook(wTable); FormData fdTable = new FormData(); fdTable.left = new FormAttachment(0, 0); - fdTable.top = new FormAttachment(wlHelp, Const.MARGIN * 2); + fdTable.top = new FormAttachment(wSave, PropsUi.getMargin()); fdTable.right = new FormAttachment(100, 0); - fdTable.bottom = new FormAttachment(wSave, -Const.MARGIN * 2); + fdTable.bottom = new FormAttachment(100, 0); wTable.setLayoutData(fdTable); refreshTable(); - - BaseTransformDialog.setSize(shell); - shell.open(); - Display display = parent.getDisplay(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - return saved; - } - - private void addColumn(String title, int width) { - TableColumn col = new TableColumn(wTable, SWT.LEFT); - col.setText(title); - col.setWidth(width); } private void refreshTable() { - wTable.removeAll(); + wTable.table.removeAll(); if (config.getRepositories() == null) { + wTable.optimizeTableView(); return; } for (MarketplaceRepository repo : config.getRepositories()) { if (repo == null) { continue; } - TableItem item = new TableItem(wTable, SWT.NONE); - item.setText(0, repo.isPrimary() ? "*" : ""); - item.setText(1, repo.isEnabled() ? "Y" : "N"); - item.setText(2, Const.NVL(repo.getId(), "")); - item.setText(3, Const.NVL(repo.displayName(), "")); - item.setText(4, Const.NVL(repo.getUrl(), "")); + TableItem item = new TableItem(wTable.table, SWT.NONE); + item.setText(1, repo.isPrimary() ? "*" : ""); + item.setText(2, repo.isEnabled() ? "Y" : "N"); + item.setText(3, Const.NVL(repo.getId(), "")); + item.setText(4, Const.NVL(repo.displayName(), "")); + item.setText(5, Const.NVL(repo.getUrl(), "")); item.setText( - 5, repo.hasCredentials() || StringUtils.isNotBlank(repo.getUsername()) ? "Y" : ""); + 6, repo.hasCredentials() || StringUtils.isNotBlank(repo.getUsername()) ? "Y" : ""); item.setData(repo); } + wTable.optimizeTableView(); } private MarketplaceRepository selected() { - TableItem[] items = wTable.getSelection(); + TableItem[] items = wTable.table.getSelection(); if (items == null || items.length == 0) { return null; } @@ -226,7 +240,7 @@ private void editSelected() { private boolean editRepository(MarketplaceRepository repo, boolean isNew) { Shell dialog = new Shell(shell, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE); - props.setLook(dialog); + PropsUi.setLook(dialog); dialog.setText( BaseMessages.getString( PKG, @@ -234,15 +248,15 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { ? "ManageRepositoriesDialog.Edit.Title.Add" : "ManageRepositoriesDialog.Edit.Title.Edit")); FormLayout layout = new FormLayout(); - layout.marginWidth = Const.FORM_MARGIN; - layout.marginHeight = Const.FORM_MARGIN; + layout.marginWidth = PropsUi.getFormMargin(); + layout.marginHeight = PropsUi.getFormMargin(); dialog.setLayout(layout); - int middle = 25; - int margin = Const.MARGIN; + int middle = PropsUi.getInstance().getMiddlePct(); + int margin = PropsUi.getMargin(); Label wlId = new Label(dialog, SWT.RIGHT); - props.setLook(wlId); + PropsUi.setLook(wlId); wlId.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Id")); FormData fdlId = new FormData(); fdlId.left = new FormAttachment(0, 0); @@ -250,17 +264,17 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { fdlId.right = new FormAttachment(middle, -margin); wlId.setLayoutData(fdlId); Text wId = new Text(dialog, SWT.SINGLE | SWT.LEFT | SWT.BORDER); - props.setLook(wId); + PropsUi.setLook(wId); wId.setText(Const.NVL(repo.getId(), "")); wId.setEditable(isNew); FormData fdId = new FormData(); - fdId.left = new FormAttachment(middle, 0); + fdId.left = new FormAttachment(middle, margin); fdId.top = new FormAttachment(wlId, 0, SWT.CENTER); fdId.right = new FormAttachment(100, 0); wId.setLayoutData(fdId); Label wlName = new Label(dialog, SWT.RIGHT); - props.setLook(wlName); + PropsUi.setLook(wlName); wlName.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Name")); FormData fdlName = new FormData(); fdlName.left = new FormAttachment(0, 0); @@ -268,16 +282,16 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { fdlName.right = new FormAttachment(middle, -margin); wlName.setLayoutData(fdlName); Text wName = new Text(dialog, SWT.SINGLE | SWT.LEFT | SWT.BORDER); - props.setLook(wName); + PropsUi.setLook(wName); wName.setText(Const.NVL(repo.getName(), "")); FormData fdName = new FormData(); - fdName.left = new FormAttachment(middle, 0); + fdName.left = new FormAttachment(middle, margin); fdName.top = new FormAttachment(wlName, 0, SWT.CENTER); fdName.right = new FormAttachment(100, 0); wName.setLayoutData(fdName); Label wlUrl = new Label(dialog, SWT.RIGHT); - props.setLook(wlUrl); + PropsUi.setLook(wlUrl); wlUrl.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Url")); FormData fdlUrl = new FormData(); fdlUrl.left = new FormAttachment(0, 0); @@ -285,16 +299,16 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { fdlUrl.right = new FormAttachment(middle, -margin); wlUrl.setLayoutData(fdlUrl); Text wUrl = new Text(dialog, SWT.SINGLE | SWT.LEFT | SWT.BORDER); - props.setLook(wUrl); + PropsUi.setLook(wUrl); wUrl.setText(Const.NVL(repo.getUrl(), "")); FormData fdUrl = new FormData(); - fdUrl.left = new FormAttachment(middle, 0); + fdUrl.left = new FormAttachment(middle, margin); fdUrl.top = new FormAttachment(wlUrl, 0, SWT.CENTER); fdUrl.right = new FormAttachment(100, 0); wUrl.setLayoutData(fdUrl); Label wlUser = new Label(dialog, SWT.RIGHT); - props.setLook(wlUser); + PropsUi.setLook(wlUser); wlUser.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Username")); FormData fdlUser = new FormData(); fdlUser.left = new FormAttachment(0, 0); @@ -302,16 +316,16 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { fdlUser.right = new FormAttachment(middle, -margin); wlUser.setLayoutData(fdlUser); Text wUser = new Text(dialog, SWT.SINGLE | SWT.LEFT | SWT.BORDER); - props.setLook(wUser); + PropsUi.setLook(wUser); wUser.setText(Const.NVL(repo.getUsername(), "")); FormData fdUser = new FormData(); - fdUser.left = new FormAttachment(middle, 0); + fdUser.left = new FormAttachment(middle, margin); fdUser.top = new FormAttachment(wlUser, 0, SWT.CENTER); fdUser.right = new FormAttachment(100, 0); wUser.setLayoutData(fdUser); Label wlPass = new Label(dialog, SWT.RIGHT); - props.setLook(wlPass); + PropsUi.setLook(wlPass); wlPass.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Password")); FormData fdlPass = new FormData(); fdlPass.left = new FormAttachment(0, 0); @@ -319,28 +333,28 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { fdlPass.right = new FormAttachment(middle, -margin); wlPass.setLayoutData(fdlPass); Text wPass = new Text(dialog, SWT.SINGLE | SWT.LEFT | SWT.BORDER | SWT.PASSWORD); - props.setLook(wPass); + PropsUi.setLook(wPass); FormData fdPass = new FormData(); - fdPass.left = new FormAttachment(middle, 0); + fdPass.left = new FormAttachment(middle, margin); fdPass.top = new FormAttachment(wlPass, 0, SWT.CENTER); fdPass.right = new FormAttachment(100, 0); wPass.setLayoutData(fdPass); Button wEnabled = new Button(dialog, SWT.CHECK); - props.setLook(wEnabled); + PropsUi.setLook(wEnabled); wEnabled.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Enabled")); wEnabled.setSelection(repo.isEnabled()); FormData fdEnabled = new FormData(); - fdEnabled.left = new FormAttachment(middle, 0); + fdEnabled.left = new FormAttachment(middle, margin); fdEnabled.top = new FormAttachment(wPass, margin); wEnabled.setLayoutData(fdEnabled); Button wPrimary = new Button(dialog, SWT.CHECK); - props.setLook(wPrimary); + PropsUi.setLook(wPrimary); wPrimary.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Primary")); wPrimary.setSelection(repo.isPrimary()); FormData fdPrimary = new FormData(); - fdPrimary.left = new FormAttachment(middle, 0); + fdPrimary.left = new FormAttachment(middle, margin); fdPrimary.top = new FormAttachment(wEnabled, margin); wPrimary.setLayoutData(fdPrimary); @@ -367,6 +381,7 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { repo.setEnabled(wEnabled.getSelection()); repo.setPrimary(wPrimary.getSelection()); ok[0] = true; + PropsUi.getInstance().setScreen(new WindowProperty(dialog)); dialog.dispose(); }); Button wCancel = new Button(dialog, SWT.PUSH); @@ -375,7 +390,7 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { BaseTransformDialog.positionBottomButtons( dialog, new Button[] {wOk, wCancel}, margin, wPrimary); - dialog.setSize(560, 360); + BaseTransformDialog.setSize(dialog); dialog.open(); Display display = shell.getDisplay(); while (!dialog.isDisposed()) { @@ -441,7 +456,7 @@ private void moveSelected(int delta) { list.remove(idx); list.add(target, repo); refreshTable(); - wTable.setSelection(target); + wTable.table.setSelection(target); } private void resetDefaults() { @@ -459,8 +474,10 @@ private void save() { try { config.ensureValidPrimary(); config.save(); - saved = true; - shell.dispose(); + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION); + box.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Save.Done.Header")); + box.setMessage(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Save.Done.Message")); + box.open(); } catch (Exception e) { new ErrorDialog( shell, diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/WelcomeMarketplace.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/WelcomeMarketplace.java new file mode 100644 index 00000000000..ca272ed41a9 --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/WelcomeMarketplace.java @@ -0,0 +1,145 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.gui; + +import org.apache.hop.core.gui.plugin.GuiElementType; +import org.apache.hop.core.gui.plugin.GuiPlugin; +import org.apache.hop.core.gui.plugin.GuiWidgetElement; +import org.apache.hop.ui.core.PropsUi; +import org.apache.hop.ui.core.dialog.ErrorDialog; +import org.apache.hop.ui.core.gui.GuiCompositeWidgets; +import org.apache.hop.ui.hopgui.HopGui; +import org.apache.hop.ui.hopgui.welcome.WelcomeDialog; +import org.apache.hop.ui.util.EnvironmentUtils; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; + +/** + * Welcome dialog topic for the plugin marketplace: why plugins moved out of the fat client, docs, + * open dialog, and how to restore the full plugin set. + */ +@GuiPlugin +public class WelcomeMarketplace { + + private static final String WELCOME_MARKETPLACE_PARENT_ID = "WelcomeMarketplace.Parent.ID"; + + public static final String WEB_NAME_MARKETPLACE_DOCS = "Marketplace documentation"; + public static final String WEB_LINK_MARKETPLACE_DOCS = + "https://hop.apache.org/manual/latest/hop-tools/hop-marketplace.html"; + + public static final String LINK_OPEN_MARKETPLACE = "Open Marketplace"; + + @GuiWidgetElement( + type = GuiElementType.COMPOSITE, + id = "21000-marketplace-welcome", + label = "Marketplace", + parentId = WelcomeDialog.PARENT_ID_WELCOME_WIDGETS) + public void welcome(Composite parent) { + PropsUi props = PropsUi.getInstance(); + + Composite parentComposite = new Composite(parent, SWT.NONE); + parentComposite.setLayout(props.createFormLayout()); + FormData fdParentComposite = new FormData(); + fdParentComposite.left = new FormAttachment(0, 0); + fdParentComposite.right = new FormAttachment(100, 0); + fdParentComposite.top = new FormAttachment(0, 0); + fdParentComposite.bottom = new FormAttachment(100, 0); + parentComposite.setLayoutData(fdParentComposite); + PropsUi.setLook(parentComposite); + + GuiCompositeWidgets compositeWidgets = + new GuiCompositeWidgets(HopGui.getInstance().getVariables()); + compositeWidgets.createCompositeWidgets( + this, null, parentComposite, WELCOME_MARKETPLACE_PARENT_ID, null); + } + + @GuiWidgetElement( + id = "WelcomeMarketplace.10010.overview", + parentId = WELCOME_MARKETPLACE_PARENT_ID, + type = GuiElementType.LINK, + label = + "Large and lesser-used plugins are no longer bundled in the default hop-client download " + + "(Apache packaging size limit).\n\n" + + "Install them from the marketplace: plugins are published as Maven zips on the " + + "Apache Repository (repository.apache.org), with Maven Central as fallback.\n\n" + + "See the " + + WEB_NAME_MARKETPLACE_DOCS + + " for CLI and GUI details.") + public void overviewLink(Event event) { + handleWebLinkEvent(event); + } + + @GuiWidgetElement( + id = "WelcomeMarketplace.10020.open-dialog", + parentId = WELCOME_MARKETPLACE_PARENT_ID, + type = GuiElementType.LINK, + label = + "\nOpen the marketplace from Tools → Marketplace…, the main toolbar icon after Save As…, " + + "or click " + + LINK_OPEN_MARKETPLACE + + ".") + public void openMarketplaceLink(Event event) { + openMarketplace(event); + } + + @GuiWidgetElement( + id = "WelcomeMarketplace.10030.install-all", + parentId = WELCOME_MARKETPLACE_PARENT_ID, + type = GuiElementType.LINK, + label = + "\nTo install all optional plugins that used to ship in the fat client:\n\n" + + " • GUI: open the marketplace, select full-client-env.yaml as the environment file " + + "(pre-filled when present at the install root), click Apply, then restart Hop.\n" + + " • CLI (from the Hop install directory):\n\n" + + " ./hop marketplace apply -f full-client-env.yaml\n\n" + + "Do not use prune unless you also want other marketplace installs removed.\n\n" + + "Click " + + LINK_OPEN_MARKETPLACE + + " to open the dialog and Apply now.") + public void installAllLink(Event event) { + openMarketplace(event); + } + + private void openMarketplace(Event event) { + try { + if (WelcomeMarketplace.LINK_OPEN_MARKETPLACE.equals(event.text)) { + MarketplaceGuiPlugin.getInstance().menuToolsMarketplace(); + } + } catch (Exception e) { + new ErrorDialog( + HopGui.getInstance().getShell(), "Error", "Unable to open the marketplace dialog", e); + } + } + + private void handleWebLinkEvent(Event event) { + try { + if (WelcomeMarketplace.WEB_NAME_MARKETPLACE_DOCS.equals(event.text)) { + EnvironmentUtils.getInstance().openUrl(WelcomeMarketplace.WEB_LINK_MARKETPLACE_DOCS); + } + } catch (Exception e) { + new ErrorDialog( + HopGui.getInstance().getShell(), + "Error", + "Error opening link to " + WelcomeMarketplace.WEB_LINK_MARKETPLACE_DOCS, + e); + } + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java index 8dc863f594a..ea0de0aa113 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java @@ -231,7 +231,7 @@ private List unzipAllowedEntries(Path zipFile, Path stageRoot) while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); String name = entry.getName(); - if (name == null || name.isBlank()) { + if (name.isBlank()) { continue; } // Normalize and reject path traversal diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java index 3b0ac2f4bac..7e3594ea075 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java @@ -127,12 +127,12 @@ public Path downloadZip(String repositoryBaseUrl, MavenCoordinates coordinates, return downloadZip(repo, coordinates, targetFile); } - public Path downloadArtifact( + public void downloadArtifact( MarketplaceRepository repository, String relativePath, String label, Path targetFile) throws HopException { String base = repository.normalizedUrl(); String url = base + (relativePath.startsWith("/") ? relativePath.substring(1) : relativePath); - return download(url, repository, label, targetFile); + download(url, repository, label, targetFile); } /** diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/xp/LifecycleEnvironmentDialogTabsExtensionPoint.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/xp/LifecycleEnvironmentDialogTabsExtensionPoint.java new file mode 100644 index 00000000000..95590eea6a6 --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/xp/LifecycleEnvironmentDialogTabsExtensionPoint.java @@ -0,0 +1,252 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.xp; + +import java.nio.file.Files; +import java.nio.file.Path; +import org.apache.commons.lang3.StringUtils; +import org.apache.hop.core.AttributesContext; +import org.apache.hop.core.Const; +import org.apache.hop.core.exception.HopException; +import org.apache.hop.core.extension.ExtensionPoint; +import org.apache.hop.core.extension.IExtensionPoint; +import org.apache.hop.core.logging.ILogChannel; +import org.apache.hop.core.variables.IVariables; +import org.apache.hop.i18n.BaseMessages; +import org.apache.hop.marketplace.env.MarketplaceAttributes; +import org.apache.hop.marketplace.gui.HopEnvironmentDialog; +import org.apache.hop.marketplace.gui.MarketplaceGuiPlugin; +import org.apache.hop.ui.core.PropsUi; +import org.apache.hop.ui.core.dialog.AttributesDialogExtension; +import org.apache.hop.ui.core.dialog.BaseDialog; +import org.apache.hop.ui.core.gui.GuiResource; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +/** + * Contributes a Marketplace / Plugins tab on the lifecycle environment dialog. Settings are stored + * under {@link MarketplaceAttributes#GROUP} on the shared {@link AttributesContext}. + */ +@ExtensionPoint( + id = "MarketplaceLifecycleEnvironmentDialogTabs", + description = "Add marketplace plugin policy tab to the lifecycle environment dialog", + extensionPointId = "HopGuiLifecycleEnvironmentDialogTabs") +public class LifecycleEnvironmentDialogTabsExtensionPoint + implements IExtensionPoint { + + private static final Class PKG = MarketplaceGuiPlugin.class; + + private Text wEnvFile; + private Combo wOnEnable; + private Button wStrict; + private Button wAutoApply; + + @Override + public void callExtensionPoint( + ILogChannel log, IVariables variables, AttributesDialogExtension extension) + throws HopException { + if (extension == null || extension.getTabFolder() == null) { + return; + } + + PropsUi props = PropsUi.getInstance(); + CTabFolder folder = extension.getTabFolder(); + int margin = PropsUi.getMargin(); + int middle = props.getMiddlePct(); + + CTabItem tab = new CTabItem(folder, SWT.NONE); + tab.setText(BaseMessages.getString(PKG, "MarketplaceLifecycleEnv.Tab.Plugins")); + tab.setImage(GuiResource.getInstance().getImagePlugin()); + Composite comp = new Composite(folder, SWT.NONE); + PropsUi.setLook(comp); + FormLayout layout = new FormLayout(); + layout.marginWidth = PropsUi.getFormMargin(); + layout.marginHeight = PropsUi.getFormMargin(); + comp.setLayout(layout); + tab.setControl(comp); + + Label wlHelp = new Label(comp, SWT.LEFT | SWT.WRAP); + PropsUi.setLook(wlHelp); + wlHelp.setText(BaseMessages.getString(PKG, "MarketplaceLifecycleEnv.Help")); + FormData fdlHelp = new FormData(); + fdlHelp.left = new FormAttachment(0, 0); + fdlHelp.top = new FormAttachment(0, 0); + fdlHelp.right = new FormAttachment(100, 0); + wlHelp.setLayoutData(fdlHelp); + + Label wlEnvFile = new Label(comp, SWT.RIGHT); + PropsUi.setLook(wlEnvFile); + wlEnvFile.setText(BaseMessages.getString(PKG, "MarketplaceLifecycleEnv.EnvFile.Label")); + FormData fdlEnv = new FormData(); + fdlEnv.left = new FormAttachment(0, 0); + fdlEnv.top = new FormAttachment(wlHelp, margin * 2); + fdlEnv.right = new FormAttachment(middle, -margin); + wlEnvFile.setLayoutData(fdlEnv); + + Button wEditEnv = new Button(comp, SWT.PUSH); + wEditEnv.setText(BaseMessages.getString(PKG, "MarketplaceLifecycleEnv.Button.EditEnv")); + FormData fdEdit = new FormData(); + fdEdit.right = new FormAttachment(100, 0); + fdEdit.top = new FormAttachment(wlEnvFile, 0, SWT.CENTER); + wEditEnv.setLayoutData(fdEdit); + wEditEnv.addListener( + SWT.Selection, + e -> { + Path initial = null; + String text = wEnvFile.getText(); + if (StringUtils.isNotBlank(text)) { + String resolved = variables != null ? variables.resolve(text.trim()) : text.trim(); + Path candidate = Path.of(resolved).toAbsolutePath().normalize(); + if (Files.isRegularFile(candidate)) { + initial = candidate; + } + } + Path saved = new HopEnvironmentDialog(extension.getShell(), initial).open(); + if (saved != null) { + wEnvFile.setText(saved.toString()); + } + }); + + Button wBrowse = new Button(comp, SWT.PUSH); + wBrowse.setText(BaseMessages.getString(PKG, "MarketplaceLifecycleEnv.Button.Browse")); + FormData fdBrowse = new FormData(); + fdBrowse.right = new FormAttachment(wEditEnv, -margin); + fdBrowse.top = new FormAttachment(wlEnvFile, 0, SWT.CENTER); + wBrowse.setLayoutData(fdBrowse); + wBrowse.addListener( + SWT.Selection, + e -> { + String path = + BaseDialog.presentFileDialog( + false, + extension.getShell(), + new String[] {"*.yaml;*.yml;*.json", "*.*"}, + new String[] { + BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Filter.Env"), + BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Filter.All") + }, + false); + if (StringUtils.isNotBlank(path)) { + wEnvFile.setText(path); + } + }); + + wEnvFile = new Text(comp, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + PropsUi.setLook(wEnvFile); + FormData fdEnv = new FormData(); + fdEnv.left = new FormAttachment(middle, 0); + fdEnv.top = new FormAttachment(wlEnvFile, 0, SWT.CENTER); + fdEnv.right = new FormAttachment(wBrowse, -margin); + wEnvFile.setLayoutData(fdEnv); + + Label wlOnEnable = new Label(comp, SWT.RIGHT); + PropsUi.setLook(wlOnEnable); + wlOnEnable.setText(BaseMessages.getString(PKG, "MarketplaceLifecycleEnv.OnEnable.Label")); + FormData fdlOn = new FormData(); + fdlOn.left = new FormAttachment(0, 0); + fdlOn.top = new FormAttachment(wEnvFile, margin * 2); + fdlOn.right = new FormAttachment(middle, -margin); + wlOnEnable.setLayoutData(fdlOn); + + wOnEnable = new Combo(comp, SWT.READ_ONLY | SWT.BORDER); + PropsUi.setLook(wOnEnable); + wOnEnable.setItems( + MarketplaceAttributes.ON_ENABLE_OFF, + MarketplaceAttributes.ON_ENABLE_WARN, + MarketplaceAttributes.ON_ENABLE_ENFORCE); + FormData fdOn = new FormData(); + fdOn.left = new FormAttachment(middle, 0); + fdOn.top = new FormAttachment(wlOnEnable, 0, SWT.CENTER); + fdOn.right = new FormAttachment(100, 0); + wOnEnable.setLayoutData(fdOn); + wOnEnable.setToolTipText( + BaseMessages.getString(PKG, "MarketplaceLifecycleEnv.OnEnable.Tooltip")); + + wStrict = new Button(comp, SWT.CHECK); + PropsUi.setLook(wStrict); + wStrict.setText(BaseMessages.getString(PKG, "MarketplaceLifecycleEnv.Strict.Label")); + wStrict.setToolTipText(BaseMessages.getString(PKG, "MarketplaceLifecycleEnv.Strict.Tooltip")); + FormData fdStrict = new FormData(); + fdStrict.left = new FormAttachment(middle, 0); + fdStrict.top = new FormAttachment(wOnEnable, margin * 2); + wStrict.setLayoutData(fdStrict); + + wAutoApply = new Button(comp, SWT.CHECK); + PropsUi.setLook(wAutoApply); + wAutoApply.setText(BaseMessages.getString(PKG, "MarketplaceLifecycleEnv.AutoApply.Label")); + wAutoApply.setToolTipText( + BaseMessages.getString(PKG, "MarketplaceLifecycleEnv.AutoApply.Tooltip")); + FormData fdAuto = new FormData(); + fdAuto.left = new FormAttachment(middle, 0); + fdAuto.top = new FormAttachment(wStrict, margin); + wAutoApply.setLayoutData(fdAuto); + + extension.addLoadCallback(this::loadFromContext); + extension.addSaveCallback(this::saveToContext); + } + + private void loadFromContext(AttributesContext context) { + if (wEnvFile == null || wEnvFile.isDisposed()) { + return; + } + wEnvFile.setText(Const.NVL(MarketplaceAttributes.envFile(context), "")); + // Explicit attribute, or purpose-based default when unset (not written until save). + wOnEnable.setText(MarketplaceAttributes.resolveOnEnable(context, context.getPurpose())); + wStrict.setSelection(MarketplaceAttributes.isStrict(context)); + wAutoApply.setSelection(MarketplaceAttributes.isAutoApply(context)); + } + + private void saveToContext(AttributesContext context) { + if (wEnvFile == null || wEnvFile.isDisposed()) { + return; + } + String envFile = wEnvFile.getText(); + if (StringUtils.isBlank(envFile)) { + // clear key if empty + if (context.getAttributes(MarketplaceAttributes.GROUP) != null) { + context + .getAttributes(MarketplaceAttributes.GROUP) + .remove(MarketplaceAttributes.KEY_ENV_FILE); + } + } else { + context.setAttribute( + MarketplaceAttributes.GROUP, MarketplaceAttributes.KEY_ENV_FILE, envFile.trim()); + } + context.setAttribute( + MarketplaceAttributes.GROUP, + MarketplaceAttributes.KEY_ON_ENABLE, + Const.NVL(wOnEnable.getText(), MarketplaceAttributes.ON_ENABLE_OFF)); + context.setAttribute( + MarketplaceAttributes.GROUP, + MarketplaceAttributes.KEY_STRICT, + Boolean.toString(wStrict.getSelection())); + context.setAttribute( + MarketplaceAttributes.GROUP, + MarketplaceAttributes.KEY_AUTO_APPLY, + Boolean.toString(wAutoApply.getSelection())); + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/xp/ProjectEnvironmentAfterEnabledExtensionPoint.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/xp/ProjectEnvironmentAfterEnabledExtensionPoint.java new file mode 100644 index 00000000000..f12002b983b --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/xp/ProjectEnvironmentAfterEnabledExtensionPoint.java @@ -0,0 +1,209 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.xp; + +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashSet; +import java.util.Set; +import org.apache.commons.lang3.StringUtils; +import org.apache.hop.core.AttributesContext; +import org.apache.hop.core.Const; +import org.apache.hop.core.exception.HopException; +import org.apache.hop.core.extension.ExtensionPoint; +import org.apache.hop.core.extension.IExtensionPoint; +import org.apache.hop.core.logging.ILogChannel; +import org.apache.hop.core.variables.IVariables; +import org.apache.hop.marketplace.config.MarketplaceConfig; +import org.apache.hop.marketplace.env.EnvironmentApplier; +import org.apache.hop.marketplace.env.EnvironmentDrift; +import org.apache.hop.marketplace.env.HopEnvironmentLoader; +import org.apache.hop.marketplace.env.HopEnvironmentSpec; +import org.apache.hop.marketplace.env.MarketplaceAttributes; +import org.apache.hop.marketplace.install.HopHome; +import org.apache.hop.marketplace.install.PluginInstaller; +import org.apache.hop.ui.core.dialog.MessageBox; +import org.apache.hop.ui.hopgui.HopGui; +import org.eclipse.swt.SWT; + +/** + * When a project lifecycle environment is enabled, optionally validate (or apply) the marketplace + * hop-env file against the local install. Settings come from {@link AttributesContext} group {@link + * MarketplaceAttributes#GROUP} — no dependency on the Projects plugin classes. + */ +@ExtensionPoint( + id = "MarketplaceProjectEnvironmentAfterEnabled", + description = + "Validate hop-env against the local install when a lifecycle environment is enabled", + extensionPointId = "HopProjectEnvironmentAfterEnabled") +public class ProjectEnvironmentAfterEnabledExtensionPoint + implements IExtensionPoint { + + @Override + public void callExtensionPoint(ILogChannel log, IVariables variables, AttributesContext context) + throws HopException { + if (context == null) { + return; + } + + String onEnable = MarketplaceAttributes.resolveOnEnable(context, context.getPurpose()); + if (MarketplaceAttributes.ON_ENABLE_OFF.equals(onEnable)) { + log.logDetailed( + "Marketplace environment check skipped (onEnable=off) for environment '" + + Const.NVL(context.getEnvironmentName(), "") + + "'"); + return; + } + + Path hopHome; + try { + hopHome = HopHome.resolve(); + } catch (HopException e) { + log.logDetailed("Marketplace environment check skipped: Hop home not resolved"); + return; + } + + Path envFile = resolveEnvFile(context, variables, hopHome); + if (envFile == null) { + String msg = + "Marketplace environment file not found for environment '" + + Const.NVL(context.getEnvironmentName(), "") + + "'. Set marketplace attribute envFile or place hop-env.yaml under the project home."; + if (MarketplaceAttributes.ON_ENABLE_ENFORCE.equals(onEnable)) { + throw new HopException(msg); + } + log.logBasic(msg); + return; + } + + try { + MarketplaceConfig config = MarketplaceConfig.load(); + HopEnvironmentSpec env = HopEnvironmentLoader.load(envFile); + EnvironmentApplier applier = new EnvironmentApplier(log, hopHome, config); + EnvironmentDrift drift = applier.validate(env); + + if (MarketplaceAttributes.isStrict(context)) { + populateExtraPlugins(hopHome, env, drift); + } + + boolean hard = + !drift.getMissingPlugins().isEmpty() + || !drift.getVersionMismatches().isEmpty() + || !drift.getMissingDependencies().isEmpty() + || (MarketplaceAttributes.isStrict(context) + && !drift.getExtraMarketplacePlugins().isEmpty()); + + if (!hard) { + log.logBasic("Marketplace environment file " + envFile + " matches local install."); + return; + } + + String report = + "Environment drift for '" + + Const.NVL(context.getEnvironmentName(), "") + + "' against " + + envFile + + ":\n" + + drift.formatReport() + + "Run 'hop marketplace apply -f " + + envFile + + "' to fix your environment."; + + if (MarketplaceAttributes.isAutoApply(context) && config.isEnabled()) { + log.logBasic("Auto-applying marketplace environment file " + envFile); + applier.apply(env, false); + return; + } + + if (MarketplaceAttributes.ON_ENABLE_ENFORCE.equals(onEnable)) { + throw new HopException("FATAL: " + report); + } + + // warn + log.logError(report); + if ("GUI".equalsIgnoreCase(Const.getHopPlatformRuntime())) { + try { + MessageBox box = + new MessageBox(HopGui.getInstance().getShell(), SWT.OK | SWT.ICON_WARNING); + box.setText("Marketplace environment drift"); + box.setMessage(report); + box.open(); + } catch (Exception e) { + // headless or shell unavailable + } + } + } catch (HopException e) { + throw e; + } catch (Exception e) { + throw new HopException("Failed to validate marketplace environment file " + envFile, e); + } + } + + private static Path resolveEnvFile( + AttributesContext context, IVariables variables, Path hopHome) { + String explicit = MarketplaceAttributes.envFile(context); + if (StringUtils.isNotBlank(explicit)) { + String resolved = variables != null ? variables.resolve(explicit.trim()) : explicit.trim(); + Path path = Path.of(resolved).toAbsolutePath().normalize(); + if (Files.isRegularFile(path)) { + return path; + } + } + + // Project home hop-env.yaml + if (StringUtils.isNotBlank(context.getProjectHome())) { + Path candidate = Path.of(context.getProjectHome()).resolve("hop-env.yaml"); + if (Files.isRegularFile(candidate)) { + return candidate.toAbsolutePath().normalize(); + } + candidate = Path.of(context.getProjectHome()).resolve("hop-env.yml"); + if (Files.isRegularFile(candidate)) { + return candidate.toAbsolutePath().normalize(); + } + } + + String varFile = variables != null ? variables.getVariable("HOP_ENV_FILE") : null; + return EnvironmentApplier.resolveEnvironmentFile(hopHome, varFile); + } + + private static void populateExtraPlugins( + Path hopHome, HopEnvironmentSpec env, EnvironmentDrift drift) throws Exception { + Set desired = new HashSet<>(); + if (env.getPlugins() != null) { + for (HopEnvironmentSpec.PluginRef ref : env.getPlugins()) { + if (ref.getArtifactId() != null) { + desired.add(ref.getArtifactId()); + } + } + } + Path receipts = hopHome.resolve(PluginInstaller.RECEIPTS_DIR); + if (!Files.isDirectory(receipts)) { + return; + } + try (DirectoryStream stream = Files.newDirectoryStream(receipts, "*.json")) { + for (Path f : stream) { + String name = f.getFileName().toString(); + String id = name.substring(0, name.length() - ".json".length()); + if (!desired.contains(id)) { + drift.getExtraMarketplacePlugins().add(id); + } + } + } + } +} diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_de_DE.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_de_DE.properties new file mode 100644 index 00000000000..b10b9ee27b1 --- /dev/null +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_de_DE.properties @@ -0,0 +1,209 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +MarketplaceGuiPlugin.Menu.Marketplace.Text=Marketplace... +MarketplaceGuiPlugin.Toolbar.Marketplace.Tooltip=Marketplace… +MarketplaceLifecycleEnv.Tab.Plugins=Marketplace-Plugins +MarketplaceLifecycleEnv.Help=Der Plugin-Satz wird in einer hop-env-Datei definiert. Diese Optionen steuern, wann Hop diese Datei für diese Lifecycle-Umgebung prüft (in der Entwicklung locker; in Produktion streng). +MarketplaceLifecycleEnv.EnvFile.Label=Umgebungsdatei +MarketplaceLifecycleEnv.Button.Browse=Durchsuchen… +MarketplaceLifecycleEnv.Button.EditEnv=Bearbeiten… +MarketplaceLifecycleEnv.OnEnable.Label=Beim Aktivieren +MarketplaceLifecycleEnv.OnEnable.Tooltip=off: keine Prüfung; warn: Protokoll/Dialog bei Abweichung; enforce: Aktivierung bei Abweichung fehlschlagen lassen +MarketplaceLifecycleEnv.Strict.Label=Streng (fehlschlagen, wenn zusätzliche Marketplace-Plugins installiert sind) +MarketplaceLifecycleEnv.Strict.Tooltip=Beim Validieren auch Marketplace-Plugins mit Receipt, die nicht in der Env-Datei stehen, als Abweichung werten +MarketplaceLifecycleEnv.AutoApply.Label=Fehlende Plugins beim Aktivieren automatisch anwenden +MarketplaceLifecycleEnv.AutoApply.Tooltip=Wenn aktiviert, wird marketplace apply für fehlende Plugins ausgeführt (nur auf kontrollierten Systemen; standardmäßig aus) +MarketplaceDialog.Shell.Title=Plugin-Marketplace +MarketplaceDialog.Tab.Plugins=Plugins +MarketplaceDialog.Tab.Environment=Umgebung +MarketplaceDialog.Tab.Repositories=Repositories +MarketplaceDialog.Repository.Label=Primäres Repository +MarketplaceDialog.Repository.SetPrimary.Error=Primäres Repository konnte nicht gesetzt werden +MarketplaceDialog.Column.Name=Name +MarketplaceDialog.Column.Artifact=Artefakt +MarketplaceDialog.Column.Category=Kategorie +MarketplaceDialog.Column.Status=Status +MarketplaceDialog.Column.Description=Beschreibung +MarketplaceDialog.Search.Label=Suche +MarketplaceDialog.Search.Placeholder=Mindestens 3 Zeichen zum Filtern… +MarketplaceDialog.Search.Clear=Suchfilter löschen +MarketplaceDialog.Button.Install=Installieren +MarketplaceDialog.Button.Uninstall=Deinstallieren +MarketplaceDialog.Button.Refresh=Aktualisieren +MarketplaceDialog.Button.Close=Schließen +MarketplaceDialog.Button.ManageRepos=Verwalten… +MarketplaceDialog.Button.BrowseEnv=Durchsuchen… +MarketplaceDialog.Button.EditEnv=Bearbeiten… +MarketplaceDialog.Button.EditEnv.Tooltip=Umgebungsdatei erstellen oder bearbeiten (Repositories, Plugins, Abhängigkeiten) +MarketplaceDialog.Button.ValidateEnv=Validieren +MarketplaceDialog.Button.ValidateEnv.Tooltip=Lokale Installation mit der Umgebungsdatei vergleichen, ohne zu installieren +MarketplaceDialog.Button.ApplyEnv=Anwenden +MarketplaceDialog.Button.ApplyEnv.Tooltip=In der Umgebungsdatei deklarierte Plugins und Abhängigkeiten installieren +MarketplaceDialog.EnvFile.Label=Umgebungsdatei +MarketplaceDialog.EnvFile.Prune=Extras beim Anwenden entfernen +MarketplaceDialog.EnvFile.Prune.Tooltip=Beim Anwenden Marketplace-Plugins mit Receipt deinstallieren, die nicht in der Datei stehen +MarketplaceDialog.EnvFile.Strict=Strenge Validierung +MarketplaceDialog.EnvFile.Strict.Tooltip=Beim Validieren auch fehlschlagen, wenn zusätzliche Marketplace-Plugins jenseits der Datei installiert sind +MarketplaceDialog.EnvFile.Filter.Env=Hop-Umgebungsdateien (*.yaml, *.yml, *.json) +MarketplaceDialog.EnvFile.Filter.All=Alle Dateien +MarketplaceDialog.EnvFile.Missing.Header=Umgebungsdatei erforderlich +MarketplaceDialog.EnvFile.Missing.Message=Wählen Sie eine hop-env.yaml (oder full-client-env.yaml) mit Durchsuchen… oder geben Sie den Pfad ein. +MarketplaceDialog.EnvFile.NotFound.Header=Datei nicht gefunden +MarketplaceDialog.EnvFile.NotFound.Message=Umgebungsdatei existiert nicht:\n{0} +MarketplaceDialog.Status.Installed=Installiert +MarketplaceDialog.Status.Present=Auf Datenträger vorhanden +MarketplaceDialog.Status.NotInstalled=Nicht installiert +MarketplaceDialog.Status.RestartHint=Starten Sie Hop nach Installation, Anwendung oder Deinstallation neu, damit Plugins neu geladen werden. Die Installation versucht zuerst das primäre Repository, dann andere aktivierte Repositories. +MarketplaceDialog.Status.Installing=Installiere {0}... +MarketplaceDialog.Status.Validating=Umgebungsdatei wird validiert... +MarketplaceDialog.Status.Applying=Umgebungsdatei wird angewendet... +MarketplaceDialog.Status.Drift=Umgebungsabweichung erkannt — mit Anwenden beheben +MarketplaceDialog.Error.Header=Marketplace-Fehler +MarketplaceDialog.Error.ResolveHome=Hop-Installationsverzeichnis konnte nicht ermittelt werden. Starten Sie Hop vom Installationsroot mit dem Hop-Launcher. +MarketplaceDialog.Install.Done.Header=Plugin installiert +MarketplaceDialog.Install.Done.Message=Installiert: {0}.\n\nBitte starten Sie Hop neu, um das Plugin zu laden. +MarketplaceDialog.Install.Error=Installation von {0} fehlgeschlagen +MarketplaceDialog.Uninstall.Confirm.Header=Plugin deinstallieren +MarketplaceDialog.Uninstall.Confirm.Message=Über den Marketplace installiertes Plugin {0} entfernen? +MarketplaceDialog.Uninstall.NoReceipt.Header=Deinstallation nicht möglich +MarketplaceDialog.Uninstall.NoReceipt.Message=Kein Marketplace-Installationsbeleg für {0}. Hier können nur über den Marketplace installierte Plugins deinstalliert werden. +MarketplaceDialog.Uninstall.Error=Deinstallation von {0} fehlgeschlagen +MarketplaceDialog.Validate.Ok.Header=Umgebung OK +MarketplaceDialog.Validate.Ok.Message=Lokale Installation stimmt überein:\n{0} +MarketplaceDialog.Validate.Drift.Header=Umgebungsabweichung +MarketplaceDialog.Validate.Drift.Message=Die lokale Installation stimmt nicht mit der Umgebungsdatei überein: +MarketplaceDialog.Validate.Drift.Hint=Verwenden Sie Anwenden, um fehlende Plugins zu installieren (oder Versionen zu korrigieren), und starten Sie Hop neu. +MarketplaceDialog.Validate.Error=Validierung der Umgebungsdatei fehlgeschlagen +MarketplaceDialog.Apply.PruneConfirm.Header=Marketplace-Plugins bereinigen? +MarketplaceDialog.Apply.PruneConfirm.Message=Anwenden mit Bereinigung deinstalliert Marketplace-Plugins, die nicht in der Umgebungsdatei stehen.\n\nFortfahren? +MarketplaceDialog.Apply.Disabled=Marketplace ist in hop-config.json deaktiviert. +MarketplaceDialog.Apply.Done.Header=Umgebung angewendet +MarketplaceDialog.Apply.Done.Message=Angewendet:\n{0}\n\nBitte starten Sie Hop neu, damit neue Plugins geladen werden. +MarketplaceDialog.Apply.Error=Anwenden der Umgebungsdatei fehlgeschlagen +ManageRepositoriesDialog.Shell.Title=Marketplace-Repositories +ManageRepositoriesDialog.Help=Das primäre Repository wird zuerst versucht. Die anderen aktivierten Repositories sind Fallbacks.\nStandard: Apache Repository (repository.apache.org), dann Maven Central.\nEinstellungen werden in hop-config.json unter '${HOP_CONFIG_FOLDER}' gespeichert. +ManageRepositoriesDialog.Column.Primary=Primär +ManageRepositoriesDialog.Column.Enabled=Aktiviert +ManageRepositoriesDialog.Column.Id=Id +ManageRepositoriesDialog.Column.Name=Name +ManageRepositoriesDialog.Column.Url=URL +ManageRepositoriesDialog.Column.Auth=Auth +ManageRepositoriesDialog.Button.Add=Hinzufügen +ManageRepositoriesDialog.Button.Edit=Bearbeiten +ManageRepositoriesDialog.Button.Remove=Entfernen +ManageRepositoriesDialog.Button.SetPrimary=Als primär setzen +ManageRepositoriesDialog.Button.MoveUp=Hoch +ManageRepositoriesDialog.Button.MoveDown=Runter +ManageRepositoriesDialog.Button.ResetDefaults=Standards zurücksetzen +ManageRepositoriesDialog.Button.Save=Speichern +ManageRepositoriesDialog.Button.Cancel=Abbrechen +ManageRepositoriesDialog.Button.Ok=OK +ManageRepositoriesDialog.Save.Done.Header=Repositories gespeichert +ManageRepositoriesDialog.Save.Done.Message=Marketplace-Repository-Einstellungen wurden in hop-config.json gespeichert. +ManageRepositoriesDialog.Error.Header=Repository-Fehler +ManageRepositoriesDialog.Error.Save=Marketplace-Konfiguration konnte nicht gespeichert werden +ManageRepositoriesDialog.Reset.Header=Repositories zurücksetzen +ManageRepositoriesDialog.Reset.Message=Repository-Liste durch Apache Repository (primär) und Maven Central ersetzen? +ManageRepositoriesDialog.Edit.Title.Add=Repository hinzufügen +ManageRepositoriesDialog.Edit.Title.Edit=Repository bearbeiten +ManageRepositoriesDialog.Edit.Id=ID +ManageRepositoriesDialog.Edit.Name=Name +ManageRepositoriesDialog.Edit.Url=URL +ManageRepositoriesDialog.Edit.Username=Benutzername +ManageRepositoriesDialog.Edit.Password=Passwort +ManageRepositoriesDialog.Edit.Enabled=Aktiviert (in Fallback-Kette verwenden) +ManageRepositoriesDialog.Edit.Primary=Primär (zuerst versucht) +ManageRepositoriesDialog.Edit.IdUrlRequired=Id und URL sind erforderlich. +HopEnvironmentDialog.Shell.Title=Marketplace-Umgebung — {0} +HopEnvironmentDialog.Untitled=Unbenannt +HopEnvironmentDialog.Button.New=Neu +HopEnvironmentDialog.Button.Open=Öffnen… +HopEnvironmentDialog.Button.Save=Speichern +HopEnvironmentDialog.Button.SaveAs=Speichern unter… +HopEnvironmentDialog.Button.Validate=Validieren +HopEnvironmentDialog.Button.Validate.Tooltip=Lokale Installation mit dieser Umgebungsdatei vergleichen, ohne zu installieren +HopEnvironmentDialog.Button.Apply=Anwenden +HopEnvironmentDialog.Button.Apply.Tooltip=In dieser Umgebungsdatei deklarierte Plugins und Abhängigkeiten installieren +HopEnvironmentDialog.Button.Close=Schließen +HopEnvironmentDialog.Button.Ok=OK +HopEnvironmentDialog.Button.Cancel=Abbrechen +HopEnvironmentDialog.Button.Add=Hinzufügen +HopEnvironmentDialog.Button.Edit=Bearbeiten +HopEnvironmentDialog.Button.Remove=Entfernen +HopEnvironmentDialog.Button.MoveUp=Hoch +HopEnvironmentDialog.Button.MoveDown=Runter +HopEnvironmentDialog.Button.AddFromCatalog=Aus Katalog… +HopEnvironmentDialog.Button.ImportRepos=Aus hop-config importieren… +HopEnvironmentDialog.Prune=Extras beim Anwenden entfernen +HopEnvironmentDialog.Prune.Tooltip=Beim Anwenden Marketplace-Plugins mit Receipt deinstallieren, die nicht in der Datei stehen +HopEnvironmentDialog.Strict=Strenge Validierung +HopEnvironmentDialog.Strict.Tooltip=Beim Validieren auch fehlschlagen, wenn zusätzliche Marketplace-Plugins jenseits der Datei installiert sind +HopEnvironmentDialog.Filter.Yaml=YAML-Umgebung (*.yaml, *.yml) +HopEnvironmentDialog.Filter.Json=JSON-Umgebung (*.json) +HopEnvironmentDialog.Tab.General=Allgemein +HopEnvironmentDialog.Tab.Repositories=Repositories +HopEnvironmentDialog.Tab.Plugins=Plugins +HopEnvironmentDialog.Tab.Dependencies=Abhängigkeiten +HopEnvironmentDialog.General.Help=Legen Sie fest, welche Plugins und JARs diese Hop-Installation haben soll. Speichern Sie als hop-env.yaml für CI/Docker oder nutzen Sie Validieren / Anwenden in diesem Dialog. +HopEnvironmentDialog.General.Version=Spec-Version +HopEnvironmentDialog.General.HopVersion=Hop-Version +HopEnvironmentDialog.General.EnforceOnRun=Bei hop-run erzwingen +HopEnvironmentDialog.General.EnforceOnRun.Tooltip=Wenn true, kann hop-run fehlschlagen, wenn die Installation von dieser Datei abweicht (auch gesteuert durch -Dhop.env.enforce=true) +HopEnvironmentDialog.Repositories.Help=Die erste Zeile ist primär (zuerst versucht); spätere Zeilen sind Fallbacks. Diese Repositories liegen in der Umgebungsdatei (nicht hop-config). Passwörter möglichst nicht committen. +HopEnvironmentDialog.Plugins.Help=Zu installierende Marketplace-Plugins. Group ID leer lassen für org.apache.hop. Version kann beim Anwenden von der Hop-Version auf der Registerkarte Allgemein kommen. +HopEnvironmentDialog.Dependencies.Help=Optionale Maven-JARs (z. B. JDBC-Treiber), installiert unter dem Zielverzeichnis der Hop-Home (Standard lib/jdbc). +HopEnvironmentDialog.Repo.Column.Id=Id +HopEnvironmentDialog.Repo.Column.Url=URL +HopEnvironmentDialog.Repo.Column.Username=Benutzername +HopEnvironmentDialog.Repo.Column.Password=Passwort +HopEnvironmentDialog.Repo.Column.Auth=Auth +HopEnvironmentDialog.Repo.Edit.Add=Repository hinzufügen +HopEnvironmentDialog.Repo.Edit.Edit=Repository bearbeiten +HopEnvironmentDialog.Plugin.Column.GroupId=Group ID +HopEnvironmentDialog.Plugin.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Plugin.Column.Version=Version +HopEnvironmentDialog.Plugin.Edit.Add=Plugin hinzufügen +HopEnvironmentDialog.Plugin.Edit.Edit=Plugin bearbeiten +HopEnvironmentDialog.Dep.Column.GroupId=Group ID +HopEnvironmentDialog.Dep.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Dep.Column.Version=Version +HopEnvironmentDialog.Dep.Column.Target=Ziel +HopEnvironmentDialog.Dep.Edit.Add=Abhängigkeit hinzufügen +HopEnvironmentDialog.Dep.Edit.Edit=Abhängigkeit bearbeiten +HopEnvironmentDialog.Dirty.Header=Ungespeicherte Änderungen +HopEnvironmentDialog.Dirty.Message=Änderungen an der Umgebungsdatei vor dem Fortfahren speichern? +HopEnvironmentDialog.SaveFirst.Header=Umgebungsdatei speichern? +HopEnvironmentDialog.SaveFirst.Message=Umgebungsdatei vor Validieren oder Anwenden speichern? +HopEnvironmentDialog.Validation.Header=Ungültige Umgebung +HopEnvironmentDialog.Validation.RepoIdUrl=Jedes Repository benötigt eine Id und URL. +HopEnvironmentDialog.Validation.PluginArtifact=Jedes Plugin benötigt eine Artifact ID. +HopEnvironmentDialog.Validation.DepGav=Jede Abhängigkeit benötigt Group ID, Artifact ID und Version. +HopEnvironmentDialog.ImportRepos.Header=Repositories importieren +HopEnvironmentDialog.ImportRepos.Message=Repository-Liste durch aktivierte Repositories aus hop-config.json ersetzen? +HopEnvironmentDialog.Error.Header=Fehler im Umgebungeneditor +HopEnvironmentDialog.Error.Load=Umgebungsdatei konnte nicht geladen werden:\n{0} +HopEnvironmentDialog.Error.Save=Umgebungsdatei konnte nicht gespeichert werden:\n{0} +HopEnvironmentDialog.Error.ImportRepos=Repositories konnten nicht aus hop-config importiert werden +AddPluginsFromCatalogDialog.Shell.Title=Plugins aus Katalog hinzufügen +AddPluginsFromCatalogDialog.Filter.Label=Filter +AddPluginsFromCatalogDialog.Button.Add=Auswahl hinzufügen +AddPluginsFromCatalogDialog.Button.Cancel=Abbrechen +AddPluginsFromCatalogDialog.Column.Name=Name +AddPluginsFromCatalogDialog.Column.Artifact=Artefakt +AddPluginsFromCatalogDialog.Column.Category=Kategorie +AddPluginsFromCatalogDialog.Column.Description=Beschreibung diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties index 941edcb677d..612232d7daf 100644 --- a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties @@ -16,8 +16,24 @@ # MarketplaceGuiPlugin.Menu.Marketplace.Text=Marketplace... +MarketplaceGuiPlugin.Toolbar.Marketplace.Tooltip=Marketplace… + +MarketplaceLifecycleEnv.Tab.Plugins=Marketplace plugins +MarketplaceLifecycleEnv.Help=Plugin set is defined in a hop-env file. These options control when Hop checks that file for this lifecycle environment (dev can stay loose; production can enforce). +MarketplaceLifecycleEnv.EnvFile.Label=Environment file +MarketplaceLifecycleEnv.Button.Browse=Browse… +MarketplaceLifecycleEnv.Button.EditEnv=Edit… +MarketplaceLifecycleEnv.OnEnable.Label=On enable +MarketplaceLifecycleEnv.OnEnable.Tooltip=off: no check; warn: log/dialog on drift; enforce: fail enabling the environment on drift +MarketplaceLifecycleEnv.Strict.Label=Strict (fail if extra marketplace plugins installed) +MarketplaceLifecycleEnv.Strict.Tooltip=When validating, also treat marketplace plugins with receipts that are not listed in the env file as drift +MarketplaceLifecycleEnv.AutoApply.Label=Auto-apply missing plugins on enable +MarketplaceLifecycleEnv.AutoApply.Tooltip=When enabled, run marketplace apply for missing plugins (use only on controlled machines; default off) MarketplaceDialog.Shell.Title=Plugin Marketplace +MarketplaceDialog.Tab.Plugins=Plugins +MarketplaceDialog.Tab.Environment=Environment +MarketplaceDialog.Tab.Repositories=Repositories MarketplaceDialog.Repository.Label=Primary repository MarketplaceDialog.Repository.SetPrimary.Error=Could not set primary repository MarketplaceDialog.Column.Name=Name @@ -25,12 +41,17 @@ MarketplaceDialog.Column.Artifact=Artifact MarketplaceDialog.Column.Category=Category MarketplaceDialog.Column.Status=Status MarketplaceDialog.Column.Description=Description +MarketplaceDialog.Search.Label=Search +MarketplaceDialog.Search.Placeholder=Type 3+ characters to filter plugins… +MarketplaceDialog.Search.Clear=Clear search filter MarketplaceDialog.Button.Install=Install MarketplaceDialog.Button.Uninstall=Uninstall MarketplaceDialog.Button.Refresh=Refresh MarketplaceDialog.Button.Close=Close MarketplaceDialog.Button.ManageRepos=Manage… MarketplaceDialog.Button.BrowseEnv=Browse… +MarketplaceDialog.Button.EditEnv=Edit… +MarketplaceDialog.Button.EditEnv.Tooltip=Create or edit the environment file (repositories, plugins, dependencies) MarketplaceDialog.Button.ValidateEnv=Validate MarketplaceDialog.Button.ValidateEnv.Tooltip=Check the local install against the environment file without installing MarketplaceDialog.Button.ApplyEnv=Apply @@ -78,7 +99,7 @@ MarketplaceDialog.Apply.Done.Message=Applied:\n{0}\n\nPlease restart Hop so new MarketplaceDialog.Apply.Error=Failed to apply the environment file ManageRepositoriesDialog.Shell.Title=Marketplace repositories -ManageRepositoriesDialog.Help=Primary repository is tried first; other enabled repositories are fallbacks. Defaults: Apache Repository (repository.apache.org) then Maven Central. Settings are saved to hop-config.json under HOP_CONFIG_FOLDER. +ManageRepositoriesDialog.Help=The primary repository is tried first. The other enabled repositories are fallbacks. \nDefaults: Apache Repository (repository.apache.org) then Maven Central. \nSettings are saved to hop-config.json under '${HOP_CONFIG_FOLDER}'. ManageRepositoriesDialog.Column.Primary=Primary ManageRepositoriesDialog.Column.Enabled=Enabled ManageRepositoriesDialog.Column.Id=Id @@ -95,13 +116,15 @@ ManageRepositoriesDialog.Button.ResetDefaults=Reset defaults ManageRepositoriesDialog.Button.Save=Save ManageRepositoriesDialog.Button.Cancel=Cancel ManageRepositoriesDialog.Button.Ok=OK +ManageRepositoriesDialog.Save.Done.Header=Repositories saved +ManageRepositoriesDialog.Save.Done.Message=Marketplace repository settings were saved to hop-config.json. ManageRepositoriesDialog.Error.Header=Repository error ManageRepositoriesDialog.Error.Save=Could not save marketplace configuration ManageRepositoriesDialog.Reset.Header=Reset repositories ManageRepositoriesDialog.Reset.Message=Replace the repository list with Apache Repository (primary) and Maven Central? ManageRepositoriesDialog.Edit.Title.Add=Add repository ManageRepositoriesDialog.Edit.Title.Edit=Edit repository -ManageRepositoriesDialog.Edit.Id=Id +ManageRepositoriesDialog.Edit.Id=ID ManageRepositoriesDialog.Edit.Name=Name ManageRepositoriesDialog.Edit.Url=URL ManageRepositoriesDialog.Edit.Username=Username @@ -109,3 +132,83 @@ ManageRepositoriesDialog.Edit.Password=Password ManageRepositoriesDialog.Edit.Enabled=Enabled (use in fallback chain) ManageRepositoriesDialog.Edit.Primary=Primary (tried first) ManageRepositoriesDialog.Edit.IdUrlRequired=Id and URL are required. + +HopEnvironmentDialog.Shell.Title=Marketplace environment — {0} +HopEnvironmentDialog.Untitled=Untitled +HopEnvironmentDialog.Button.New=New +HopEnvironmentDialog.Button.Open=Open… +HopEnvironmentDialog.Button.Save=Save +HopEnvironmentDialog.Button.SaveAs=Save As… +HopEnvironmentDialog.Button.Validate=Validate +HopEnvironmentDialog.Button.Validate.Tooltip=Check the local install against this environment file without installing +HopEnvironmentDialog.Button.Apply=Apply +HopEnvironmentDialog.Button.Apply.Tooltip=Install plugins and dependencies declared in this environment file +HopEnvironmentDialog.Button.Close=Close +HopEnvironmentDialog.Button.Ok=OK +HopEnvironmentDialog.Button.Cancel=Cancel +HopEnvironmentDialog.Button.Add=Add +HopEnvironmentDialog.Button.Edit=Edit +HopEnvironmentDialog.Button.Remove=Remove +HopEnvironmentDialog.Button.MoveUp=Up +HopEnvironmentDialog.Button.MoveDown=Down +HopEnvironmentDialog.Button.AddFromCatalog=From catalog… +HopEnvironmentDialog.Button.ImportRepos=Import from hop-config… +HopEnvironmentDialog.Prune=Prune extras on apply +HopEnvironmentDialog.Prune.Tooltip=When applying, uninstall marketplace plugins that have a receipt but are not listed in the file +HopEnvironmentDialog.Strict=Strict validate +HopEnvironmentDialog.Strict.Tooltip=When validating, also fail if extra marketplace plugins are installed beyond the file +HopEnvironmentDialog.Filter.Yaml=YAML environment (*.yaml, *.yml) +HopEnvironmentDialog.Filter.Json=JSON environment (*.json) +HopEnvironmentDialog.Tab.General=General +HopEnvironmentDialog.Tab.Repositories=Repositories +HopEnvironmentDialog.Tab.Plugins=Plugins +HopEnvironmentDialog.Tab.Dependencies=Dependencies +HopEnvironmentDialog.General.Help=Declare which plugins and jars this Hop install should have. Save as hop-env.yaml for CI/Docker, or use Validate / Apply from this dialog. +HopEnvironmentDialog.General.Version=Spec version +HopEnvironmentDialog.General.HopVersion=Hop version +HopEnvironmentDialog.General.EnforceOnRun=Enforce on hop-run +HopEnvironmentDialog.General.EnforceOnRun.Tooltip=When true, hop-run can fail if the install drifts from this file (also controlled by -Dhop.env.enforce=true) +HopEnvironmentDialog.Repositories.Help=First row is primary (tried first); later rows are fallbacks. These repositories live in the environment file (not hop-config). Prefer not to commit passwords. +HopEnvironmentDialog.Plugins.Help=Marketplace plugins to install. Leave Group ID blank to use org.apache.hop. Version can default from Hop version on the General tab when applying. +HopEnvironmentDialog.Dependencies.Help=Optional Maven jars (for example JDBC drivers) installed under the Hop home target directory (default lib/jdbc). +HopEnvironmentDialog.Repo.Column.Id=Id +HopEnvironmentDialog.Repo.Column.Url=URL +HopEnvironmentDialog.Repo.Column.Username=Username +HopEnvironmentDialog.Repo.Column.Password=Password +HopEnvironmentDialog.Repo.Column.Auth=Auth +HopEnvironmentDialog.Repo.Edit.Add=Add repository +HopEnvironmentDialog.Repo.Edit.Edit=Edit repository +HopEnvironmentDialog.Plugin.Column.GroupId=Group ID +HopEnvironmentDialog.Plugin.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Plugin.Column.Version=Version +HopEnvironmentDialog.Plugin.Edit.Add=Add plugin +HopEnvironmentDialog.Plugin.Edit.Edit=Edit plugin +HopEnvironmentDialog.Dep.Column.GroupId=Group ID +HopEnvironmentDialog.Dep.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Dep.Column.Version=Version +HopEnvironmentDialog.Dep.Column.Target=Target +HopEnvironmentDialog.Dep.Edit.Add=Add dependency +HopEnvironmentDialog.Dep.Edit.Edit=Edit dependency +HopEnvironmentDialog.Dirty.Header=Unsaved changes +HopEnvironmentDialog.Dirty.Message=Save changes to the environment file before continuing? +HopEnvironmentDialog.SaveFirst.Header=Save environment file? +HopEnvironmentDialog.SaveFirst.Message=Save the environment file before Validate or Apply? +HopEnvironmentDialog.Validation.Header=Invalid environment +HopEnvironmentDialog.Validation.RepoIdUrl=Each repository needs an Id and URL. +HopEnvironmentDialog.Validation.PluginArtifact=Each plugin needs an Artifact ID. +HopEnvironmentDialog.Validation.DepGav=Each dependency needs Group ID, Artifact ID, and Version. +HopEnvironmentDialog.ImportRepos.Header=Import repositories +HopEnvironmentDialog.ImportRepos.Message=Replace the repository list with enabled repositories from hop-config.json? +HopEnvironmentDialog.Error.Header=Environment editor error +HopEnvironmentDialog.Error.Load=Could not load environment file:\n{0} +HopEnvironmentDialog.Error.Save=Could not save environment file:\n{0} +HopEnvironmentDialog.Error.ImportRepos=Could not import repositories from hop-config + +AddPluginsFromCatalogDialog.Shell.Title=Add plugins from catalog +AddPluginsFromCatalogDialog.Filter.Label=Filter +AddPluginsFromCatalogDialog.Button.Add=Add selected +AddPluginsFromCatalogDialog.Button.Cancel=Cancel +AddPluginsFromCatalogDialog.Column.Name=Name +AddPluginsFromCatalogDialog.Column.Artifact=Artifact +AddPluginsFromCatalogDialog.Column.Category=Category +AddPluginsFromCatalogDialog.Column.Description=Description diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_es_AR.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_es_AR.properties new file mode 100644 index 00000000000..2035e764fd5 --- /dev/null +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_es_AR.properties @@ -0,0 +1,209 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +MarketplaceGuiPlugin.Menu.Marketplace.Text=Marketplace... +MarketplaceGuiPlugin.Toolbar.Marketplace.Tooltip=Marketplace… +MarketplaceLifecycleEnv.Tab.Plugins=Plugins de Marketplace +MarketplaceLifecycleEnv.Help=El conjunto de plugins se define en un archivo hop-env. Estas opciones controlan cuándo Hop verifica ese archivo para este entorno de ciclo de vida (desarrollo flexible; producción estricta). +MarketplaceLifecycleEnv.EnvFile.Label=Archivo de entorno +MarketplaceLifecycleEnv.Button.Browse=Examinar… +MarketplaceLifecycleEnv.Button.EditEnv=Editar… +MarketplaceLifecycleEnv.OnEnable.Label=Al habilitar +MarketplaceLifecycleEnv.OnEnable.Tooltip=off: sin comprobación; warn: registro/diálogo si hay divergencia; enforce: fallar al habilitar el entorno si hay divergencia +MarketplaceLifecycleEnv.Strict.Label=Estricto (fallar si hay plugins de marketplace extra instalados) +MarketplaceLifecycleEnv.Strict.Tooltip=Al validar, tratar también como divergencia los plugins de marketplace con recibo que no estén en el archivo de entorno +MarketplaceLifecycleEnv.AutoApply.Label=Aplicar automáticamente plugins faltantes al habilitar +MarketplaceLifecycleEnv.AutoApply.Tooltip=Si está habilitado, ejecuta marketplace apply para plugins faltantes (solo en máquinas controladas; desactivado por defecto) +MarketplaceDialog.Shell.Title=Marketplace de plugins +MarketplaceDialog.Tab.Plugins=Plugins +MarketplaceDialog.Tab.Environment=Entorno +MarketplaceDialog.Tab.Repositories=Repositorios +MarketplaceDialog.Repository.Label=Repositorio principal +MarketplaceDialog.Repository.SetPrimary.Error=No se pudo establecer el repositorio principal +MarketplaceDialog.Column.Name=Nombre +MarketplaceDialog.Column.Artifact=Artefacto +MarketplaceDialog.Column.Category=Categoría +MarketplaceDialog.Column.Status=Estado +MarketplaceDialog.Column.Description=Descripción +MarketplaceDialog.Search.Label=Buscar +MarketplaceDialog.Search.Placeholder=Escriba 3+ caracteres para filtrar plugins… +MarketplaceDialog.Search.Clear=Borrar filtro de búsqueda +MarketplaceDialog.Button.Install=Instalar +MarketplaceDialog.Button.Uninstall=Desinstalar +MarketplaceDialog.Button.Refresh=Actualizar +MarketplaceDialog.Button.Close=Cerrar +MarketplaceDialog.Button.ManageRepos=Administrar… +MarketplaceDialog.Button.BrowseEnv=Examinar… +MarketplaceDialog.Button.EditEnv=Editar… +MarketplaceDialog.Button.EditEnv.Tooltip=Crear o editar el archivo de entorno (repositorios, plugins, dependencias) +MarketplaceDialog.Button.ValidateEnv=Validar +MarketplaceDialog.Button.ValidateEnv.Tooltip=Comprobar la instalación local con el archivo de entorno sin instalar +MarketplaceDialog.Button.ApplyEnv=Aplicar +MarketplaceDialog.Button.ApplyEnv.Tooltip=Instalar plugins y dependencias declarados en el archivo de entorno +MarketplaceDialog.EnvFile.Label=Archivo de entorno +MarketplaceDialog.EnvFile.Prune=Eliminar extras al aplicar +MarketplaceDialog.EnvFile.Prune.Tooltip=Al aplicar, desinstalar plugins de marketplace con recibo que no estén en el archivo +MarketplaceDialog.EnvFile.Strict=Validación estricta +MarketplaceDialog.EnvFile.Strict.Tooltip=Al validar, fallar también si hay plugins de marketplace instalados más allá del archivo +MarketplaceDialog.EnvFile.Filter.Env=Archivos de entorno Hop (*.yaml, *.yml, *.json) +MarketplaceDialog.EnvFile.Filter.All=Todos los archivos +MarketplaceDialog.EnvFile.Missing.Header=Archivo de entorno requerido +MarketplaceDialog.EnvFile.Missing.Message=Seleccione un hop-env.yaml (o full-client-env.yaml) con Examinar…, o escriba la ruta. +MarketplaceDialog.EnvFile.NotFound.Header=Archivo no encontrado +MarketplaceDialog.EnvFile.NotFound.Message=El archivo de entorno no existe:\n{0} +MarketplaceDialog.Status.Installed=Instalado +MarketplaceDialog.Status.Present=Presente en disco +MarketplaceDialog.Status.NotInstalled=No instalado +MarketplaceDialog.Status.RestartHint=Reinicie Hop tras instalar, aplicar o desinstalar para recargar los plugins. La instalación prueba el repositorio principal y luego otros repositorios habilitados. +MarketplaceDialog.Status.Installing=Instalando {0}... +MarketplaceDialog.Status.Validating=Validando archivo de entorno... +MarketplaceDialog.Status.Applying=Aplicando archivo de entorno... +MarketplaceDialog.Status.Drift=Divergencia de entorno detectada — use Aplicar para corregir +MarketplaceDialog.Error.Header=Error de Marketplace +MarketplaceDialog.Error.ResolveHome=No se pudo determinar el directorio de instalación de Hop. Inicie Hop desde la raíz de instalación con el lanzador de Hop. +MarketplaceDialog.Install.Done.Header=Plugin instalado +MarketplaceDialog.Install.Done.Message=Instalado {0}.\n\nReinicie Hop para cargar el plugin. +MarketplaceDialog.Install.Error=Error al instalar {0} +MarketplaceDialog.Uninstall.Confirm.Header=Desinstalar plugin +MarketplaceDialog.Uninstall.Confirm.Message=¿Quitar el plugin instalado por marketplace {0}? +MarketplaceDialog.Uninstall.NoReceipt.Header=No se puede desinstalar +MarketplaceDialog.Uninstall.NoReceipt.Message=No hay recibo de instalación de marketplace para {0}. Solo se pueden desinstalar aquí plugins instalados vía marketplace. +MarketplaceDialog.Uninstall.Error=Error al desinstalar {0} +MarketplaceDialog.Validate.Ok.Header=Entorno correcto +MarketplaceDialog.Validate.Ok.Message=La instalación local coincide:\n{0} +MarketplaceDialog.Validate.Drift.Header=Divergencia de entorno +MarketplaceDialog.Validate.Drift.Message=La instalación local no coincide con el archivo de entorno: +MarketplaceDialog.Validate.Drift.Hint=Use Aplicar para instalar plugins faltantes (o corregir versiones) y reinicie Hop. +MarketplaceDialog.Validate.Error=Error al validar el archivo de entorno +MarketplaceDialog.Apply.PruneConfirm.Header=¿Podar plugins de marketplace? +MarketplaceDialog.Apply.PruneConfirm.Message=Aplicar con poda desinstalará plugins de marketplace que no estén en el archivo de entorno.\n\n¿Continuar? +MarketplaceDialog.Apply.Disabled=Marketplace está deshabilitado en hop-config.json. +MarketplaceDialog.Apply.Done.Header=Entorno aplicado +MarketplaceDialog.Apply.Done.Message=Aplicado:\n{0}\n\nReinicie Hop para cargar los nuevos plugins. +MarketplaceDialog.Apply.Error=Error al aplicar el archivo de entorno +ManageRepositoriesDialog.Shell.Title=Repositorios de Marketplace +ManageRepositoriesDialog.Help=El repositorio principal se prueba primero. Los demás repositorios habilitados son de respaldo.\nPredeterminados: Apache Repository (repository.apache.org) y luego Maven Central.\nLa configuración se guarda en hop-config.json bajo '${HOP_CONFIG_FOLDER}'. +ManageRepositoriesDialog.Column.Primary=Principal +ManageRepositoriesDialog.Column.Enabled=Habilitado +ManageRepositoriesDialog.Column.Id=Id +ManageRepositoriesDialog.Column.Name=Nombre +ManageRepositoriesDialog.Column.Url=URL +ManageRepositoriesDialog.Column.Auth=Auth +ManageRepositoriesDialog.Button.Add=Agregar +ManageRepositoriesDialog.Button.Edit=Editar +ManageRepositoriesDialog.Button.Remove=Quitar +ManageRepositoriesDialog.Button.SetPrimary=Establecer principal +ManageRepositoriesDialog.Button.MoveUp=Arriba +ManageRepositoriesDialog.Button.MoveDown=Abajo +ManageRepositoriesDialog.Button.ResetDefaults=Restablecer valores predeterminados +ManageRepositoriesDialog.Button.Save=Guardar +ManageRepositoriesDialog.Button.Cancel=Cancelar +ManageRepositoriesDialog.Button.Ok=Aceptar +ManageRepositoriesDialog.Save.Done.Header=Repositorios guardados +ManageRepositoriesDialog.Save.Done.Message=La configuración de repositorios de Marketplace se guardó en hop-config.json. +ManageRepositoriesDialog.Error.Header=Error de repositorio +ManageRepositoriesDialog.Error.Save=No se pudo guardar la configuración de Marketplace +ManageRepositoriesDialog.Reset.Header=Restablecer repositorios +ManageRepositoriesDialog.Reset.Message=¿Reemplazar la lista de repositorios por Apache Repository (principal) y Maven Central? +ManageRepositoriesDialog.Edit.Title.Add=Agregar repositorio +ManageRepositoriesDialog.Edit.Title.Edit=Editar repositorio +ManageRepositoriesDialog.Edit.Id=ID +ManageRepositoriesDialog.Edit.Name=Nombre +ManageRepositoriesDialog.Edit.Url=URL +ManageRepositoriesDialog.Edit.Username=Usuario +ManageRepositoriesDialog.Edit.Password=Contraseña +ManageRepositoriesDialog.Edit.Enabled=Habilitado (usar en cadena de respaldo) +ManageRepositoriesDialog.Edit.Primary=Principal (se prueba primero) +ManageRepositoriesDialog.Edit.IdUrlRequired=Se requieren Id y URL. +HopEnvironmentDialog.Shell.Title=Entorno Marketplace — {0} +HopEnvironmentDialog.Untitled=Sin título +HopEnvironmentDialog.Button.New=Nuevo +HopEnvironmentDialog.Button.Open=Abrir… +HopEnvironmentDialog.Button.Save=Guardar +HopEnvironmentDialog.Button.SaveAs=Guardar como… +HopEnvironmentDialog.Button.Validate=Validar +HopEnvironmentDialog.Button.Validate.Tooltip=Comprobar la instalación local con este archivo de entorno sin instalar +HopEnvironmentDialog.Button.Apply=Aplicar +HopEnvironmentDialog.Button.Apply.Tooltip=Instalar plugins y dependencias declarados en este archivo de entorno +HopEnvironmentDialog.Button.Close=Cerrar +HopEnvironmentDialog.Button.Ok=Aceptar +HopEnvironmentDialog.Button.Cancel=Cancelar +HopEnvironmentDialog.Button.Add=Agregar +HopEnvironmentDialog.Button.Edit=Editar +HopEnvironmentDialog.Button.Remove=Quitar +HopEnvironmentDialog.Button.MoveUp=Arriba +HopEnvironmentDialog.Button.MoveDown=Abajo +HopEnvironmentDialog.Button.AddFromCatalog=Desde catálogo… +HopEnvironmentDialog.Button.ImportRepos=Importar desde hop-config… +HopEnvironmentDialog.Prune=Eliminar extras al aplicar +HopEnvironmentDialog.Prune.Tooltip=Al aplicar, desinstalar plugins de marketplace con recibo que no estén en el archivo +HopEnvironmentDialog.Strict=Validación estricta +HopEnvironmentDialog.Strict.Tooltip=Al validar, fallar también si hay plugins de marketplace instalados más allá del archivo +HopEnvironmentDialog.Filter.Yaml=Entorno YAML (*.yaml, *.yml) +HopEnvironmentDialog.Filter.Json=Entorno JSON (*.json) +HopEnvironmentDialog.Tab.General=General +HopEnvironmentDialog.Tab.Repositories=Repositorios +HopEnvironmentDialog.Tab.Plugins=Plugins +HopEnvironmentDialog.Tab.Dependencies=Dependencias +HopEnvironmentDialog.General.Help=Declare qué plugins y jars debe tener esta instalación de Hop. Guarde como hop-env.yaml para CI/Docker, o use Validar / Aplicar en este diálogo. +HopEnvironmentDialog.General.Version=Versión de especificación +HopEnvironmentDialog.General.HopVersion=Versión de Hop +HopEnvironmentDialog.General.EnforceOnRun=Forzar en hop-run +HopEnvironmentDialog.General.EnforceOnRun.Tooltip=Si es true, hop-run puede fallar si la instalación se desvía de este archivo (también controlado por -Dhop.env.enforce=true) +HopEnvironmentDialog.Repositories.Help=La primera fila es principal (se prueba primero); las siguientes son de respaldo. Estos repositorios viven en el archivo de entorno (no hop-config). Prefiera no confirmar contraseñas. +HopEnvironmentDialog.Plugins.Help=Plugins de marketplace a instalar. Deje Group ID en blanco para usar org.apache.hop. La versión puede tomarse de la versión de Hop en la pestaña General al aplicar. +HopEnvironmentDialog.Dependencies.Help=Jars Maven opcionales (por ejemplo controladores JDBC) instalados bajo el directorio destino de Hop home (predeterminado lib/jdbc). +HopEnvironmentDialog.Repo.Column.Id=Id +HopEnvironmentDialog.Repo.Column.Url=URL +HopEnvironmentDialog.Repo.Column.Username=Usuario +HopEnvironmentDialog.Repo.Column.Password=Contraseña +HopEnvironmentDialog.Repo.Column.Auth=Auth +HopEnvironmentDialog.Repo.Edit.Add=Agregar repositorio +HopEnvironmentDialog.Repo.Edit.Edit=Editar repositorio +HopEnvironmentDialog.Plugin.Column.GroupId=Group ID +HopEnvironmentDialog.Plugin.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Plugin.Column.Version=Versión +HopEnvironmentDialog.Plugin.Edit.Add=Agregar plugin +HopEnvironmentDialog.Plugin.Edit.Edit=Editar plugin +HopEnvironmentDialog.Dep.Column.GroupId=Group ID +HopEnvironmentDialog.Dep.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Dep.Column.Version=Versión +HopEnvironmentDialog.Dep.Column.Target=Destino +HopEnvironmentDialog.Dep.Edit.Add=Agregar dependencia +HopEnvironmentDialog.Dep.Edit.Edit=Editar dependencia +HopEnvironmentDialog.Dirty.Header=Cambios sin guardar +HopEnvironmentDialog.Dirty.Message=¿Guardar los cambios del archivo de entorno antes de continuar? +HopEnvironmentDialog.SaveFirst.Header=¿Guardar archivo de entorno? +HopEnvironmentDialog.SaveFirst.Message=¿Guardar el archivo de entorno antes de Validar o Aplicar? +HopEnvironmentDialog.Validation.Header=Entorno no válido +HopEnvironmentDialog.Validation.RepoIdUrl=Cada repositorio necesita un Id y una URL. +HopEnvironmentDialog.Validation.PluginArtifact=Cada plugin necesita un Artifact ID. +HopEnvironmentDialog.Validation.DepGav=Cada dependencia necesita Group ID, Artifact ID y Version. +HopEnvironmentDialog.ImportRepos.Header=Importar repositorios +HopEnvironmentDialog.ImportRepos.Message=¿Reemplazar la lista de repositorios con los repositorios habilitados de hop-config.json? +HopEnvironmentDialog.Error.Header=Error del editor de entorno +HopEnvironmentDialog.Error.Load=No se pudo cargar el archivo de entorno:\n{0} +HopEnvironmentDialog.Error.Save=No se pudo guardar el archivo de entorno:\n{0} +HopEnvironmentDialog.Error.ImportRepos=No se pudieron importar repositorios desde hop-config +AddPluginsFromCatalogDialog.Shell.Title=Agregar plugins del catálogo +AddPluginsFromCatalogDialog.Filter.Label=Filtro +AddPluginsFromCatalogDialog.Button.Add=Agregar seleccionados +AddPluginsFromCatalogDialog.Button.Cancel=Cancelar +AddPluginsFromCatalogDialog.Column.Name=Nombre +AddPluginsFromCatalogDialog.Column.Artifact=Artefacto +AddPluginsFromCatalogDialog.Column.Category=Categoría +AddPluginsFromCatalogDialog.Column.Description=Descripción diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_es_ES.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_es_ES.properties new file mode 100644 index 00000000000..3ecbb0de7df --- /dev/null +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_es_ES.properties @@ -0,0 +1,209 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +MarketplaceGuiPlugin.Menu.Marketplace.Text=Marketplace... +MarketplaceGuiPlugin.Toolbar.Marketplace.Tooltip=Marketplace… +MarketplaceLifecycleEnv.Tab.Plugins=Plugins de Marketplace +MarketplaceLifecycleEnv.Help=El conjunto de plugins se define en un archivo hop-env. Estas opciones controlan cuándo Hop comprueba ese archivo para este entorno de ciclo de vida (desarrollo flexible; producción estricta). +MarketplaceLifecycleEnv.EnvFile.Label=Archivo de entorno +MarketplaceLifecycleEnv.Button.Browse=Examinar… +MarketplaceLifecycleEnv.Button.EditEnv=Editar… +MarketplaceLifecycleEnv.OnEnable.Label=Al habilitar +MarketplaceLifecycleEnv.OnEnable.Tooltip=off: sin comprobación; warn: registro/diálogo si hay divergencia; enforce: fallar al habilitar el entorno si hay divergencia +MarketplaceLifecycleEnv.Strict.Label=Estricto (fallar si hay plugins de marketplace extra instalados) +MarketplaceLifecycleEnv.Strict.Tooltip=Al validar, tratar también como divergencia los plugins de marketplace con recibo que no estén en el archivo de entorno +MarketplaceLifecycleEnv.AutoApply.Label=Aplicar automáticamente plugins faltantes al habilitar +MarketplaceLifecycleEnv.AutoApply.Tooltip=Si está habilitado, ejecuta marketplace apply para plugins faltantes (solo en máquinas controladas; desactivado por defecto) +MarketplaceDialog.Shell.Title=Marketplace de plugins +MarketplaceDialog.Tab.Plugins=Plugins +MarketplaceDialog.Tab.Environment=Entorno +MarketplaceDialog.Tab.Repositories=Repositorios +MarketplaceDialog.Repository.Label=Repositorio principal +MarketplaceDialog.Repository.SetPrimary.Error=No se pudo establecer el repositorio principal +MarketplaceDialog.Column.Name=Nombre +MarketplaceDialog.Column.Artifact=Artefacto +MarketplaceDialog.Column.Category=Categoría +MarketplaceDialog.Column.Status=Estado +MarketplaceDialog.Column.Description=Descripción +MarketplaceDialog.Search.Label=Buscar +MarketplaceDialog.Search.Placeholder=Escriba 3+ caracteres para filtrar plugins… +MarketplaceDialog.Search.Clear=Borrar filtro de búsqueda +MarketplaceDialog.Button.Install=Instalar +MarketplaceDialog.Button.Uninstall=Desinstalar +MarketplaceDialog.Button.Refresh=Actualizar +MarketplaceDialog.Button.Close=Cerrar +MarketplaceDialog.Button.ManageRepos=Administrar… +MarketplaceDialog.Button.BrowseEnv=Examinar… +MarketplaceDialog.Button.EditEnv=Editar… +MarketplaceDialog.Button.EditEnv.Tooltip=Crear o editar el archivo de entorno (repositorios, plugins, dependencias) +MarketplaceDialog.Button.ValidateEnv=Validar +MarketplaceDialog.Button.ValidateEnv.Tooltip=Comprobar la instalación local con el archivo de entorno sin instalar +MarketplaceDialog.Button.ApplyEnv=Aplicar +MarketplaceDialog.Button.ApplyEnv.Tooltip=Instalar plugins y dependencias declarados en el archivo de entorno +MarketplaceDialog.EnvFile.Label=Archivo de entorno +MarketplaceDialog.EnvFile.Prune=Eliminar extras al aplicar +MarketplaceDialog.EnvFile.Prune.Tooltip=Al aplicar, desinstalar plugins de marketplace con recibo que no estén en el archivo +MarketplaceDialog.EnvFile.Strict=Validación estricta +MarketplaceDialog.EnvFile.Strict.Tooltip=Al validar, fallar también si hay plugins de marketplace instalados más allá del archivo +MarketplaceDialog.EnvFile.Filter.Env=Archivos de entorno Hop (*.yaml, *.yml, *.json) +MarketplaceDialog.EnvFile.Filter.All=Todos los archivos +MarketplaceDialog.EnvFile.Missing.Header=Archivo de entorno requerido +MarketplaceDialog.EnvFile.Missing.Message=Seleccione un hop-env.yaml (o full-client-env.yaml) con Examinar…, o escriba la ruta. +MarketplaceDialog.EnvFile.NotFound.Header=Archivo no encontrado +MarketplaceDialog.EnvFile.NotFound.Message=El archivo de entorno no existe:\n{0} +MarketplaceDialog.Status.Installed=Instalado +MarketplaceDialog.Status.Present=Presente en disco +MarketplaceDialog.Status.NotInstalled=No instalado +MarketplaceDialog.Status.RestartHint=Reinicie Hop tras instalar, aplicar o desinstalar para recargar los plugins. La instalación prueba el repositorio principal y luego otros repositorios habilitados. +MarketplaceDialog.Status.Installing=Instalando {0}... +MarketplaceDialog.Status.Validating=Validando archivo de entorno... +MarketplaceDialog.Status.Applying=Aplicando archivo de entorno... +MarketplaceDialog.Status.Drift=Divergencia de entorno detectada — use Aplicar para corregir +MarketplaceDialog.Error.Header=Error de Marketplace +MarketplaceDialog.Error.ResolveHome=No se pudo determinar el directorio de instalación de Hop. Inicie Hop desde la raíz de instalación con el lanzador de Hop. +MarketplaceDialog.Install.Done.Header=Plugin instalado +MarketplaceDialog.Install.Done.Message=Instalado {0}.\n\nReinicie Hop para cargar el plugin. +MarketplaceDialog.Install.Error=Error al instalar {0} +MarketplaceDialog.Uninstall.Confirm.Header=Desinstalar plugin +MarketplaceDialog.Uninstall.Confirm.Message=¿Quitar el plugin instalado por marketplace {0}? +MarketplaceDialog.Uninstall.NoReceipt.Header=No se puede desinstalar +MarketplaceDialog.Uninstall.NoReceipt.Message=No hay recibo de instalación de marketplace para {0}. Solo se pueden desinstalar aquí plugins instalados vía marketplace. +MarketplaceDialog.Uninstall.Error=Error al desinstalar {0} +MarketplaceDialog.Validate.Ok.Header=Entorno correcto +MarketplaceDialog.Validate.Ok.Message=La instalación local coincide:\n{0} +MarketplaceDialog.Validate.Drift.Header=Divergencia de entorno +MarketplaceDialog.Validate.Drift.Message=La instalación local no coincide con el archivo de entorno: +MarketplaceDialog.Validate.Drift.Hint=Use Aplicar para instalar plugins faltantes (o corregir versiones) y reinicie Hop. +MarketplaceDialog.Validate.Error=Error al validar el archivo de entorno +MarketplaceDialog.Apply.PruneConfirm.Header=¿Podar plugins de marketplace? +MarketplaceDialog.Apply.PruneConfirm.Message=Aplicar con poda desinstalará plugins de marketplace que no estén en el archivo de entorno.\n\n¿Continuar? +MarketplaceDialog.Apply.Disabled=Marketplace está deshabilitado en hop-config.json. +MarketplaceDialog.Apply.Done.Header=Entorno aplicado +MarketplaceDialog.Apply.Done.Message=Aplicado:\n{0}\n\nReinicie Hop para cargar los nuevos plugins. +MarketplaceDialog.Apply.Error=Error al aplicar el archivo de entorno +ManageRepositoriesDialog.Shell.Title=Repositorios de Marketplace +ManageRepositoriesDialog.Help=El repositorio principal se prueba primero. Los demás repositorios habilitados son de respaldo.\nPredeterminados: Apache Repository (repository.apache.org) y luego Maven Central.\nLa configuración se guarda en hop-config.json bajo '${HOP_CONFIG_FOLDER}'. +ManageRepositoriesDialog.Column.Primary=Principal +ManageRepositoriesDialog.Column.Enabled=Habilitado +ManageRepositoriesDialog.Column.Id=Id +ManageRepositoriesDialog.Column.Name=Nombre +ManageRepositoriesDialog.Column.Url=URL +ManageRepositoriesDialog.Column.Auth=Auth +ManageRepositoriesDialog.Button.Add=Añadir +ManageRepositoriesDialog.Button.Edit=Editar +ManageRepositoriesDialog.Button.Remove=Quitar +ManageRepositoriesDialog.Button.SetPrimary=Establecer principal +ManageRepositoriesDialog.Button.MoveUp=Arriba +ManageRepositoriesDialog.Button.MoveDown=Abajo +ManageRepositoriesDialog.Button.ResetDefaults=Restablecer valores predeterminados +ManageRepositoriesDialog.Button.Save=Guardar +ManageRepositoriesDialog.Button.Cancel=Cancelar +ManageRepositoriesDialog.Button.Ok=Aceptar +ManageRepositoriesDialog.Save.Done.Header=Repositorios guardados +ManageRepositoriesDialog.Save.Done.Message=La configuración de repositorios de Marketplace se guardó en hop-config.json. +ManageRepositoriesDialog.Error.Header=Error de repositorio +ManageRepositoriesDialog.Error.Save=No se pudo guardar la configuración de Marketplace +ManageRepositoriesDialog.Reset.Header=Restablecer repositorios +ManageRepositoriesDialog.Reset.Message=¿Reemplazar la lista de repositorios por Apache Repository (principal) y Maven Central? +ManageRepositoriesDialog.Edit.Title.Add=Añadir repositorio +ManageRepositoriesDialog.Edit.Title.Edit=Editar repositorio +ManageRepositoriesDialog.Edit.Id=ID +ManageRepositoriesDialog.Edit.Name=Nombre +ManageRepositoriesDialog.Edit.Url=URL +ManageRepositoriesDialog.Edit.Username=Usuario +ManageRepositoriesDialog.Edit.Password=Contraseña +ManageRepositoriesDialog.Edit.Enabled=Habilitado (usar en cadena de respaldo) +ManageRepositoriesDialog.Edit.Primary=Principal (se prueba primero) +ManageRepositoriesDialog.Edit.IdUrlRequired=Se requieren Id y URL. +HopEnvironmentDialog.Shell.Title=Entorno Marketplace — {0} +HopEnvironmentDialog.Untitled=Sin título +HopEnvironmentDialog.Button.New=Nuevo +HopEnvironmentDialog.Button.Open=Abrir… +HopEnvironmentDialog.Button.Save=Guardar +HopEnvironmentDialog.Button.SaveAs=Guardar como… +HopEnvironmentDialog.Button.Validate=Validar +HopEnvironmentDialog.Button.Validate.Tooltip=Comprobar la instalación local con este archivo de entorno sin instalar +HopEnvironmentDialog.Button.Apply=Aplicar +HopEnvironmentDialog.Button.Apply.Tooltip=Instalar plugins y dependencias declarados en este archivo de entorno +HopEnvironmentDialog.Button.Close=Cerrar +HopEnvironmentDialog.Button.Ok=Aceptar +HopEnvironmentDialog.Button.Cancel=Cancelar +HopEnvironmentDialog.Button.Add=Agregar +HopEnvironmentDialog.Button.Edit=Editar +HopEnvironmentDialog.Button.Remove=Quitar +HopEnvironmentDialog.Button.MoveUp=Arriba +HopEnvironmentDialog.Button.MoveDown=Abajo +HopEnvironmentDialog.Button.AddFromCatalog=Desde catálogo… +HopEnvironmentDialog.Button.ImportRepos=Importar desde hop-config… +HopEnvironmentDialog.Prune=Eliminar extras al aplicar +HopEnvironmentDialog.Prune.Tooltip=Al aplicar, desinstalar plugins de marketplace con recibo que no estén en el archivo +HopEnvironmentDialog.Strict=Validación estricta +HopEnvironmentDialog.Strict.Tooltip=Al validar, fallar también si hay plugins de marketplace instalados más allá del archivo +HopEnvironmentDialog.Filter.Yaml=Entorno YAML (*.yaml, *.yml) +HopEnvironmentDialog.Filter.Json=Entorno JSON (*.json) +HopEnvironmentDialog.Tab.General=General +HopEnvironmentDialog.Tab.Repositories=Repositorios +HopEnvironmentDialog.Tab.Plugins=Plugins +HopEnvironmentDialog.Tab.Dependencies=Dependencias +HopEnvironmentDialog.General.Help=Declare qué plugins y jars debe tener esta instalación de Hop. Guarde como hop-env.yaml para CI/Docker, o use Validar / Aplicar en este diálogo. +HopEnvironmentDialog.General.Version=Versión de especificación +HopEnvironmentDialog.General.HopVersion=Versión de Hop +HopEnvironmentDialog.General.EnforceOnRun=Forzar en hop-run +HopEnvironmentDialog.General.EnforceOnRun.Tooltip=Si es true, hop-run puede fallar si la instalación se desvía de este archivo (también controlado por -Dhop.env.enforce=true) +HopEnvironmentDialog.Repositories.Help=La primera fila es principal (se prueba primero); las siguientes son de respaldo. Estos repositorios viven en el archivo de entorno (no hop-config). Prefiera no confirmar contraseñas. +HopEnvironmentDialog.Plugins.Help=Plugins de marketplace a instalar. Deje Group ID en blanco para usar org.apache.hop. La versión puede tomarse de la versión de Hop en la pestaña General al aplicar. +HopEnvironmentDialog.Dependencies.Help=Jars Maven opcionales (por ejemplo controladores JDBC) instalados bajo el directorio destino de Hop home (predeterminado lib/jdbc). +HopEnvironmentDialog.Repo.Column.Id=Id +HopEnvironmentDialog.Repo.Column.Url=URL +HopEnvironmentDialog.Repo.Column.Username=Usuario +HopEnvironmentDialog.Repo.Column.Password=Contraseña +HopEnvironmentDialog.Repo.Column.Auth=Auth +HopEnvironmentDialog.Repo.Edit.Add=Añadir repositorio +HopEnvironmentDialog.Repo.Edit.Edit=Editar repositorio +HopEnvironmentDialog.Plugin.Column.GroupId=Group ID +HopEnvironmentDialog.Plugin.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Plugin.Column.Version=Versión +HopEnvironmentDialog.Plugin.Edit.Add=Añadir plugin +HopEnvironmentDialog.Plugin.Edit.Edit=Editar plugin +HopEnvironmentDialog.Dep.Column.GroupId=Group ID +HopEnvironmentDialog.Dep.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Dep.Column.Version=Versión +HopEnvironmentDialog.Dep.Column.Target=Destino +HopEnvironmentDialog.Dep.Edit.Add=Añadir dependencia +HopEnvironmentDialog.Dep.Edit.Edit=Editar dependencia +HopEnvironmentDialog.Dirty.Header=Cambios sin guardar +HopEnvironmentDialog.Dirty.Message=¿Guardar los cambios del archivo de entorno antes de continuar? +HopEnvironmentDialog.SaveFirst.Header=¿Guardar archivo de entorno? +HopEnvironmentDialog.SaveFirst.Message=¿Guardar el archivo de entorno antes de Validar o Aplicar? +HopEnvironmentDialog.Validation.Header=Entorno no válido +HopEnvironmentDialog.Validation.RepoIdUrl=Cada repositorio necesita un Id y una URL. +HopEnvironmentDialog.Validation.PluginArtifact=Cada plugin necesita un Artifact ID. +HopEnvironmentDialog.Validation.DepGav=Cada dependencia necesita Group ID, Artifact ID y Version. +HopEnvironmentDialog.ImportRepos.Header=Importar repositorios +HopEnvironmentDialog.ImportRepos.Message=¿Reemplazar la lista de repositorios con los repositorios habilitados de hop-config.json? +HopEnvironmentDialog.Error.Header=Error del editor de entorno +HopEnvironmentDialog.Error.Load=No se pudo cargar el archivo de entorno:\n{0} +HopEnvironmentDialog.Error.Save=No se pudo guardar el archivo de entorno:\n{0} +HopEnvironmentDialog.Error.ImportRepos=No se pudieron importar repositorios desde hop-config +AddPluginsFromCatalogDialog.Shell.Title=Añadir plugins del catálogo +AddPluginsFromCatalogDialog.Filter.Label=Filtro +AddPluginsFromCatalogDialog.Button.Add=Añadir seleccionados +AddPluginsFromCatalogDialog.Button.Cancel=Cancelar +AddPluginsFromCatalogDialog.Column.Name=Nombre +AddPluginsFromCatalogDialog.Column.Artifact=Artefacto +AddPluginsFromCatalogDialog.Column.Category=Categoría +AddPluginsFromCatalogDialog.Column.Description=Descripción diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_fr_FR.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_fr_FR.properties new file mode 100644 index 00000000000..6379dfc1546 --- /dev/null +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_fr_FR.properties @@ -0,0 +1,209 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +MarketplaceGuiPlugin.Menu.Marketplace.Text=Marketplace... +MarketplaceGuiPlugin.Toolbar.Marketplace.Tooltip=Marketplace… +MarketplaceLifecycleEnv.Tab.Plugins=Plugins Marketplace +MarketplaceLifecycleEnv.Help=L'ensemble des plugins est défini dans un fichier hop-env. Ces options contrôlent quand Hop vérifie ce fichier pour cet environnement de cycle de vie (souple en dev ; strict en production). +MarketplaceLifecycleEnv.EnvFile.Label=Fichier d'environnement +MarketplaceLifecycleEnv.Button.Browse=Parcourir… +MarketplaceLifecycleEnv.Button.EditEnv=Modifier… +MarketplaceLifecycleEnv.OnEnable.Label=À l'activation +MarketplaceLifecycleEnv.OnEnable.Tooltip=off : pas de contrôle ; warn : journal/dialogue en cas d'écart ; enforce : échouer à l'activation en cas d'écart +MarketplaceLifecycleEnv.Strict.Label=Strict (échouer si des plugins marketplace supplémentaires sont installés) +MarketplaceLifecycleEnv.Strict.Tooltip=Lors de la validation, traiter aussi comme écart les plugins marketplace avec reçu absents du fichier d'environnement +MarketplaceLifecycleEnv.AutoApply.Label=Appliquer automatiquement les plugins manquants à l'activation +MarketplaceLifecycleEnv.AutoApply.Tooltip=Si activé, exécute marketplace apply pour les plugins manquants (uniquement sur machines contrôlées ; désactivé par défaut) +MarketplaceDialog.Shell.Title=Marketplace de plugins +MarketplaceDialog.Tab.Plugins=Plugins +MarketplaceDialog.Tab.Environment=Environnement +MarketplaceDialog.Tab.Repositories=Dépôts +MarketplaceDialog.Repository.Label=Dépôt principal +MarketplaceDialog.Repository.SetPrimary.Error=Impossible de définir le dépôt principal +MarketplaceDialog.Column.Name=Nom +MarketplaceDialog.Column.Artifact=Artefact +MarketplaceDialog.Column.Category=Catégorie +MarketplaceDialog.Column.Status=Statut +MarketplaceDialog.Column.Description=Description +MarketplaceDialog.Search.Label=Rechercher +MarketplaceDialog.Search.Placeholder=Saisissez 3 caractères ou plus pour filtrer les plugins… +MarketplaceDialog.Search.Clear=Effacer le filtre de recherche +MarketplaceDialog.Button.Install=Installer +MarketplaceDialog.Button.Uninstall=Désinstaller +MarketplaceDialog.Button.Refresh=Actualiser +MarketplaceDialog.Button.Close=Fermer +MarketplaceDialog.Button.ManageRepos=Gérer… +MarketplaceDialog.Button.BrowseEnv=Parcourir… +MarketplaceDialog.Button.EditEnv=Modifier… +MarketplaceDialog.Button.EditEnv.Tooltip=Créer ou modifier le fichier d'environnement (dépôts, plugins, dépendances) +MarketplaceDialog.Button.ValidateEnv=Valider +MarketplaceDialog.Button.ValidateEnv.Tooltip=Comparer l'installation locale au fichier d'environnement sans installer +MarketplaceDialog.Button.ApplyEnv=Appliquer +MarketplaceDialog.Button.ApplyEnv.Tooltip=Installer les plugins et dépendances déclarés dans le fichier d'environnement +MarketplaceDialog.EnvFile.Label=Fichier d'environnement +MarketplaceDialog.EnvFile.Prune=Supprimer les extras à l'application +MarketplaceDialog.EnvFile.Prune.Tooltip=Lors de l'application, désinstaller les plugins marketplace avec reçu absents du fichier +MarketplaceDialog.EnvFile.Strict=Validation stricte +MarketplaceDialog.EnvFile.Strict.Tooltip=Lors de la validation, échouer aussi si des plugins marketplace supplémentaires sont installés au-delà du fichier +MarketplaceDialog.EnvFile.Filter.Env=Fichiers d'environnement Hop (*.yaml, *.yml, *.json) +MarketplaceDialog.EnvFile.Filter.All=Tous les fichiers +MarketplaceDialog.EnvFile.Missing.Header=Fichier d'environnement requis +MarketplaceDialog.EnvFile.Missing.Message=Sélectionnez un hop-env.yaml (ou full-client-env.yaml) avec Parcourir…, ou saisissez le chemin. +MarketplaceDialog.EnvFile.NotFound.Header=Fichier introuvable +MarketplaceDialog.EnvFile.NotFound.Message=Le fichier d''environnement n''existe pas :\n{0} +MarketplaceDialog.Status.Installed=Installé +MarketplaceDialog.Status.Present=Présent sur le disque +MarketplaceDialog.Status.NotInstalled=Non installé +MarketplaceDialog.Status.RestartHint=Redémarrez Hop après installation, application ou désinstallation pour recharger les plugins. L'installation tente d'abord le dépôt principal, puis les autres dépôts activés. +MarketplaceDialog.Status.Installing=Installation de {0}... +MarketplaceDialog.Status.Validating=Validation du fichier d'environnement... +MarketplaceDialog.Status.Applying=Application du fichier d'environnement... +MarketplaceDialog.Status.Drift=Écart d'environnement détecté — utilisez Appliquer pour corriger +MarketplaceDialog.Error.Header=Erreur Marketplace +MarketplaceDialog.Error.ResolveHome=Impossible de déterminer le répertoire d'installation de Hop. Démarrez Hop depuis la racine d'installation avec le lanceur Hop. +MarketplaceDialog.Install.Done.Header=Plugin installé +MarketplaceDialog.Install.Done.Message=Installé : {0}.\n\nVeuillez redémarrer Hop pour charger le plugin. +MarketplaceDialog.Install.Error=Échec de l''installation de {0} +MarketplaceDialog.Uninstall.Confirm.Header=Désinstaller le plugin +MarketplaceDialog.Uninstall.Confirm.Message=Supprimer le plugin installé via le marketplace {0} ? +MarketplaceDialog.Uninstall.NoReceipt.Header=Désinstallation impossible +MarketplaceDialog.Uninstall.NoReceipt.Message=Aucun reçu d''installation marketplace pour {0}. Seuls les plugins installés via le marketplace peuvent être désinstallés ici. +MarketplaceDialog.Uninstall.Error=Échec de la désinstallation de {0} +MarketplaceDialog.Validate.Ok.Header=Environnement OK +MarketplaceDialog.Validate.Ok.Message=L''installation locale correspond :\n{0} +MarketplaceDialog.Validate.Drift.Header=Écart d'environnement +MarketplaceDialog.Validate.Drift.Message=L'installation locale ne correspond pas au fichier d'environnement : +MarketplaceDialog.Validate.Drift.Hint=Utilisez Appliquer pour installer les plugins manquants (ou corriger les versions), puis redémarrez Hop. +MarketplaceDialog.Validate.Error=Échec de la validation du fichier d'environnement +MarketplaceDialog.Apply.PruneConfirm.Header=Élaguer les plugins marketplace ? +MarketplaceDialog.Apply.PruneConfirm.Message=Appliquer avec élagage désinstallera les plugins marketplace absents du fichier d'environnement.\n\nContinuer ? +MarketplaceDialog.Apply.Disabled=Le marketplace est désactivé dans hop-config.json. +MarketplaceDialog.Apply.Done.Header=Environnement appliqué +MarketplaceDialog.Apply.Done.Message=Appliqué :\n{0}\n\nVeuillez redémarrer Hop pour charger les nouveaux plugins. +MarketplaceDialog.Apply.Error=Échec de l'application du fichier d'environnement +ManageRepositoriesDialog.Shell.Title=Dépôts Marketplace +ManageRepositoriesDialog.Help=Le dépôt principal est essayé en premier. Les autres dépôts activés sont des bascules.\nPar défaut : Apache Repository (repository.apache.org) puis Maven Central.\nLes paramètres sont enregistrés dans hop-config.json sous '${HOP_CONFIG_FOLDER}'. +ManageRepositoriesDialog.Column.Primary=Principal +ManageRepositoriesDialog.Column.Enabled=Activé +ManageRepositoriesDialog.Column.Id=Id +ManageRepositoriesDialog.Column.Name=Nom +ManageRepositoriesDialog.Column.Url=URL +ManageRepositoriesDialog.Column.Auth=Auth +ManageRepositoriesDialog.Button.Add=Ajouter +ManageRepositoriesDialog.Button.Edit=Modifier +ManageRepositoriesDialog.Button.Remove=Supprimer +ManageRepositoriesDialog.Button.SetPrimary=Définir comme principal +ManageRepositoriesDialog.Button.MoveUp=Haut +ManageRepositoriesDialog.Button.MoveDown=Bas +ManageRepositoriesDialog.Button.ResetDefaults=Réinitialiser les valeurs par défaut +ManageRepositoriesDialog.Button.Save=Enregistrer +ManageRepositoriesDialog.Button.Cancel=Annuler +ManageRepositoriesDialog.Button.Ok=OK +ManageRepositoriesDialog.Save.Done.Header=Dépôts enregistrés +ManageRepositoriesDialog.Save.Done.Message=Les paramètres des dépôts Marketplace ont été enregistrés dans hop-config.json. +ManageRepositoriesDialog.Error.Header=Erreur de dépôt +ManageRepositoriesDialog.Error.Save=Impossible d'enregistrer la configuration Marketplace +ManageRepositoriesDialog.Reset.Header=Réinitialiser les dépôts +ManageRepositoriesDialog.Reset.Message=Remplacer la liste des dépôts par Apache Repository (principal) et Maven Central ? +ManageRepositoriesDialog.Edit.Title.Add=Ajouter un dépôt +ManageRepositoriesDialog.Edit.Title.Edit=Modifier le dépôt +ManageRepositoriesDialog.Edit.Id=ID +ManageRepositoriesDialog.Edit.Name=Nom +ManageRepositoriesDialog.Edit.Url=URL +ManageRepositoriesDialog.Edit.Username=Nom d'utilisateur +ManageRepositoriesDialog.Edit.Password=Mot de passe +ManageRepositoriesDialog.Edit.Enabled=Activé (utiliser dans la chaîne de bascule) +ManageRepositoriesDialog.Edit.Primary=Principal (essayé en premier) +ManageRepositoriesDialog.Edit.IdUrlRequired=L'Id et l'URL sont obligatoires. +HopEnvironmentDialog.Shell.Title=Environnement Marketplace — {0} +HopEnvironmentDialog.Untitled=Sans titre +HopEnvironmentDialog.Button.New=Nouveau +HopEnvironmentDialog.Button.Open=Ouvrir… +HopEnvironmentDialog.Button.Save=Enregistrer +HopEnvironmentDialog.Button.SaveAs=Enregistrer sous… +HopEnvironmentDialog.Button.Validate=Valider +HopEnvironmentDialog.Button.Validate.Tooltip=Comparer l'installation locale à ce fichier d'environnement sans installer +HopEnvironmentDialog.Button.Apply=Appliquer +HopEnvironmentDialog.Button.Apply.Tooltip=Installer les plugins et dépendances déclarés dans ce fichier d'environnement +HopEnvironmentDialog.Button.Close=Fermer +HopEnvironmentDialog.Button.Ok=OK +HopEnvironmentDialog.Button.Cancel=Annuler +HopEnvironmentDialog.Button.Add=Ajouter +HopEnvironmentDialog.Button.Edit=Modifier +HopEnvironmentDialog.Button.Remove=Supprimer +HopEnvironmentDialog.Button.MoveUp=Haut +HopEnvironmentDialog.Button.MoveDown=Bas +HopEnvironmentDialog.Button.AddFromCatalog=Depuis le catalogue… +HopEnvironmentDialog.Button.ImportRepos=Importer depuis hop-config… +HopEnvironmentDialog.Prune=Supprimer les extras à l'application +HopEnvironmentDialog.Prune.Tooltip=Lors de l'application, désinstaller les plugins marketplace avec reçu absents du fichier +HopEnvironmentDialog.Strict=Validation stricte +HopEnvironmentDialog.Strict.Tooltip=Lors de la validation, échouer aussi si des plugins marketplace supplémentaires sont installés au-delà du fichier +HopEnvironmentDialog.Filter.Yaml=Environnement YAML (*.yaml, *.yml) +HopEnvironmentDialog.Filter.Json=Environnement JSON (*.json) +HopEnvironmentDialog.Tab.General=Général +HopEnvironmentDialog.Tab.Repositories=Dépôts +HopEnvironmentDialog.Tab.Plugins=Plugins +HopEnvironmentDialog.Tab.Dependencies=Dépendances +HopEnvironmentDialog.General.Help=Déclarez quels plugins et jars cette installation Hop doit avoir. Enregistrez en hop-env.yaml pour CI/Docker, ou utilisez Valider / Appliquer dans ce dialogue. +HopEnvironmentDialog.General.Version=Version de spécification +HopEnvironmentDialog.General.HopVersion=Version Hop +HopEnvironmentDialog.General.EnforceOnRun=Appliquer sur hop-run +HopEnvironmentDialog.General.EnforceOnRun.Tooltip=Si vrai, hop-run peut échouer si l'installation s'écarte de ce fichier (aussi contrôlé par -Dhop.env.enforce=true) +HopEnvironmentDialog.Repositories.Help=La première ligne est principale (essayée en premier) ; les suivantes sont des bascules. Ces dépôts sont dans le fichier d'environnement (pas hop-config). Évitez de versionner les mots de passe. +HopEnvironmentDialog.Plugins.Help=Plugins marketplace à installer. Laissez Group ID vide pour org.apache.hop. La version peut provenir de la version Hop de l'onglet Général à l'application. +HopEnvironmentDialog.Dependencies.Help=Jars Maven optionnels (par ex. pilotes JDBC) installés sous le répertoire cible de Hop home (par défaut lib/jdbc). +HopEnvironmentDialog.Repo.Column.Id=Id +HopEnvironmentDialog.Repo.Column.Url=URL +HopEnvironmentDialog.Repo.Column.Username=Nom d'utilisateur +HopEnvironmentDialog.Repo.Column.Password=Mot de passe +HopEnvironmentDialog.Repo.Column.Auth=Auth +HopEnvironmentDialog.Repo.Edit.Add=Ajouter un dépôt +HopEnvironmentDialog.Repo.Edit.Edit=Modifier le dépôt +HopEnvironmentDialog.Plugin.Column.GroupId=Group ID +HopEnvironmentDialog.Plugin.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Plugin.Column.Version=Version +HopEnvironmentDialog.Plugin.Edit.Add=Ajouter un plugin +HopEnvironmentDialog.Plugin.Edit.Edit=Modifier le plugin +HopEnvironmentDialog.Dep.Column.GroupId=Group ID +HopEnvironmentDialog.Dep.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Dep.Column.Version=Version +HopEnvironmentDialog.Dep.Column.Target=Cible +HopEnvironmentDialog.Dep.Edit.Add=Ajouter une dépendance +HopEnvironmentDialog.Dep.Edit.Edit=Modifier la dépendance +HopEnvironmentDialog.Dirty.Header=Modifications non enregistrées +HopEnvironmentDialog.Dirty.Message=Enregistrer les modifications du fichier d'environnement avant de continuer ? +HopEnvironmentDialog.SaveFirst.Header=Enregistrer le fichier d'environnement ? +HopEnvironmentDialog.SaveFirst.Message=Enregistrer le fichier d'environnement avant Valider ou Appliquer ? +HopEnvironmentDialog.Validation.Header=Environnement non valide +HopEnvironmentDialog.Validation.RepoIdUrl=Chaque dépôt doit avoir un Id et une URL. +HopEnvironmentDialog.Validation.PluginArtifact=Chaque plugin doit avoir un Artifact ID. +HopEnvironmentDialog.Validation.DepGav=Chaque dépendance doit avoir Group ID, Artifact ID et Version. +HopEnvironmentDialog.ImportRepos.Header=Importer les dépôts +HopEnvironmentDialog.ImportRepos.Message=Remplacer la liste des dépôts par les dépôts activés de hop-config.json ? +HopEnvironmentDialog.Error.Header=Erreur de l'éditeur d'environnement +HopEnvironmentDialog.Error.Load=Impossible de charger le fichier d''environnement :\n{0} +HopEnvironmentDialog.Error.Save=Impossible d''enregistrer le fichier d''environnement :\n{0} +HopEnvironmentDialog.Error.ImportRepos=Impossible d'importer les dépôts depuis hop-config +AddPluginsFromCatalogDialog.Shell.Title=Ajouter des plugins depuis le catalogue +AddPluginsFromCatalogDialog.Filter.Label=Filtre +AddPluginsFromCatalogDialog.Button.Add=Ajouter la sélection +AddPluginsFromCatalogDialog.Button.Cancel=Annuler +AddPluginsFromCatalogDialog.Column.Name=Nom +AddPluginsFromCatalogDialog.Column.Artifact=Artefact +AddPluginsFromCatalogDialog.Column.Category=Catégorie +AddPluginsFromCatalogDialog.Column.Description=Description diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_it_IT.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_it_IT.properties new file mode 100644 index 00000000000..2507bc7af71 --- /dev/null +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_it_IT.properties @@ -0,0 +1,209 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +MarketplaceGuiPlugin.Menu.Marketplace.Text=Marketplace... +MarketplaceGuiPlugin.Toolbar.Marketplace.Tooltip=Marketplace… +MarketplaceLifecycleEnv.Tab.Plugins=Plugin Marketplace +MarketplaceLifecycleEnv.Help=Il set di plugin è definito in un file hop-env. Queste opzioni controllano quando Hop verifica quel file per questo ambiente di lifecycle (flessibile in dev; rigoroso in produzione). +MarketplaceLifecycleEnv.EnvFile.Label=File ambiente +MarketplaceLifecycleEnv.Button.Browse=Sfoglia… +MarketplaceLifecycleEnv.Button.EditEnv=Modifica… +MarketplaceLifecycleEnv.OnEnable.Label=All'abilitazione +MarketplaceLifecycleEnv.OnEnable.Tooltip=off: nessun controllo; warn: log/dialogo in caso di scostamento; enforce: fallire l'abilitazione dell'ambiente in caso di scostamento +MarketplaceLifecycleEnv.Strict.Label=Rigoroso (fallire se sono installati plugin marketplace extra) +MarketplaceLifecycleEnv.Strict.Tooltip=In validazione, considera anche come scostamento i plugin marketplace con ricevuta non elencati nel file ambiente +MarketplaceLifecycleEnv.AutoApply.Label=Applica automaticamente i plugin mancanti all'abilitazione +MarketplaceLifecycleEnv.AutoApply.Tooltip=Se abilitato, esegue marketplace apply per i plugin mancanti (solo su macchine controllate; predefinito off) +MarketplaceDialog.Shell.Title=Marketplace dei plugin +MarketplaceDialog.Tab.Plugins=Plugin +MarketplaceDialog.Tab.Environment=Ambiente +MarketplaceDialog.Tab.Repositories=Repository +MarketplaceDialog.Repository.Label=Repository principale +MarketplaceDialog.Repository.SetPrimary.Error=Impossibile impostare il repository principale +MarketplaceDialog.Column.Name=Nome +MarketplaceDialog.Column.Artifact=Artifact +MarketplaceDialog.Column.Category=Categoria +MarketplaceDialog.Column.Status=Stato +MarketplaceDialog.Column.Description=Descrizione +MarketplaceDialog.Search.Label=Cerca +MarketplaceDialog.Search.Placeholder=Digitare 3+ caratteri per filtrare i plugin… +MarketplaceDialog.Search.Clear=Cancella filtro di ricerca +MarketplaceDialog.Button.Install=Installa +MarketplaceDialog.Button.Uninstall=Disinstalla +MarketplaceDialog.Button.Refresh=Aggiorna +MarketplaceDialog.Button.Close=Chiudi +MarketplaceDialog.Button.ManageRepos=Gestisci… +MarketplaceDialog.Button.BrowseEnv=Sfoglia… +MarketplaceDialog.Button.EditEnv=Modifica… +MarketplaceDialog.Button.EditEnv.Tooltip=Crea o modifica il file ambiente (repository, plugin, dipendenze) +MarketplaceDialog.Button.ValidateEnv=Valida +MarketplaceDialog.Button.ValidateEnv.Tooltip=Confronta l'installazione locale con il file ambiente senza installare +MarketplaceDialog.Button.ApplyEnv=Applica +MarketplaceDialog.Button.ApplyEnv.Tooltip=Installa plugin e dipendenze dichiarati nel file ambiente +MarketplaceDialog.EnvFile.Label=File ambiente +MarketplaceDialog.EnvFile.Prune=Rimuovi extra all'applicazione +MarketplaceDialog.EnvFile.Prune.Tooltip=All'applicazione, disinstalla i plugin marketplace con ricevuta non elencati nel file +MarketplaceDialog.EnvFile.Strict=Validazione rigorosa +MarketplaceDialog.EnvFile.Strict.Tooltip=In validazione, fallire anche se sono installati plugin marketplace extra oltre al file +MarketplaceDialog.EnvFile.Filter.Env=File ambiente Hop (*.yaml, *.yml, *.json) +MarketplaceDialog.EnvFile.Filter.All=Tutti i file +MarketplaceDialog.EnvFile.Missing.Header=File ambiente richiesto +MarketplaceDialog.EnvFile.Missing.Message=Selezionare un hop-env.yaml (o full-client-env.yaml) con Sfoglia…, oppure digitare il percorso. +MarketplaceDialog.EnvFile.NotFound.Header=File non trovato +MarketplaceDialog.EnvFile.NotFound.Message=Il file ambiente non esiste:\n{0} +MarketplaceDialog.Status.Installed=Installato +MarketplaceDialog.Status.Present=Presente su disco +MarketplaceDialog.Status.NotInstalled=Non installato +MarketplaceDialog.Status.RestartHint=Riavviare Hop dopo installazione, applicazione o disinstallazione per ricaricare i plugin. L'installazione prova prima il repository principale, poi gli altri abilitati. +MarketplaceDialog.Status.Installing=Installazione di {0}... +MarketplaceDialog.Status.Validating=Validazione del file ambiente... +MarketplaceDialog.Status.Applying=Applicazione del file ambiente... +MarketplaceDialog.Status.Drift=Scostamento ambiente rilevato — usare Applica per correggere +MarketplaceDialog.Error.Header=Errore Marketplace +MarketplaceDialog.Error.ResolveHome=Impossibile determinare la directory di installazione di Hop. Avviare Hop dalla root di installazione con il launcher Hop. +MarketplaceDialog.Install.Done.Header=Plugin installato +MarketplaceDialog.Install.Done.Message=Installato {0}.\n\nRiavviare Hop per caricare il plugin. +MarketplaceDialog.Install.Error=Installazione di {0} non riuscita +MarketplaceDialog.Uninstall.Confirm.Header=Disinstalla plugin +MarketplaceDialog.Uninstall.Confirm.Message=Rimuovere il plugin installato dal marketplace {0}? +MarketplaceDialog.Uninstall.NoReceipt.Header=Impossibile disinstallare +MarketplaceDialog.Uninstall.NoReceipt.Message=Nessuna ricevuta di installazione marketplace per {0}. Qui si possono disinstallare solo i plugin installati tramite marketplace. +MarketplaceDialog.Uninstall.Error=Disinstallazione di {0} non riuscita +MarketplaceDialog.Validate.Ok.Header=Ambiente OK +MarketplaceDialog.Validate.Ok.Message=L''installazione locale corrisponde:\n{0} +MarketplaceDialog.Validate.Drift.Header=Scostamento ambiente +MarketplaceDialog.Validate.Drift.Message=L'installazione locale non corrisponde al file ambiente: +MarketplaceDialog.Validate.Drift.Hint=Usare Applica per installare i plugin mancanti (o correggere le versioni), poi riavviare Hop. +MarketplaceDialog.Validate.Error=Validazione del file ambiente non riuscita +MarketplaceDialog.Apply.PruneConfirm.Header=Rimuovere plugin marketplace extra? +MarketplaceDialog.Apply.PruneConfirm.Message=Applica con rimozione extra disinstallerà i plugin marketplace non elencati nel file ambiente.\n\nContinuare? +MarketplaceDialog.Apply.Disabled=Il marketplace è disabilitato in hop-config.json. +MarketplaceDialog.Apply.Done.Header=Ambiente applicato +MarketplaceDialog.Apply.Done.Message=Applicato:\n{0}\n\nRiavviare Hop per caricare i nuovi plugin. +MarketplaceDialog.Apply.Error=Applicazione del file ambiente non riuscita +ManageRepositoriesDialog.Shell.Title=Repository Marketplace +ManageRepositoriesDialog.Help=Il repository principale viene provato per primo. Gli altri repository abilitati sono fallback.\nPredefiniti: Apache Repository (repository.apache.org) poi Maven Central.\nLe impostazioni sono salvate in hop-config.json sotto '${HOP_CONFIG_FOLDER}'. +ManageRepositoriesDialog.Column.Primary=Principale +ManageRepositoriesDialog.Column.Enabled=Abilitato +ManageRepositoriesDialog.Column.Id=Id +ManageRepositoriesDialog.Column.Name=Nome +ManageRepositoriesDialog.Column.Url=URL +ManageRepositoriesDialog.Column.Auth=Auth +ManageRepositoriesDialog.Button.Add=Aggiungi +ManageRepositoriesDialog.Button.Edit=Modifica +ManageRepositoriesDialog.Button.Remove=Rimuovi +ManageRepositoriesDialog.Button.SetPrimary=Imposta principale +ManageRepositoriesDialog.Button.MoveUp=Su +ManageRepositoriesDialog.Button.MoveDown=Giù +ManageRepositoriesDialog.Button.ResetDefaults=Ripristina predefiniti +ManageRepositoriesDialog.Button.Save=Salva +ManageRepositoriesDialog.Button.Cancel=Annulla +ManageRepositoriesDialog.Button.Ok=OK +ManageRepositoriesDialog.Save.Done.Header=Repository salvati +ManageRepositoriesDialog.Save.Done.Message=Le impostazioni dei repository Marketplace sono state salvate in hop-config.json. +ManageRepositoriesDialog.Error.Header=Errore repository +ManageRepositoriesDialog.Error.Save=Impossibile salvare la configurazione Marketplace +ManageRepositoriesDialog.Reset.Header=Ripristina repository +ManageRepositoriesDialog.Reset.Message=Sostituire l'elenco dei repository con Apache Repository (principale) e Maven Central? +ManageRepositoriesDialog.Edit.Title.Add=Aggiungi repository +ManageRepositoriesDialog.Edit.Title.Edit=Modifica repository +ManageRepositoriesDialog.Edit.Id=ID +ManageRepositoriesDialog.Edit.Name=Nome +ManageRepositoriesDialog.Edit.Url=URL +ManageRepositoriesDialog.Edit.Username=Nome utente +ManageRepositoriesDialog.Edit.Password=Password +ManageRepositoriesDialog.Edit.Enabled=Abilitato (usa nella catena di fallback) +ManageRepositoriesDialog.Edit.Primary=Principale (provato per primo) +ManageRepositoriesDialog.Edit.IdUrlRequired=Id e URL sono obbligatori. +HopEnvironmentDialog.Shell.Title=Ambiente Marketplace — {0} +HopEnvironmentDialog.Untitled=Senza titolo +HopEnvironmentDialog.Button.New=Nuovo +HopEnvironmentDialog.Button.Open=Apri… +HopEnvironmentDialog.Button.Save=Salva +HopEnvironmentDialog.Button.SaveAs=Salva con nome… +HopEnvironmentDialog.Button.Validate=Valida +HopEnvironmentDialog.Button.Validate.Tooltip=Confronta l'installazione locale con questo file ambiente senza installare +HopEnvironmentDialog.Button.Apply=Applica +HopEnvironmentDialog.Button.Apply.Tooltip=Installa plugin e dipendenze dichiarati in questo file ambiente +HopEnvironmentDialog.Button.Close=Chiudi +HopEnvironmentDialog.Button.Ok=OK +HopEnvironmentDialog.Button.Cancel=Annulla +HopEnvironmentDialog.Button.Add=Aggiungi +HopEnvironmentDialog.Button.Edit=Modifica +HopEnvironmentDialog.Button.Remove=Rimuovi +HopEnvironmentDialog.Button.MoveUp=Su +HopEnvironmentDialog.Button.MoveDown=Giù +HopEnvironmentDialog.Button.AddFromCatalog=Dal catalogo… +HopEnvironmentDialog.Button.ImportRepos=Importa da hop-config… +HopEnvironmentDialog.Prune=Rimuovi extra all'applicazione +HopEnvironmentDialog.Prune.Tooltip=All'applicazione, disinstalla i plugin marketplace con ricevuta non elencati nel file +HopEnvironmentDialog.Strict=Validazione rigorosa +HopEnvironmentDialog.Strict.Tooltip=In validazione, fallire anche se sono installati plugin marketplace extra oltre al file +HopEnvironmentDialog.Filter.Yaml=Ambiente YAML (*.yaml, *.yml) +HopEnvironmentDialog.Filter.Json=Ambiente JSON (*.json) +HopEnvironmentDialog.Tab.General=Generale +HopEnvironmentDialog.Tab.Repositories=Repository +HopEnvironmentDialog.Tab.Plugins=Plugin +HopEnvironmentDialog.Tab.Dependencies=Dipendenze +HopEnvironmentDialog.General.Help=Dichiarare quali plugin e jar deve avere questa installazione Hop. Salvare come hop-env.yaml per CI/Docker, oppure usare Valida / Applica in questa finestra. +HopEnvironmentDialog.General.Version=Versione specifica +HopEnvironmentDialog.General.HopVersion=Versione Hop +HopEnvironmentDialog.General.EnforceOnRun=Applica su hop-run +HopEnvironmentDialog.General.EnforceOnRun.Tooltip=Se true, hop-run può fallire se l'installazione si discosta da questo file (anche controllato da -Dhop.env.enforce=true) +HopEnvironmentDialog.Repositories.Help=La prima riga è principale (provata per prima); le successive sono fallback. Questi repository sono nel file ambiente (non hop-config). Preferire non committare le password. +HopEnvironmentDialog.Plugins.Help=Plugin marketplace da installare. Lasciare Group ID vuoto per usare org.apache.hop. La versione può derivare dalla versione Hop nella scheda Generale all'applicazione. +HopEnvironmentDialog.Dependencies.Help=Jar Maven opzionali (ad es. driver JDBC) installati sotto la directory di destinazione di Hop home (predefinito lib/jdbc). +HopEnvironmentDialog.Repo.Column.Id=Id +HopEnvironmentDialog.Repo.Column.Url=URL +HopEnvironmentDialog.Repo.Column.Username=Nome utente +HopEnvironmentDialog.Repo.Column.Password=Password +HopEnvironmentDialog.Repo.Column.Auth=Auth +HopEnvironmentDialog.Repo.Edit.Add=Aggiungi repository +HopEnvironmentDialog.Repo.Edit.Edit=Modifica repository +HopEnvironmentDialog.Plugin.Column.GroupId=Group ID +HopEnvironmentDialog.Plugin.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Plugin.Column.Version=Versione +HopEnvironmentDialog.Plugin.Edit.Add=Aggiungi plugin +HopEnvironmentDialog.Plugin.Edit.Edit=Modifica plugin +HopEnvironmentDialog.Dep.Column.GroupId=Group ID +HopEnvironmentDialog.Dep.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Dep.Column.Version=Versione +HopEnvironmentDialog.Dep.Column.Target=Destinazione +HopEnvironmentDialog.Dep.Edit.Add=Aggiungi dipendenza +HopEnvironmentDialog.Dep.Edit.Edit=Modifica dipendenza +HopEnvironmentDialog.Dirty.Header=Modifiche non salvate +HopEnvironmentDialog.Dirty.Message=Salvare le modifiche al file ambiente prima di continuare? +HopEnvironmentDialog.SaveFirst.Header=Salvare il file ambiente? +HopEnvironmentDialog.SaveFirst.Message=Salvare il file ambiente prima di Valida o Applica? +HopEnvironmentDialog.Validation.Header=Ambiente non valido +HopEnvironmentDialog.Validation.RepoIdUrl=Ogni repository richiede un Id e un URL. +HopEnvironmentDialog.Validation.PluginArtifact=Ogni plugin richiede un Artifact ID. +HopEnvironmentDialog.Validation.DepGav=Ogni dipendenza richiede Group ID, Artifact ID e Version. +HopEnvironmentDialog.ImportRepos.Header=Importa repository +HopEnvironmentDialog.ImportRepos.Message=Sostituire l'elenco dei repository con i repository abilitati da hop-config.json? +HopEnvironmentDialog.Error.Header=Errore dell'editor ambiente +HopEnvironmentDialog.Error.Load=Impossibile caricare il file ambiente:\n{0} +HopEnvironmentDialog.Error.Save=Impossibile salvare il file ambiente:\n{0} +HopEnvironmentDialog.Error.ImportRepos=Impossibile importare i repository da hop-config +AddPluginsFromCatalogDialog.Shell.Title=Aggiungi plugin dal catalogo +AddPluginsFromCatalogDialog.Filter.Label=Filtro +AddPluginsFromCatalogDialog.Button.Add=Aggiungi selezionati +AddPluginsFromCatalogDialog.Button.Cancel=Annulla +AddPluginsFromCatalogDialog.Column.Name=Nome +AddPluginsFromCatalogDialog.Column.Artifact=Artifact +AddPluginsFromCatalogDialog.Column.Category=Categoria +AddPluginsFromCatalogDialog.Column.Description=Descrizione diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_ja_JP.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_ja_JP.properties new file mode 100644 index 00000000000..a8435bc32e8 --- /dev/null +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_ja_JP.properties @@ -0,0 +1,209 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +MarketplaceGuiPlugin.Menu.Marketplace.Text=Marketplace... +MarketplaceGuiPlugin.Toolbar.Marketplace.Tooltip=Marketplace… +MarketplaceLifecycleEnv.Tab.Plugins=Marketplaceプラグイン +MarketplaceLifecycleEnv.Help=プラグインのセットは hop-env ファイルで定義します。これらのオプションは、このライフサイクル環境で Hop がそのファイルをいつ確認するかを制御します(開発は緩く、本番は厳格に)。 +MarketplaceLifecycleEnv.EnvFile.Label=環境ファイル +MarketplaceLifecycleEnv.Button.Browse=参照… +MarketplaceLifecycleEnv.Button.EditEnv=編集… +MarketplaceLifecycleEnv.OnEnable.Label=有効化時 +MarketplaceLifecycleEnv.OnEnable.Tooltip=off: チェックなし; warn: 差分時にログ/ダイアログ; enforce: 差分時に環境の有効化を失敗させる +MarketplaceLifecycleEnv.Strict.Label=厳密(追加の Marketplace プラグインがインストールされている場合は失敗) +MarketplaceLifecycleEnv.Strict.Tooltip=検証時、環境ファイルにないレシート付き Marketplace プラグインも差分として扱います +MarketplaceLifecycleEnv.AutoApply.Label=有効化時に不足プラグインを自動適用 +MarketplaceLifecycleEnv.AutoApply.Tooltip=有効にすると、不足プラグインに対して marketplace apply を実行します(管理されたマシンのみ;既定はオフ) +MarketplaceDialog.Shell.Title=プラグイン Marketplace +MarketplaceDialog.Tab.Plugins=プラグイン +MarketplaceDialog.Tab.Environment=環境 +MarketplaceDialog.Tab.Repositories=リポジトリ +MarketplaceDialog.Repository.Label=プライマリリポジトリ +MarketplaceDialog.Repository.SetPrimary.Error=プライマリリポジトリを設定できませんでした +MarketplaceDialog.Column.Name=名前 +MarketplaceDialog.Column.Artifact=アーティファクト +MarketplaceDialog.Column.Category=カテゴリ +MarketplaceDialog.Column.Status=状態 +MarketplaceDialog.Column.Description=説明 +MarketplaceDialog.Search.Label=検索 +MarketplaceDialog.Search.Placeholder=3文字以上入力してプラグインを絞り込み… +MarketplaceDialog.Search.Clear=検索フィルタをクリア +MarketplaceDialog.Button.Install=インストール +MarketplaceDialog.Button.Uninstall=アンインストール +MarketplaceDialog.Button.Refresh=更新 +MarketplaceDialog.Button.Close=閉じる +MarketplaceDialog.Button.ManageRepos=管理… +MarketplaceDialog.Button.BrowseEnv=参照… +MarketplaceDialog.Button.EditEnv=編集… +MarketplaceDialog.Button.EditEnv.Tooltip=環境ファイルの作成または編集(リポジトリ、プラグイン、依存関係) +MarketplaceDialog.Button.ValidateEnv=検証 +MarketplaceDialog.Button.ValidateEnv.Tooltip=インストールせずにローカル環境と環境ファイルを照合します +MarketplaceDialog.Button.ApplyEnv=適用 +MarketplaceDialog.Button.ApplyEnv.Tooltip=環境ファイルで宣言されたプラグインと依存関係をインストールします +MarketplaceDialog.EnvFile.Label=環境ファイル +MarketplaceDialog.EnvFile.Prune=適用時に余分なものを削除 +MarketplaceDialog.EnvFile.Prune.Tooltip=適用時、ファイルにないレシート付き Marketplace プラグインをアンインストールします +MarketplaceDialog.EnvFile.Strict=厳密な検証 +MarketplaceDialog.EnvFile.Strict.Tooltip=検証時、ファイル以外の追加 Marketplace プラグインがインストールされている場合も失敗します +MarketplaceDialog.EnvFile.Filter.Env=Hop 環境ファイル (*.yaml, *.yml, *.json) +MarketplaceDialog.EnvFile.Filter.All=すべてのファイル +MarketplaceDialog.EnvFile.Missing.Header=環境ファイルが必要です +MarketplaceDialog.EnvFile.Missing.Message=参照… で hop-env.yaml(または full-client-env.yaml)を選択するか、パスを入力してください。 +MarketplaceDialog.EnvFile.NotFound.Header=ファイルが見つかりません +MarketplaceDialog.EnvFile.NotFound.Message=環境ファイルが存在しません:\n{0} +MarketplaceDialog.Status.Installed=インストール済み +MarketplaceDialog.Status.Present=ディスク上に存在 +MarketplaceDialog.Status.NotInstalled=未インストール +MarketplaceDialog.Status.RestartHint=インストール、適用、アンインストール後はプラグイン再読込のため Hop を再起動してください。インストールはプライマリリポジトリ、次いで他の有効なリポジトリを試します。 +MarketplaceDialog.Status.Installing={0} をインストール中... +MarketplaceDialog.Status.Validating=環境ファイルを検証中... +MarketplaceDialog.Status.Applying=環境ファイルを適用中... +MarketplaceDialog.Status.Drift=環境の差分を検出 — 適用で修正してください +MarketplaceDialog.Error.Header=Marketplace エラー +MarketplaceDialog.Error.ResolveHome=Hop のインストールディレクトリを特定できませんでした。インストールルートから hop ランチャーで起動してください。 +MarketplaceDialog.Install.Done.Header=プラグインをインストールしました +MarketplaceDialog.Install.Done.Message={0} をインストールしました。\n\nプラグインを読み込むには Hop を再起動してください。 +MarketplaceDialog.Install.Error={0} のインストールに失敗しました +MarketplaceDialog.Uninstall.Confirm.Header=プラグインのアンインストール +MarketplaceDialog.Uninstall.Confirm.Message=Marketplace でインストールしたプラグイン {0} を削除しますか? +MarketplaceDialog.Uninstall.NoReceipt.Header=アンインストールできません +MarketplaceDialog.Uninstall.NoReceipt.Message={0} の Marketplace インストールレシートがありません。ここでアンインストールできるのは Marketplace 経由のプラグインのみです。 +MarketplaceDialog.Uninstall.Error={0} のアンインストールに失敗しました +MarketplaceDialog.Validate.Ok.Header=環境 OK +MarketplaceDialog.Validate.Ok.Message=ローカルインストールは一致しています:\n{0} +MarketplaceDialog.Validate.Drift.Header=環境の差分 +MarketplaceDialog.Validate.Drift.Message=ローカルインストールが環境ファイルと一致しません: +MarketplaceDialog.Validate.Drift.Hint=適用で不足プラグインをインストール(またはバージョンを修正)し、Hop を再起動してください。 +MarketplaceDialog.Validate.Error=環境ファイルの検証に失敗しました +MarketplaceDialog.Apply.PruneConfirm.Header=Marketplace プラグインを整理しますか? +MarketplaceDialog.Apply.PruneConfirm.Message=整理付きの適用は、環境ファイルにない Marketplace プラグインをアンインストールします。\n\n続行しますか? +MarketplaceDialog.Apply.Disabled=Marketplace は hop-config.json で無効です。 +MarketplaceDialog.Apply.Done.Header=環境を適用しました +MarketplaceDialog.Apply.Done.Message=適用しました:\n{0}\n\n新しいプラグインを読み込むには Hop を再起動してください。 +MarketplaceDialog.Apply.Error=環境ファイルの適用に失敗しました +ManageRepositoriesDialog.Shell.Title=Marketplace リポジトリ +ManageRepositoriesDialog.Help=プライマリリポジトリが最初に試されます。他の有効なリポジトリはフォールバックです。\n既定: Apache Repository (repository.apache.org)、次に Maven Central。\n設定は '${HOP_CONFIG_FOLDER}' の hop-config.json に保存されます。 +ManageRepositoriesDialog.Column.Primary=プライマリ +ManageRepositoriesDialog.Column.Enabled=有効 +ManageRepositoriesDialog.Column.Id=Id +ManageRepositoriesDialog.Column.Name=名前 +ManageRepositoriesDialog.Column.Url=URL +ManageRepositoriesDialog.Column.Auth=認証 +ManageRepositoriesDialog.Button.Add=追加 +ManageRepositoriesDialog.Button.Edit=編集 +ManageRepositoriesDialog.Button.Remove=削除 +ManageRepositoriesDialog.Button.SetPrimary=プライマリに設定 +ManageRepositoriesDialog.Button.MoveUp=上へ +ManageRepositoriesDialog.Button.MoveDown=下へ +ManageRepositoriesDialog.Button.ResetDefaults=既定にリセット +ManageRepositoriesDialog.Button.Save=保存 +ManageRepositoriesDialog.Button.Cancel=キャンセル +ManageRepositoriesDialog.Button.Ok=OK +ManageRepositoriesDialog.Save.Done.Header=リポジトリを保存しました +ManageRepositoriesDialog.Save.Done.Message=Marketplace リポジトリ設定を hop-config.json に保存しました。 +ManageRepositoriesDialog.Error.Header=リポジトリエラー +ManageRepositoriesDialog.Error.Save=Marketplace 設定を保存できませんでした +ManageRepositoriesDialog.Reset.Header=リポジトリをリセット +ManageRepositoriesDialog.Reset.Message=リポジトリ一覧を Apache Repository(プライマリ)と Maven Central に置き換えますか? +ManageRepositoriesDialog.Edit.Title.Add=リポジトリを追加 +ManageRepositoriesDialog.Edit.Title.Edit=リポジトリを編集 +ManageRepositoriesDialog.Edit.Id=ID +ManageRepositoriesDialog.Edit.Name=名前 +ManageRepositoriesDialog.Edit.Url=URL +ManageRepositoriesDialog.Edit.Username=ユーザー名 +ManageRepositoriesDialog.Edit.Password=パスワード +ManageRepositoriesDialog.Edit.Enabled=有効(フォールバックチェーンで使用) +ManageRepositoriesDialog.Edit.Primary=プライマリ(最初に試行) +ManageRepositoriesDialog.Edit.IdUrlRequired=Id と URL は必須です。 +HopEnvironmentDialog.Shell.Title=Marketplace 環境 — {0} +HopEnvironmentDialog.Untitled=無題 +HopEnvironmentDialog.Button.New=新規 +HopEnvironmentDialog.Button.Open=開く… +HopEnvironmentDialog.Button.Save=保存 +HopEnvironmentDialog.Button.SaveAs=名前を付けて保存… +HopEnvironmentDialog.Button.Validate=検証 +HopEnvironmentDialog.Button.Validate.Tooltip=インストールせずにローカル環境とこの環境ファイルを照合します +HopEnvironmentDialog.Button.Apply=適用 +HopEnvironmentDialog.Button.Apply.Tooltip=この環境ファイルで宣言されたプラグインと依存関係をインストールします +HopEnvironmentDialog.Button.Close=閉じる +HopEnvironmentDialog.Button.Ok=OK +HopEnvironmentDialog.Button.Cancel=キャンセル +HopEnvironmentDialog.Button.Add=追加 +HopEnvironmentDialog.Button.Edit=編集 +HopEnvironmentDialog.Button.Remove=削除 +HopEnvironmentDialog.Button.MoveUp=上へ +HopEnvironmentDialog.Button.MoveDown=下へ +HopEnvironmentDialog.Button.AddFromCatalog=カタログから… +HopEnvironmentDialog.Button.ImportRepos=hop-config からインポート… +HopEnvironmentDialog.Prune=適用時に余分なものを削除 +HopEnvironmentDialog.Prune.Tooltip=適用時、ファイルにないレシート付き Marketplace プラグインをアンインストールします +HopEnvironmentDialog.Strict=厳密な検証 +HopEnvironmentDialog.Strict.Tooltip=検証時、ファイル以外の追加 Marketplace プラグインがインストールされている場合も失敗します +HopEnvironmentDialog.Filter.Yaml=YAML 環境 (*.yaml, *.yml) +HopEnvironmentDialog.Filter.Json=JSON 環境 (*.json) +HopEnvironmentDialog.Tab.General=全般 +HopEnvironmentDialog.Tab.Repositories=リポジトリ +HopEnvironmentDialog.Tab.Plugins=プラグイン +HopEnvironmentDialog.Tab.Dependencies=依存関係 +HopEnvironmentDialog.General.Help=この Hop インストールに必要なプラグインと JAR を宣言します。CI/Docker 用に hop-env.yaml として保存するか、このダイアログで検証/適用を使用します。 +HopEnvironmentDialog.General.Version=仕様バージョン +HopEnvironmentDialog.General.HopVersion=Hop バージョン +HopEnvironmentDialog.General.EnforceOnRun=hop-run で強制 +HopEnvironmentDialog.General.EnforceOnRun.Tooltip=true の場合、インストールがこのファイルから逸脱すると hop-run が失敗できます(-Dhop.env.enforce=true でも制御) +HopEnvironmentDialog.Repositories.Help=最初の行がプライマリ(最初に試行)、以降はフォールバックです。これらのリポジトリは環境ファイル内にあり(hop-config ではありません)。パスワードはコミットしないでください。 +HopEnvironmentDialog.Plugins.Help=インストールする Marketplace プラグイン。Group ID を空にすると org.apache.hop を使用します。適用時に全般タブの Hop バージョンが既定になることがあります。 +HopEnvironmentDialog.Dependencies.Help=オプションの Maven JAR(例: JDBC ドライバ)。Hop ホームのターゲットディレクトリ配下にインストール(既定 lib/jdbc)。 +HopEnvironmentDialog.Repo.Column.Id=Id +HopEnvironmentDialog.Repo.Column.Url=URL +HopEnvironmentDialog.Repo.Column.Username=ユーザー名 +HopEnvironmentDialog.Repo.Column.Password=パスワード +HopEnvironmentDialog.Repo.Column.Auth=認証 +HopEnvironmentDialog.Repo.Edit.Add=リポジトリを追加 +HopEnvironmentDialog.Repo.Edit.Edit=リポジトリを編集 +HopEnvironmentDialog.Plugin.Column.GroupId=Group ID +HopEnvironmentDialog.Plugin.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Plugin.Column.Version=バージョン +HopEnvironmentDialog.Plugin.Edit.Add=プラグインを追加 +HopEnvironmentDialog.Plugin.Edit.Edit=プラグインを編集 +HopEnvironmentDialog.Dep.Column.GroupId=Group ID +HopEnvironmentDialog.Dep.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Dep.Column.Version=バージョン +HopEnvironmentDialog.Dep.Column.Target=ターゲット +HopEnvironmentDialog.Dep.Edit.Add=依存関係を追加 +HopEnvironmentDialog.Dep.Edit.Edit=依存関係を編集 +HopEnvironmentDialog.Dirty.Header=未保存の変更 +HopEnvironmentDialog.Dirty.Message=続行する前に環境ファイルの変更を保存しますか? +HopEnvironmentDialog.SaveFirst.Header=環境ファイルを保存しますか? +HopEnvironmentDialog.SaveFirst.Message=検証または適用の前に環境ファイルを保存しますか? +HopEnvironmentDialog.Validation.Header=無効な環境 +HopEnvironmentDialog.Validation.RepoIdUrl=各リポジトリには Id と URL が必要です。 +HopEnvironmentDialog.Validation.PluginArtifact=各プラグインには Artifact ID が必要です。 +HopEnvironmentDialog.Validation.DepGav=各依存関係には Group ID、Artifact ID、Version が必要です。 +HopEnvironmentDialog.ImportRepos.Header=リポジトリをインポート +HopEnvironmentDialog.ImportRepos.Message=リポジトリ一覧を hop-config.json の有効なリポジトリで置き換えますか? +HopEnvironmentDialog.Error.Header=環境エディタエラー +HopEnvironmentDialog.Error.Load=環境ファイルを読み込めませんでした:\n{0} +HopEnvironmentDialog.Error.Save=環境ファイルを保存できませんでした:\n{0} +HopEnvironmentDialog.Error.ImportRepos=hop-config からリポジトリをインポートできませんでした +AddPluginsFromCatalogDialog.Shell.Title=カタログからプラグインを追加 +AddPluginsFromCatalogDialog.Filter.Label=フィルタ +AddPluginsFromCatalogDialog.Button.Add=選択を追加 +AddPluginsFromCatalogDialog.Button.Cancel=キャンセル +AddPluginsFromCatalogDialog.Column.Name=名前 +AddPluginsFromCatalogDialog.Column.Artifact=アーティファクト +AddPluginsFromCatalogDialog.Column.Category=カテゴリ +AddPluginsFromCatalogDialog.Column.Description=説明 diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_ko_KR.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_ko_KR.properties new file mode 100644 index 00000000000..edd62e6877a --- /dev/null +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_ko_KR.properties @@ -0,0 +1,209 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +MarketplaceGuiPlugin.Menu.Marketplace.Text=Marketplace... +MarketplaceGuiPlugin.Toolbar.Marketplace.Tooltip=Marketplace… +MarketplaceLifecycleEnv.Tab.Plugins=Marketplace 플러그인 +MarketplaceLifecycleEnv.Help=플러그인 집합은 hop-env 파일에 정의됩니다. 이 옵션은 이 라이프사이클 환경에서 Hop이 해당 파일을 언제 검사할지 제어합니다(개발은 유연, 운영은 엄격). +MarketplaceLifecycleEnv.EnvFile.Label=환경 파일 +MarketplaceLifecycleEnv.Button.Browse=찾아보기… +MarketplaceLifecycleEnv.Button.EditEnv=편집… +MarketplaceLifecycleEnv.OnEnable.Label=활성화 시 +MarketplaceLifecycleEnv.OnEnable.Tooltip=off: 검사 안 함; warn: 불일치 시 로그/대화상자; enforce: 불일치 시 환경 활성화 실패 +MarketplaceLifecycleEnv.Strict.Label=엄격(추가 Marketplace 플러그인이 설치되어 있으면 실패) +MarketplaceLifecycleEnv.Strict.Tooltip=검증 시 환경 파일에 없는 영수증이 있는 Marketplace 플러그인도 불일치로 처리합니다 +MarketplaceLifecycleEnv.AutoApply.Label=활성화 시 누락된 플러그인 자동 적용 +MarketplaceLifecycleEnv.AutoApply.Tooltip=활성화하면 누락된 플러그인에 대해 marketplace apply를 실행합니다(통제된 머신만; 기본 꺼짐) +MarketplaceDialog.Shell.Title=플러그인 Marketplace +MarketplaceDialog.Tab.Plugins=플러그인 +MarketplaceDialog.Tab.Environment=환경 +MarketplaceDialog.Tab.Repositories=리포지토리 +MarketplaceDialog.Repository.Label=기본 리포지토리 +MarketplaceDialog.Repository.SetPrimary.Error=기본 리포지토리를 설정할 수 없습니다 +MarketplaceDialog.Column.Name=이름 +MarketplaceDialog.Column.Artifact=아티팩트 +MarketplaceDialog.Column.Category=범주 +MarketplaceDialog.Column.Status=상태 +MarketplaceDialog.Column.Description=설명 +MarketplaceDialog.Search.Label=검색 +MarketplaceDialog.Search.Placeholder=플러그인 필터링을 위해 3자 이상 입력… +MarketplaceDialog.Search.Clear=검색 필터 지우기 +MarketplaceDialog.Button.Install=설치 +MarketplaceDialog.Button.Uninstall=제거 +MarketplaceDialog.Button.Refresh=새로고침 +MarketplaceDialog.Button.Close=닫기 +MarketplaceDialog.Button.ManageRepos=관리… +MarketplaceDialog.Button.BrowseEnv=찾아보기… +MarketplaceDialog.Button.EditEnv=편집… +MarketplaceDialog.Button.EditEnv.Tooltip=환경 파일 생성 또는 편집(리포지토리, 플러그인, 종속성) +MarketplaceDialog.Button.ValidateEnv=검증 +MarketplaceDialog.Button.ValidateEnv.Tooltip=설치하지 않고 로컬 설치를 환경 파일과 대조합니다 +MarketplaceDialog.Button.ApplyEnv=적용 +MarketplaceDialog.Button.ApplyEnv.Tooltip=환경 파일에 선언된 플러그인 및 종속성을 설치합니다 +MarketplaceDialog.EnvFile.Label=환경 파일 +MarketplaceDialog.EnvFile.Prune=적용 시 추가 항목 제거 +MarketplaceDialog.EnvFile.Prune.Tooltip=적용 시 파일에 없는 영수증이 있는 Marketplace 플러그인을 제거합니다 +MarketplaceDialog.EnvFile.Strict=엄격 검증 +MarketplaceDialog.EnvFile.Strict.Tooltip=검증 시 파일 범위를 넘는 추가 Marketplace 플러그인이 설치되어 있어도 실패합니다 +MarketplaceDialog.EnvFile.Filter.Env=Hop 환경 파일 (*.yaml, *.yml, *.json) +MarketplaceDialog.EnvFile.Filter.All=모든 파일 +MarketplaceDialog.EnvFile.Missing.Header=환경 파일 필요 +MarketplaceDialog.EnvFile.Missing.Message=찾아보기…로 hop-env.yaml(또는 full-client-env.yaml)을 선택하거나 경로를 입력하세요. +MarketplaceDialog.EnvFile.NotFound.Header=파일을 찾을 수 없음 +MarketplaceDialog.EnvFile.NotFound.Message=환경 파일이 존재하지 않습니다:\n{0} +MarketplaceDialog.Status.Installed=설치됨 +MarketplaceDialog.Status.Present=디스크에 있음 +MarketplaceDialog.Status.NotInstalled=설치되지 않음 +MarketplaceDialog.Status.RestartHint=설치·적용·제거 후 플러그인을 다시 로드하려면 Hop을 다시 시작하세요. 설치는 기본 리포지토리를 먼저 시도한 뒤 다른 사용 리포지토리를 사용합니다. +MarketplaceDialog.Status.Installing={0} 설치 중... +MarketplaceDialog.Status.Validating=환경 파일 검증 중... +MarketplaceDialog.Status.Applying=환경 파일 적용 중... +MarketplaceDialog.Status.Drift=환경 불일치 감지 — 적용으로 수정하세요 +MarketplaceDialog.Error.Header=Marketplace 오류 +MarketplaceDialog.Error.ResolveHome=Hop 설치 디렉터리를 확인할 수 없습니다. 설치 루트에서 hop 런처로 시작하세요. +MarketplaceDialog.Install.Done.Header=플러그인 설치됨 +MarketplaceDialog.Install.Done.Message={0}을(를) 설치했습니다.\n\n플러그인을 로드하려면 Hop을 다시 시작하세요. +MarketplaceDialog.Install.Error={0} 설치 실패 +MarketplaceDialog.Uninstall.Confirm.Header=플러그인 제거 +MarketplaceDialog.Uninstall.Confirm.Message=Marketplace로 설치한 플러그인 {0}을(를) 제거할까요? +MarketplaceDialog.Uninstall.NoReceipt.Header=제거할 수 없음 +MarketplaceDialog.Uninstall.NoReceipt.Message={0}에 대한 Marketplace 설치 영수증이 없습니다. 여기서는 Marketplace로 설치한 플러그인만 제거할 수 있습니다. +MarketplaceDialog.Uninstall.Error={0} 제거 실패 +MarketplaceDialog.Validate.Ok.Header=환경 정상 +MarketplaceDialog.Validate.Ok.Message=로컬 설치가 일치합니다:\n{0} +MarketplaceDialog.Validate.Drift.Header=환경 불일치 +MarketplaceDialog.Validate.Drift.Message=로컬 설치가 환경 파일과 일치하지 않습니다: +MarketplaceDialog.Validate.Drift.Hint=적용으로 누락된 플러그인을 설치하거나 버전을 수정한 뒤 Hop을 다시 시작하세요. +MarketplaceDialog.Validate.Error=환경 파일 검증 실패 +MarketplaceDialog.Apply.PruneConfirm.Header=Marketplace 플러그인을 정리할까요? +MarketplaceDialog.Apply.PruneConfirm.Message=정리와 함께 적용하면 환경 파일에 없는 Marketplace 플러그인이 제거됩니다.\n\n계속할까요? +MarketplaceDialog.Apply.Disabled=Marketplace가 hop-config.json에서 비활성화되어 있습니다. +MarketplaceDialog.Apply.Done.Header=환경 적용됨 +MarketplaceDialog.Apply.Done.Message=적용됨:\n{0}\n\n새 플러그인을 로드하려면 Hop을 다시 시작하세요. +MarketplaceDialog.Apply.Error=환경 파일 적용 실패 +ManageRepositoriesDialog.Shell.Title=Marketplace 리포지토리 +ManageRepositoriesDialog.Help=기본 리포지토리를 먼저 시도합니다. 다른 사용 리포지토리는 대체입니다.\n기본값: Apache Repository(repository.apache.org) 다음 Maven Central.\n설정은 '${HOP_CONFIG_FOLDER}'의 hop-config.json에 저장됩니다. +ManageRepositoriesDialog.Column.Primary=기본 +ManageRepositoriesDialog.Column.Enabled=사용 +ManageRepositoriesDialog.Column.Id=Id +ManageRepositoriesDialog.Column.Name=이름 +ManageRepositoriesDialog.Column.Url=URL +ManageRepositoriesDialog.Column.Auth=인증 +ManageRepositoriesDialog.Button.Add=추가 +ManageRepositoriesDialog.Button.Edit=편집 +ManageRepositoriesDialog.Button.Remove=제거 +ManageRepositoriesDialog.Button.SetPrimary=기본으로 설정 +ManageRepositoriesDialog.Button.MoveUp=위로 +ManageRepositoriesDialog.Button.MoveDown=아래로 +ManageRepositoriesDialog.Button.ResetDefaults=기본값으로 재설정 +ManageRepositoriesDialog.Button.Save=저장 +ManageRepositoriesDialog.Button.Cancel=취소 +ManageRepositoriesDialog.Button.Ok=확인 +ManageRepositoriesDialog.Save.Done.Header=리포지토리 저장됨 +ManageRepositoriesDialog.Save.Done.Message=Marketplace 리포지토리 설정이 hop-config.json에 저장되었습니다. +ManageRepositoriesDialog.Error.Header=리포지토리 오류 +ManageRepositoriesDialog.Error.Save=Marketplace 구성을 저장할 수 없습니다 +ManageRepositoriesDialog.Reset.Header=리포지토리 재설정 +ManageRepositoriesDialog.Reset.Message=리포지토리 목록을 Apache Repository(기본)와 Maven Central로 바꿀까요? +ManageRepositoriesDialog.Edit.Title.Add=리포지토리 추가 +ManageRepositoriesDialog.Edit.Title.Edit=리포지토리 편집 +ManageRepositoriesDialog.Edit.Id=ID +ManageRepositoriesDialog.Edit.Name=이름 +ManageRepositoriesDialog.Edit.Url=URL +ManageRepositoriesDialog.Edit.Username=사용자 이름 +ManageRepositoriesDialog.Edit.Password=비밀번호 +ManageRepositoriesDialog.Edit.Enabled=사용(대체 체인에서 사용) +ManageRepositoriesDialog.Edit.Primary=기본(먼저 시도) +ManageRepositoriesDialog.Edit.IdUrlRequired=Id와 URL이 필요합니다. +HopEnvironmentDialog.Shell.Title=Marketplace 환경 — {0} +HopEnvironmentDialog.Untitled=제목 없음 +HopEnvironmentDialog.Button.New=새로 만들기 +HopEnvironmentDialog.Button.Open=열기… +HopEnvironmentDialog.Button.Save=저장 +HopEnvironmentDialog.Button.SaveAs=다른 이름으로 저장… +HopEnvironmentDialog.Button.Validate=검증 +HopEnvironmentDialog.Button.Validate.Tooltip=설치하지 않고 로컬 설치를 이 환경 파일과 대조합니다 +HopEnvironmentDialog.Button.Apply=적용 +HopEnvironmentDialog.Button.Apply.Tooltip=이 환경 파일에 선언된 플러그인 및 종속성을 설치합니다 +HopEnvironmentDialog.Button.Close=닫기 +HopEnvironmentDialog.Button.Ok=확인 +HopEnvironmentDialog.Button.Cancel=취소 +HopEnvironmentDialog.Button.Add=추가 +HopEnvironmentDialog.Button.Edit=편집 +HopEnvironmentDialog.Button.Remove=제거 +HopEnvironmentDialog.Button.MoveUp=위로 +HopEnvironmentDialog.Button.MoveDown=아래로 +HopEnvironmentDialog.Button.AddFromCatalog=카탈로그에서… +HopEnvironmentDialog.Button.ImportRepos=hop-config에서 가져오기… +HopEnvironmentDialog.Prune=적용 시 추가 항목 제거 +HopEnvironmentDialog.Prune.Tooltip=적용 시 파일에 없는 영수증이 있는 Marketplace 플러그인을 제거합니다 +HopEnvironmentDialog.Strict=엄격 검증 +HopEnvironmentDialog.Strict.Tooltip=검증 시 파일 범위를 넘는 추가 Marketplace 플러그인이 설치되어 있어도 실패합니다 +HopEnvironmentDialog.Filter.Yaml=YAML 환경 (*.yaml, *.yml) +HopEnvironmentDialog.Filter.Json=JSON 환경 (*.json) +HopEnvironmentDialog.Tab.General=일반 +HopEnvironmentDialog.Tab.Repositories=리포지토리 +HopEnvironmentDialog.Tab.Plugins=플러그인 +HopEnvironmentDialog.Tab.Dependencies=종속성 +HopEnvironmentDialog.General.Help=이 Hop 설치에 있어야 할 플러그인과 jar를 선언하세요. CI/Docker용 hop-env.yaml로 저장하거나 이 대화상자에서 검증/적용을 사용하세요. +HopEnvironmentDialog.General.Version=스펙 버전 +HopEnvironmentDialog.General.HopVersion=Hop 버전 +HopEnvironmentDialog.General.EnforceOnRun=hop-run에서 강제 +HopEnvironmentDialog.General.EnforceOnRun.Tooltip=true이면 설치가 이 파일에서 벗어나면 hop-run이 실패할 수 있습니다(-Dhop.env.enforce=true로도 제어) +HopEnvironmentDialog.Repositories.Help=첫 행이 기본(먼저 시도)이고 이후 행은 대체입니다. 이 리포지토리는 환경 파일에 있으며(hop-config 아님) 비밀번호는 커밋하지 않는 것이 좋습니다. +HopEnvironmentDialog.Plugins.Help=설치할 Marketplace 플러그인. Group ID를 비우면 org.apache.hop을 사용합니다. 적용 시 일반 탭의 Hop 버전이 기본값이 될 수 있습니다. +HopEnvironmentDialog.Dependencies.Help=선택적 Maven jar(예: JDBC 드라이버). Hop 홈의 대상 디렉터리 아래에 설치됩니다(기본 lib/jdbc). +HopEnvironmentDialog.Repo.Column.Id=Id +HopEnvironmentDialog.Repo.Column.Url=URL +HopEnvironmentDialog.Repo.Column.Username=사용자 이름 +HopEnvironmentDialog.Repo.Column.Password=비밀번호 +HopEnvironmentDialog.Repo.Column.Auth=인증 +HopEnvironmentDialog.Repo.Edit.Add=리포지토리 추가 +HopEnvironmentDialog.Repo.Edit.Edit=리포지토리 편집 +HopEnvironmentDialog.Plugin.Column.GroupId=Group ID +HopEnvironmentDialog.Plugin.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Plugin.Column.Version=버전 +HopEnvironmentDialog.Plugin.Edit.Add=플러그인 추가 +HopEnvironmentDialog.Plugin.Edit.Edit=플러그인 편집 +HopEnvironmentDialog.Dep.Column.GroupId=Group ID +HopEnvironmentDialog.Dep.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Dep.Column.Version=버전 +HopEnvironmentDialog.Dep.Column.Target=대상 +HopEnvironmentDialog.Dep.Edit.Add=종속성 추가 +HopEnvironmentDialog.Dep.Edit.Edit=종속성 편집 +HopEnvironmentDialog.Dirty.Header=저장되지 않은 변경 사항 +HopEnvironmentDialog.Dirty.Message=계속하기 전에 환경 파일 변경 사항을 저장할까요? +HopEnvironmentDialog.SaveFirst.Header=환경 파일을 저장할까요? +HopEnvironmentDialog.SaveFirst.Message=검증 또는 적용 전에 환경 파일을 저장할까요? +HopEnvironmentDialog.Validation.Header=잘못된 환경 +HopEnvironmentDialog.Validation.RepoIdUrl=각 리포지토리에는 Id와 URL이 필요합니다. +HopEnvironmentDialog.Validation.PluginArtifact=각 플러그인에는 Artifact ID가 필요합니다. +HopEnvironmentDialog.Validation.DepGav=각 종속성에는 Group ID, Artifact ID 및 Version이 필요합니다. +HopEnvironmentDialog.ImportRepos.Header=리포지토리 가져오기 +HopEnvironmentDialog.ImportRepos.Message=리포지토리 목록을 hop-config.json의 사용 중인 리포지토리로 바꿀까요? +HopEnvironmentDialog.Error.Header=환경 편집기 오류 +HopEnvironmentDialog.Error.Load=환경 파일을 로드할 수 없습니다:\n{0} +HopEnvironmentDialog.Error.Save=환경 파일을 저장할 수 없습니다:\n{0} +HopEnvironmentDialog.Error.ImportRepos=hop-config에서 리포지토리를 가져올 수 없습니다 +AddPluginsFromCatalogDialog.Shell.Title=카탈로그에서 플러그인 추가 +AddPluginsFromCatalogDialog.Filter.Label=필터 +AddPluginsFromCatalogDialog.Button.Add=선택 항목 추가 +AddPluginsFromCatalogDialog.Button.Cancel=취소 +AddPluginsFromCatalogDialog.Column.Name=이름 +AddPluginsFromCatalogDialog.Column.Artifact=아티팩트 +AddPluginsFromCatalogDialog.Column.Category=범주 +AddPluginsFromCatalogDialog.Column.Description=설명 diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_nl_NL.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_nl_NL.properties new file mode 100644 index 00000000000..1950e506b3c --- /dev/null +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_nl_NL.properties @@ -0,0 +1,209 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +MarketplaceGuiPlugin.Menu.Marketplace.Text=Marketplace... +MarketplaceGuiPlugin.Toolbar.Marketplace.Tooltip=Marketplace… +MarketplaceLifecycleEnv.Tab.Plugins=Marketplace-plugins +MarketplaceLifecycleEnv.Help=De pluginset wordt gedefinieerd in een hop-env-bestand. Deze opties bepalen wanneer Hop dat bestand controleert voor deze lifecycle-omgeving (los in development; strikt in productie). +MarketplaceLifecycleEnv.EnvFile.Label=Omgevingsbestand +MarketplaceLifecycleEnv.Button.Browse=Bladeren… +MarketplaceLifecycleEnv.Button.EditEnv=Bewerken… +MarketplaceLifecycleEnv.OnEnable.Label=Bij activeren +MarketplaceLifecycleEnv.OnEnable.Tooltip=off: geen controle; warn: log/dialoog bij afwijking; enforce: activeren van de omgeving mislukt bij afwijking +MarketplaceLifecycleEnv.Strict.Label=Strikt (mislukken als er extra marketplace-plugins geïnstalleerd zijn) +MarketplaceLifecycleEnv.Strict.Tooltip=Bij validatie ook marketplace-plugins met receipt die niet in het env-bestand staan als afwijking behandelen +MarketplaceLifecycleEnv.AutoApply.Label=Ontbrekende plugins automatisch toepassen bij activeren +MarketplaceLifecycleEnv.AutoApply.Tooltip=Indien ingeschakeld, voert marketplace apply uit voor ontbrekende plugins (alleen op gecontroleerde machines; standaard uit) +MarketplaceDialog.Shell.Title=Plugin-marketplace +MarketplaceDialog.Tab.Plugins=Plugins +MarketplaceDialog.Tab.Environment=Omgeving +MarketplaceDialog.Tab.Repositories=Repositories +MarketplaceDialog.Repository.Label=Primaire repository +MarketplaceDialog.Repository.SetPrimary.Error=Kon de primaire repository niet instellen +MarketplaceDialog.Column.Name=Naam +MarketplaceDialog.Column.Artifact=Artifact +MarketplaceDialog.Column.Category=Categorie +MarketplaceDialog.Column.Status=Status +MarketplaceDialog.Column.Description=Beschrijving +MarketplaceDialog.Search.Label=Zoeken +MarketplaceDialog.Search.Placeholder=Typ 3+ tekens om plugins te filteren… +MarketplaceDialog.Search.Clear=Zoekfilter wissen +MarketplaceDialog.Button.Install=Installeren +MarketplaceDialog.Button.Uninstall=Deïnstalleren +MarketplaceDialog.Button.Refresh=Vernieuwen +MarketplaceDialog.Button.Close=Sluiten +MarketplaceDialog.Button.ManageRepos=Beheren… +MarketplaceDialog.Button.BrowseEnv=Bladeren… +MarketplaceDialog.Button.EditEnv=Bewerken… +MarketplaceDialog.Button.EditEnv.Tooltip=Omgevingsbestand maken of bewerken (repositories, plugins, afhankelijkheden) +MarketplaceDialog.Button.ValidateEnv=Valideren +MarketplaceDialog.Button.ValidateEnv.Tooltip=Lokale installatie controleren tegen het omgevingsbestand zonder te installeren +MarketplaceDialog.Button.ApplyEnv=Toepassen +MarketplaceDialog.Button.ApplyEnv.Tooltip=Plugins en afhankelijkheden uit het omgevingsbestand installeren +MarketplaceDialog.EnvFile.Label=Omgevingsbestand +MarketplaceDialog.EnvFile.Prune=Extra's bij toepassen opruimen +MarketplaceDialog.EnvFile.Prune.Tooltip=Bij toepassen marketplace-plugins met receipt deïnstalleren die niet in het bestand staan +MarketplaceDialog.EnvFile.Strict=Strikte validatie +MarketplaceDialog.EnvFile.Strict.Tooltip=Bij validatie ook mislukken als er extra marketplace-plugins buiten het bestand geïnstalleerd zijn +MarketplaceDialog.EnvFile.Filter.Env=Hop-omgevingsbestanden (*.yaml, *.yml, *.json) +MarketplaceDialog.EnvFile.Filter.All=Alle bestanden +MarketplaceDialog.EnvFile.Missing.Header=Omgevingsbestand vereist +MarketplaceDialog.EnvFile.Missing.Message=Selecteer een hop-env.yaml (of full-client-env.yaml) met Bladeren…, of typ het pad. +MarketplaceDialog.EnvFile.NotFound.Header=Bestand niet gevonden +MarketplaceDialog.EnvFile.NotFound.Message=Omgevingsbestand bestaat niet:\n{0} +MarketplaceDialog.Status.Installed=Geïnstalleerd +MarketplaceDialog.Status.Present=Aanwezig op schijf +MarketplaceDialog.Status.NotInstalled=Niet geïnstalleerd +MarketplaceDialog.Status.RestartHint=Herstart Hop na installeren, toepassen of deïnstalleren zodat plugins opnieuw worden geladen. Installatie probeert eerst de primaire repository, daarna andere ingeschakelde repositories. +MarketplaceDialog.Status.Installing={0} installeren... +MarketplaceDialog.Status.Validating=Omgevingsbestand valideren... +MarketplaceDialog.Status.Applying=Omgevingsbestand toepassen... +MarketplaceDialog.Status.Drift=Omgevingsafwijking gedetecteerd — gebruik Toepassen om te herstellen +MarketplaceDialog.Error.Header=Marketplace-fout +MarketplaceDialog.Error.ResolveHome=Kon de Hop-installatiemap niet bepalen. Start Hop vanaf de installatieroot met de hop-launcher. +MarketplaceDialog.Install.Done.Header=Plugin geïnstalleerd +MarketplaceDialog.Install.Done.Message={0} geïnstalleerd.\n\nHerstart Hop om de plugin te laden. +MarketplaceDialog.Install.Error=Installatie van {0} mislukt +MarketplaceDialog.Uninstall.Confirm.Header=Plugin deïnstalleren +MarketplaceDialog.Uninstall.Confirm.Message=Via marketplace geïnstalleerde plugin {0} verwijderen? +MarketplaceDialog.Uninstall.NoReceipt.Header=Kan niet deïnstalleren +MarketplaceDialog.Uninstall.NoReceipt.Message=Geen marketplace-installatiebewijs voor {0}. Hier kunnen alleen via de marketplace geïnstalleerde plugins worden deïnstalleerd. +MarketplaceDialog.Uninstall.Error=Deïnstallatie van {0} mislukt +MarketplaceDialog.Validate.Ok.Header=Omgeving OK +MarketplaceDialog.Validate.Ok.Message=Lokale installatie komt overeen:\n{0} +MarketplaceDialog.Validate.Drift.Header=Omgevingsafwijking +MarketplaceDialog.Validate.Drift.Message=De lokale installatie komt niet overeen met het omgevingsbestand: +MarketplaceDialog.Validate.Drift.Hint=Gebruik Toepassen om ontbrekende plugins te installeren (of versies te herstellen) en herstart Hop. +MarketplaceDialog.Validate.Error=Validatie van omgevingsbestand mislukt +MarketplaceDialog.Apply.PruneConfirm.Header=Marketplace-plugins opruimen? +MarketplaceDialog.Apply.PruneConfirm.Message=Toepassen met opruimen deïnstalleert marketplace-plugins die niet in het omgevingsbestand staan.\n\nDoorgaan? +MarketplaceDialog.Apply.Disabled=Marketplace is uitgeschakeld in hop-config.json. +MarketplaceDialog.Apply.Done.Header=Omgeving toegepast +MarketplaceDialog.Apply.Done.Message=Toegepast:\n{0}\n\nHerstart Hop om nieuwe plugins te laden. +MarketplaceDialog.Apply.Error=Toepassen van omgevingsbestand mislukt +ManageRepositoriesDialog.Shell.Title=Marketplace-repositories +ManageRepositoriesDialog.Help=De primaire repository wordt eerst geprobeerd. De overige ingeschakelde repositories zijn fallbacks.\nStandaard: Apache Repository (repository.apache.org) en daarna Maven Central.\nInstellingen worden opgeslagen in hop-config.json onder '${HOP_CONFIG_FOLDER}'. +ManageRepositoriesDialog.Column.Primary=Primair +ManageRepositoriesDialog.Column.Enabled=Ingeschakeld +ManageRepositoriesDialog.Column.Id=Id +ManageRepositoriesDialog.Column.Name=Naam +ManageRepositoriesDialog.Column.Url=URL +ManageRepositoriesDialog.Column.Auth=Auth +ManageRepositoriesDialog.Button.Add=Toevoegen +ManageRepositoriesDialog.Button.Edit=Bewerken +ManageRepositoriesDialog.Button.Remove=Verwijderen +ManageRepositoriesDialog.Button.SetPrimary=Als primair instellen +ManageRepositoriesDialog.Button.MoveUp=Omhoog +ManageRepositoriesDialog.Button.MoveDown=Omlaag +ManageRepositoriesDialog.Button.ResetDefaults=Standaardwaarden herstellen +ManageRepositoriesDialog.Button.Save=Opslaan +ManageRepositoriesDialog.Button.Cancel=Annuleren +ManageRepositoriesDialog.Button.Ok=OK +ManageRepositoriesDialog.Save.Done.Header=Repositories opgeslagen +ManageRepositoriesDialog.Save.Done.Message=Marketplace-repository-instellingen zijn opgeslagen in hop-config.json. +ManageRepositoriesDialog.Error.Header=Repositoryfout +ManageRepositoriesDialog.Error.Save=Kon marketplace-configuratie niet opslaan +ManageRepositoriesDialog.Reset.Header=Repositories herstellen +ManageRepositoriesDialog.Reset.Message=Repositorylijst vervangen door Apache Repository (primair) en Maven Central? +ManageRepositoriesDialog.Edit.Title.Add=Repository toevoegen +ManageRepositoriesDialog.Edit.Title.Edit=Repository bewerken +ManageRepositoriesDialog.Edit.Id=ID +ManageRepositoriesDialog.Edit.Name=Naam +ManageRepositoriesDialog.Edit.Url=URL +ManageRepositoriesDialog.Edit.Username=Gebruikersnaam +ManageRepositoriesDialog.Edit.Password=Wachtwoord +ManageRepositoriesDialog.Edit.Enabled=Ingeschakeld (gebruiken in fallback-keten) +ManageRepositoriesDialog.Edit.Primary=Primair (eerst geprobeerd) +ManageRepositoriesDialog.Edit.IdUrlRequired=Id en URL zijn verplicht. +HopEnvironmentDialog.Shell.Title=Marketplace-omgeving — {0} +HopEnvironmentDialog.Untitled=Naamloos +HopEnvironmentDialog.Button.New=Nieuw +HopEnvironmentDialog.Button.Open=Openen… +HopEnvironmentDialog.Button.Save=Opslaan +HopEnvironmentDialog.Button.SaveAs=Opslaan als… +HopEnvironmentDialog.Button.Validate=Valideren +HopEnvironmentDialog.Button.Validate.Tooltip=Lokale installatie controleren tegen dit omgevingsbestand zonder te installeren +HopEnvironmentDialog.Button.Apply=Toepassen +HopEnvironmentDialog.Button.Apply.Tooltip=Plugins en afhankelijkheden uit dit omgevingsbestand installeren +HopEnvironmentDialog.Button.Close=Sluiten +HopEnvironmentDialog.Button.Ok=OK +HopEnvironmentDialog.Button.Cancel=Annuleren +HopEnvironmentDialog.Button.Add=Toevoegen +HopEnvironmentDialog.Button.Edit=Bewerken +HopEnvironmentDialog.Button.Remove=Verwijderen +HopEnvironmentDialog.Button.MoveUp=Omhoog +HopEnvironmentDialog.Button.MoveDown=Omlaag +HopEnvironmentDialog.Button.AddFromCatalog=Uit catalogus… +HopEnvironmentDialog.Button.ImportRepos=Importeren uit hop-config… +HopEnvironmentDialog.Prune=Extra's bij toepassen opruimen +HopEnvironmentDialog.Prune.Tooltip=Bij toepassen marketplace-plugins met receipt deïnstalleren die niet in het bestand staan +HopEnvironmentDialog.Strict=Strikte validatie +HopEnvironmentDialog.Strict.Tooltip=Bij validatie ook mislukken als er extra marketplace-plugins buiten het bestand geïnstalleerd zijn +HopEnvironmentDialog.Filter.Yaml=YAML-omgeving (*.yaml, *.yml) +HopEnvironmentDialog.Filter.Json=JSON-omgeving (*.json) +HopEnvironmentDialog.Tab.General=Algemeen +HopEnvironmentDialog.Tab.Repositories=Repositories +HopEnvironmentDialog.Tab.Plugins=Plugins +HopEnvironmentDialog.Tab.Dependencies=Afhankelijkheden +HopEnvironmentDialog.General.Help=Geef aan welke plugins en jars deze Hop-installatie moet hebben. Sla op als hop-env.yaml voor CI/Docker, of gebruik Valideren / Toepassen in dit dialoogvenster. +HopEnvironmentDialog.General.Version=Specificatieversie +HopEnvironmentDialog.General.HopVersion=Hop-versie +HopEnvironmentDialog.General.EnforceOnRun=Afdwingen bij hop-run +HopEnvironmentDialog.General.EnforceOnRun.Tooltip=Indien true kan hop-run mislukken als de installatie van dit bestand afwijkt (ook gestuurd door -Dhop.env.enforce=true) +HopEnvironmentDialog.Repositories.Help=De eerste rij is primair (eerst geprobeerd); latere rijen zijn fallbacks. Deze repositories staan in het omgevingsbestand (niet hop-config). Commit bij voorkeur geen wachtwoorden. +HopEnvironmentDialog.Plugins.Help=Te installeren marketplace-plugins. Laat Group ID leeg voor org.apache.hop. Versie kan bij toepassen van de Hop-versie op het tabblad Algemeen komen. +HopEnvironmentDialog.Dependencies.Help=Optionele Maven-jars (bijv. JDBC-drivers) geïnstalleerd onder de doelmap van Hop home (standaard lib/jdbc). +HopEnvironmentDialog.Repo.Column.Id=Id +HopEnvironmentDialog.Repo.Column.Url=URL +HopEnvironmentDialog.Repo.Column.Username=Gebruikersnaam +HopEnvironmentDialog.Repo.Column.Password=Wachtwoord +HopEnvironmentDialog.Repo.Column.Auth=Auth +HopEnvironmentDialog.Repo.Edit.Add=Repository toevoegen +HopEnvironmentDialog.Repo.Edit.Edit=Repository bewerken +HopEnvironmentDialog.Plugin.Column.GroupId=Group ID +HopEnvironmentDialog.Plugin.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Plugin.Column.Version=Versie +HopEnvironmentDialog.Plugin.Edit.Add=Plugin toevoegen +HopEnvironmentDialog.Plugin.Edit.Edit=Plugin bewerken +HopEnvironmentDialog.Dep.Column.GroupId=Group ID +HopEnvironmentDialog.Dep.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Dep.Column.Version=Versie +HopEnvironmentDialog.Dep.Column.Target=Doel +HopEnvironmentDialog.Dep.Edit.Add=Afhankelijkheid toevoegen +HopEnvironmentDialog.Dep.Edit.Edit=Afhankelijkheid bewerken +HopEnvironmentDialog.Dirty.Header=Niet-opgeslagen wijzigingen +HopEnvironmentDialog.Dirty.Message=Wijzigingen in het omgevingsbestand opslaan voordat u doorgaat? +HopEnvironmentDialog.SaveFirst.Header=Omgevingsbestand opslaan? +HopEnvironmentDialog.SaveFirst.Message=Omgevingsbestand opslaan vóór Valideren of Toepassen? +HopEnvironmentDialog.Validation.Header=Ongeldige omgeving +HopEnvironmentDialog.Validation.RepoIdUrl=Elke repository heeft een Id en URL nodig. +HopEnvironmentDialog.Validation.PluginArtifact=Elke plugin heeft een Artifact ID nodig. +HopEnvironmentDialog.Validation.DepGav=Elke afhankelijkheid heeft Group ID, Artifact ID en Version nodig. +HopEnvironmentDialog.ImportRepos.Header=Repositories importeren +HopEnvironmentDialog.ImportRepos.Message=Repositorylijst vervangen door ingeschakelde repositories uit hop-config.json? +HopEnvironmentDialog.Error.Header=Fout in omgevingseditor +HopEnvironmentDialog.Error.Load=Kon omgevingsbestand niet laden:\n{0} +HopEnvironmentDialog.Error.Save=Kon omgevingsbestand niet opslaan:\n{0} +HopEnvironmentDialog.Error.ImportRepos=Kon repositories niet importeren uit hop-config +AddPluginsFromCatalogDialog.Shell.Title=Plugins uit catalogus toevoegen +AddPluginsFromCatalogDialog.Filter.Label=Filter +AddPluginsFromCatalogDialog.Button.Add=Selectie toevoegen +AddPluginsFromCatalogDialog.Button.Cancel=Annuleren +AddPluginsFromCatalogDialog.Column.Name=Naam +AddPluginsFromCatalogDialog.Column.Artifact=Artifact +AddPluginsFromCatalogDialog.Column.Category=Categorie +AddPluginsFromCatalogDialog.Column.Description=Beschrijving diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_no_NO.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_no_NO.properties new file mode 100644 index 00000000000..5d95bccb61c --- /dev/null +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_no_NO.properties @@ -0,0 +1,209 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +MarketplaceGuiPlugin.Menu.Marketplace.Text=Marketplace... +MarketplaceGuiPlugin.Toolbar.Marketplace.Tooltip=Marketplace… +MarketplaceLifecycleEnv.Tab.Plugins=Marketplace-plugins +MarketplaceLifecycleEnv.Help=Plugin-settet defineres i en hop-env-fil. Disse alternativene styrer når Hop sjekker filen for dette livssyklusmiljøet (løst i dev; strengt i produksjon). +MarketplaceLifecycleEnv.EnvFile.Label=Miljøfil +MarketplaceLifecycleEnv.Button.Browse=Bla gjennom… +MarketplaceLifecycleEnv.Button.EditEnv=Rediger… +MarketplaceLifecycleEnv.OnEnable.Label=Ved aktivering +MarketplaceLifecycleEnv.OnEnable.Tooltip=off: ingen sjekk; warn: logg/dialog ved avvik; enforce: mislykk aktivering ved avvik +MarketplaceLifecycleEnv.Strict.Label=Streng (mislykkes hvis ekstra marketplace-plugins er installert) +MarketplaceLifecycleEnv.Strict.Tooltip=Ved validering, behandle også marketplace-plugins med kvittering som ikke er i env-filen som avvik +MarketplaceLifecycleEnv.AutoApply.Label=Auto-bruk manglende plugins ved aktivering +MarketplaceLifecycleEnv.AutoApply.Tooltip=Når aktivert, kjører marketplace apply for manglende plugins (kun på kontrollerte maskiner; av som standard) +MarketplaceDialog.Shell.Title=Plugin-marketplace +MarketplaceDialog.Tab.Plugins=Plugins +MarketplaceDialog.Tab.Environment=Miljø +MarketplaceDialog.Tab.Repositories=Depot +MarketplaceDialog.Repository.Label=Primært depot +MarketplaceDialog.Repository.SetPrimary.Error=Kunne ikke sette primært depot +MarketplaceDialog.Column.Name=Navn +MarketplaceDialog.Column.Artifact=Artifact +MarketplaceDialog.Column.Category=Kategori +MarketplaceDialog.Column.Status=Status +MarketplaceDialog.Column.Description=Beskrivelse +MarketplaceDialog.Search.Label=Søk +MarketplaceDialog.Search.Placeholder=Skriv 3+ tegn for å filtrere plugins… +MarketplaceDialog.Search.Clear=Tøm søkefilter +MarketplaceDialog.Button.Install=Installer +MarketplaceDialog.Button.Uninstall=Avinstaller +MarketplaceDialog.Button.Refresh=Oppdater +MarketplaceDialog.Button.Close=Lukk +MarketplaceDialog.Button.ManageRepos=Administrer… +MarketplaceDialog.Button.BrowseEnv=Bla gjennom… +MarketplaceDialog.Button.EditEnv=Rediger… +MarketplaceDialog.Button.EditEnv.Tooltip=Opprett eller rediger miljøfilen (depot, plugins, avhengigheter) +MarketplaceDialog.Button.ValidateEnv=Valider +MarketplaceDialog.Button.ValidateEnv.Tooltip=Sjekk den lokale installasjonen mot miljøfilen uten å installere +MarketplaceDialog.Button.ApplyEnv=Bruk +MarketplaceDialog.Button.ApplyEnv.Tooltip=Installer plugins og avhengigheter erklært i miljøfilen +MarketplaceDialog.EnvFile.Label=Miljøfil +MarketplaceDialog.EnvFile.Prune=Fjern ekstra ved bruk +MarketplaceDialog.EnvFile.Prune.Tooltip=Ved bruk, avinstaller marketplace-plugins med kvittering som ikke er i filen +MarketplaceDialog.EnvFile.Strict=Streng validering +MarketplaceDialog.EnvFile.Strict.Tooltip=Ved validering, mislykkes også hvis ekstra marketplace-plugins er installert utover filen +MarketplaceDialog.EnvFile.Filter.Env=Hop-miljøfiler (*.yaml, *.yml, *.json) +MarketplaceDialog.EnvFile.Filter.All=Alle filer +MarketplaceDialog.EnvFile.Missing.Header=Miljøfil kreves +MarketplaceDialog.EnvFile.Missing.Message=Velg en hop-env.yaml (eller full-client-env.yaml) med Bla gjennom…, eller skriv inn banen. +MarketplaceDialog.EnvFile.NotFound.Header=Fil ikke funnet +MarketplaceDialog.EnvFile.NotFound.Message=Miljøfilen finnes ikke:\n{0} +MarketplaceDialog.Status.Installed=Installert +MarketplaceDialog.Status.Present=Tilstede på disk +MarketplaceDialog.Status.NotInstalled=Ikke installert +MarketplaceDialog.Status.RestartHint=Start Hop på nytt etter installasjon, bruk eller avinstallasjon slik at plugins lastes på nytt. Installasjon prøver primært depot først, deretter andre aktiverte depot. +MarketplaceDialog.Status.Installing=Installerer {0}... +MarketplaceDialog.Status.Validating=Validerer miljøfil... +MarketplaceDialog.Status.Applying=Bruker miljøfil... +MarketplaceDialog.Status.Drift=Miljøavvik oppdaget — bruk Bruk for å rette +MarketplaceDialog.Error.Header=Marketplace-feil +MarketplaceDialog.Error.ResolveHome=Kunne ikke fastslå Hop-installasjonskatalogen. Start Hop fra installasjonsroten med hop-starteren. +MarketplaceDialog.Install.Done.Header=Plugin installert +MarketplaceDialog.Install.Done.Message=Installert {0}.\n\nStart Hop på nytt for å laste pluginen. +MarketplaceDialog.Install.Error=Kunne ikke installere {0} +MarketplaceDialog.Uninstall.Confirm.Header=Avinstaller plugin +MarketplaceDialog.Uninstall.Confirm.Message=Fjerne marketplace-installert plugin {0}? +MarketplaceDialog.Uninstall.NoReceipt.Header=Kan ikke avinstallere +MarketplaceDialog.Uninstall.NoReceipt.Message=Ingen marketplace-installasjonskvittering for {0}. Bare plugins installert via marketplace kan avinstalleres her. +MarketplaceDialog.Uninstall.Error=Kunne ikke avinstallere {0} +MarketplaceDialog.Validate.Ok.Header=Miljø OK +MarketplaceDialog.Validate.Ok.Message=Lokal installasjon samsvarer:\n{0} +MarketplaceDialog.Validate.Drift.Header=Miljøavvik +MarketplaceDialog.Validate.Drift.Message=Den lokale installasjonen samsvarer ikke med miljøfilen: +MarketplaceDialog.Validate.Drift.Hint=Bruk Bruk for å installere manglende plugins (eller rette versjoner), og start Hop på nytt. +MarketplaceDialog.Validate.Error=Kunne ikke validere miljøfilen +MarketplaceDialog.Apply.PruneConfirm.Header=Rydde marketplace-plugins? +MarketplaceDialog.Apply.PruneConfirm.Message=Bruk med opprydding avinstallerer marketplace-plugins som ikke er i miljøfilen.\n\nFortsette? +MarketplaceDialog.Apply.Disabled=Marketplace er deaktivert i hop-config.json. +MarketplaceDialog.Apply.Done.Header=Miljø brukt +MarketplaceDialog.Apply.Done.Message=Brukt:\n{0}\n\nStart Hop på nytt for å laste nye plugins. +MarketplaceDialog.Apply.Error=Kunne ikke bruke miljøfilen +ManageRepositoriesDialog.Shell.Title=Marketplace-depot +ManageRepositoriesDialog.Help=Det primære depotet prøves først. Andre aktiverte depot er reserve.\nStandard: Apache Repository (repository.apache.org) deretter Maven Central.\nInnstillinger lagres i hop-config.json under '${HOP_CONFIG_FOLDER}'. +ManageRepositoriesDialog.Column.Primary=Primær +ManageRepositoriesDialog.Column.Enabled=Aktivert +ManageRepositoriesDialog.Column.Id=Id +ManageRepositoriesDialog.Column.Name=Navn +ManageRepositoriesDialog.Column.Url=URL +ManageRepositoriesDialog.Column.Auth=Auth +ManageRepositoriesDialog.Button.Add=Legg til +ManageRepositoriesDialog.Button.Edit=Rediger +ManageRepositoriesDialog.Button.Remove=Fjern +ManageRepositoriesDialog.Button.SetPrimary=Sett som primær +ManageRepositoriesDialog.Button.MoveUp=Opp +ManageRepositoriesDialog.Button.MoveDown=Ned +ManageRepositoriesDialog.Button.ResetDefaults=Tilbakestill standarder +ManageRepositoriesDialog.Button.Save=Lagre +ManageRepositoriesDialog.Button.Cancel=Avbryt +ManageRepositoriesDialog.Button.Ok=OK +ManageRepositoriesDialog.Save.Done.Header=Depot lagret +ManageRepositoriesDialog.Save.Done.Message=Marketplace-depotinnstillinger ble lagret i hop-config.json. +ManageRepositoriesDialog.Error.Header=Depotfeil +ManageRepositoriesDialog.Error.Save=Kunne ikke lagre marketplace-konfigurasjonen +ManageRepositoriesDialog.Reset.Header=Tilbakestill depot +ManageRepositoriesDialog.Reset.Message=Erstatte depotlisten med Apache Repository (primær) og Maven Central? +ManageRepositoriesDialog.Edit.Title.Add=Legg til depot +ManageRepositoriesDialog.Edit.Title.Edit=Rediger depot +ManageRepositoriesDialog.Edit.Id=ID +ManageRepositoriesDialog.Edit.Name=Navn +ManageRepositoriesDialog.Edit.Url=URL +ManageRepositoriesDialog.Edit.Username=Brukernavn +ManageRepositoriesDialog.Edit.Password=Passord +ManageRepositoriesDialog.Edit.Enabled=Aktivert (bruk i reservekjeden) +ManageRepositoriesDialog.Edit.Primary=Primær (prøves først) +ManageRepositoriesDialog.Edit.IdUrlRequired=Id og URL er påkrevd. +HopEnvironmentDialog.Shell.Title=Marketplace-miljø — {0} +HopEnvironmentDialog.Untitled=Uten navn +HopEnvironmentDialog.Button.New=Ny +HopEnvironmentDialog.Button.Open=Åpne… +HopEnvironmentDialog.Button.Save=Lagre +HopEnvironmentDialog.Button.SaveAs=Lagre som… +HopEnvironmentDialog.Button.Validate=Valider +HopEnvironmentDialog.Button.Validate.Tooltip=Sjekk den lokale installasjonen mot denne miljøfilen uten å installere +HopEnvironmentDialog.Button.Apply=Bruk +HopEnvironmentDialog.Button.Apply.Tooltip=Installer plugins og avhengigheter erklært i denne miljøfilen +HopEnvironmentDialog.Button.Close=Lukk +HopEnvironmentDialog.Button.Ok=OK +HopEnvironmentDialog.Button.Cancel=Avbryt +HopEnvironmentDialog.Button.Add=Legg til +HopEnvironmentDialog.Button.Edit=Rediger +HopEnvironmentDialog.Button.Remove=Fjern +HopEnvironmentDialog.Button.MoveUp=Opp +HopEnvironmentDialog.Button.MoveDown=Ned +HopEnvironmentDialog.Button.AddFromCatalog=Fra katalog… +HopEnvironmentDialog.Button.ImportRepos=Importer fra hop-config… +HopEnvironmentDialog.Prune=Fjern ekstra ved bruk +HopEnvironmentDialog.Prune.Tooltip=Ved bruk, avinstaller marketplace-plugins med kvittering som ikke er i filen +HopEnvironmentDialog.Strict=Streng validering +HopEnvironmentDialog.Strict.Tooltip=Ved validering, mislykkes også hvis ekstra marketplace-plugins er installert utover filen +HopEnvironmentDialog.Filter.Yaml=YAML-miljø (*.yaml, *.yml) +HopEnvironmentDialog.Filter.Json=JSON-miljø (*.json) +HopEnvironmentDialog.Tab.General=Generelt +HopEnvironmentDialog.Tab.Repositories=Depot +HopEnvironmentDialog.Tab.Plugins=Plugins +HopEnvironmentDialog.Tab.Dependencies=Avhengigheter +HopEnvironmentDialog.General.Help=Angi hvilke plugins og jars denne Hop-installasjonen skal ha. Lagre som hop-env.yaml for CI/Docker, eller bruk Valider / Bruk i denne dialogen. +HopEnvironmentDialog.General.Version=Spesifikasjonsversjon +HopEnvironmentDialog.General.HopVersion=Hop-versjon +HopEnvironmentDialog.General.EnforceOnRun=Håndhev på hop-run +HopEnvironmentDialog.General.EnforceOnRun.Tooltip=Hvis true, kan hop-run mislykkes hvis installasjonen avviker fra denne filen (også styrt av -Dhop.env.enforce=true) +HopEnvironmentDialog.Repositories.Help=Første rad er primær (prøves først); senere rader er reserve. Disse depotene ligger i miljøfilen (ikke hop-config). Unngå å committe passord. +HopEnvironmentDialog.Plugins.Help=Marketplace-plugins som skal installeres. La Group ID stå tom for org.apache.hop. Versjon kan standard fra Hop-versjon på Generelt-fanen ved bruk. +HopEnvironmentDialog.Dependencies.Help=Valgfrie Maven-jars (f.eks. JDBC-drivere) installert under målkatalogen i Hop home (standard lib/jdbc). +HopEnvironmentDialog.Repo.Column.Id=Id +HopEnvironmentDialog.Repo.Column.Url=URL +HopEnvironmentDialog.Repo.Column.Username=Brukernavn +HopEnvironmentDialog.Repo.Column.Password=Passord +HopEnvironmentDialog.Repo.Column.Auth=Auth +HopEnvironmentDialog.Repo.Edit.Add=Legg til depot +HopEnvironmentDialog.Repo.Edit.Edit=Rediger depot +HopEnvironmentDialog.Plugin.Column.GroupId=Group ID +HopEnvironmentDialog.Plugin.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Plugin.Column.Version=Versjon +HopEnvironmentDialog.Plugin.Edit.Add=Legg til plugin +HopEnvironmentDialog.Plugin.Edit.Edit=Rediger plugin +HopEnvironmentDialog.Dep.Column.GroupId=Group ID +HopEnvironmentDialog.Dep.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Dep.Column.Version=Versjon +HopEnvironmentDialog.Dep.Column.Target=Mål +HopEnvironmentDialog.Dep.Edit.Add=Legg til avhengighet +HopEnvironmentDialog.Dep.Edit.Edit=Rediger avhengighet +HopEnvironmentDialog.Dirty.Header=Ulagrede endringer +HopEnvironmentDialog.Dirty.Message=Lagre endringer i miljøfilen før du fortsetter? +HopEnvironmentDialog.SaveFirst.Header=Lagre miljøfil? +HopEnvironmentDialog.SaveFirst.Message=Lagre miljøfilen før Valider eller Bruk? +HopEnvironmentDialog.Validation.Header=Ugyldig miljø +HopEnvironmentDialog.Validation.RepoIdUrl=Hvert depot trenger en Id og URL. +HopEnvironmentDialog.Validation.PluginArtifact=Hver plugin trenger en Artifact ID. +HopEnvironmentDialog.Validation.DepGav=Hver avhengighet trenger Group ID, Artifact ID og Version. +HopEnvironmentDialog.ImportRepos.Header=Importer depot +HopEnvironmentDialog.ImportRepos.Message=Erstatte depotlisten med aktiverte depot fra hop-config.json? +HopEnvironmentDialog.Error.Header=Feil i miljøredigering +HopEnvironmentDialog.Error.Load=Kunne ikke laste miljøfil:\n{0} +HopEnvironmentDialog.Error.Save=Kunne ikke lagre miljøfil:\n{0} +HopEnvironmentDialog.Error.ImportRepos=Kunne ikke importere depot fra hop-config +AddPluginsFromCatalogDialog.Shell.Title=Legg til plugins fra katalog +AddPluginsFromCatalogDialog.Filter.Label=Filter +AddPluginsFromCatalogDialog.Button.Add=Legg til valgte +AddPluginsFromCatalogDialog.Button.Cancel=Avbryt +AddPluginsFromCatalogDialog.Column.Name=Navn +AddPluginsFromCatalogDialog.Column.Artifact=Artifact +AddPluginsFromCatalogDialog.Column.Category=Kategori +AddPluginsFromCatalogDialog.Column.Description=Beskrivelse diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_pl_PL.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_pl_PL.properties new file mode 100644 index 00000000000..b382add0da4 --- /dev/null +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_pl_PL.properties @@ -0,0 +1,209 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +MarketplaceGuiPlugin.Menu.Marketplace.Text=Marketplace... +MarketplaceGuiPlugin.Toolbar.Marketplace.Tooltip=Marketplace… +MarketplaceLifecycleEnv.Tab.Plugins=Wtyczki Marketplace +MarketplaceLifecycleEnv.Help=Zestaw wtyczek jest zdefiniowany w pliku hop-env. Te opcje kontrolują, kiedy Hop sprawdza ten plik dla tego środowiska cyklu życia (luźno w dev; rygorystycznie w produkcji). +MarketplaceLifecycleEnv.EnvFile.Label=Plik środowiska +MarketplaceLifecycleEnv.Button.Browse=Przeglądaj… +MarketplaceLifecycleEnv.Button.EditEnv=Edytuj… +MarketplaceLifecycleEnv.OnEnable.Label=Przy włączaniu +MarketplaceLifecycleEnv.OnEnable.Tooltip=off: bez sprawdzenia; warn: log/dialog przy rozbieżności; enforce: niepowodzenie włączania środowiska przy rozbieżności +MarketplaceLifecycleEnv.Strict.Label=Ścisłe (niepowodzenie, jeśli zainstalowano dodatkowe wtyczki marketplace) +MarketplaceLifecycleEnv.Strict.Tooltip=Przy walidacji traktuj też wtyczki marketplace z potwierdzeniem spoza pliku env jako rozbieżność +MarketplaceLifecycleEnv.AutoApply.Label=Automatycznie zastosuj brakujące wtyczki przy włączaniu +MarketplaceLifecycleEnv.AutoApply.Tooltip=Gdy włączone, uruchamia marketplace apply dla brakujących wtyczek (tylko na kontrolowanych maszynach; domyślnie wyłączone) +MarketplaceDialog.Shell.Title=Marketplace wtyczek +MarketplaceDialog.Tab.Plugins=Wtyczki +MarketplaceDialog.Tab.Environment=Środowisko +MarketplaceDialog.Tab.Repositories=Repozytoria +MarketplaceDialog.Repository.Label=Główne repozytorium +MarketplaceDialog.Repository.SetPrimary.Error=Nie można ustawić głównego repozytorium +MarketplaceDialog.Column.Name=Nazwa +MarketplaceDialog.Column.Artifact=Artefakt +MarketplaceDialog.Column.Category=Kategoria +MarketplaceDialog.Column.Status=Status +MarketplaceDialog.Column.Description=Opis +MarketplaceDialog.Search.Label=Szukaj +MarketplaceDialog.Search.Placeholder=Wpisz 3+ znaki, aby filtrować wtyczki… +MarketplaceDialog.Search.Clear=Wyczyść filtr wyszukiwania +MarketplaceDialog.Button.Install=Zainstaluj +MarketplaceDialog.Button.Uninstall=Odinstaluj +MarketplaceDialog.Button.Refresh=Odśwież +MarketplaceDialog.Button.Close=Zamknij +MarketplaceDialog.Button.ManageRepos=Zarządzaj… +MarketplaceDialog.Button.BrowseEnv=Przeglądaj… +MarketplaceDialog.Button.EditEnv=Edytuj… +MarketplaceDialog.Button.EditEnv.Tooltip=Utwórz lub edytuj plik środowiska (repozytoria, wtyczki, zależności) +MarketplaceDialog.Button.ValidateEnv=Waliduj +MarketplaceDialog.Button.ValidateEnv.Tooltip=Sprawdź lokalną instalację względem pliku środowiska bez instalowania +MarketplaceDialog.Button.ApplyEnv=Zastosuj +MarketplaceDialog.Button.ApplyEnv.Tooltip=Zainstaluj wtyczki i zależności zadeklarowane w pliku środowiska +MarketplaceDialog.EnvFile.Label=Plik środowiska +MarketplaceDialog.EnvFile.Prune=Usuń dodatkowe przy zastosowaniu +MarketplaceDialog.EnvFile.Prune.Tooltip=Przy zastosowaniu odinstaluj wtyczki marketplace z potwierdzeniem spoza pliku +MarketplaceDialog.EnvFile.Strict=Ścisła walidacja +MarketplaceDialog.EnvFile.Strict.Tooltip=Przy walidacji niepowodzenie także, gdy zainstalowano dodatkowe wtyczki marketplace poza plikiem +MarketplaceDialog.EnvFile.Filter.Env=Pliki środowiska Hop (*.yaml, *.yml, *.json) +MarketplaceDialog.EnvFile.Filter.All=Wszystkie pliki +MarketplaceDialog.EnvFile.Missing.Header=Wymagany plik środowiska +MarketplaceDialog.EnvFile.Missing.Message=Wybierz hop-env.yaml (lub full-client-env.yaml) przez Przeglądaj… albo wpisz ścieżkę. +MarketplaceDialog.EnvFile.NotFound.Header=Nie znaleziono pliku +MarketplaceDialog.EnvFile.NotFound.Message=Plik środowiska nie istnieje:\n{0} +MarketplaceDialog.Status.Installed=Zainstalowano +MarketplaceDialog.Status.Present=Obecny na dysku +MarketplaceDialog.Status.NotInstalled=Niezainstalowany +MarketplaceDialog.Status.RestartHint=Uruchom ponownie Hop po instalacji, zastosowaniu lub odinstalowaniu, aby przeładować wtyczki. Instalacja najpierw próbuje główne repozytorium, potem inne włączone. +MarketplaceDialog.Status.Installing=Instalowanie {0}... +MarketplaceDialog.Status.Validating=Walidacja pliku środowiska... +MarketplaceDialog.Status.Applying=Stosowanie pliku środowiska... +MarketplaceDialog.Status.Drift=Wykryto rozbieżność środowiska — użyj Zastosuj, aby naprawić +MarketplaceDialog.Error.Header=Błąd Marketplace +MarketplaceDialog.Error.ResolveHome=Nie można ustalić katalogu instalacji Hop. Uruchom Hop z katalogu głównego instalacji za pomocą launchera hop. +MarketplaceDialog.Install.Done.Header=Wtyczka zainstalowana +MarketplaceDialog.Install.Done.Message=Zainstalowano {0}.\n\nUruchom ponownie Hop, aby załadować wtyczkę. +MarketplaceDialog.Install.Error=Nie udało się zainstalować {0} +MarketplaceDialog.Uninstall.Confirm.Header=Odinstaluj wtyczkę +MarketplaceDialog.Uninstall.Confirm.Message=Usunąć wtyczkę zainstalowaną przez marketplace {0}? +MarketplaceDialog.Uninstall.NoReceipt.Header=Nie można odinstalować +MarketplaceDialog.Uninstall.NoReceipt.Message=Brak potwierdzenia instalacji marketplace dla {0}. Tutaj można odinstalować tylko wtyczki zainstalowane przez marketplace. +MarketplaceDialog.Uninstall.Error=Nie udało się odinstalować {0} +MarketplaceDialog.Validate.Ok.Header=Środowisko OK +MarketplaceDialog.Validate.Ok.Message=Lokalna instalacja jest zgodna:\n{0} +MarketplaceDialog.Validate.Drift.Header=Rozbieżność środowiska +MarketplaceDialog.Validate.Drift.Message=Lokalna instalacja nie jest zgodna z plikiem środowiska: +MarketplaceDialog.Validate.Drift.Hint=Użyj Zastosuj, aby zainstalować brakujące wtyczki (lub poprawić wersje), a następnie uruchom ponownie Hop. +MarketplaceDialog.Validate.Error=Nie udało się zwalidować pliku środowiska +MarketplaceDialog.Apply.PruneConfirm.Header=Przyciąć wtyczki marketplace? +MarketplaceDialog.Apply.PruneConfirm.Message=Zastosowanie z przycinaniem odinstaluje wtyczki marketplace spoza pliku środowiska.\n\nKontynuować? +MarketplaceDialog.Apply.Disabled=Marketplace jest wyłączony w hop-config.json. +MarketplaceDialog.Apply.Done.Header=Środowisko zastosowane +MarketplaceDialog.Apply.Done.Message=Zastosowano:\n{0}\n\nUruchom ponownie Hop, aby załadować nowe wtyczki. +MarketplaceDialog.Apply.Error=Nie udało się zastosować pliku środowiska +ManageRepositoriesDialog.Shell.Title=Repozytoria Marketplace +ManageRepositoriesDialog.Help=Główne repozytorium jest próbowane pierwsze. Pozostałe włączone repozytoria to zapasowe.\nDomyślnie: Apache Repository (repository.apache.org), potem Maven Central.\nUstawienia są zapisywane w hop-config.json w '${HOP_CONFIG_FOLDER}'. +ManageRepositoriesDialog.Column.Primary=Główne +ManageRepositoriesDialog.Column.Enabled=Włączone +ManageRepositoriesDialog.Column.Id=Id +ManageRepositoriesDialog.Column.Name=Nazwa +ManageRepositoriesDialog.Column.Url=URL +ManageRepositoriesDialog.Column.Auth=Auth +ManageRepositoriesDialog.Button.Add=Dodaj +ManageRepositoriesDialog.Button.Edit=Edytuj +ManageRepositoriesDialog.Button.Remove=Usuń +ManageRepositoriesDialog.Button.SetPrimary=Ustaw jako główne +ManageRepositoriesDialog.Button.MoveUp=W górę +ManageRepositoriesDialog.Button.MoveDown=W dół +ManageRepositoriesDialog.Button.ResetDefaults=Przywróć domyślne +ManageRepositoriesDialog.Button.Save=Zapisz +ManageRepositoriesDialog.Button.Cancel=Anuluj +ManageRepositoriesDialog.Button.Ok=OK +ManageRepositoriesDialog.Save.Done.Header=Repozytoria zapisane +ManageRepositoriesDialog.Save.Done.Message=Ustawienia repozytoriów Marketplace zostały zapisane w hop-config.json. +ManageRepositoriesDialog.Error.Header=Błąd repozytorium +ManageRepositoriesDialog.Error.Save=Nie można zapisać konfiguracji Marketplace +ManageRepositoriesDialog.Reset.Header=Resetuj repozytoria +ManageRepositoriesDialog.Reset.Message=Zastąpić listę repozytoriów Apache Repository (główne) i Maven Central? +ManageRepositoriesDialog.Edit.Title.Add=Dodaj repozytorium +ManageRepositoriesDialog.Edit.Title.Edit=Edytuj repozytorium +ManageRepositoriesDialog.Edit.Id=ID +ManageRepositoriesDialog.Edit.Name=Nazwa +ManageRepositoriesDialog.Edit.Url=URL +ManageRepositoriesDialog.Edit.Username=Nazwa użytkownika +ManageRepositoriesDialog.Edit.Password=Hasło +ManageRepositoriesDialog.Edit.Enabled=Włączone (użyj w łańcuchu zapasowym) +ManageRepositoriesDialog.Edit.Primary=Główne (próbowane pierwsze) +ManageRepositoriesDialog.Edit.IdUrlRequired=Id i URL są wymagane. +HopEnvironmentDialog.Shell.Title=Środowisko Marketplace — {0} +HopEnvironmentDialog.Untitled=Bez tytułu +HopEnvironmentDialog.Button.New=Nowy +HopEnvironmentDialog.Button.Open=Otwórz… +HopEnvironmentDialog.Button.Save=Zapisz +HopEnvironmentDialog.Button.SaveAs=Zapisz jako… +HopEnvironmentDialog.Button.Validate=Waliduj +HopEnvironmentDialog.Button.Validate.Tooltip=Sprawdź lokalną instalację względem tego pliku środowiska bez instalowania +HopEnvironmentDialog.Button.Apply=Zastosuj +HopEnvironmentDialog.Button.Apply.Tooltip=Zainstaluj wtyczki i zależności zadeklarowane w tym pliku środowiska +HopEnvironmentDialog.Button.Close=Zamknij +HopEnvironmentDialog.Button.Ok=OK +HopEnvironmentDialog.Button.Cancel=Anuluj +HopEnvironmentDialog.Button.Add=Dodaj +HopEnvironmentDialog.Button.Edit=Edytuj +HopEnvironmentDialog.Button.Remove=Usuń +HopEnvironmentDialog.Button.MoveUp=W górę +HopEnvironmentDialog.Button.MoveDown=W dół +HopEnvironmentDialog.Button.AddFromCatalog=Z katalogu… +HopEnvironmentDialog.Button.ImportRepos=Importuj z hop-config… +HopEnvironmentDialog.Prune=Usuń dodatkowe przy zastosowaniu +HopEnvironmentDialog.Prune.Tooltip=Przy zastosowaniu odinstaluj wtyczki marketplace z potwierdzeniem spoza pliku +HopEnvironmentDialog.Strict=Ścisła walidacja +HopEnvironmentDialog.Strict.Tooltip=Przy walidacji niepowodzenie także, gdy zainstalowano dodatkowe wtyczki marketplace poza plikiem +HopEnvironmentDialog.Filter.Yaml=Środowisko YAML (*.yaml, *.yml) +HopEnvironmentDialog.Filter.Json=Środowisko JSON (*.json) +HopEnvironmentDialog.Tab.General=Ogólne +HopEnvironmentDialog.Tab.Repositories=Repozytoria +HopEnvironmentDialog.Tab.Plugins=Wtyczki +HopEnvironmentDialog.Tab.Dependencies=Zależności +HopEnvironmentDialog.General.Help=Zadeklaruj, które wtyczki i jar-y ma mieć ta instalacja Hop. Zapisz jako hop-env.yaml na potrzeby CI/Docker lub użyj Waliduj / Zastosuj w tym oknie. +HopEnvironmentDialog.General.Version=Wersja specyfikacji +HopEnvironmentDialog.General.HopVersion=Wersja Hop +HopEnvironmentDialog.General.EnforceOnRun=Wymuś przy hop-run +HopEnvironmentDialog.General.EnforceOnRun.Tooltip=Gdy true, hop-run może zakończyć się niepowodzeniem, jeśli instalacja odbiega od tego pliku (także -Dhop.env.enforce=true) +HopEnvironmentDialog.Repositories.Help=Pierwszy wiersz jest główny (próbowany pierwszy); kolejne to zapasowe. Te repozytoria są w pliku środowiska (nie hop-config). Lepiej nie committować haseł. +HopEnvironmentDialog.Plugins.Help=Wtyczki marketplace do instalacji. Pozostaw Group ID puste, aby użyć org.apache.hop. Wersja może domyślnie pochodzić z wersji Hop na karcie Ogólne przy zastosowaniu. +HopEnvironmentDialog.Dependencies.Help=Opcjonalne jary Maven (np. sterowniki JDBC) instalowane w katalogu docelowym Hop home (domyślnie lib/jdbc). +HopEnvironmentDialog.Repo.Column.Id=Id +HopEnvironmentDialog.Repo.Column.Url=URL +HopEnvironmentDialog.Repo.Column.Username=Nazwa użytkownika +HopEnvironmentDialog.Repo.Column.Password=Hasło +HopEnvironmentDialog.Repo.Column.Auth=Auth +HopEnvironmentDialog.Repo.Edit.Add=Dodaj repozytorium +HopEnvironmentDialog.Repo.Edit.Edit=Edytuj repozytorium +HopEnvironmentDialog.Plugin.Column.GroupId=Group ID +HopEnvironmentDialog.Plugin.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Plugin.Column.Version=Wersja +HopEnvironmentDialog.Plugin.Edit.Add=Dodaj wtyczkę +HopEnvironmentDialog.Plugin.Edit.Edit=Edytuj wtyczkę +HopEnvironmentDialog.Dep.Column.GroupId=Group ID +HopEnvironmentDialog.Dep.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Dep.Column.Version=Wersja +HopEnvironmentDialog.Dep.Column.Target=Cel +HopEnvironmentDialog.Dep.Edit.Add=Dodaj zależność +HopEnvironmentDialog.Dep.Edit.Edit=Edytuj zależność +HopEnvironmentDialog.Dirty.Header=Niezapisane zmiany +HopEnvironmentDialog.Dirty.Message=Zapisać zmiany w pliku środowiska przed kontynuacją? +HopEnvironmentDialog.SaveFirst.Header=Zapisać plik środowiska? +HopEnvironmentDialog.SaveFirst.Message=Zapisać plik środowiska przed Waliduj lub Zastosuj? +HopEnvironmentDialog.Validation.Header=Nieprawidłowe środowisko +HopEnvironmentDialog.Validation.RepoIdUrl=Każde repozytorium wymaga Id i URL. +HopEnvironmentDialog.Validation.PluginArtifact=Każda wtyczka wymaga Artifact ID. +HopEnvironmentDialog.Validation.DepGav=Każda zależność wymaga Group ID, Artifact ID i Version. +HopEnvironmentDialog.ImportRepos.Header=Importuj repozytoria +HopEnvironmentDialog.ImportRepos.Message=Zastąpić listę repozytoriów włączonymi repozytoriami z hop-config.json? +HopEnvironmentDialog.Error.Header=Błąd edytora środowiska +HopEnvironmentDialog.Error.Load=Nie można wczytać pliku środowiska:\n{0} +HopEnvironmentDialog.Error.Save=Nie można zapisać pliku środowiska:\n{0} +HopEnvironmentDialog.Error.ImportRepos=Nie można zaimportować repozytoriów z hop-config +AddPluginsFromCatalogDialog.Shell.Title=Dodaj wtyczki z katalogu +AddPluginsFromCatalogDialog.Filter.Label=Filtr +AddPluginsFromCatalogDialog.Button.Add=Dodaj zaznaczone +AddPluginsFromCatalogDialog.Button.Cancel=Anuluj +AddPluginsFromCatalogDialog.Column.Name=Nazwa +AddPluginsFromCatalogDialog.Column.Artifact=Artefakt +AddPluginsFromCatalogDialog.Column.Category=Kategoria +AddPluginsFromCatalogDialog.Column.Description=Opis diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_pt_BR.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_pt_BR.properties new file mode 100644 index 00000000000..79627241436 --- /dev/null +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_pt_BR.properties @@ -0,0 +1,209 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +MarketplaceGuiPlugin.Menu.Marketplace.Text=Marketplace... +MarketplaceGuiPlugin.Toolbar.Marketplace.Tooltip=Marketplace… +MarketplaceLifecycleEnv.Tab.Plugins=Plugins do Marketplace +MarketplaceLifecycleEnv.Help=O conjunto de plugins é definido em um arquivo hop-env. Estas opções controlam quando o Hop verifica esse arquivo para este ambiente de ciclo de vida (flexível em dev; rígido em produção). +MarketplaceLifecycleEnv.EnvFile.Label=Arquivo de ambiente +MarketplaceLifecycleEnv.Button.Browse=Procurar… +MarketplaceLifecycleEnv.Button.EditEnv=Editar… +MarketplaceLifecycleEnv.OnEnable.Label=Ao habilitar +MarketplaceLifecycleEnv.OnEnable.Tooltip=off: sem verificação; warn: log/diálogo em caso de divergência; enforce: falhar ao habilitar o ambiente em caso de divergência +MarketplaceLifecycleEnv.Strict.Label=Rigoroso (falhar se houver plugins de marketplace extras instalados) +MarketplaceLifecycleEnv.Strict.Tooltip=Ao validar, também tratar como divergência plugins de marketplace com recibo que não estejam no arquivo de ambiente +MarketplaceLifecycleEnv.AutoApply.Label=Aplicar automaticamente plugins ausentes ao habilitar +MarketplaceLifecycleEnv.AutoApply.Tooltip=Quando habilitado, executa marketplace apply para plugins ausentes (apenas em máquinas controladas; padrão desligado) +MarketplaceDialog.Shell.Title=Marketplace de plugins +MarketplaceDialog.Tab.Plugins=Plugins +MarketplaceDialog.Tab.Environment=Ambiente +MarketplaceDialog.Tab.Repositories=Repositórios +MarketplaceDialog.Repository.Label=Repositório principal +MarketplaceDialog.Repository.SetPrimary.Error=Não foi possível definir o repositório principal +MarketplaceDialog.Column.Name=Nome +MarketplaceDialog.Column.Artifact=Artefato +MarketplaceDialog.Column.Category=Categoria +MarketplaceDialog.Column.Status=Status +MarketplaceDialog.Column.Description=Descrição +MarketplaceDialog.Search.Label=Pesquisar +MarketplaceDialog.Search.Placeholder=Digite 3+ caracteres para filtrar plugins… +MarketplaceDialog.Search.Clear=Limpar filtro de pesquisa +MarketplaceDialog.Button.Install=Instalar +MarketplaceDialog.Button.Uninstall=Desinstalar +MarketplaceDialog.Button.Refresh=Atualizar +MarketplaceDialog.Button.Close=Fechar +MarketplaceDialog.Button.ManageRepos=Gerenciar… +MarketplaceDialog.Button.BrowseEnv=Procurar… +MarketplaceDialog.Button.EditEnv=Editar… +MarketplaceDialog.Button.EditEnv.Tooltip=Criar ou editar o arquivo de ambiente (repositórios, plugins, dependências) +MarketplaceDialog.Button.ValidateEnv=Validar +MarketplaceDialog.Button.ValidateEnv.Tooltip=Verificar a instalação local com o arquivo de ambiente sem instalar +MarketplaceDialog.Button.ApplyEnv=Aplicar +MarketplaceDialog.Button.ApplyEnv.Tooltip=Instalar plugins e dependências declarados no arquivo de ambiente +MarketplaceDialog.EnvFile.Label=Arquivo de ambiente +MarketplaceDialog.EnvFile.Prune=Remover extras ao aplicar +MarketplaceDialog.EnvFile.Prune.Tooltip=Ao aplicar, desinstalar plugins de marketplace com recibo que não estejam no arquivo +MarketplaceDialog.EnvFile.Strict=Validação rigorosa +MarketplaceDialog.EnvFile.Strict.Tooltip=Ao validar, também falhar se houver plugins de marketplace instalados além do arquivo +MarketplaceDialog.EnvFile.Filter.Env=Arquivos de ambiente Hop (*.yaml, *.yml, *.json) +MarketplaceDialog.EnvFile.Filter.All=Todos os arquivos +MarketplaceDialog.EnvFile.Missing.Header=Arquivo de ambiente obrigatório +MarketplaceDialog.EnvFile.Missing.Message=Selecione um hop-env.yaml (ou full-client-env.yaml) com Procurar…, ou digite o caminho. +MarketplaceDialog.EnvFile.NotFound.Header=Arquivo não encontrado +MarketplaceDialog.EnvFile.NotFound.Message=O arquivo de ambiente não existe:\n{0} +MarketplaceDialog.Status.Installed=Instalado +MarketplaceDialog.Status.Present=Presente no disco +MarketplaceDialog.Status.NotInstalled=Não instalado +MarketplaceDialog.Status.RestartHint=Reinicie o Hop após instalar, aplicar ou desinstalar para recarregar os plugins. A instalação tenta o repositório principal e depois outros repositórios habilitados. +MarketplaceDialog.Status.Installing=Instalando {0}... +MarketplaceDialog.Status.Validating=Validando arquivo de ambiente... +MarketplaceDialog.Status.Applying=Aplicando arquivo de ambiente... +MarketplaceDialog.Status.Drift=Divergência de ambiente detectada — use Aplicar para corrigir +MarketplaceDialog.Error.Header=Erro do Marketplace +MarketplaceDialog.Error.ResolveHome=Não foi possível determinar o diretório de instalação do Hop. Inicie o Hop a partir da raiz da instalação com o lançador hop. +MarketplaceDialog.Install.Done.Header=Plugin instalado +MarketplaceDialog.Install.Done.Message=Instalado {0}.\n\nReinicie o Hop para carregar o plugin. +MarketplaceDialog.Install.Error=Falha ao instalar {0} +MarketplaceDialog.Uninstall.Confirm.Header=Desinstalar plugin +MarketplaceDialog.Uninstall.Confirm.Message=Remover o plugin instalado pelo marketplace {0}? +MarketplaceDialog.Uninstall.NoReceipt.Header=Não é possível desinstalar +MarketplaceDialog.Uninstall.NoReceipt.Message=Nenhum recibo de instalação do marketplace para {0}. Apenas plugins instalados pelo marketplace podem ser desinstalados aqui. +MarketplaceDialog.Uninstall.Error=Falha ao desinstalar {0} +MarketplaceDialog.Validate.Ok.Header=Ambiente OK +MarketplaceDialog.Validate.Ok.Message=A instalação local corresponde:\n{0} +MarketplaceDialog.Validate.Drift.Header=Divergência de ambiente +MarketplaceDialog.Validate.Drift.Message=A instalação local não corresponde ao arquivo de ambiente: +MarketplaceDialog.Validate.Drift.Hint=Use Aplicar para instalar plugins ausentes (ou corrigir versões) e reinicie o Hop. +MarketplaceDialog.Validate.Error=Falha ao validar o arquivo de ambiente +MarketplaceDialog.Apply.PruneConfirm.Header=Remover plugins de marketplace extras? +MarketplaceDialog.Apply.PruneConfirm.Message=Aplicar com remoção desinstalará plugins de marketplace que não estejam no arquivo de ambiente.\n\nContinuar? +MarketplaceDialog.Apply.Disabled=O Marketplace está desabilitado em hop-config.json. +MarketplaceDialog.Apply.Done.Header=Ambiente aplicado +MarketplaceDialog.Apply.Done.Message=Aplicado:\n{0}\n\nReinicie o Hop para carregar novos plugins. +MarketplaceDialog.Apply.Error=Falha ao aplicar o arquivo de ambiente +ManageRepositoriesDialog.Shell.Title=Repositórios do Marketplace +ManageRepositoriesDialog.Help=O repositório principal é tentado primeiro. Os demais repositórios habilitados são fallbacks.\nPadrões: Apache Repository (repository.apache.org) e depois Maven Central.\nAs configurações são salvas em hop-config.json em '${HOP_CONFIG_FOLDER}'. +ManageRepositoriesDialog.Column.Primary=Principal +ManageRepositoriesDialog.Column.Enabled=Habilitado +ManageRepositoriesDialog.Column.Id=Id +ManageRepositoriesDialog.Column.Name=Nome +ManageRepositoriesDialog.Column.Url=URL +ManageRepositoriesDialog.Column.Auth=Auth +ManageRepositoriesDialog.Button.Add=Adicionar +ManageRepositoriesDialog.Button.Edit=Editar +ManageRepositoriesDialog.Button.Remove=Remover +ManageRepositoriesDialog.Button.SetPrimary=Definir como principal +ManageRepositoriesDialog.Button.MoveUp=Acima +ManageRepositoriesDialog.Button.MoveDown=Abaixo +ManageRepositoriesDialog.Button.ResetDefaults=Restaurar padrões +ManageRepositoriesDialog.Button.Save=Salvar +ManageRepositoriesDialog.Button.Cancel=Cancelar +ManageRepositoriesDialog.Button.Ok=OK +ManageRepositoriesDialog.Save.Done.Header=Repositórios salvos +ManageRepositoriesDialog.Save.Done.Message=As configurações de repositórios do Marketplace foram salvas em hop-config.json. +ManageRepositoriesDialog.Error.Header=Erro de repositório +ManageRepositoriesDialog.Error.Save=Não foi possível salvar a configuração do Marketplace +ManageRepositoriesDialog.Reset.Header=Redefinir repositórios +ManageRepositoriesDialog.Reset.Message=Substituir a lista de repositórios por Apache Repository (principal) e Maven Central? +ManageRepositoriesDialog.Edit.Title.Add=Adicionar repositório +ManageRepositoriesDialog.Edit.Title.Edit=Editar repositório +ManageRepositoriesDialog.Edit.Id=ID +ManageRepositoriesDialog.Edit.Name=Nome +ManageRepositoriesDialog.Edit.Url=URL +ManageRepositoriesDialog.Edit.Username=Nome de usuário +ManageRepositoriesDialog.Edit.Password=Senha +ManageRepositoriesDialog.Edit.Enabled=Habilitado (usar na cadeia de fallback) +ManageRepositoriesDialog.Edit.Primary=Principal (tentado primeiro) +ManageRepositoriesDialog.Edit.IdUrlRequired=Id e URL são obrigatórios. +HopEnvironmentDialog.Shell.Title=Ambiente Marketplace — {0} +HopEnvironmentDialog.Untitled=Sem título +HopEnvironmentDialog.Button.New=Novo +HopEnvironmentDialog.Button.Open=Abrir… +HopEnvironmentDialog.Button.Save=Salvar +HopEnvironmentDialog.Button.SaveAs=Salvar como… +HopEnvironmentDialog.Button.Validate=Validar +HopEnvironmentDialog.Button.Validate.Tooltip=Verificar a instalação local com este arquivo de ambiente sem instalar +HopEnvironmentDialog.Button.Apply=Aplicar +HopEnvironmentDialog.Button.Apply.Tooltip=Instalar plugins e dependências declarados neste arquivo de ambiente +HopEnvironmentDialog.Button.Close=Fechar +HopEnvironmentDialog.Button.Ok=OK +HopEnvironmentDialog.Button.Cancel=Cancelar +HopEnvironmentDialog.Button.Add=Adicionar +HopEnvironmentDialog.Button.Edit=Editar +HopEnvironmentDialog.Button.Remove=Remover +HopEnvironmentDialog.Button.MoveUp=Acima +HopEnvironmentDialog.Button.MoveDown=Abaixo +HopEnvironmentDialog.Button.AddFromCatalog=Do catálogo… +HopEnvironmentDialog.Button.ImportRepos=Importar do hop-config… +HopEnvironmentDialog.Prune=Remover extras ao aplicar +HopEnvironmentDialog.Prune.Tooltip=Ao aplicar, desinstalar plugins de marketplace com recibo que não estejam no arquivo +HopEnvironmentDialog.Strict=Validação rigorosa +HopEnvironmentDialog.Strict.Tooltip=Ao validar, também falhar se houver plugins de marketplace instalados além do arquivo +HopEnvironmentDialog.Filter.Yaml=Ambiente YAML (*.yaml, *.yml) +HopEnvironmentDialog.Filter.Json=Ambiente JSON (*.json) +HopEnvironmentDialog.Tab.General=Geral +HopEnvironmentDialog.Tab.Repositories=Repositórios +HopEnvironmentDialog.Tab.Plugins=Plugins +HopEnvironmentDialog.Tab.Dependencies=Dependências +HopEnvironmentDialog.General.Help=Declare quais plugins e jars esta instalação Hop deve ter. Salve como hop-env.yaml para CI/Docker, ou use Validar / Aplicar neste diálogo. +HopEnvironmentDialog.General.Version=Versão da especificação +HopEnvironmentDialog.General.HopVersion=Versão do Hop +HopEnvironmentDialog.General.EnforceOnRun=Forçar no hop-run +HopEnvironmentDialog.General.EnforceOnRun.Tooltip=Se true, o hop-run pode falhar se a instalação divergir deste arquivo (também controlado por -Dhop.env.enforce=true) +HopEnvironmentDialog.Repositories.Help=A primeira linha é principal (tentada primeiro); as seguintes são fallbacks. Estes repositórios ficam no arquivo de ambiente (não hop-config). Prefira não fazer commit de senhas. +HopEnvironmentDialog.Plugins.Help=Plugins de marketplace a instalar. Deixe Group ID em branco para usar org.apache.hop. A versão pode vir da versão do Hop na aba Geral ao aplicar. +HopEnvironmentDialog.Dependencies.Help=Jars Maven opcionais (por exemplo drivers JDBC) instalados no diretório de destino do Hop home (padrão lib/jdbc). +HopEnvironmentDialog.Repo.Column.Id=Id +HopEnvironmentDialog.Repo.Column.Url=URL +HopEnvironmentDialog.Repo.Column.Username=Nome de usuário +HopEnvironmentDialog.Repo.Column.Password=Senha +HopEnvironmentDialog.Repo.Column.Auth=Auth +HopEnvironmentDialog.Repo.Edit.Add=Adicionar repositório +HopEnvironmentDialog.Repo.Edit.Edit=Editar repositório +HopEnvironmentDialog.Plugin.Column.GroupId=Group ID +HopEnvironmentDialog.Plugin.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Plugin.Column.Version=Versão +HopEnvironmentDialog.Plugin.Edit.Add=Adicionar plugin +HopEnvironmentDialog.Plugin.Edit.Edit=Editar plugin +HopEnvironmentDialog.Dep.Column.GroupId=Group ID +HopEnvironmentDialog.Dep.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Dep.Column.Version=Versão +HopEnvironmentDialog.Dep.Column.Target=Destino +HopEnvironmentDialog.Dep.Edit.Add=Adicionar dependência +HopEnvironmentDialog.Dep.Edit.Edit=Editar dependência +HopEnvironmentDialog.Dirty.Header=Alterações não salvas +HopEnvironmentDialog.Dirty.Message=Salvar as alterações do arquivo de ambiente antes de continuar? +HopEnvironmentDialog.SaveFirst.Header=Salvar arquivo de ambiente? +HopEnvironmentDialog.SaveFirst.Message=Salvar o arquivo de ambiente antes de Validar ou Aplicar? +HopEnvironmentDialog.Validation.Header=Ambiente inválido +HopEnvironmentDialog.Validation.RepoIdUrl=Cada repositório precisa de um Id e uma URL. +HopEnvironmentDialog.Validation.PluginArtifact=Cada plugin precisa de um Artifact ID. +HopEnvironmentDialog.Validation.DepGav=Cada dependência precisa de Group ID, Artifact ID e Version. +HopEnvironmentDialog.ImportRepos.Header=Importar repositórios +HopEnvironmentDialog.ImportRepos.Message=Substituir a lista de repositórios pelos repositórios habilitados de hop-config.json? +HopEnvironmentDialog.Error.Header=Erro do editor de ambiente +HopEnvironmentDialog.Error.Load=Não foi possível carregar o arquivo de ambiente:\n{0} +HopEnvironmentDialog.Error.Save=Não foi possível salvar o arquivo de ambiente:\n{0} +HopEnvironmentDialog.Error.ImportRepos=Não foi possível importar repositórios do hop-config +AddPluginsFromCatalogDialog.Shell.Title=Adicionar plugins do catálogo +AddPluginsFromCatalogDialog.Filter.Label=Filtro +AddPluginsFromCatalogDialog.Button.Add=Adicionar selecionados +AddPluginsFromCatalogDialog.Button.Cancel=Cancelar +AddPluginsFromCatalogDialog.Column.Name=Nome +AddPluginsFromCatalogDialog.Column.Artifact=Artefato +AddPluginsFromCatalogDialog.Column.Category=Categoria +AddPluginsFromCatalogDialog.Column.Description=Descrição diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_pt_PT.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_pt_PT.properties new file mode 100644 index 00000000000..b8ee7a19477 --- /dev/null +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_pt_PT.properties @@ -0,0 +1,209 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +MarketplaceGuiPlugin.Menu.Marketplace.Text=Marketplace... +MarketplaceGuiPlugin.Toolbar.Marketplace.Tooltip=Marketplace… +MarketplaceLifecycleEnv.Tab.Plugins=Plugins do Marketplace +MarketplaceLifecycleEnv.Help=O conjunto de plugins é definido num ficheiro hop-env. Estas opções controlam quando o Hop verifica esse ficheiro para este ambiente de ciclo de vida (flexível em dev; rigoroso em produção). +MarketplaceLifecycleEnv.EnvFile.Label=Ficheiro de ambiente +MarketplaceLifecycleEnv.Button.Browse=Procurar… +MarketplaceLifecycleEnv.Button.EditEnv=Editar… +MarketplaceLifecycleEnv.OnEnable.Label=Ao ativar +MarketplaceLifecycleEnv.OnEnable.Tooltip=off: sem verificação; warn: registo/diálogo em caso de divergência; enforce: falhar ao ativar o ambiente em caso de divergência +MarketplaceLifecycleEnv.Strict.Label=Rigoroso (falhar se existirem plugins de marketplace extra instalados) +MarketplaceLifecycleEnv.Strict.Tooltip=Ao validar, também tratar como divergência plugins de marketplace com recibo que não estejam no ficheiro de ambiente +MarketplaceLifecycleEnv.AutoApply.Label=Aplicar automaticamente plugins em falta ao ativar +MarketplaceLifecycleEnv.AutoApply.Tooltip=Quando ativado, executa marketplace apply para plugins em falta (apenas em máquinas controladas; predefinição desligado) +MarketplaceDialog.Shell.Title=Marketplace de plugins +MarketplaceDialog.Tab.Plugins=Plugins +MarketplaceDialog.Tab.Environment=Ambiente +MarketplaceDialog.Tab.Repositories=Repositórios +MarketplaceDialog.Repository.Label=Repositório principal +MarketplaceDialog.Repository.SetPrimary.Error=Não foi possível definir o repositório principal +MarketplaceDialog.Column.Name=Nome +MarketplaceDialog.Column.Artifact=Artefato +MarketplaceDialog.Column.Category=Categoria +MarketplaceDialog.Column.Status=Status +MarketplaceDialog.Column.Description=Descrição +MarketplaceDialog.Search.Label=Pesquisar +MarketplaceDialog.Search.Placeholder=Introduza 3+ caracteres para filtrar plugins… +MarketplaceDialog.Search.Clear=Limpar filtro de pesquisa +MarketplaceDialog.Button.Install=Instalar +MarketplaceDialog.Button.Uninstall=Desinstalar +MarketplaceDialog.Button.Refresh=Atualizar +MarketplaceDialog.Button.Close=Fechar +MarketplaceDialog.Button.ManageRepos=Gerir… +MarketplaceDialog.Button.BrowseEnv=Procurar… +MarketplaceDialog.Button.EditEnv=Editar… +MarketplaceDialog.Button.EditEnv.Tooltip=Criar ou editar o ficheiro de ambiente (repositórios, plugins, dependências) +MarketplaceDialog.Button.ValidateEnv=Validar +MarketplaceDialog.Button.ValidateEnv.Tooltip=Verificar a instalação local com o ficheiro de ambiente sem instalar +MarketplaceDialog.Button.ApplyEnv=Aplicar +MarketplaceDialog.Button.ApplyEnv.Tooltip=Instalar plugins e dependências declarados no ficheiro de ambiente +MarketplaceDialog.EnvFile.Label=Ficheiro de ambiente +MarketplaceDialog.EnvFile.Prune=Remover extras ao aplicar +MarketplaceDialog.EnvFile.Prune.Tooltip=Ao aplicar, desinstalar plugins de marketplace com recibo que não estejam no ficheiro +MarketplaceDialog.EnvFile.Strict=Validação rigorosa +MarketplaceDialog.EnvFile.Strict.Tooltip=Ao validar, também falhar se existirem plugins de marketplace instalados para além do ficheiro +MarketplaceDialog.EnvFile.Filter.Env=Ficheiros de ambiente Hop (*.yaml, *.yml, *.json) +MarketplaceDialog.EnvFile.Filter.All=Todos os ficheiros +MarketplaceDialog.EnvFile.Missing.Header=Ficheiro de ambiente obrigatório +MarketplaceDialog.EnvFile.Missing.Message=Selecione um hop-env.yaml (ou full-client-env.yaml) com Procurar…, ou introduza o caminho. +MarketplaceDialog.EnvFile.NotFound.Header=Ficheiro não encontrado +MarketplaceDialog.EnvFile.NotFound.Message=O ficheiro de ambiente não existe:\n{0} +MarketplaceDialog.Status.Installed=Instalado +MarketplaceDialog.Status.Present=Presente no disco +MarketplaceDialog.Status.NotInstalled=Não instalado +MarketplaceDialog.Status.RestartHint=Reinicie o Hop após instalar, aplicar ou desinstalar para recarregar os plugins. A instalação tenta o repositório principal e depois outros repositórios ativados. +MarketplaceDialog.Status.Installing=A instalar {0}... +MarketplaceDialog.Status.Validating=A validar ficheiro de ambiente... +MarketplaceDialog.Status.Applying=A aplicar ficheiro de ambiente... +MarketplaceDialog.Status.Drift=Divergência de ambiente detetada — use Aplicar para corrigir +MarketplaceDialog.Error.Header=Erro do Marketplace +MarketplaceDialog.Error.ResolveHome=Não foi possível determinar o diretório de instalação do Hop. Inicie o Hop a partir da raiz da instalação com o lançador hop. +MarketplaceDialog.Install.Done.Header=Plugin instalado +MarketplaceDialog.Install.Done.Message=Instalado {0}.\n\nReinicie o Hop para carregar o plugin. +MarketplaceDialog.Install.Error=Falha ao instalar {0} +MarketplaceDialog.Uninstall.Confirm.Header=Desinstalar plugin +MarketplaceDialog.Uninstall.Confirm.Message=Remover o plugin instalado pelo marketplace {0}? +MarketplaceDialog.Uninstall.NoReceipt.Header=Não é possível desinstalar +MarketplaceDialog.Uninstall.NoReceipt.Message=Nenhum recibo de instalação do marketplace para {0}. Apenas plugins instalados pelo marketplace podem ser desinstalados aqui. +MarketplaceDialog.Uninstall.Error=Falha ao desinstalar {0} +MarketplaceDialog.Validate.Ok.Header=Ambiente OK +MarketplaceDialog.Validate.Ok.Message=A instalação local corresponde:\n{0} +MarketplaceDialog.Validate.Drift.Header=Divergência de ambiente +MarketplaceDialog.Validate.Drift.Message=A instalação local não corresponde ao ficheiro de ambiente: +MarketplaceDialog.Validate.Drift.Hint=Use Aplicar para instalar plugins em falta (ou corrigir versões) e reinicie o Hop. +MarketplaceDialog.Validate.Error=Falha ao validar o ficheiro de ambiente +MarketplaceDialog.Apply.PruneConfirm.Header=Remover plugins de marketplace extra? +MarketplaceDialog.Apply.PruneConfirm.Message=Aplicar com remoção desinstalará plugins de marketplace que não estejam no ficheiro de ambiente.\n\nContinuar? +MarketplaceDialog.Apply.Disabled=O Marketplace está desativado em hop-config.json. +MarketplaceDialog.Apply.Done.Header=Ambiente aplicado +MarketplaceDialog.Apply.Done.Message=Aplicado:\n{0}\n\nReinicie o Hop para carregar novos plugins. +MarketplaceDialog.Apply.Error=Falha ao aplicar o ficheiro de ambiente +ManageRepositoriesDialog.Shell.Title=Repositórios do Marketplace +ManageRepositoriesDialog.Help=O repositório principal é tentado primeiro. Os restantes repositórios ativados são fallbacks.\nPredefinições: Apache Repository (repository.apache.org) e depois Maven Central.\nAs definições são guardadas em hop-config.json em '${HOP_CONFIG_FOLDER}'. +ManageRepositoriesDialog.Column.Primary=Principal +ManageRepositoriesDialog.Column.Enabled=Habilitado +ManageRepositoriesDialog.Column.Id=Id +ManageRepositoriesDialog.Column.Name=Nome +ManageRepositoriesDialog.Column.Url=URL +ManageRepositoriesDialog.Column.Auth=Auth +ManageRepositoriesDialog.Button.Add=Adicionar +ManageRepositoriesDialog.Button.Edit=Editar +ManageRepositoriesDialog.Button.Remove=Remover +ManageRepositoriesDialog.Button.SetPrimary=Definir como principal +ManageRepositoriesDialog.Button.MoveUp=Acima +ManageRepositoriesDialog.Button.MoveDown=Abaixo +ManageRepositoriesDialog.Button.ResetDefaults=Repor predefinições +ManageRepositoriesDialog.Button.Save=Guardar +ManageRepositoriesDialog.Button.Cancel=Cancelar +ManageRepositoriesDialog.Button.Ok=OK +ManageRepositoriesDialog.Save.Done.Header=Repositórios guardados +ManageRepositoriesDialog.Save.Done.Message=As definições de repositórios do Marketplace foram guardadas em hop-config.json. +ManageRepositoriesDialog.Error.Header=Erro de repositório +ManageRepositoriesDialog.Error.Save=Não foi possível guardar a configuração do Marketplace +ManageRepositoriesDialog.Reset.Header=Repor repositórios +ManageRepositoriesDialog.Reset.Message=Substituir a lista de repositórios por Apache Repository (principal) e Maven Central? +ManageRepositoriesDialog.Edit.Title.Add=Adicionar repositório +ManageRepositoriesDialog.Edit.Title.Edit=Editar repositório +ManageRepositoriesDialog.Edit.Id=ID +ManageRepositoriesDialog.Edit.Name=Nome +ManageRepositoriesDialog.Edit.Url=URL +ManageRepositoriesDialog.Edit.Username=Nome de utilizador +ManageRepositoriesDialog.Edit.Password=Palavra-passe +ManageRepositoriesDialog.Edit.Enabled=Ativado (usar na cadeia de fallback) +ManageRepositoriesDialog.Edit.Primary=Principal (tentado primeiro) +ManageRepositoriesDialog.Edit.IdUrlRequired=Id e URL são obrigatórios. +HopEnvironmentDialog.Shell.Title=Ambiente Marketplace — {0} +HopEnvironmentDialog.Untitled=Sem título +HopEnvironmentDialog.Button.New=Novo +HopEnvironmentDialog.Button.Open=Abrir… +HopEnvironmentDialog.Button.Save=Guardar +HopEnvironmentDialog.Button.SaveAs=Guardar como… +HopEnvironmentDialog.Button.Validate=Validar +HopEnvironmentDialog.Button.Validate.Tooltip=Verificar a instalação local com este ficheiro de ambiente sem instalar +HopEnvironmentDialog.Button.Apply=Aplicar +HopEnvironmentDialog.Button.Apply.Tooltip=Instalar plugins e dependências declarados neste ficheiro de ambiente +HopEnvironmentDialog.Button.Close=Fechar +HopEnvironmentDialog.Button.Ok=OK +HopEnvironmentDialog.Button.Cancel=Cancelar +HopEnvironmentDialog.Button.Add=Adicionar +HopEnvironmentDialog.Button.Edit=Editar +HopEnvironmentDialog.Button.Remove=Remover +HopEnvironmentDialog.Button.MoveUp=Acima +HopEnvironmentDialog.Button.MoveDown=Abaixo +HopEnvironmentDialog.Button.AddFromCatalog=Do catálogo… +HopEnvironmentDialog.Button.ImportRepos=Importar do hop-config… +HopEnvironmentDialog.Prune=Remover extras ao aplicar +HopEnvironmentDialog.Prune.Tooltip=Ao aplicar, desinstalar plugins de marketplace com recibo que não estejam no ficheiro +HopEnvironmentDialog.Strict=Validação rigorosa +HopEnvironmentDialog.Strict.Tooltip=Ao validar, também falhar se existirem plugins de marketplace instalados para além do ficheiro +HopEnvironmentDialog.Filter.Yaml=Ambiente YAML (*.yaml, *.yml) +HopEnvironmentDialog.Filter.Json=Ambiente JSON (*.json) +HopEnvironmentDialog.Tab.General=Geral +HopEnvironmentDialog.Tab.Repositories=Repositórios +HopEnvironmentDialog.Tab.Plugins=Plugins +HopEnvironmentDialog.Tab.Dependencies=Dependências +HopEnvironmentDialog.General.Help=Declare quais plugins e jars esta instalação Hop deve ter. Guarde como hop-env.yaml para CI/Docker, ou use Validar / Aplicar neste diálogo. +HopEnvironmentDialog.General.Version=Versão da especificação +HopEnvironmentDialog.General.HopVersion=Versão do Hop +HopEnvironmentDialog.General.EnforceOnRun=Forçar no hop-run +HopEnvironmentDialog.General.EnforceOnRun.Tooltip=Se true, o hop-run pode falhar se a instalação divergir deste ficheiro (também controlado por -Dhop.env.enforce=true) +HopEnvironmentDialog.Repositories.Help=A primeira linha é principal (tentada primeiro); as seguintes são fallbacks. Estes repositórios ficam no ficheiro de ambiente (não hop-config). Prefira não fazer commit de palavras-passe. +HopEnvironmentDialog.Plugins.Help=Plugins de marketplace a instalar. Deixe Group ID em branco para usar org.apache.hop. A versão pode vir da versão do Hop no separador Geral ao aplicar. +HopEnvironmentDialog.Dependencies.Help=Jars Maven opcionais (por exemplo controladores JDBC) instalados no diretório de destino do Hop home (predefinição lib/jdbc). +HopEnvironmentDialog.Repo.Column.Id=Id +HopEnvironmentDialog.Repo.Column.Url=URL +HopEnvironmentDialog.Repo.Column.Username=Nome de utilizador +HopEnvironmentDialog.Repo.Column.Password=Palavra-passe +HopEnvironmentDialog.Repo.Column.Auth=Auth +HopEnvironmentDialog.Repo.Edit.Add=Adicionar repositório +HopEnvironmentDialog.Repo.Edit.Edit=Editar repositório +HopEnvironmentDialog.Plugin.Column.GroupId=Group ID +HopEnvironmentDialog.Plugin.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Plugin.Column.Version=Versão +HopEnvironmentDialog.Plugin.Edit.Add=Adicionar plugin +HopEnvironmentDialog.Plugin.Edit.Edit=Editar plugin +HopEnvironmentDialog.Dep.Column.GroupId=Group ID +HopEnvironmentDialog.Dep.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Dep.Column.Version=Versão +HopEnvironmentDialog.Dep.Column.Target=Destino +HopEnvironmentDialog.Dep.Edit.Add=Adicionar dependência +HopEnvironmentDialog.Dep.Edit.Edit=Editar dependência +HopEnvironmentDialog.Dirty.Header=Alterações não guardadas +HopEnvironmentDialog.Dirty.Message=Guardar as alterações do ficheiro de ambiente antes de continuar? +HopEnvironmentDialog.SaveFirst.Header=Guardar ficheiro de ambiente? +HopEnvironmentDialog.SaveFirst.Message=Guardar o ficheiro de ambiente antes de Validar ou Aplicar? +HopEnvironmentDialog.Validation.Header=Ambiente inválido +HopEnvironmentDialog.Validation.RepoIdUrl=Cada repositório precisa de um Id e um URL. +HopEnvironmentDialog.Validation.PluginArtifact=Cada plugin precisa de um Artifact ID. +HopEnvironmentDialog.Validation.DepGav=Cada dependência precisa de Group ID, Artifact ID e Version. +HopEnvironmentDialog.ImportRepos.Header=Importar repositórios +HopEnvironmentDialog.ImportRepos.Message=Substituir a lista de repositórios pelos repositórios ativados de hop-config.json? +HopEnvironmentDialog.Error.Header=Erro do editor de ambiente +HopEnvironmentDialog.Error.Load=Não foi possível carregar o ficheiro de ambiente:\n{0} +HopEnvironmentDialog.Error.Save=Não foi possível guardar o ficheiro de ambiente:\n{0} +HopEnvironmentDialog.Error.ImportRepos=Não foi possível importar repositórios do hop-config +AddPluginsFromCatalogDialog.Shell.Title=Adicionar plugins do catálogo +AddPluginsFromCatalogDialog.Filter.Label=Filtro +AddPluginsFromCatalogDialog.Button.Add=Adicionar selecionados +AddPluginsFromCatalogDialog.Button.Cancel=Cancelar +AddPluginsFromCatalogDialog.Column.Name=Nome +AddPluginsFromCatalogDialog.Column.Artifact=Artefato +AddPluginsFromCatalogDialog.Column.Category=Categoria +AddPluginsFromCatalogDialog.Column.Description=Descrição diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_zh_CN.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_zh_CN.properties new file mode 100644 index 00000000000..a19e48d2a6a --- /dev/null +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_zh_CN.properties @@ -0,0 +1,209 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +MarketplaceGuiPlugin.Menu.Marketplace.Text=Marketplace... +MarketplaceGuiPlugin.Toolbar.Marketplace.Tooltip=Marketplace… +MarketplaceLifecycleEnv.Tab.Plugins=Marketplace 插件 +MarketplaceLifecycleEnv.Help=插件集在 hop-env 文件中定义。这些选项控制 Hop 何时针对此生命周期环境检查该文件(开发可宽松;生产可强制)。 +MarketplaceLifecycleEnv.EnvFile.Label=环境文件 +MarketplaceLifecycleEnv.Button.Browse=浏览… +MarketplaceLifecycleEnv.Button.EditEnv=编辑… +MarketplaceLifecycleEnv.OnEnable.Label=启用时 +MarketplaceLifecycleEnv.OnEnable.Tooltip=off:不检查;warn:漂移时记录/对话框;enforce:漂移时使环境启用失败 +MarketplaceLifecycleEnv.Strict.Label=严格(若安装了额外的 marketplace 插件则失败) +MarketplaceLifecycleEnv.Strict.Tooltip=验证时,也将环境文件未列出但有安装回执的 marketplace 插件视为漂移 +MarketplaceLifecycleEnv.AutoApply.Label=启用时自动应用缺失的插件 +MarketplaceLifecycleEnv.AutoApply.Tooltip=启用后,对缺失插件运行 marketplace apply(仅用于受控机器;默认关闭) +MarketplaceDialog.Shell.Title=插件 Marketplace +MarketplaceDialog.Tab.Plugins=插件 +MarketplaceDialog.Tab.Environment=环境 +MarketplaceDialog.Tab.Repositories=仓库 +MarketplaceDialog.Repository.Label=主仓库 +MarketplaceDialog.Repository.SetPrimary.Error=无法设置主仓库 +MarketplaceDialog.Column.Name=名称 +MarketplaceDialog.Column.Artifact=构件 +MarketplaceDialog.Column.Category=类别 +MarketplaceDialog.Column.Status=状态 +MarketplaceDialog.Column.Description=描述 +MarketplaceDialog.Search.Label=搜索 +MarketplaceDialog.Search.Placeholder=输入 3 个以上字符以筛选插件… +MarketplaceDialog.Search.Clear=清除搜索筛选 +MarketplaceDialog.Button.Install=安装 +MarketplaceDialog.Button.Uninstall=卸载 +MarketplaceDialog.Button.Refresh=刷新 +MarketplaceDialog.Button.Close=关闭 +MarketplaceDialog.Button.ManageRepos=管理… +MarketplaceDialog.Button.BrowseEnv=浏览… +MarketplaceDialog.Button.EditEnv=编辑… +MarketplaceDialog.Button.EditEnv.Tooltip=创建或编辑环境文件(仓库、插件、依赖) +MarketplaceDialog.Button.ValidateEnv=验证 +MarketplaceDialog.Button.ValidateEnv.Tooltip=对照环境文件检查本地安装,不执行安装 +MarketplaceDialog.Button.ApplyEnv=应用 +MarketplaceDialog.Button.ApplyEnv.Tooltip=安装环境文件中声明的插件和依赖 +MarketplaceDialog.EnvFile.Label=环境文件 +MarketplaceDialog.EnvFile.Prune=应用时修剪多余项 +MarketplaceDialog.EnvFile.Prune.Tooltip=应用时卸载文件中未列出但有安装回执的 marketplace 插件 +MarketplaceDialog.EnvFile.Strict=严格验证 +MarketplaceDialog.EnvFile.Strict.Tooltip=验证时,若安装了文件之外的额外 marketplace 插件也失败 +MarketplaceDialog.EnvFile.Filter.Env=Hop 环境文件 (*.yaml, *.yml, *.json) +MarketplaceDialog.EnvFile.Filter.All=所有文件 +MarketplaceDialog.EnvFile.Missing.Header=需要环境文件 +MarketplaceDialog.EnvFile.Missing.Message=使用“浏览…”选择 hop-env.yaml(或 full-client-env.yaml),或输入路径。 +MarketplaceDialog.EnvFile.NotFound.Header=未找到文件 +MarketplaceDialog.EnvFile.NotFound.Message=环境文件不存在:\n{0} +MarketplaceDialog.Status.Installed=已安装 +MarketplaceDialog.Status.Present=磁盘上存在 +MarketplaceDialog.Status.NotInstalled=未安装 +MarketplaceDialog.Status.RestartHint=安装、应用或卸载后请重启 Hop 以重新加载插件。安装先尝试主仓库,再尝试其他已启用的仓库。 +MarketplaceDialog.Status.Installing=正在安装 {0}... +MarketplaceDialog.Status.Validating=正在验证环境文件... +MarketplaceDialog.Status.Applying=正在应用环境文件... +MarketplaceDialog.Status.Drift=检测到环境漂移 — 使用“应用”修复 +MarketplaceDialog.Error.Header=Marketplace 错误 +MarketplaceDialog.Error.ResolveHome=无法确定 Hop 安装目录。请从安装根目录使用 hop 启动器启动 Hop。 +MarketplaceDialog.Install.Done.Header=插件已安装 +MarketplaceDialog.Install.Done.Message=已安装 {0}。\n\n请重启 Hop 以加载插件。 +MarketplaceDialog.Install.Error=安装 {0} 失败 +MarketplaceDialog.Uninstall.Confirm.Header=卸载插件 +MarketplaceDialog.Uninstall.Confirm.Message=移除通过 marketplace 安装的插件 {0}? +MarketplaceDialog.Uninstall.NoReceipt.Header=无法卸载 +MarketplaceDialog.Uninstall.NoReceipt.Message=没有 {0} 的 marketplace 安装回执。此处只能卸载通过 marketplace 安装的插件。 +MarketplaceDialog.Uninstall.Error=卸载 {0} 失败 +MarketplaceDialog.Validate.Ok.Header=环境正常 +MarketplaceDialog.Validate.Ok.Message=本地安装匹配:\n{0} +MarketplaceDialog.Validate.Drift.Header=环境漂移 +MarketplaceDialog.Validate.Drift.Message=本地安装与环境文件不匹配: +MarketplaceDialog.Validate.Drift.Hint=使用“应用”安装缺失插件(或修正版本),然后重启 Hop。 +MarketplaceDialog.Validate.Error=验证环境文件失败 +MarketplaceDialog.Apply.PruneConfirm.Header=修剪 marketplace 插件? +MarketplaceDialog.Apply.PruneConfirm.Message=带修剪的应用将卸载环境文件中未列出的 marketplace 插件。\n\n是否继续? +MarketplaceDialog.Apply.Disabled=Marketplace 在 hop-config.json 中已禁用。 +MarketplaceDialog.Apply.Done.Header=环境已应用 +MarketplaceDialog.Apply.Done.Message=已应用:\n{0}\n\n请重启 Hop 以加载新插件。 +MarketplaceDialog.Apply.Error=应用环境文件失败 +ManageRepositoriesDialog.Shell.Title=Marketplace 仓库 +ManageRepositoriesDialog.Help=先尝试主仓库。其他已启用的仓库为回退。\n默认:Apache Repository (repository.apache.org),然后是 Maven Central。\n设置保存在 '${HOP_CONFIG_FOLDER}' 下的 hop-config.json。 +ManageRepositoriesDialog.Column.Primary=主 +ManageRepositoriesDialog.Column.Enabled=启用 +ManageRepositoriesDialog.Column.Id=Id +ManageRepositoriesDialog.Column.Name=名称 +ManageRepositoriesDialog.Column.Url=URL +ManageRepositoriesDialog.Column.Auth=认证 +ManageRepositoriesDialog.Button.Add=添加 +ManageRepositoriesDialog.Button.Edit=编辑 +ManageRepositoriesDialog.Button.Remove=删除 +ManageRepositoriesDialog.Button.SetPrimary=设为主仓库 +ManageRepositoriesDialog.Button.MoveUp=上移 +ManageRepositoriesDialog.Button.MoveDown=下移 +ManageRepositoriesDialog.Button.ResetDefaults=重置默认 +ManageRepositoriesDialog.Button.Save=保存 +ManageRepositoriesDialog.Button.Cancel=取消 +ManageRepositoriesDialog.Button.Ok=确定 +ManageRepositoriesDialog.Save.Done.Header=仓库已保存 +ManageRepositoriesDialog.Save.Done.Message=Marketplace 仓库设置已保存到 hop-config.json。 +ManageRepositoriesDialog.Error.Header=仓库错误 +ManageRepositoriesDialog.Error.Save=无法保存 Marketplace 配置 +ManageRepositoriesDialog.Reset.Header=重置仓库 +ManageRepositoriesDialog.Reset.Message=将仓库列表替换为 Apache Repository(主)和 Maven Central? +ManageRepositoriesDialog.Edit.Title.Add=添加仓库 +ManageRepositoriesDialog.Edit.Title.Edit=编辑仓库 +ManageRepositoriesDialog.Edit.Id=ID +ManageRepositoriesDialog.Edit.Name=名称 +ManageRepositoriesDialog.Edit.Url=URL +ManageRepositoriesDialog.Edit.Username=用户名 +ManageRepositoriesDialog.Edit.Password=密码 +ManageRepositoriesDialog.Edit.Enabled=已启用(用于回退链) +ManageRepositoriesDialog.Edit.Primary=主仓库(优先尝试) +ManageRepositoriesDialog.Edit.IdUrlRequired=Id 和 URL 为必填项。 +HopEnvironmentDialog.Shell.Title=Marketplace 环境 — {0} +HopEnvironmentDialog.Untitled=未命名 +HopEnvironmentDialog.Button.New=新建 +HopEnvironmentDialog.Button.Open=打开… +HopEnvironmentDialog.Button.Save=保存 +HopEnvironmentDialog.Button.SaveAs=另存为… +HopEnvironmentDialog.Button.Validate=验证 +HopEnvironmentDialog.Button.Validate.Tooltip=对照此环境文件检查本地安装,不执行安装 +HopEnvironmentDialog.Button.Apply=应用 +HopEnvironmentDialog.Button.Apply.Tooltip=安装此环境文件中声明的插件和依赖 +HopEnvironmentDialog.Button.Close=关闭 +HopEnvironmentDialog.Button.Ok=确定 +HopEnvironmentDialog.Button.Cancel=取消 +HopEnvironmentDialog.Button.Add=添加 +HopEnvironmentDialog.Button.Edit=编辑 +HopEnvironmentDialog.Button.Remove=删除 +HopEnvironmentDialog.Button.MoveUp=上移 +HopEnvironmentDialog.Button.MoveDown=下移 +HopEnvironmentDialog.Button.AddFromCatalog=从目录… +HopEnvironmentDialog.Button.ImportRepos=从 hop-config 导入… +HopEnvironmentDialog.Prune=应用时修剪多余项 +HopEnvironmentDialog.Prune.Tooltip=应用时卸载文件中未列出但有安装回执的 marketplace 插件 +HopEnvironmentDialog.Strict=严格验证 +HopEnvironmentDialog.Strict.Tooltip=验证时,若安装了文件之外的额外 marketplace 插件也失败 +HopEnvironmentDialog.Filter.Yaml=YAML 环境 (*.yaml, *.yml) +HopEnvironmentDialog.Filter.Json=JSON 环境 (*.json) +HopEnvironmentDialog.Tab.General=常规 +HopEnvironmentDialog.Tab.Repositories=仓库 +HopEnvironmentDialog.Tab.Plugins=插件 +HopEnvironmentDialog.Tab.Dependencies=依赖 +HopEnvironmentDialog.General.Help=声明此 Hop 安装应具备的插件与 jar。保存为 hop-env.yaml 供 CI/Docker 使用,或在此对话框中使用验证/应用。 +HopEnvironmentDialog.General.Version=规范版本 +HopEnvironmentDialog.General.HopVersion=Hop 版本 +HopEnvironmentDialog.General.EnforceOnRun=在 hop-run 时强制 +HopEnvironmentDialog.General.EnforceOnRun.Tooltip=为 true 时,若安装偏离此文件,hop-run 可能失败(也可由 -Dhop.env.enforce=true 控制) +HopEnvironmentDialog.Repositories.Help=第一行为主(优先尝试);后续行为回退。这些仓库位于环境文件中(非 hop-config)。请尽量不要提交密码。 +HopEnvironmentDialog.Plugins.Help=要安装的 Marketplace 插件。Group ID 留空则使用 org.apache.hop。应用时版本可默认取自“常规”页的 Hop 版本。 +HopEnvironmentDialog.Dependencies.Help=可选 Maven jar(例如 JDBC 驱动),安装到 Hop home 下的目标目录(默认 lib/jdbc)。 +HopEnvironmentDialog.Repo.Column.Id=Id +HopEnvironmentDialog.Repo.Column.Url=URL +HopEnvironmentDialog.Repo.Column.Username=用户名 +HopEnvironmentDialog.Repo.Column.Password=密码 +HopEnvironmentDialog.Repo.Column.Auth=认证 +HopEnvironmentDialog.Repo.Edit.Add=添加仓库 +HopEnvironmentDialog.Repo.Edit.Edit=编辑仓库 +HopEnvironmentDialog.Plugin.Column.GroupId=Group ID +HopEnvironmentDialog.Plugin.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Plugin.Column.Version=版本 +HopEnvironmentDialog.Plugin.Edit.Add=添加插件 +HopEnvironmentDialog.Plugin.Edit.Edit=编辑插件 +HopEnvironmentDialog.Dep.Column.GroupId=Group ID +HopEnvironmentDialog.Dep.Column.ArtifactId=Artifact ID +HopEnvironmentDialog.Dep.Column.Version=版本 +HopEnvironmentDialog.Dep.Column.Target=目标 +HopEnvironmentDialog.Dep.Edit.Add=添加依赖 +HopEnvironmentDialog.Dep.Edit.Edit=编辑依赖 +HopEnvironmentDialog.Dirty.Header=未保存的更改 +HopEnvironmentDialog.Dirty.Message=继续前是否保存对环境文件的更改? +HopEnvironmentDialog.SaveFirst.Header=保存环境文件? +HopEnvironmentDialog.SaveFirst.Message=在验证或应用之前保存环境文件? +HopEnvironmentDialog.Validation.Header=无效环境 +HopEnvironmentDialog.Validation.RepoIdUrl=每个仓库需要 Id 和 URL。 +HopEnvironmentDialog.Validation.PluginArtifact=每个插件需要 Artifact ID。 +HopEnvironmentDialog.Validation.DepGav=每个依赖需要 Group ID、Artifact ID 和 Version。 +HopEnvironmentDialog.ImportRepos.Header=导入仓库 +HopEnvironmentDialog.ImportRepos.Message=用 hop-config.json 中已启用的仓库替换仓库列表? +HopEnvironmentDialog.Error.Header=环境编辑器错误 +HopEnvironmentDialog.Error.Load=无法加载环境文件:\n{0} +HopEnvironmentDialog.Error.Save=无法保存环境文件:\n{0} +HopEnvironmentDialog.Error.ImportRepos=无法从 hop-config 导入仓库 +AddPluginsFromCatalogDialog.Shell.Title=从目录添加插件 +AddPluginsFromCatalogDialog.Filter.Label=筛选 +AddPluginsFromCatalogDialog.Button.Add=添加所选 +AddPluginsFromCatalogDialog.Button.Cancel=取消 +AddPluginsFromCatalogDialog.Column.Name=名称 +AddPluginsFromCatalogDialog.Column.Artifact=构件 +AddPluginsFromCatalogDialog.Column.Category=类别 +AddPluginsFromCatalogDialog.Column.Description=描述 diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml index 2a0b01ea72c..f6a49b35d1a 100644 --- a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml @@ -20,6 +20,9 @@ schemaVersion: "1" groupId: org.apache.hop plugins: + # + # Engines + # - artifactId: hop-engines-spark name: Native Spark engine category: Engines @@ -32,18 +35,15 @@ plugins: description: Beam pipeline engine and transforms; SDKs under plugins/engines/beam/lib-beam. installPath: plugins/engines/beam modulePath: plugins/engines/beam + # + # Transforms + # - artifactId: hop-transform-script - name: Script transform + name: Script category: Transforms description: Scripting transform with embedded language runtimes. installPath: plugins/transforms/script modulePath: plugins/transforms/script - - artifactId: hop-tech-cassandra - name: Cassandra - category: Technology - description: Apache Cassandra input/output and related tech. - installPath: plugins/tech/cassandra - modulePath: plugins/tech/cassandra - artifactId: hop-transform-tika name: Apache Tika category: Transforms @@ -56,18 +56,39 @@ plugins: description: Business rules with Drools. installPath: plugins/transforms/drools modulePath: plugins/transforms/drools - - artifactId: hop-tech-parquet - name: Parquet - category: Technology - description: Parquet file format support. - installPath: plugins/tech/parquet - modulePath: plugins/tech/parquet - artifactId: hop-transform-stanfordnlp name: Stanford NLP category: Transforms description: Natural language processing with Stanford NLP. installPath: plugins/transforms/stanfordnlp modulePath: plugins/transforms/stanfordnlp + - artifactId: hop-transform-vcard + name: vCard + category: Transforms + description: vCard input/output + installPath: plugins/transforms/vcard + modulePath: plugins/transforms/vcard + - artifactId: hop-transform-fake + name: Fake + category: Transforms + description: Generate fake data + installPath: plugins/transforms/fake + modulePath: plugins/transforms/fake + # + # Technology + # + - artifactId: hop-tech-cassandra + name: Cassandra + category: Technology + description: Apache Cassandra input/output and related tech. + installPath: plugins/tech/cassandra + modulePath: plugins/tech/cassandra + - artifactId: hop-tech-parquet + name: Parquet + category: Technology + description: Parquet file format support. + installPath: plugins/tech/parquet + modulePath: plugins/tech/parquet - artifactId: hop-tech-arrow name: Apache Arrow category: Technology @@ -86,3 +107,102 @@ plugins: description: Convert EDI messages to XML. installPath: plugins/transforms/edi2xml modulePath: plugins/transforms/edi2xml + - artifactId: hop-tech-neo4j + name: Neo4j + category: Technology + description: Neo4j Graph Database + installPath: plugins/tech/neo4j + modulePath: plugins/tech/neo4j + - artifactId: hop-tech-azure + name: Azure + category: Technology + description: Microsoft Azure Cloud platform + installPath: plugins/tech/azure + modulePath: plugins/tech/azure + - artifactId: hop-tech-aws + name: AWS + category: Technology + description: Amazon Web Services (AWS) + installPath: plugins/tech/aws + modulePath: plugins/tech/aws + - artifactId: hop-tech-mongodb + name: MongoDB + category: Technology + description: MongoDB + installPath: plugins/tech/mongodb + modulePath: plugins/tech/mongodb + - artifactId: hop-tech-elastic + name: Elastic + category: Technology + description: Elastic + installPath: plugins/tech/elastic + modulePath: plugins/tech/elastic + - artifactId: hop-tech-opensearch + name: OpenSearch + category: Technology + description: OpenSearch + installPath: plugins/tech/opensearch + modulePath: plugins/tech/opensearch + - artifactId: hop-tech-salesforce + name: SaleForce + category: Technology + description: SalesForce (SFDC) + installPath: plugins/tech/salesforce + modulePath: plugins/tech/salesforce + - artifactId: hop-tech-avro + name: Avro + category: Technology + description: Avro format + installPath: plugins/tech/avro + modulePath: plugins/tech/avro + - artifactId: hop-tech-google + name: Google + category: Google + description: Google technology + installPath: plugins/tech/google + modulePath: plugins/tech/google + - artifactId: hop-tech-minio + name: MinIO + category: Technology + description: MinIO + installPath: plugins/tech/minio + modulePath: plugins/tech/minio + - artifactId: hop-tech-databricks + name: Databricks + category: Technology + description: Databricks platform, VFS, Spark, jobs + installPath: plugins/tech/databricks + modulePath: plugins/tech/databricks + # + # Miscellaneous + # + - artifactId: hop-misc-py4j + name: PyHop + category: Miscellaneous + description: Hop for Python (PyHop) + installPath: plugins/misc/py4j + modulePath: plugins/misc/py4j + - artifactId: hop-misc-rest + name: REST + category: Miscellaneous + description: REST support + installPath: plugins/misc/rest + modulePath: plugins/misc/rest + - artifactId: hop-misc-documentation + name: Documentation + category: Miscellaneous + description: Generate Hop documentation + installPath: plugins/misc/documentation + modulePath: plugins/misc/documentation + - artifactId: hop-misc-import + name: Import + category: Miscellaneous + description: Import Kettle / Pentaho Data Integration metadata + installPath: plugins/misc/import + modulePath: plugins/misc/import + - artifactId: hop-misc-mail + name: Mail + category: Miscellaneous + description: Send / Receive mail + installPath: plugins/misc/mail + modulePath: plugins/misc/mail diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/env/HopEnvironmentLoaderTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/env/HopEnvironmentLoaderTest.java index d5343e654cb..6ae387c25fe 100644 --- a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/env/HopEnvironmentLoaderTest.java +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/env/HopEnvironmentLoaderTest.java @@ -19,6 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import java.nio.charset.StandardCharsets; @@ -85,4 +86,93 @@ void loadJson() throws Exception { assertEquals(1, env.getPlugins().size()); assertEquals("hop-tech-arrow", env.getPlugins().get(0).getArtifactId()); } + + @Test + void saveAndLoadYamlRoundTrip() throws Exception { + HopEnvironmentSpec spec = sampleSpec(); + Path file = tempDir.resolve("roundtrip.yaml"); + HopEnvironmentLoader.save(file, spec); + + String content = Files.readString(file, StandardCharsets.UTF_8); + assertTrue(content.contains("hopVersion:")); + assertTrue(content.contains("hop-tech-parquet")); + assertTrue(content.contains("postgresql")); + // blank groupId omitted + assertFalse(content.contains("groupId: org.apache.hop")); + + HopEnvironmentSpec loaded = HopEnvironmentLoader.load(file); + assertEquals("1.0", loaded.getVersion()); + assertEquals("2.19.0", loaded.getHopVersion()); + assertTrue(loaded.isEnforceOnRun()); + assertEquals(2, loaded.getRepositories().size()); + assertEquals("asf", loaded.getRepositories().get(0).getId()); + assertEquals("secret", loaded.getRepositories().get(1).getPassword()); + assertEquals(1, loaded.getPlugins().size()); + assertEquals("hop-tech-parquet", loaded.getPlugins().get(0).getArtifactId()); + assertNull(loaded.getPlugins().get(0).getGroupId()); + assertEquals(1, loaded.getDependencies().size()); + assertEquals("postgresql", loaded.getDependencies().get(0).getArtifactId()); + assertEquals("lib/jdbc", loaded.getDependencies().get(0).getTarget()); + } + + @Test + void saveAndLoadJsonRoundTrip() throws Exception { + HopEnvironmentSpec spec = sampleSpec(); + Path file = tempDir.resolve("roundtrip.json"); + HopEnvironmentLoader.save(file, spec); + + HopEnvironmentSpec loaded = HopEnvironmentLoader.load(file); + assertEquals(spec.getHopVersion(), loaded.getHopVersion()); + assertEquals(spec.getPlugins().size(), loaded.getPlugins().size()); + assertEquals( + spec.getPlugins().get(0).getArtifactId(), loaded.getPlugins().get(0).getArtifactId()); + assertEquals(spec.getDependencies().size(), loaded.getDependencies().size()); + } + + @Test + void saveMinimalOmitsEmptyLists() throws Exception { + HopEnvironmentSpec spec = new HopEnvironmentSpec(); + spec.setVersion("1.0"); + spec.setHopVersion("2.19.0"); + Path file = tempDir.resolve("minimal.yaml"); + HopEnvironmentLoader.save(file, spec); + String content = Files.readString(file, StandardCharsets.UTF_8); + assertFalse(content.contains("repositories:")); + assertFalse(content.contains("plugins:")); + assertFalse(content.contains("dependencies:")); + HopEnvironmentSpec loaded = HopEnvironmentLoader.load(file); + assertEquals("2.19.0", loaded.getHopVersion()); + assertTrue(loaded.getPlugins().isEmpty()); + } + + private static HopEnvironmentSpec sampleSpec() { + HopEnvironmentSpec spec = new HopEnvironmentSpec(); + spec.setVersion("1.0"); + spec.setHopVersion("2.19.0"); + spec.setEnforceOnRun(true); + + HopEnvironmentSpec.RepositoryRef asf = new HopEnvironmentSpec.RepositoryRef(); + asf.setId("asf"); + asf.setUrl("https://repository.apache.org/content/groups/public/"); + HopEnvironmentSpec.RepositoryRef privateRepo = new HopEnvironmentSpec.RepositoryRef(); + privateRepo.setId("private"); + privateRepo.setUrl("https://nexus.example/repository/hop/"); + privateRepo.setUsername("ci"); + privateRepo.setPassword("secret"); + spec.getRepositories().add(asf); + spec.getRepositories().add(privateRepo); + + HopEnvironmentSpec.PluginRef plugin = new HopEnvironmentSpec.PluginRef(); + plugin.setArtifactId("hop-tech-parquet"); + plugin.setVersion("2.19.0"); + spec.getPlugins().add(plugin); + + HopEnvironmentSpec.DependencyRef dep = new HopEnvironmentSpec.DependencyRef(); + dep.setGroupId("org.postgresql"); + dep.setArtifactId("postgresql"); + dep.setVersion("42.7.3"); + dep.setTarget("lib/jdbc"); + spec.getDependencies().add(dep); + return spec; + } } diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/env/MarketplaceAttributesTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/env/MarketplaceAttributesTest.java new file mode 100644 index 00000000000..a7e28d0e565 --- /dev/null +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/env/MarketplaceAttributesTest.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.env; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.apache.hop.core.AttributesContext; +import org.junit.jupiter.api.Test; + +class MarketplaceAttributesTest { + + @Test + void purposeDefaults() { + assertEquals( + MarketplaceAttributes.ON_ENABLE_ENFORCE, + MarketplaceAttributes.defaultOnEnableForPurpose("Production")); + assertEquals( + MarketplaceAttributes.ON_ENABLE_WARN, + MarketplaceAttributes.defaultOnEnableForPurpose("Testing")); + assertEquals( + MarketplaceAttributes.ON_ENABLE_WARN, + MarketplaceAttributes.defaultOnEnableForPurpose("Acceptance")); + assertEquals( + MarketplaceAttributes.ON_ENABLE_OFF, + MarketplaceAttributes.defaultOnEnableForPurpose("Development")); + assertEquals( + MarketplaceAttributes.ON_ENABLE_OFF, MarketplaceAttributes.defaultOnEnableForPurpose(null)); + } + + @Test + void explicitOverridesPurpose() { + AttributesContext ctx = new AttributesContext(); + ctx.setAttribute( + MarketplaceAttributes.GROUP, + MarketplaceAttributes.KEY_ON_ENABLE, + MarketplaceAttributes.ON_ENABLE_OFF); + assertEquals( + MarketplaceAttributes.ON_ENABLE_OFF, + MarketplaceAttributes.resolveOnEnable(ctx, "Production")); + } + + @Test + void strictAndAutoApply() { + AttributesContext ctx = new AttributesContext(); + assertFalse(MarketplaceAttributes.isStrict(ctx)); + ctx.setAttribute(MarketplaceAttributes.GROUP, MarketplaceAttributes.KEY_STRICT, "true"); + assertTrue(MarketplaceAttributes.isStrict(ctx)); + ctx.setAttribute(MarketplaceAttributes.GROUP, MarketplaceAttributes.KEY_AUTO_APPLY, "Y"); + assertTrue(MarketplaceAttributes.isAutoApply(ctx)); + } +} diff --git a/plugins/misc/projects/src/main/java/org/apache/hop/projects/environment/LifecycleEnvironment.java b/plugins/misc/projects/src/main/java/org/apache/hop/projects/environment/LifecycleEnvironment.java index 9dbf5ed793f..140a82d751f 100644 --- a/plugins/misc/projects/src/main/java/org/apache/hop/projects/environment/LifecycleEnvironment.java +++ b/plugins/misc/projects/src/main/java/org/apache/hop/projects/environment/LifecycleEnvironment.java @@ -18,11 +18,20 @@ package org.apache.hop.projects.environment; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; +import org.apache.hop.core.IAttributes; -/** A project lifecycle environment describes the state of a project and its configuration. */ -public class LifecycleEnvironment { +/** + * A project lifecycle environment describes the state of a project and its configuration. + * + *

Implements {@link IAttributes} so optional plugins (marketplace, resource checks, …) can store + * namespaced group/key/value settings without hard-wiring fields into this class. Groups are + * persisted under {@code attributesMap} in hop-config projects configuration. + */ +public class LifecycleEnvironment implements IAttributes { private String name; @@ -32,8 +41,12 @@ public class LifecycleEnvironment { private List configurationFiles; + /** Group → (key → value); see {@link IAttributes}. */ + private Map> attributesMap; + public LifecycleEnvironment() { configurationFiles = new ArrayList<>(); + attributesMap = new HashMap<>(); } public LifecycleEnvironment( @@ -41,7 +54,8 @@ public LifecycleEnvironment( this.name = name; this.purpose = purpose; this.projectName = projectName; - this.configurationFiles = configurationFiles; + this.configurationFiles = configurationFiles != null ? configurationFiles : new ArrayList<>(); + this.attributesMap = new HashMap<>(); } public LifecycleEnvironment(LifecycleEnvironment env) { @@ -49,6 +63,24 @@ public LifecycleEnvironment(LifecycleEnvironment env) { this.purpose = env.purpose; this.projectName = env.projectName; this.configurationFiles = new ArrayList<>(env.configurationFiles); + this.attributesMap = deepCopyAttributes(env.attributesMap); + } + + private static Map> deepCopyAttributes( + Map> source) { + Map> copy = new HashMap<>(); + if (source == null) { + return copy; + } + for (Map.Entry> entry : source.entrySet()) { + if (entry.getKey() == null) { + continue; + } + copy.put( + entry.getKey(), + entry.getValue() == null ? new HashMap<>() : new HashMap<>(entry.getValue())); + } + return copy; } @Override @@ -131,4 +163,52 @@ public List getConfigurationFiles() { public void setConfigurationFiles(List configurationFiles) { this.configurationFiles = configurationFiles; } + + @Override + public void setAttributesMap(Map> attributesMap) { + this.attributesMap = attributesMap != null ? attributesMap : new HashMap<>(); + } + + @Override + public Map> getAttributesMap() { + if (attributesMap == null) { + attributesMap = new HashMap<>(); + } + return attributesMap; + } + + @Override + public void setAttributes(String groupName, Map attributes) { + if (groupName == null) { + return; + } + getAttributesMap().put(groupName, attributes != null ? attributes : new HashMap<>()); + } + + @Override + public void setAttribute(String groupName, String key, String value) { + if (groupName == null || key == null) { + return; + } + Map attributes = getAttributes(groupName); + if (attributes == null) { + attributes = new HashMap<>(); + getAttributesMap().put(groupName, attributes); + } + attributes.put(key, value); + } + + @Override + public Map getAttributes(String groupName) { + return getAttributesMap().get(groupName); + } + + @Override + public String getAttribute(String groupName, String key) { + Map attributes = getAttributes(groupName); + if (attributes == null) { + return null; + } + return attributes.get(key); + } } diff --git a/plugins/misc/projects/src/main/java/org/apache/hop/projects/environment/LifecycleEnvironmentDialog.java b/plugins/misc/projects/src/main/java/org/apache/hop/projects/environment/LifecycleEnvironmentDialog.java index 3a19b4c9171..2e3ace1dffb 100644 --- a/plugins/misc/projects/src/main/java/org/apache/hop/projects/environment/LifecycleEnvironmentDialog.java +++ b/plugins/misc/projects/src/main/java/org/apache/hop/projects/environment/LifecycleEnvironmentDialog.java @@ -19,9 +19,13 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.vfs2.FileObject; +import org.apache.hop.core.AttributesContext; import org.apache.hop.core.Const; import org.apache.hop.core.config.DescribedVariablesConfigFile; import org.apache.hop.core.exception.HopException; +import org.apache.hop.core.extension.ExtensionPointHandler; +import org.apache.hop.core.extension.HopExtensionPoint; +import org.apache.hop.core.logging.LogChannel; import org.apache.hop.core.variables.IVariables; import org.apache.hop.core.vfs.HopVfs; import org.apache.hop.i18n.BaseMessages; @@ -30,6 +34,7 @@ import org.apache.hop.projects.project.ProjectConfig; import org.apache.hop.ui.core.ConstUi; import org.apache.hop.ui.core.PropsUi; +import org.apache.hop.ui.core.dialog.AttributesDialogExtension; import org.apache.hop.ui.core.dialog.BaseDialog; import org.apache.hop.ui.core.dialog.ErrorDialog; import org.apache.hop.ui.core.dialog.MessageBox; @@ -40,12 +45,14 @@ import org.apache.hop.ui.hopgui.HopGui; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Dialog; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; @@ -76,6 +83,8 @@ public class LifecycleEnvironmentDialog extends Dialog { private boolean needingEnvironmentRefresh; + private AttributesDialogExtension dialogExtension; + public LifecycleEnvironmentDialog( Shell parent, LifecycleEnvironment environment, IVariables variables) { super(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE); @@ -105,7 +114,6 @@ public String open() { PropsUi.setLook(shell); int margin = PropsUi.getMargin() + 2; - int middle = props.getMiddlePct(); FormLayout formLayout = new FormLayout(); formLayout.marginWidth = PropsUi.getFormMargin(); @@ -124,7 +132,67 @@ public String open() { wCancel.addListener(SWT.Selection, event -> cancel()); BaseTransformDialog.positionBottomButtons(shell, new Button[] {wOK, wCancel}, margin * 3, null); - Label wlName = new Label(shell, SWT.RIGHT); + CTabFolder wTabFolder = new CTabFolder(shell, SWT.BORDER); + PropsUi.setLook(wTabFolder); + FormData fdTabs = new FormData(); + fdTabs.left = new FormAttachment(0, 0); + fdTabs.top = new FormAttachment(0, 0); + fdTabs.right = new FormAttachment(100, 0); + fdTabs.bottom = new FormAttachment(wOK, -margin * 2); + wTabFolder.setLayoutData(fdTabs); + + createGeneralTab(wTabFolder, margin); + createConfigurationFilesTab(wTabFolder, margin); + + // Optional plugins (marketplace, resource checks, …) contribute extra tabs + AttributesContext attributesContext = new AttributesContext(environment); + attributesContext.setProjectName(environment.getProjectName()); + attributesContext.setEnvironmentName(environment.getName()); + attributesContext.setPurpose(environment.getPurpose()); + if (environment.getConfigurationFiles() != null) { + attributesContext.setConfigurationFiles( + new java.util.ArrayList<>(environment.getConfigurationFiles())); + } + dialogExtension = + new AttributesDialogExtension(shell, wTabFolder, variables, attributesContext); + try { + ExtensionPointHandler.callExtensionPoint( + LogChannel.UI, + variables, + HopExtensionPoint.HopGuiLifecycleEnvironmentDialogTabs.id, + dialogExtension); + } catch (Exception e) { + new ErrorDialog(shell, CONST_ERROR, "Error loading optional environment dialog tabs", e); + } + + wTabFolder.setSelection(0); + + getData(); + if (dialogExtension != null) { + dialogExtension.runLoadCallbacks(); + } + + wName.setFocus(); + + BaseDialog.defaultShellHandling(shell, c -> ok(), c -> cancel()); + + return returnValue; + } + + private void createGeneralTab(CTabFolder folder, int margin) { + CTabItem tab = new CTabItem(folder, SWT.NONE); + tab.setText(BaseMessages.getString(PKG, "LifecycleEnvironmentDialog.Tab.General")); + Composite comp = new Composite(folder, SWT.NONE); + PropsUi.setLook(comp); + FormLayout layout = new FormLayout(); + layout.marginWidth = PropsUi.getFormMargin(); + layout.marginHeight = PropsUi.getFormMargin(); + comp.setLayout(layout); + tab.setControl(comp); + + int middle = props.getMiddlePct(); + + Label wlName = new Label(comp, SWT.RIGHT); PropsUi.setLook(wlName); wlName.setText(BaseMessages.getString(PKG, "LifecycleEnvironmentDialog.Label.EnvironmentName")); FormData fdlName = new FormData(); @@ -132,25 +200,24 @@ public String open() { fdlName.right = new FormAttachment(middle, 0); fdlName.top = new FormAttachment(0, margin); wlName.setLayoutData(fdlName); - wName = new Text(shell, SWT.SINGLE | SWT.BORDER | SWT.LEFT); + wName = new Text(comp, SWT.SINGLE | SWT.BORDER | SWT.LEFT); PropsUi.setLook(wName); FormData fdName = new FormData(); fdName.left = new FormAttachment(middle, margin); fdName.right = new FormAttachment(100, 0); fdName.top = new FormAttachment(wlName, 0, SWT.CENTER); wName.setLayoutData(fdName); - Control lastControl = wName; - Label wlPurpose = new Label(shell, SWT.RIGHT); + Label wlPurpose = new Label(comp, SWT.RIGHT); PropsUi.setLook(wlPurpose); wlPurpose.setText( BaseMessages.getString(PKG, "LifecycleEnvironmentDialog.Label.EnvironmentPurpose")); FormData fdlPurpose = new FormData(); fdlPurpose.left = new FormAttachment(0, 0); fdlPurpose.right = new FormAttachment(middle, 0); - fdlPurpose.top = new FormAttachment(lastControl, margin); + fdlPurpose.top = new FormAttachment(wName, margin); wlPurpose.setLayoutData(fdlPurpose); - wPurpose = new Combo(shell, SWT.SINGLE | SWT.BORDER | SWT.LEFT); + wPurpose = new Combo(comp, SWT.SINGLE | SWT.BORDER | SWT.LEFT); PropsUi.setLook(wPurpose); FormData fdPurpose = new FormData(); fdPurpose.left = new FormAttachment(middle, margin); @@ -158,18 +225,17 @@ public String open() { fdPurpose.top = new FormAttachment(wlPurpose, 0, SWT.CENTER); wPurpose.setLayoutData(fdPurpose); wPurpose.addListener(SWT.Modify, e -> needingEnvironmentRefresh = true); - lastControl = wPurpose; - Label wlProject = new Label(shell, SWT.RIGHT); + Label wlProject = new Label(comp, SWT.RIGHT); PropsUi.setLook(wlProject); wlProject.setText( BaseMessages.getString(PKG, "LifecycleEnvironmentDialog.Label.ReferencedProject")); FormData fdlProject = new FormData(); fdlProject.left = new FormAttachment(0, 0); fdlProject.right = new FormAttachment(middle, 0); - fdlProject.top = new FormAttachment(lastControl, margin); + fdlProject.top = new FormAttachment(wPurpose, margin); wlProject.setLayoutData(fdlProject); - wProject = new Combo(shell, SWT.SINGLE | SWT.BORDER | SWT.LEFT); + wProject = new Combo(comp, SWT.SINGLE | SWT.BORDER | SWT.LEFT); PropsUi.setLook(wProject); FormData fdProject = new FormData(); fdProject.left = new FormAttachment(middle, margin); @@ -177,19 +243,30 @@ public String open() { fdProject.top = new FormAttachment(wlProject, 0, SWT.CENTER); wProject.setLayoutData(fdProject); wProject.addListener(SWT.Modify, e -> needingEnvironmentRefresh = true); - lastControl = wProject; + } - Label wlConfigFiles = new Label(shell, SWT.LEFT); + private void createConfigurationFilesTab(CTabFolder folder, int margin) { + CTabItem tab = new CTabItem(folder, SWT.NONE); + tab.setText(BaseMessages.getString(PKG, "LifecycleEnvironmentDialog.Tab.ConfigurationFiles")); + Composite comp = new Composite(folder, SWT.NONE); + PropsUi.setLook(comp); + FormLayout layout = new FormLayout(); + layout.marginWidth = PropsUi.getFormMargin(); + layout.marginHeight = PropsUi.getFormMargin(); + comp.setLayout(layout); + tab.setControl(comp); + + Label wlConfigFiles = new Label(comp, SWT.LEFT); PropsUi.setLook(wlConfigFiles); wlConfigFiles.setText( BaseMessages.getString(PKG, "LifecycleEnvironmentDialog.Group.Label.ConfigurationFiles")); FormData fdlConfigFiles = new FormData(); fdlConfigFiles.left = new FormAttachment(0, 0); fdlConfigFiles.right = new FormAttachment(100, 0); - fdlConfigFiles.top = new FormAttachment(lastControl, margin); + fdlConfigFiles.top = new FormAttachment(0, 0); wlConfigFiles.setLayoutData(fdlConfigFiles); - Button wbSelect = new Button(shell, SWT.PUSH); + Button wbSelect = new Button(comp, SWT.PUSH); PropsUi.setLook(wbSelect); wbSelect.setText(BaseMessages.getString(PKG, "LifecycleEnvironmentDialog.Button.Select")); FormData fdAdd = new FormData(); @@ -211,10 +288,10 @@ public String open() { wConfigFiles = new TableView( variables, - shell, + comp, SWT.SINGLE | SWT.BORDER, columnInfo, - environment.getConfigurationFiles().size(), + Math.max(environment.getConfigurationFiles().size(), 1), null, props); PropsUi.setLook(wConfigFiles); @@ -222,11 +299,11 @@ public String open() { fdConfigFiles.left = new FormAttachment(0, 0); fdConfigFiles.right = new FormAttachment(wbSelect, -2 * margin); fdConfigFiles.top = new FormAttachment(wlConfigFiles, margin); - fdConfigFiles.bottom = new FormAttachment(wOK, -margin * 2); + fdConfigFiles.bottom = new FormAttachment(100, 0); wConfigFiles.setLayoutData(fdConfigFiles); wConfigFiles.table.addListener(SWT.Selection, this::setButtonStates); - Button wbNew = new Button(shell, SWT.PUSH); + Button wbNew = new Button(comp, SWT.PUSH); PropsUi.setLook(wbNew); wbNew.setText(BaseMessages.getString(PKG, "LifecycleEnvironmentDialog.Button.New")); FormData fdNew = new FormData(); @@ -236,7 +313,7 @@ public String open() { wbNew.setLayoutData(fdNew); wbNew.addListener(SWT.Selection, this::newConfigFile); - wbEdit = new Button(shell, SWT.PUSH); + wbEdit = new Button(comp, SWT.PUSH); PropsUi.setLook(wbEdit); wbEdit.setText(BaseMessages.getString(PKG, "LifecycleEnvironmentDialog.Button.Edit")); FormData fdEdit = new FormData(); @@ -245,14 +322,6 @@ public String open() { fdEdit.top = new FormAttachment(wbNew, margin); wbEdit.setLayoutData(fdEdit); wbEdit.addListener(SWT.Selection, this::editConfigFile); - - getData(); - - wName.setFocus(); - - BaseDialog.defaultShellHandling(shell, c -> ok(), c -> cancel()); - - return returnValue; } private void editConfigFile(Event event) { @@ -385,6 +454,16 @@ private void ok() { } getInfo(environment); + if (dialogExtension != null) { + dialogExtension.getContext().setProjectName(environment.getProjectName()); + dialogExtension.getContext().setEnvironmentName(environment.getName()); + dialogExtension.getContext().setPurpose(environment.getPurpose()); + dialogExtension + .getContext() + .setConfigurationFiles(new java.util.ArrayList<>(environment.getConfigurationFiles())); + dialogExtension.runSaveCallbacks(); + dialogExtension.getContext().copyAttributesTo(environment); + } returnValue = environment.getName(); dispose(); @@ -421,11 +500,15 @@ private void getData() { wPurpose.setText(Const.NVL(environment.getPurpose(), "")); wProject.setText(Const.NVL(environment.getProjectName(), "")); + wConfigFiles.table.removeAll(); for (int i = 0; i < environment.getConfigurationFiles().size(); i++) { String configurationFile = environment.getConfigurationFiles().get(i); - TableItem item = wConfigFiles.table.getItem(i); + TableItem item = new TableItem(wConfigFiles.table, SWT.NONE); item.setText(1, Const.NVL(configurationFile, "")); } + if (environment.getConfigurationFiles().isEmpty()) { + new TableItem(wConfigFiles.table, SWT.NONE); + } wConfigFiles.setRowNums(); wConfigFiles.optWidth(true); diff --git a/plugins/misc/projects/src/main/java/org/apache/hop/projects/util/ProjectsUtil.java b/plugins/misc/projects/src/main/java/org/apache/hop/projects/util/ProjectsUtil.java index d6a6e709711..813e12c1cef 100644 --- a/plugins/misc/projects/src/main/java/org/apache/hop/projects/util/ProjectsUtil.java +++ b/plugins/misc/projects/src/main/java/org/apache/hop/projects/util/ProjectsUtil.java @@ -23,11 +23,13 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.vfs2.FileObject; import org.apache.commons.vfs2.FileSystemException; +import org.apache.hop.core.AttributesContext; import org.apache.hop.core.Const; import org.apache.hop.core.DbCache; import org.apache.hop.core.encryption.Encr; import org.apache.hop.core.exception.HopException; import org.apache.hop.core.extension.ExtensionPointHandler; +import org.apache.hop.core.extension.HopExtensionPoint; import org.apache.hop.core.logging.ILogChannel; import org.apache.hop.core.variables.IVariables; import org.apache.hop.core.vfs.HopVfs; @@ -38,6 +40,7 @@ import org.apache.hop.metadata.util.HopMetadataUtil; import org.apache.hop.projects.config.ProjectsConfig; import org.apache.hop.projects.config.ProjectsConfigSingleton; +import org.apache.hop.projects.environment.LifecycleEnvironment; import org.apache.hop.projects.project.Project; import org.apache.hop.projects.project.ProjectConfig; import org.apache.hop.ui.core.gui.HopNamespace; @@ -145,6 +148,57 @@ public static void enableProject( // ExtensionPointHandler.callExtensionPoint( log, variables, Defaults.EXTENSION_POINT_PROJECT_ACTIVATED, projectName); + + // Plugin-agnostic attributes context for marketplace, resource checks, etc. + // Thrown HopException from listeners aborts environment enablement. + // + AttributesContext attributesContext = + buildAttributesContext(config, projectConfig, projectName, environmentName, variables); + ExtensionPointHandler.callExtensionPoint( + log, variables, HopExtensionPoint.HopProjectEnvironmentAfterEnabled.id, attributesContext); + } + + /** + * Build a core {@link AttributesContext} for the enabled project/environment so optional plugins + * can read identity fields and namespaced {@link org.apache.hop.core.IAttributes} groups without + * depending on Projects classes. + */ + public static AttributesContext buildAttributesContext( + ProjectsConfig config, + ProjectConfig projectConfig, + String projectName, + String environmentName, + IVariables variables) + throws HopException { + AttributesContext context = new AttributesContext(); + context.setProjectName(projectName); + context.setEnvironmentName(environmentName); + + if (projectConfig != null) { + try { + String home = projectConfig.getProjectHome(); + if (variables != null && StringUtils.isNotEmpty(home)) { + home = variables.resolve(home); + } + context.setProjectHome(home); + } catch (Exception e) { + // best-effort project home + context.setProjectHome(projectConfig.getProjectHome()); + } + } + + LifecycleEnvironment environment = + StringUtils.isNotEmpty(environmentName) && config != null + ? config.findEnvironment(environmentName) + : null; + if (environment != null) { + context.setPurpose(environment.getPurpose()); + if (environment.getConfigurationFiles() != null) { + context.setConfigurationFiles(new ArrayList<>(environment.getConfigurationFiles())); + } + context.copyAttributesFrom(environment); + } + return context; } public static void validateFileInProject( diff --git a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_en_US.properties b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_en_US.properties index 4bd84281148..4c5fb283dbf 100644 --- a/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_en_US.properties +++ b/plugins/misc/projects/src/main/resources/org/apache/hop/projects/environment/messages/messages_en_US.properties @@ -31,3 +31,5 @@ LifecycleEnvironmentDialog.Purpose.Text.Development=Development LifecycleEnvironmentDialog.Purpose.Text.Production=Production LifecycleEnvironmentDialog.Purpose.Text.Testing=Testing LifecycleEnvironmentDialog.Shell.Name=Environment Properties +LifecycleEnvironmentDialog.Tab.General=General +LifecycleEnvironmentDialog.Tab.ConfigurationFiles=Configuration files diff --git a/tools/build-marketplace-list.sh b/tools/build-marketplace-list.sh new file mode 100755 index 00000000000..80c324c58c7 --- /dev/null +++ b/tools/build-marketplace-list.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Compatibility wrapper: list marketplace plugin zip paths from optional-plugins.yaml. +# Prefer: ./tools/list-marketplace-plugins.sh --zips +# +# Output lines: artifactId|modulePath/target/artifactId-${HOP_VERSION}.zip +# +set -euo pipefail +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +exec "${ROOT}/tools/list-marketplace-plugins.sh" --zips diff --git a/tools/install-wave1-plugins.sh b/tools/install-wave1-plugins.sh index 4b64a4ca4f8..7a81cacc554 100755 --- a/tools/install-wave1-plugins.sh +++ b/tools/install-wave1-plugins.sh @@ -8,20 +8,21 @@ # # http://www.apache.org/licenses/LICENSE-2.0 # -# Unpack Wave 1 marketplace plugin zips into a Hop install (e.g. for IT images). +# Unpack marketplace-optional plugin zips into a Hop install (e.g. for IT images). +# Plugin list is read only from optional-plugins.yaml (via list-marketplace-plugins.sh). +# # Usage: # ./tools/install-wave1-plugins.sh [HOP_INSTALL_DIR] # Default install dir: assemblies/client/target/hop # # Requires plugin modules to have been packaged (*.zip under plugins/**/target/). -# Keep the plugin list in sync with: -# plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml -# (source of truth for full-client-env.yaml and the GUI catalog). +# set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" INSTALL_DIR="${1:-${ROOT}/assemblies/client/target/hop}" VERSION="${HOP_VERSION:-2.19.0-SNAPSHOT}" +LIST_SCRIPT="${ROOT}/tools/list-marketplace-plugins.sh" if [[ ! -d "${INSTALL_DIR}" ]]; then echo "Hop install not found: ${INSTALL_DIR}" >&2 @@ -29,20 +30,11 @@ if [[ ! -d "${INSTALL_DIR}" ]]; then exit 1 fi -# artifactId|relative path to zip under repo root -PLUGINS=( - "hop-engines-spark|plugins/engines/spark/target/hop-engines-spark-${VERSION}.zip" - "hop-engines-beam|plugins/engines/beam/target/hop-engines-beam-${VERSION}.zip" - "hop-transform-script|plugins/transforms/script/target/hop-transform-script-${VERSION}.zip" - "hop-tech-cassandra|plugins/tech/cassandra/target/hop-tech-cassandra-${VERSION}.zip" - "hop-transform-tika|plugins/transforms/tika/target/hop-transform-tika-${VERSION}.zip" - "hop-transform-drools|plugins/transforms/drools/target/hop-transform-drools-${VERSION}.zip" - "hop-tech-parquet|plugins/tech/parquet/target/hop-tech-parquet-${VERSION}.zip" - "hop-transform-stanfordnlp|plugins/transforms/stanfordnlp/target/hop-transform-stanfordnlp-${VERSION}.zip" - "hop-tech-arrow|plugins/tech/arrow/target/hop-tech-arrow-${VERSION}.zip" - "hop-tech-dropbox|plugins/tech/dropbox/target/hop-tech-dropbox-${VERSION}.zip" - "hop-transform-edi2xml|plugins/transforms/edi2xml/target/hop-transform-edi2xml-${VERSION}.zip" -) +if [[ ! -x "${LIST_SCRIPT}" ]]; then + chmod +x "${LIST_SCRIPT}" 2>/dev/null || true +fi + +mapfile -t PLUGINS < <(HOP_VERSION="${VERSION}" "${LIST_SCRIPT}" --zips) installed=0 skipped=0 @@ -60,5 +52,5 @@ for entry in "${PLUGINS[@]}"; do installed=$((installed + 1)) done -echo "Wave 1 plugins: installed=${installed} skipped=${skipped} into ${INSTALL_DIR}" +echo "Marketplace plugins: installed=${installed} skipped=${skipped} into ${INSTALL_DIR}" # Note: beam plugin zip includes lib-beam (Beam SDKs). diff --git a/tools/list-marketplace-plugins.sh b/tools/list-marketplace-plugins.sh new file mode 100755 index 00000000000..8a1b55ec568 --- /dev/null +++ b/tools/list-marketplace-plugins.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# List marketplace-optional plugins from optional-plugins.yaml (source of truth). +# +# Output (one line per unique artifactId, registry order): +# artifactId|modulePath +# +# Usage: +# ./tools/list-marketplace-plugins.sh +# HOP_VERSION=2.19.0-SNAPSHOT ./tools/list-marketplace-plugins.sh --zips +# → artifactId|modulePath/target/artifactId-${HOP_VERSION}.zip +# +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +REGISTRY="${ROOT}/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml" +VERSION="${HOP_VERSION:-2.19.0-SNAPSHOT}" +MODE="pairs" + +if [[ "${1:-}" == "--zips" ]]; then + MODE="zips" +elif [[ "${1:-}" == "--modules" ]]; then + MODE="modules" +elif [[ -n "${1:-}" ]]; then + echo "Usage: $0 [--zips|--modules]" >&2 + exit 2 +fi + +if [[ ! -f "${REGISTRY}" ]]; then + echo "Registry not found: ${REGISTRY}" >&2 + exit 1 +fi + +# Parse simple YAML entries: - artifactId: … then modulePath: … +# Deduplicate by artifactId (first wins). No yq required. +awk ' + /^[[:space:]]*-[[:space:]]*artifactId:[[:space:]]*/ { + if (aid != "" && path != "" && !(aid in seen)) { + seen[aid] = 1 + print aid "|" path + order[++n] = aid + } + line = $0 + sub(/^[[:space:]]*-[[:space:]]*artifactId:[[:space:]]*/, "", line) + gsub(/[[:space:]]+$/, "", line) + gsub(/^["'\'']|["'\'']$/, "", line) + aid = line + path = "" + next + } + /^[[:space:]]*modulePath:[[:space:]]*/ { + line = $0 + sub(/^[[:space:]]*modulePath:[[:space:]]*/, "", line) + gsub(/[[:space:]]+$/, "", line) + gsub(/^["'\'']|["'\'']$/, "", line) + path = line + next + } + END { + if (aid != "" && path != "" && !(aid in seen)) { + print aid "|" path + } + } +' "${REGISTRY}" | while IFS='|' read -r artifactId modulePath; do + [[ -n "${artifactId}" && -n "${modulePath}" ]] || continue + case "${MODE}" in + pairs) + printf '%s|%s\n' "${artifactId}" "${modulePath}" + ;; + zips) + printf '%s|%s/target/%s-%s.zip\n' \ + "${artifactId}" "${modulePath}" "${artifactId}" "${VERSION}" + ;; + modules) + printf '%s\n' "${modulePath}" + ;; + esac +done diff --git a/ui/src/main/java/org/apache/hop/ui/core/dialog/AttributesDialogExtension.java b/ui/src/main/java/org/apache/hop/ui/core/dialog/AttributesDialogExtension.java new file mode 100644 index 00000000000..79c3e6425ef --- /dev/null +++ b/ui/src/main/java/org/apache/hop/ui/core/dialog/AttributesDialogExtension.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.ui.core.dialog; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import lombok.Getter; +import org.apache.hop.core.AttributesContext; +import org.apache.hop.core.variables.IVariables; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.widgets.Shell; + +/** + * Payload for dialog-tab contribution extension points (e.g. lifecycle environment dialog). + * + *

Optional plugins receive a {@link CTabFolder} to add tabs and a mutable {@link + * AttributesContext} for namespaced settings. Register load/save callbacks so the host dialog can + * refresh widgets from attributes and flush widget values back before OK. + */ +@Getter +public class AttributesDialogExtension { + + private final Shell shell; + private final CTabFolder tabFolder; + private final IVariables variables; + private final AttributesContext context; + private final List> loadCallbacks = new ArrayList<>(); + private final List> saveCallbacks = new ArrayList<>(); + + public AttributesDialogExtension( + Shell shell, CTabFolder tabFolder, IVariables variables, AttributesContext context) { + this.shell = shell; + this.tabFolder = tabFolder; + this.variables = variables; + this.context = context; + } + + /** Called by the host after building standard tabs so plugins can create widgets. */ + public void addLoadCallback(Consumer callback) { + if (callback != null) { + loadCallbacks.add(callback); + } + } + + /** Called by the host before persisting so plugins can write widgets into attributes. */ + public void addSaveCallback(Consumer callback) { + if (callback != null) { + saveCallbacks.add(callback); + } + } + + public void runLoadCallbacks() { + for (Consumer callback : loadCallbacks) { + callback.accept(context); + } + } + + public void runSaveCallbacks() { + for (Consumer callback : saveCallbacks) { + callback.accept(context); + } + } +} From c1c4d8e247e2af9987c80d8e0aef4a8110bb06a7 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Mon, 20 Jul 2026 15:50:28 +0200 Subject: [PATCH 26/28] issue #7547 : spotless --- .../java/org/apache/hop/marketplace/gui/MarketplaceDialog.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java index a0e1b2b41a7..1f9effde7e4 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java @@ -108,7 +108,8 @@ public void open() { Button wClose = new Button(shell, SWT.PUSH); wClose.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.Close")); wClose.addListener(SWT.Selection, e -> close()); - BaseTransformDialog.positionBottomButtons(shell, new Button[] {wClose}, PropsUi.getMargin(), null); + BaseTransformDialog.positionBottomButtons( + shell, new Button[] {wClose}, PropsUi.getMargin(), null); // Status (shared across tabs) wStatus = new Label(shell, SWT.LEFT); From 8421f124f16de6ff9e964ddaf0c88d2cfcd69154 Mon Sep 17 00:00:00 2001 From: mattcasters Date: Tue, 21 Jul 2026 12:44:57 +0200 Subject: [PATCH 27/28] issue #7547 : SNAPSHOT plugin zip publish path and CI confidence checks Enable Jenkins wagon upload of marketplace plugin zips, keep release plugin assemblies, and add scripts/docs to verify file:// deploy layout before merging to main. --- .gitignore | 3 + docker/marketplace-nexus/README.md | 28 +++ docker/marketplace-nexus/dummy-staging.sh | 229 ++++++++++++++++++ .../publish-marketplace-plugins.sh | 19 +- .../apache-release/checking-a-release.adoc | 40 +++ .../apache-release/creating-a-release.adoc | 33 ++- plugins/misc/marketplace/README.md | 126 +++++++++- pom.xml | 24 +- tools/deploy-snapshots-data-hopper.sh | 96 ++++++++ tools/verify-ci-snapshot-zips.sh | 88 +++++++ 10 files changed, 663 insertions(+), 23 deletions(-) create mode 100755 docker/marketplace-nexus/dummy-staging.sh create mode 100755 tools/deploy-snapshots-data-hopper.sh create mode 100755 tools/verify-ci-snapshot-zips.sh diff --git a/.gitignore b/.gitignore index 64433a06aaa..28e2f00e632 100644 --- a/.gitignore +++ b/.gitignore @@ -83,3 +83,6 @@ screenshots/ # Docker script leaving audit data docker/local-data/ /docker/marketplace-nexus/.env + +# Jenkins-style local deploy output (verify-ci-snapshot-zips.sh) +local-snapshots-dir/ diff --git a/docker/marketplace-nexus/README.md b/docker/marketplace-nexus/README.md index 261d0e75e31..95321f6d434 100644 --- a/docker/marketplace-nexus/README.md +++ b/docker/marketplace-nexus/README.md @@ -119,6 +119,33 @@ Uses a temporary `HOP_CONFIG_FOLDER` (does not touch your real hop-config) and installs two small plugins into `assemblies/client/target/hop` (override with `HOP_DIR`). +## Dummy staging (full registry verify + smoke) + +End-to-end dry-run of “stage plugin zips → confirm Maven layout → install”: + +```bash +./docker/marketplace-nexus/start.sh +export NEXUS_PASSWORD=hop-nexus-dev + +# Publish all optional-plugins.yaml zips, HTTP-verify each GAV, smoke install: +./docker/marketplace-nexus/dummy-staging.sh + +# Package modules first if zips are missing: +./docker/marketplace-nexus/dummy-staging.sh --package + +# Already published; only verify + smoke: +./docker/marketplace-nexus/dummy-staging.sh --skip-publish +``` + +After a real ASF `release:perform`, point the same checks at the staging repo: + +```bash +export REPO_URL='https://repository.apache.org/content/repositories/orgapachehop-XXXX/' +# or NEXUS_REPO_URL=… +./docker/marketplace-nexus/dummy-staging.sh --skip-publish +# then drop the staging repository if it was only a dry-run +``` + ## Scripts | Script | Role | @@ -127,6 +154,7 @@ installs two small plugins into `assemblies/client/target/hop` (override with | `configure-nexus.sh` | Anonymous + hosted repo (idempotent) | | `publish-marketplace-plugins.sh` | `deploy-file` of all zips from `optional-plugins.yaml` | | `publish-wave1-plugins.sh` | Deprecated alias of `publish-marketplace-plugins.sh` | +| `dummy-staging.sh` | Publish (optional) + verify all registry zips + install smoke | | `smoke-test.sh` | Anonymous install / list / validate / apply / uninstall | ## Stop diff --git a/docker/marketplace-nexus/dummy-staging.sh b/docker/marketplace-nexus/dummy-staging.sh new file mode 100755 index 00000000000..11e51e317fb --- /dev/null +++ b/docker/marketplace-nexus/dummy-staging.sh @@ -0,0 +1,229 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Dummy marketplace staging: publish optional-plugin zips (from the registry) to +# a Maven repo, verify HTTP layout, and smoke-test hop marketplace install. +# +# Default target is local Sonatype Nexus (same as publish-marketplace-plugins.sh). +# This is the dry-run analogue of an ASF Nexus staging repository check. +# +# Prerequisites: +# - ./docker/marketplace-nexus/start.sh (for default local Nexus) +# - Plugin zips built, or pass --package +# - Optional: hop client at assemblies/client/target/hop (or HOP_DIR) for install smoke +# +# Usage (repo root): +# ./docker/marketplace-nexus/dummy-staging.sh +# ./docker/marketplace-nexus/dummy-staging.sh --package +# ./docker/marketplace-nexus/dummy-staging.sh --skip-publish # only verify + smoke +# ./docker/marketplace-nexus/dummy-staging.sh --skip-smoke +# +# ASF staging (when you have apache.releases.https credentials): +# After release:perform, set: +# REPO_URL=https://repository.apache.org/content/repositories/orgapachehop-XXXX/ +# ./docker/marketplace-nexus/dummy-staging.sh --skip-publish +# Then drop the staging repo if it was only a dry-run. +# +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +LIST_SCRIPT="${ROOT}/tools/list-marketplace-plugins.sh" +PUBLISH_SCRIPT="${SCRIPT_DIR}/publish-marketplace-plugins.sh" + +if [[ -f "${SCRIPT_DIR}/.env" ]]; then + # shellcheck disable=SC1091 + set -a + source "${SCRIPT_DIR}/.env" + set +a +fi + +VERSION="${HOP_VERSION:-2.19.0-SNAPSHOT}" +GROUP_ID="${GROUP_ID:-org.apache.hop}" +# NEXUS_REPO_URL / ARTIFACTORY_URL / REPO_URL (ASF staging) all accepted +REPO_URL="${NEXUS_REPO_URL:-${ARTIFACTORY_URL:-${REPO_URL:-http://127.0.0.1:8081/repository/hop-plugins}}}" +REPO_URL="${REPO_URL%/}/" +HOP_DIR="${HOP_DIR:-${ROOT}/assemblies/client/target/hop}" + +PACKAGE=0 +SKIP_PUBLISH=0 +SKIP_SMOKE=0 +SMOKE_A="${SMOKE_PLUGIN_A:-hop-tech-dropbox}" +SMOKE_B="${SMOKE_PLUGIN_B:-hop-transform-fake}" + +for arg in "$@"; do + case "${arg}" in + --package) PACKAGE=1 ;; + --skip-publish) SKIP_PUBLISH=1 ;; + --skip-smoke) SKIP_SMOKE=1 ;; + -h | --help) + sed -n '2,40p' "$0" | sed 's/^# \{0,1\}//' + exit 0 + ;; + *) + echo "Unknown argument: ${arg}" >&2 + exit 2 + ;; + esac +done + +echo "==> Dummy marketplace staging" +echo " version: ${VERSION}" +echo " repo: ${REPO_URL}" +echo " hop dir: ${HOP_DIR}" +echo + +if [[ ! -x "${LIST_SCRIPT}" ]]; then + chmod +x "${LIST_SCRIPT}" 2>/dev/null || true +fi + +mapfile -t ENTRIES < <(HOP_VERSION="${VERSION}" "${LIST_SCRIPT}" --zips) +if [[ ${#ENTRIES[@]} -eq 0 ]]; then + echo "No plugins in optional-plugins.yaml registry" >&2 + exit 1 +fi +echo " registry: ${#ENTRIES[@]} plugin(s)" + +# --- Publish (local Nexus / Artifactory) --- +if [[ "${SKIP_PUBLISH}" -eq 0 ]]; then + echo + echo "==> Publish marketplace plugin zips" + if [[ ! -f "${PUBLISH_SCRIPT}" ]]; then + echo "Missing ${PUBLISH_SCRIPT}" >&2 + exit 1 + fi + publish_args=() + if [[ "${PACKAGE}" -eq 1 ]]; then + publish_args+=(--package) + fi + # Prefer 127.0.0.1 for deploy URL consistency with Hop client + export NEXUS_REPO_URL="${REPO_URL%/}" + export HOP_VERSION="${VERSION}" + "${PUBLISH_SCRIPT}" "${publish_args[@]+"${publish_args[@]}"}" +else + echo + echo "==> Skip publish (--skip-publish)" +fi + +# --- Verify HTTP Maven layout for every registry plugin --- +echo +echo "==> Verify zip URLs (Maven layout)" +ok=0 +fail=0 +declare -a FAILED=() +for entry in "${ENTRIES[@]}"; do + artifactId="${entry%%|*}" + # SNAPSHOT path uses version folder; unique timestamp filename resolved via maven-metadata later. + # For releases: {base}{g}/{a}/{v}/{a}-{v}.zip + # For SNAPSHOT: try literal SNAPSHOT zip first, then accept 200 on metadata + any zip listing. + gpath="${GROUP_ID//.//}" + base="${REPO_URL}${gpath}/${artifactId}/${VERSION}/" + literal_zip="${base}${artifactId}-${VERSION}.zip" + code=$(curl -sS -o /dev/null -w '%{http_code}' -L "${literal_zip}" || true) + if [[ "${code}" == "200" ]]; then + ok=$((ok + 1)) + echo " OK ${artifactId} (HTTP ${code})" + continue + fi + # SNAPSHOT unique versions: maven-metadata.xml lists zip + meta="${base}maven-metadata.xml" + mcode=$(curl -sS -o /tmp/hop-staging-meta.xml -w '%{http_code}' -L "${meta}" || true) + if [[ "${mcode}" == "200" ]]; then + # Prefer value that appears with extension zip (snapshotVersion block) + value=$( + tr '\n' ' ' /\n/g' \ + | grep -F 'zip' \ + | sed -n 's/.*\([^<]*\)<\/value>.*/\1/p' \ + | head -1 || true + ) + if [[ -z "${value}" ]]; then + value=$(sed -n 's/.*\([^<]*\)<\/value>.*/\1/p' /tmp/hop-staging-meta.xml | head -1 || true) + fi + if [[ -n "${value}" ]]; then + snap_zip="${base}${artifactId}-${value}.zip" + scode=$(curl -sS -o /dev/null -w '%{http_code}' -L "${snap_zip}" || true) + if [[ "${scode}" == "200" ]]; then + ok=$((ok + 1)) + echo " OK ${artifactId} (unique SNAPSHOT ${value}.zip)" + continue + fi + FAILED+=("${artifactId} snap_zip=${scode} value=${value}") + echo " FAIL ${artifactId} (SNAPSHOT zip HTTP ${scode} for ${value})" + fail=$((fail + 1)) + continue + fi + fi + fail=$((fail + 1)) + FAILED+=("${artifactId} literal=${code} meta=${mcode:-n/a}") + echo " FAIL ${artifactId} (zip HTTP ${code}, meta HTTP ${mcode:-n/a})" +done +rm -f /tmp/hop-staging-meta.xml + +echo +echo " verified OK=${ok} FAIL=${fail} (of ${#ENTRIES[@]})" +if [[ "${fail}" -gt 0 ]]; then + echo "Missing or unreachable zips:" >&2 + printf ' - %s\n' "${FAILED[@]}" >&2 + exit 1 +fi + +# --- Hop marketplace smoke install --- +if [[ "${SKIP_SMOKE}" -eq 1 ]]; then + echo + echo "==> Skip install smoke (--skip-smoke)" + echo "OK — dummy staging verify passed against ${REPO_URL}" + exit 0 +fi + +if [[ ! -x "${HOP_DIR}/hop" ]]; then + echo + echo "WARN: Hop launcher not found at ${HOP_DIR}/hop — skip install smoke." + echo " Build/unzip hop-client or set HOP_DIR." + echo "OK — dummy staging publish+verify passed against ${REPO_URL}" + exit 0 +fi + +# Ensure marketplace CLI plugin is present in the hop install (bundled plugin). +MKT_ZIP="${ROOT}/plugins/misc/marketplace/target/hop-misc-marketplace-${VERSION}.zip" +if [[ ! -f "${HOP_DIR}/plugins/misc/marketplace/version.xml" ]]; then + if [[ -f "${MKT_ZIP}" ]]; then + echo "==> Installing marketplace plugin into ${HOP_DIR}" + unzip -o -q "${MKT_ZIP}" -d "${HOP_DIR}" + else + echo "WARN: marketplace plugin not in hop install and zip missing: ${MKT_ZIP}" >&2 + echo " Smoke may fail with 'Unmatched arguments: marketplace'." >&2 + fi +fi + +echo +echo "==> Hop marketplace install smoke (${SMOKE_A}, ${SMOKE_B})" +export NEXUS_REPO_URL="${REPO_URL}" +export HOP_DIR +export HOP_VERSION="${VERSION}" +export SMOKE_PLUGIN_A="${SMOKE_A}" +export SMOKE_PLUGIN_B="${SMOKE_B}" +# Prefer 127.0.0.1 for Hop client (IPv6 localhost issues with Docker) +export NEXUS_REPO_URL="${REPO_URL/localhost/127.0.0.1}" +"${SCRIPT_DIR}/smoke-test.sh" + +echo +echo "================================================================" +echo "Dummy staging complete." +echo " Repository: ${REPO_URL}" +echo " Registry plugins verified: ${ok}" +echo +echo "ASF release staging (RM) — after release:perform:" +echo " 1. Open https://repository.apache.org/#stagingRepositories" +echo " 2. Open the orgapachehop-* staging repo content" +echo " 3. Confirm e.g. org/apache/hop/hop-tech-parquet//…zip" +echo " 4. REPO_URL=/ ./docker/marketplace-nexus/dummy-staging.sh --skip-publish" +echo " 5. Drop the staging repository if this was only a dry-run" +echo "================================================================" diff --git a/docker/marketplace-nexus/publish-marketplace-plugins.sh b/docker/marketplace-nexus/publish-marketplace-plugins.sh index 191d2721541..bb1e461dd64 100755 --- a/docker/marketplace-nexus/publish-marketplace-plugins.sh +++ b/docker/marketplace-nexus/publish-marketplace-plugins.sh @@ -54,14 +54,29 @@ for arg in "$@"; do esac done -# Load .env from start/configure if present +# Capture caller overrides before optional .env (local docker defaults must not win). +_OV_REPO_URL="${NEXUS_REPO_URL:-${ARTIFACTORY_URL:-}}" +_OV_REPO_ID="${NEXUS_REPO_ID:-}" +_OV_USER="${NEXUS_USER:-${ARTIFACTORY_USER:-}}" +_OV_PASS="${NEXUS_PASSWORD:-${ARTIFACTORY_PASSWORD:-}}" +_OV_VERSION="${HOP_VERSION:-}" + +# Load .env from start/configure if present (defaults for local Nexus only) if [[ -f "${SCRIPT_DIR}/.env" ]]; then # shellcheck disable=SC1091 set -a + # shellcheck source=/dev/null source "${SCRIPT_DIR}/.env" set +a fi +# Restore explicit environment / caller exports +[[ -n "${_OV_REPO_URL}" ]] && NEXUS_REPO_URL="${_OV_REPO_URL}" && ARTIFACTORY_URL="${_OV_REPO_URL}" +[[ -n "${_OV_REPO_ID}" ]] && NEXUS_REPO_ID="${_OV_REPO_ID}" +[[ -n "${_OV_USER}" ]] && NEXUS_USER="${_OV_USER}" && ARTIFACTORY_USER="${_OV_USER}" +[[ -n "${_OV_PASS}" ]] && NEXUS_PASSWORD="${_OV_PASS}" && ARTIFACTORY_PASSWORD="${_OV_PASS}" +[[ -n "${_OV_VERSION}" ]] && HOP_VERSION="${_OV_VERSION}" + REPO_URL="${NEXUS_REPO_URL:-${ARTIFACTORY_URL:-http://127.0.0.1:8081/repository/hop-plugins}}" REPO_URL="${REPO_URL%/}" REPO_ID="${NEXUS_REPO_ID:-hop-plugins}" @@ -69,6 +84,8 @@ USER="${NEXUS_USER:-${NEXUS_ADMIN_USER:-${ARTIFACTORY_USER:-admin}}}" PASS="${NEXUS_PASSWORD:-${NEXUS_ADMIN_PASSWORD:-${ARTIFACTORY_PASSWORD:-}}}" VERSION="${HOP_VERSION:-2.19.0-SNAPSHOT}" +echo "Deploy target: ${REPO_URL} (server id=${REPO_ID}, user=${USER})" + # Prefer groupId from registry when set GROUP_ID="${GROUP_ID:-}" if [[ -z "${GROUP_ID}" && -f "${REGISTRY}" ]]; then diff --git a/docs/hop-dev-manual/modules/ROOT/pages/apache-release/checking-a-release.adoc b/docs/hop-dev-manual/modules/ROOT/pages/apache-release/checking-a-release.adoc index e1a1b4a8ef8..e8a4af44411 100644 --- a/docs/hop-dev-manual/modules/ROOT/pages/apache-release/checking-a-release.adoc +++ b/docs/hop-dev-manual/modules/ROOT/pages/apache-release/checking-a-release.adoc @@ -137,6 +137,46 @@ cd hop ./hop-gui.sh ---- +== Marketplace plugin zips (Nexus staging) + +Optional plugins install from Maven **zip** artifacts (not only jars). After +`release:perform`, open the staging repository on +https://repository.apache.org/#stagingRepositories[repository.apache.org] and +confirm zips exist for marketplace-optional plugins, for example: + +---- +org/apache/hop/hop-tech-parquet//hop-tech-parquet-.zip +org/apache/hop/hop-engines-spark//hop-engines-spark-.zip +---- + +The full optional list is in `plugins/misc/marketplace/.../optional-plugins.yaml`. + +Quick smoke (point marketplace at the **staging** repository URL as primary, then): + +[source,bash] +---- +./hop marketplace install hop-tech-parquet: +# or apply a small env file / full-client-env.yaml against staging +---- + +From a Hop **source** checkout with a built hop-client, you can automate the same +checks against local Nexus or an ASF staging URL: + +[source,bash] +---- +# Local dummy staging (publish + verify all optional-plugins.yaml zips + install smoke) +./docker/marketplace-nexus/start.sh +export NEXUS_PASSWORD=hop-nexus-dev +./docker/marketplace-nexus/dummy-staging.sh + +# Against an ASF staging repository (after release:perform): +export NEXUS_REPO_URL='https://repository.apache.org/content/repositories/orgapachehop-XXXX/' +./docker/marketplace-nexus/dummy-staging.sh --skip-publish +---- + +Do not use prune on a partial install. Restart Hop after install. Drop the staging +repository if this was only a dry-run validation. + == Extra checks You can also check for unwanted binary files on the checked out tag (note: this requires the .git folder to still be present) diff --git a/docs/hop-dev-manual/modules/ROOT/pages/apache-release/creating-a-release.adoc b/docs/hop-dev-manual/modules/ROOT/pages/apache-release/creating-a-release.adoc index 0c1b350d492..048d1bd96d0 100644 --- a/docs/hop-dev-manual/modules/ROOT/pages/apache-release/creating-a-release.adoc +++ b/docs/hop-dev-manual/modules/ROOT/pages/apache-release/creating-a-release.adoc @@ -55,21 +55,36 @@ Build the software using the apache release profile mvn clean install -Papache-release ---- -=== Optional marketplace plugins (Wave 1) +=== Optional marketplace plugins -Large plugins are *not* bundled in the hop-client zip. Each optional plugin module -still builds a standalone zip (Maven assembly with `appendAssemblyId=false`), so -`mvn deploy` / the apache-release process publishes both the jar and the zip under -the same GAV, for example: +Large / lesser-used plugins are *not* bundled in the hop-client zip (ASF package size). +Each plugin module with `src/assembly/assembly.xml` builds a standalone zip (Maven +assembly with `appendAssemblyId=false`). + +The root `maven-release-plugin` is configured with `-P=-assemblies -DskipTests`: + +* **`-assemblies`** — skip the `assemblies/` reactor (hop-client / hop-web products go to + dist.apache.org, not Maven Central). +* **Do not** disable the per-module **`assembly`** profile — that would drop plugin zips + from staging and break the marketplace. + +So `release:perform` publishes both the jar and the zip under the same GAV, for example: ---- https://repository.apache.org/content/groups/public/org/apache/hop/hop-tech-parquet//hop-tech-parquet-.zip ---- -After staging a release, verify Wave 1 zips resolve from the ASF public group (and -later Maven Central). Local SNAPSHOT testing can use `docker/marketplace-nexus/` -instead. Keep the client under the ASF ~850 MB package limit by running -`tools/check-assembly-size.sh` before promoting artifacts. +After staging a release candidate, verify marketplace zips in the Nexus staging +repository (see xref:apache-release/checking-a-release.adoc[Checking a release]). +Optional plugins are listed in +`plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/optional-plugins.yaml`. + +**SNAPSHOT** testing: Jenkins deploys plugin zips to the ASF snapshots repository so +marketplace can install them during development. Local-only testing can still use +`docker/marketplace-nexus/` and `publish-marketplace-plugins.sh`. + +Keep the client under the ASF ~850 MB package limit by running +`tools/check-assembly-size.sh` before promoting distribution artifacts. we are going to use the `mvn release:prepare` command to prepare the release process diff --git a/plugins/misc/marketplace/README.md b/plugins/misc/marketplace/README.md index 42713eb13bd..37bb7e45427 100644 --- a/plugins/misc/marketplace/README.md +++ b/plugins/misc/marketplace/README.md @@ -328,9 +328,129 @@ publish side (admin / CI user). ## Packaging & size Optional plugins are **not** bundled in the default hop-client zip so the download stays -under the ASF packaging limit. Production releases publish the same GAV zips to -Apache Repository / Maven Central; day-to-day SNAPSHOT testing uses local Nexus or -Artifactory as above. +under the ASF packaging limit. + +### Production / ASF Nexus + +Release `release:perform` uses `-P=-assemblies -DskipTests` (root `pom.xml`): + +- Skips the `assemblies/` reactor (hop-client goes to dist.apache.org). +- Keeps the per-module **`assembly`** profile so each plugin zip is attached and + staged to `repository.apache.org`, then Maven Central after the vote. + +Example after release: + +```text +https://repository.apache.org/content/groups/public/org/apache/hop/hop-tech-parquet//hop-tech-parquet-.zip +``` + +### SNAPSHOT (CI) + +Jenkins on **main** does two steps (see `Jenkinsfile`): + +1. `mvn … -DaltDeploymentRepository=…::file:./local-snapshots-dir clean deploy` + (full reactor: tests, assemblies, plugin zips) +2. `mvn -P deploy-snapshots wagon:upload` → ASF snapshots + (`repository.apache.org`). Plugin zips are **included**; hop-assemblies and + core/engine/ui zips stay excluded. + +**Pre-merge confidence (does not need ASF credentials):** + +```bash +# 1) Same deploy *layout* as Jenkins step 1 (skipTests optional on a laptop) +rm -rf local-snapshots-dir && mkdir local-snapshots-dir +./mvnw -T 2 -B -DskipTests \ + -DaltDeploymentRepository=snapshot-repo::default::file:$(pwd)/local-snapshots-dir \ + clean deploy + +# 2) Every optional-plugins.yaml artifact must have a .zip in that tree +./tools/verify-ci-snapshot-zips.sh + +# Full CI flags (longer; needs xvfb for UI tests) — closer to Jenkins: +# xvfb-run -a --server-args='-screen 0 1280x1024x24' ./mvnw -T 2 -U -B -e -fae -V \ +# -Dmaven.compiler.fork=true -Dsurefire.rerunFailingTestsCount=2 -DSkipTestContainers=true \ +# -DaltDeploymentRepository=snapshot-repo::default::file:$(pwd)/local-snapshots-dir \ +# clean deploy +``` + +**After merge to apache/hop main:** wait for Jenkins Deploy green, then check e.g. + +`https://repository.apache.org/content/repositories/snapshots/org/apache/hop/hop-tech-parquet/` + +for a `.zip` under the SNAPSHOT folder. Private data-hopper deploys do **not** replace this check. + +Point marketplace at ASF snapshots when testing SNAPSHOT Hop builds from Apache CI. + +### SNAPSHOT to a private Nexus (e.g. data-hopper) + +For local or private builders (same idea as Jenkins deploy, different target), use +a Maven server id + URL such as: + +```text +https://repository.data-hopper.com/repository/apache-hop-plugins/ +``` + +**Do not** put deploy passwords in the Hop git tree. Use env vars or `~/.m2/settings.xml`. + +**Fast path — optional plugin zips only** (recommended for marketplace work): + +```bash +export HOP_DEPLOY_USER=hop_build +export HOP_DEPLOY_PASSWORD='…' # from your password manager +export DATA_HOPPER_URL='https://repository.data-hopper.com/repository/apache-hop-plugins' +./tools/deploy-snapshots-data-hopper.sh marketplace +``` + +**Jenkins-like full reactor** (jars + plugin zips; skips `assemblies/` hop-client module): + +```xml + + + apache-hop-plugins + hop_build + + +``` + +```bash +./tools/deploy-snapshots-data-hopper.sh reactor +# equivalent: +# ./mvnw clean deploy -DskipTests -P=-assemblies \ +# -DaltDeploymentRepository=apache-hop-plugins::default::https://repository.data-hopper.com/repository/apache-hop-plugins/ +``` + +Then point Hop at the repo: + +```bash +./hop marketplace repo add --id data-hopper \ + --url https://repository.data-hopper.com/repository/apache-hop-plugins/ --primary +./hop marketplace install hop-tech-parquet +``` + +Verify zips: + +```bash +export NEXUS_REPO_URL='https://repository.data-hopper.com/repository/apache-hop-plugins/' +./docker/marketplace-nexus/dummy-staging.sh --skip-publish +``` + +Official product defaults remain ASF public + Maven Central; private Nexus is optional. + +### Local Nexus / Artifactory + +Offline / sandbox work still uses `docker/marketplace-nexus/` and +`publish-marketplace-plugins.sh` as documented above. + +**Dummy staging** (publish every registry zip, HTTP-verify Maven layout, CLI install smoke): + +```bash +./docker/marketplace-nexus/start.sh +export NEXUS_PASSWORD=hop-nexus-dev +./docker/marketplace-nexus/dummy-staging.sh +``` + +Same script can validate an ASF staging repo with +`NEXUS_REPO_URL= ./docker/marketplace-nexus/dummy-staging.sh --skip-publish`. Lean client size check: diff --git a/pom.xml b/pom.xml index 012c37c1d9f..b4f46abebd8 100644 --- a/pom.xml +++ b/pom.xml @@ -323,7 +323,13 @@ maven-release-plugin - -P=-assemblies,-assembly -DskipTests + + -P=-assemblies -DskipTests @@ -898,6 +904,11 @@ deploy-snapshots @@ -908,15 +919,8 @@ ${project.basedir}/local-snapshots-dir ** - **/hop-assemblies*/** - hop-plugins/**.zip - hop-core/**.zip - hop-engine/**.zip - hop-ui-rap/**.zip - hop-ui-rcp/**.zip - hop-rest/**.zip - hop-ui/**.zip - **/org.eclipse.tm4e.core/** + + **/hop-assemblies*/**,hop-core/**/*.zip,hop-engine/**/*.zip,hop-ui/**/*.zip,hop-ui-rap/**/*.zip,hop-ui-rcp/**/*.zip,hop-rest/**/*.zip,**/org.eclipse.tm4e.core/** apache.snapshots.https ${distMgmtSnapshotsUrl} diff --git a/tools/deploy-snapshots-data-hopper.sh b/tools/deploy-snapshots-data-hopper.sh new file mode 100755 index 00000000000..71d3af16992 --- /dev/null +++ b/tools/deploy-snapshots-data-hopper.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Deploy Hop SNAPSHOT artifacts to a private Maven repo (e.g. data-hopper), +# similar in spirit to Jenkins local deploy + upload — without changing the +# committed apache/hop distributionManagement. +# +# Modes: +# marketplace (default) — package + deploy-file all optional-plugins.yaml zips +# reactor — full mvn clean deploy (-P=-assemblies) to the repo +# +# Credentials (never commit these): +# marketplace mode: HOP_DEPLOY_USER + HOP_DEPLOY_PASSWORD (or NEXUS_* / ARTIFACTORY_*) +# reactor mode: ~/.m2/settings.xml server id matching DATA_HOPPER_SERVER_ID +# +# Usage (from Hop repo root): +# export HOP_DEPLOY_PASSWORD='…' +# ./tools/deploy-snapshots-data-hopper.sh +# ./tools/deploy-snapshots-data-hopper.sh marketplace +# ./tools/deploy-snapshots-data-hopper.sh reactor +# +# Env overrides: +# DATA_HOPPER_URL default https://repository.data-hopper.com/repository/apache-hop-plugins/ +# DATA_HOPPER_SERVER_ID default apache-hop-plugins +# HOP_DEPLOY_USER default hop_build +# HOP_DEPLOY_PASSWORD required for marketplace mode +# HOP_VERSION default 2.19.0-SNAPSHOT +# +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +URL="${DATA_HOPPER_URL:-https://repository.data-hopper.com/repository/apache-hop-plugins/}" +URL="${URL%/}" +ID="${DATA_HOPPER_SERVER_ID:-apache-hop-plugins}" +MODE="${1:-marketplace}" +VERSION="${HOP_VERSION:-2.19.0-SNAPSHOT}" +USER="${HOP_DEPLOY_USER:-${NEXUS_USER:-${ARTIFACTORY_USER:-hop_build}}}" +PASS="${HOP_DEPLOY_PASSWORD:-${NEXUS_PASSWORD:-${ARTIFACTORY_PASSWORD:-}}}" + +MVN="${ROOT}/mvnw" +if [[ ! -x "${MVN}" ]]; then + MVN=mvn +fi + +case "${MODE}" in + marketplace | plugins) + if [[ -z "${PASS}" ]]; then + echo "Set HOP_DEPLOY_PASSWORD (or NEXUS_PASSWORD / ARTIFACTORY_PASSWORD) for marketplace deploy." >&2 + exit 1 + fi + echo "==> Marketplace plugin SNAPSHOTs → ${URL}" + echo " server id: ${ID} user: ${USER} version: ${VERSION}" + # Force data-hopper (or override) — must win over docker/marketplace-nexus/.env + export ARTIFACTORY_URL="${URL}" + export NEXUS_REPO_URL="${URL}" + export NEXUS_URL="${URL}" + export NEXUS_REPO_ID="${ID}" + export ARTIFACTORY_USER="${USER}" + export NEXUS_USER="${USER}" + # Do not let local .env admin password replace hop_build + export ARTIFACTORY_PASSWORD="${PASS}" + export NEXUS_PASSWORD="${PASS}" + unset NEXUS_ADMIN_PASSWORD 2>/dev/null || true + export HOP_VERSION="${VERSION}" + exec "${ROOT}/docker/marketplace-nexus/publish-marketplace-plugins.sh" --package + ;; + + reactor | full) + echo "==> Reactor SNAPSHOT deploy (-P=-assemblies) → ${URL}" + echo " server id: ${ID} (credentials from ~/.m2/settings.xml)" + echo " Requires ${ID}… in settings.xml" + # shellcheck disable=SC2086 + exec "${MVN}" -f "${ROOT}/pom.xml" clean deploy \ + -DskipTests \ + -P=-assemblies \ + -DaltDeploymentRepository="${ID}::default::${URL}/" \ + ${MVN_EXTRA_ARGS:-} + ;; + + -h | --help | help) + sed -n '2,45p' "$0" | sed 's/^# \{0,1\}//' + exit 0 + ;; + + *) + echo "Usage: $0 [marketplace|reactor]" >&2 + exit 2 + ;; +esac diff --git a/tools/verify-ci-snapshot-zips.sh b/tools/verify-ci-snapshot-zips.sh new file mode 100755 index 00000000000..102c320fa9b --- /dev/null +++ b/tools/verify-ci-snapshot-zips.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# After a Jenkins-like: +# mvn … -DaltDeploymentRepository=…::file:./local-snapshots-dir clean deploy +# verify that marketplace-optional plugins have zip artifacts in that tree +# (what wagon:upload would send to ASF snapshots, given current deploy-snapshots +# excludes that keep plugin zips). +# +# Usage (repo root): +# ./tools/verify-ci-snapshot-zips.sh +# ./tools/verify-ci-snapshot-zips.sh ./local-snapshots-dir +# +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +DIR="${1:-${ROOT}/local-snapshots-dir}" +LIST="${ROOT}/tools/list-marketplace-plugins.sh" +GROUP_PATH="org/apache/hop" + +if [[ ! -d "${DIR}" ]]; then + echo "ERROR: directory not found: ${DIR}" >&2 + echo "Run a Jenkins-like clean deploy first, e.g.:" >&2 + echo " rm -rf local-snapshots-dir && mkdir local-snapshots-dir" >&2 + echo " ./mvnw -T 2 -B -DskipTests \\" >&2 + echo " -DaltDeploymentRepository=snapshot-repo::default::file:\$(pwd)/local-snapshots-dir \\" >&2 + echo " clean deploy" >&2 + exit 1 +fi + +if [[ ! -x "${LIST}" ]]; then + chmod +x "${LIST}" 2>/dev/null || true +fi + +mapfile -t IDS < <("${LIST}" | cut -d'|' -f1 | awk 'NF && !seen[$0]++') +if [[ ${#IDS[@]} -eq 0 ]]; then + echo "ERROR: no plugins listed from optional-plugins.yaml" >&2 + exit 1 +fi + +echo "==> Checking marketplace plugin zips under ${DIR}" +echo " (registry: ${#IDS[@]} artifactIds)" +echo + +ok=0 +missing=0 +declare -a MISSING=() + +for id in "${IDS[@]}"; do + # Any zip under the GAV folder (SNAPSHOT unique names included) + hits=$(find "${DIR}/${GROUP_PATH}/${id}" -name '*.zip' 2>/dev/null | wc -l | tr -d ' ') + if [[ "${hits}" -gt 0 ]]; then + sample=$(find "${DIR}/${GROUP_PATH}/${id}" -name '*.zip' 2>/dev/null | head -1) + echo " OK ${id} (${hits} zip(s), e.g. ${sample#${DIR}/})" + ok=$((ok + 1)) + else + echo " MISSING ${id}" + missing=$((missing + 1)) + MISSING+=("${id}") + fi +done + +echo +echo "Summary: ok=${ok} missing=${missing} (of ${#IDS[@]})" + +# Remind about wagon excludes (plugin zips are intentionally kept) +echo +echo "Jenkins Deploy stage uses -P deploy-snapshots wagon:upload from local-snapshots-dir." +echo "Current excludes drop hop-assemblies* and core/engine/ui zips — not marketplace plugins." +echo "After merge to main, confirm a zip on ASF snapshots, e.g.:" +echo " https://repository.apache.org/content/repositories/snapshots/org/apache/hop/hop-tech-parquet/" + +if [[ "${missing}" -gt 0 ]]; then + echo >&2 + echo "FAILED — no zip in ${DIR} for:" >&2 + printf ' - %s\n' "${MISSING[@]}" >&2 + exit 1 +fi + +echo +echo "PASSED — all marketplace-optional plugins have zips in the CI deploy tree." From d36f25e6accf0a7e5f07e3753d98940c1e236e7d Mon Sep 17 00:00:00 2001 From: mattcasters Date: Tue, 21 Jul 2026 18:14:02 +0200 Subject: [PATCH 28/28] Issue #7547 : marketplace improvements --- .../marketplace-dialog-plugins.png | Bin 229657 -> 329287 bytes .../marketplace-dialog-repositories.png | Bin 114604 -> 160966 bytes ...place-dialog-repository-editor-plugins.png | Bin 0 -> 83189 bytes .../marketplace-dialog-repository-editor.png | Bin 46033 -> 98273 bytes plugins/misc/marketplace/README.md | 48 +- .../catalog/NexusRepositoryBrowser.java | 321 ++++++++++ .../catalog/OptionalPluginInfo.java | 21 + .../marketplace/catalog/PluginDiscovery.java | 402 +++++++++++++ .../catalog/RemotePluginCatalog.java | 214 +++++++ .../marketplace/catalog/VersionCompat.java | 160 +++++ .../hop/marketplace/command/CliTable.java | 169 ++++++ .../command/MarketplaceCommand.java | 316 ++++++++-- .../marketplace/config/MarketplaceConfig.java | 2 - .../config/MarketplaceRepository.java | 41 ++ .../MarketplaceRepositoryDefinition.java | 374 ++++++++++++ .../marketplace/gui/MarketplaceDialog.java | 250 ++++++-- .../gui/MarketplaceRepositoriesPanel.java | 569 +++++++++++++++--- .../marketplace/install/PluginInstaller.java | 37 +- .../resolve/MavenRepositoryClient.java | 34 +- .../marketplace/resolve/SnapshotVersions.java | 107 ++++ .../gui/messages/messages_en_US.properties | 42 +- .../hop-marketplace-catalog.example.yaml | 22 + ...op-marketplace-repo.community.example.yaml | 40 ++ .../catalog/PluginDiscoveryEnrichTest.java | 81 +++ .../PluginDiscoveryResolveInstallTest.java | 83 +++ .../catalog/RemotePluginCatalogTest.java | 86 +++ .../catalog/VersionCompatTest.java | 87 +++ .../hop/marketplace/command/CliTableTest.java | 94 +++ .../MarketplaceRepositoryDefinitionTest.java | 115 ++++ .../MavenRepositoryClientSnapshotTest.java | 15 + .../resolve/SnapshotVersionsTest.java | 65 ++ 31 files changed, 3598 insertions(+), 197 deletions(-) create mode 100644 docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-dialog-repository-editor-plugins.png create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/NexusRepositoryBrowser.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/PluginDiscovery.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/RemotePluginCatalog.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/VersionCompat.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/CliTable.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepositoryDefinition.java create mode 100644 plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/SnapshotVersions.java create mode 100644 plugins/misc/marketplace/src/main/samples/hop-marketplace-catalog.example.yaml create mode 100644 plugins/misc/marketplace/src/main/samples/hop-marketplace-repo.community.example.yaml create mode 100644 plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/PluginDiscoveryEnrichTest.java create mode 100644 plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/PluginDiscoveryResolveInstallTest.java create mode 100644 plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/RemotePluginCatalogTest.java create mode 100644 plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/VersionCompatTest.java create mode 100644 plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/command/CliTableTest.java create mode 100644 plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/config/MarketplaceRepositoryDefinitionTest.java create mode 100644 plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/resolve/SnapshotVersionsTest.java diff --git a/docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-dialog-plugins.png b/docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-dialog-plugins.png index 2d7126d41be36b0bd36153193db23da5f574a8f1..e9f6341577c55c0b432b640540a70cdbc139740b 100644 GIT binary patch literal 329287 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® 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 z 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 z z;sg=!Un<9K4sr5(a-32W&h&wXKe!$d5bdN6y6<)v4I9SvLvW6qV8oGF!8&y6U&*3= zEb{s9zfUow1-0BKo^HW6iWeaKx^#M;Pho*x?V}rh(<&6`{Q?Dh=|`3p-JdF2;KXaKfJPK|foKJ@uMwlYI^!vlt}zc)Ob%(W&{*;hazGOYw>a zE3n`yH@ENo&7C3xU^0rp&L7h6wldZ`fn0@g%1_|%Hn*iB=9EJV>UI;ljUUqUku-4v z&DOiR9ZQXq$g@@k4XtJ^V;c^y*=I2iubpZV< zI}%(zprrSitwW!4K2!-8s!so0v}f3TO_NxYmXg#rS`NAGi_YL*7j3xftv5`>dihjV^^^Fm6ul;=b`7_TdXP z6^Ed~g$^~BNE`y9J;q-1@8hus((&vw>F8?g40x)mH$b#NzW<|DvH&ArVMqalX)(VR z)`h3T%Rq=GqUh@d=~+~`GvIkFEo-vczzJwSsp*m3{`ydxmP{4|UmnUYNz$swx|Ara z+ati`^XHj<9`E{7Q&|>T!Z43nKIf#iQE_vQ3Z|{$d{CLN7V-S*$_p}E-jN_L??|2* zqT6(>iCFOZA^_o`kl+%iz+v&aq(1EsDT1Iz$x+iYg&wz�_X_bi1Bzm&&Ako#Nd! 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 z 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 z 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%0A&1Q~t`1 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 RW#K2;09Bobi2ILU{xA4swle?# diff --git a/docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-dialog-repositories.png b/docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-dialog-repositories.png index ba86410f1041788e720759fe3ad15fe94358b15c..5d4e46021996d36094107e678808690efa0d8c5d 100644 GIT binary patch literal 160966 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 z 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 literal 114604 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 literal 0 HcmV?d00001 diff --git a/docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-dialog-repository-editor.png b/docs/hop-user-manual/modules/ROOT/assets/images/marketplace/marketplace-dialog-repository-editor.png index be34977e7b20d0458aaef07dcac8b9634deee285..52c4e2804fc499c5ec2b4e4cf681e69334742cb1 100644 GIT binary patch literal 98273 zcmd421yo$i6E{eN2pSS3kN_b-a0u>@1a}`~kPsli;5PUWNPq-)g1gM%GDGkH4+u8s z;O_1^!0-`y|M&ji?w)VY?pf(`=G?yb_EcBbt*)-BU-uVPWf^=N3LGpfEPOdxNp&o& zd-_;dw{-5^xqfn>WfgaQxox6|x8Tj*eBYbJk3=8WSmYn2kO*g~MDOYC_)co)S>L#3;O{aUl7PJV_s!31 zGKDYhzwfDuzWw`lm+1e)*O3#t_Aj`&xnmZj7beyYqW@xU*O!J#fKJl3YG?0$ znkO9tRot7d{LLv2=5!BQb6yNh!UTW?6KqbLo&0?29u`h~OicFfuDvb z$qSV#_}J){Xesy%ZYDS#wPWzckQm1I0h#E!jI>k>i2Ac81e<&Lfb-$*jjhpgWrdZ? z!kxU5VN9V{DAKixccRdy( z9Q%@ZKB)vcDOVWN9ovkHN;~H=5cbNyLswrwuEEj#s<{;c`G+ecu=Vjbd#L=C_R;a~ zGP8}IJbHm!RB&EP>8f@%=yHAO;AoJadR5Bx+w+@Y%q?SBD{(0qe@WbRdA0+mIfrkQ z;On6`!V@_c@x6H}8~h56`%|VGhP^fBIU=w=<`l9b5cZB*Hc)^=Zp>m~wSfNS%H98T zK6_y%gd5b!>hm$xy)xyw5^!xpysu9<^?(8)Ag3JlP=h06=|VxGhA-q?R=gb;MU>yh zw$9QwcAJcVRtH{Nsl^*#F`s5nka}>ie(@iwSo)wK%RpQo-a41h<1t)j=5|BvDs>q% z(Y+8~-t;%Xqs9Zk(RQB>ywkrc)q~HRv5ViwFtYG zBR~t_aN;e7t9(ZPBz5!}Uzk0AAMH#-p07h3UxQP@9j|hO>6))3cUK3$oIri6WflSs z2Mer{qgMf%(HqVy9|}+i2uUnHJl4ZLaF{g_YS(ZI2tJ7)oKgkmHPJ7(IY zIiI6WdYC+Fauj45d~~Ly+0>5r!bJ>SrRo}gQ0`ensZ%vG>S5Y?%1x9N#P17=!){P&p zl{~4b0$eip<8X7wlv-txDqZPOhZ<$pyVr&h6F+eEM-$YkX;&4OtaBPWnlV_;42$zz zweO*=*QtYglaw{g5()Zf3Gr1&#)+y4&z4$v%*IOVddnZ?TIlp%SvpKh%3=DChSp%k z>uyrC28IQGnF`n)DJg{?g|CJNj2cmS3oBMK8G{RXi$*?};=ZJ1RFL`h=D+o+%(Te#aot7uH;7KT^4*O{3m-XXKI z@r@|Fwk&o0a5b~)&QvZxATK39#`)MphM9T5$Uzj7)oZww1-sFHw|CgL{;sJUm%LHI zhW#aq?BQDeYhd$D%?TE$s}W}Kb*j&O9%8X^+yI*}i}^X1z( z$lJySzB#E(J?WY@4cu6O)v8Iy7V!6dXv*TrG&7yPkeg#R$}2(}48O5i7b$vemkXNx zO6F{p65$2xI%PosaF3v4`dd%x(_e=xqu5mpmpF4X$0tkprKhrMjL&vDWVLMjG0GWgv^D`y=LzEGiE6_?m}Sk?}ms#nL#vu3Hyb1#3ZuC;7U82#WLZ z9U+ihC;v|SnHczf8udSB!A*_T7gxJA7xZu=DyB$$xqD=;LO=VYz$I_`u~Q&BA+mqE z+HUQve}UIdqt5Y7XFBZ^Zde69MI^c5xP;PSfi*kpyqrH$h(z$0%x1K>FN+dIe|6~t={&~QZ&r!u=CC! zXK`g7x0bKLVt+P#Y5DEZ>2G-}3HYK3FCmFp(Y!djk6yiuI^3W-FR_Bbhq0$zj z_>jdrJ&$>mC%nm9>*RT5SO^pk@A@LB)tm1Hj zO2?YAp;zg>4+nR~NzCKJ<>XB|O(OJLDsRSuLbpC(7>slsKdK{}nVjFtFf*fjMw)U59w`fwPh zoX;mC<72y}49$ue1KY@^)PyFp2_hG%lb&N$we~8JzHt`>;(q%nwK@y>{0ZT}?zZ@b zFEznREd#!ki?@EsBuZy4Am^0CXcfi(!m24wqH{l7{pf{(%lWP_@9JJ+Cs={`!3(C& zQF`}(Et0baWw+V8gS529VipCndy)vrEJa1a)d2O(STvkM>L0x+#MbuL{ zOEV%l8Q>7eQ`GCS`oN84!j<)@BBYkS2F=`Sy#sU+#s0DMlDDy_O$DhJ<{P+%*<$=r z4~b4yuu$BU>I9g|hgZrWWGnCeEnDqj#C;0L1ULHVLxo`!Wyub8o%D=wP{pIF)sYcu zEyV?+!x;b#Xu25c_d+G!i7?EGLDt2Vyl^`**K})eQt-*5*IK)vF<=;9qC{O#qw~zl zPkK^ZnngW~%{|Y0upDYaU89L1ZU6h@E4z2O2cSwrt*K#-d`zDu%hw%vv}+E*-?RQV%PI0;HgTQ0F3# z14Gfnv*Wsy$5B;mLkucQjJC~IH8gy0*nlIkGZ#x|hF>1$P_@``4DI9VUyOSt@rr~z-DUw!Y-?!A?wYw?^g%W zp(-1u1VA0c!w9U)uUR=|MH%7=$tdC@AL*!FeC#hrp63T4-W)I8^NXgyF} zF>kfHL|>MhGCpJ0n>)K>k6O)Fjx~r%$!In5g5I=SjWpd#%eY<<8OPzmt)s2EbZ!5b zVf%ijI7)WqLc%9!7=51C_$8{|J`&(%3O3y}vm-zhR~6_$St01!Bkcik!Lz=uYod6GvCs)a& zs!q{3%tF5NOd~jsp44%R3;urTj+xPjp}&oz+PCI5c4d0bpMn4H@*!C1+Wa`GYs45U z+>mCH`sAr{&kd|JoW;+oxw{8)eKd8_p;5!d>cbNMj-|C@CL-iJ(!;D3P#@Je9-Q9y zpqjqD_y(fZi+Ov(OoGucU1)OW zr@I|9JZ6hY4G-N@0_n!$xE`KZ98fFpTCGbe>6J=Ar?rv2HzfMY`W?xmVryh-!->KD z*@d^xiS3}DeQ|-hcL^8o*wmF3nw)&n{Y3fP+Kf^tznNeP;V3>9?JW5v&ytqb$D%`X zY`?7f#PpSLXkxu&*8X}OF5dlPN0rq35;UK$ zE^5S5tAEX0b}}|;q{rU;_|Z(ZT$Eg14#`;R`AGwiSVgZ6Oh`z;4xi%*ve`U5 z)YyFapwPp$uGp1&BU|8FQ^A>FyRrNwA3A1UZW#n#ENo1VtspH%k_iAtdxdUZ1(Cj= zC>I&)R8&xN^a$%cSgN>SnQ+I$zI}T!0B?Xh#v$lqDYvqL4+v2nWUrD;4%F4v&AYM= zU#UD9>cGRkb9ZSv8j!2ryO^qY0#->?j#!@*Q7@SqkuJjoY;IO|>7`{4v4&fd z;}nc5_7nsNp~?3Ncg4Y51F?{x`=#7C1sv<64UAv@NmBfbi5Tq5OhSk0bzvH9Dn~$m zjnz+U@?bt8iFUHqt-qi(ja!fOX3w>coW=~bT~(l?ZDRiEq~WWfSJ%VlR+wlwFQI~L z1B+C;8$-6$>jNP}RV_$^**D;ThlG?vzO3f0)n>PEGnc+vo|n{Vx+ieNqKOx;z%C)= zU7qnkYRmNnvcr6$v$H$piLgTe)y7#JX-cqX`C7flS`%LoZw1_YoWZr%J{_~N)=d_h0FoF4hzK_hXsD<-e`3pCsHM=?u^wwj z9KP&nUg;sB%qqtwU9xGV7Gdp*>+W+5!e!}u7EVr;@wvHx<4qjFwlHHjTY@o(CR6!t zHCqi9?+!|7$snL`Dw=oy3>x;*kB%JY9!~dE$2=W^fLcC+z5_2*t6D=}SXXlA$!v7Al~A;ir|w?et(BYaw$8LPAS%%|w_#%` zgfLfZqis1LlZ=L`0+$I3R6YILtBTEC)Ku9P)#a1!$Hqv#B%Zz?m>L-B-4I| zcBA9gq`W(wu7^RAMyb`L+&L`N+#OF_8l`vmmxHMK^=4PN)O!Yt;~#f?QR+=(nas;9(DuXO9?BWwOJwh%FKw@5(?uy2L#8w^p1@ zoO8K2^4*#44Bt?q*_I_eWPbtA6Y>Be|X|`CsK>gO$-}{3{={+q~=% zbL>@WWu=OR|!QLf)xS9K}TR?fM3i}-?ok{nKV=+u->ZZ0)4($f4J-ud~^T*i0+F~qn zQ;FJYv{beJXnYDpiju4nIV-kx-_L$gUA_#8s@P;rnJ8o1O61W?J37<3f@w$>?Of?J z67;Ge+9T2?=p_V&UYcibUz8>rUd`KTfx+T-V?k+qxznov?eMA~P3zj)Bahlz72C+Y z_!nZ_%G*BTMPfNBuqe}w-NN{zRhcph?rh(8K*D~OqQD;r8@T{HiE?$m)rx)=)O?vQ zY-1A=*)@%hl@=k*jF*|peGz%&ve3e@-WHfrL}$h}KrExS9JGfvbtk*5m106|a;ry| z_yDf`7tgZPHO@C0;dqaY%j_uyBzQAQ;9uFz z-C~_vWKr3bY-miv6P}FhVuIUrnr=yI8w~Lah(^Rn_rg*H2?!;K#gIO3FE7 z8MYdnId`TL)Bvkif)MLDp4*K|MJ-BWV?LJq+PKa`V938nVA22V?NP2D3$ON!r(S+Z z#rk96^AF3R5WStE4rjnWs}+`N<~{vck+&?y%PbzUQ`Z_xiz+fyTgqx7dAQ2J&7gGu z+|{Bb2s@F_p&T-n%-S{fFGS9t8NP8#mp>GnthTIvic*;*-TRg21ctbYcu3k zr|#0DUs%|8dgk;?Hm)v!dgmxnc{HJL!9T4(#j2_Ho)h06b>3PaMSqkJw|QnbWqexYvqnIV0$x*dDScYlQZZB~aY zg_P@P#kpQFM?#Tzr(b=k-EJ6+DZ2fWG8S2>U!(5NIm}LyI;AJDM8-DdCA${KCRbjB zM>$@u&z;LUKoFi)PZqEScq?n!in7iR8^IseFlpP!b5Pl6tI07Hc#`#b5;lAWo^mm` z<)#X=j_QuA6KWC?YO`+&@ZqtWnW9ym0Q77JI zNmgSy#8b|j3M1EnM6{2t9q^W4vFLqGId^T@Dv9{~SgUyIm5tDeW;jbHOC4B6bPr<& zJ6gPjp1E)%(b4#1HyOV+J}1HZY|WtOYmKyA_1I%9G74cer?gtREkiJqFbfcy%It40 ze1CKCo$OB>^|AVDYo-=B!B^O~xzh$(+{M(`o(AeY+==vq73@^dx+w5+Al4y7?mY}U6}L|Fdb3qbQX>A5+6^6LS)7TT`g#$*2`;%!0iEPNz?6 z<*l{YkhKI$U1%c4Tqv9mv_Qbdpm*|TOy@t?i;TD=7Q`q@S_Q{C1*Mjo#cNW93{YB> zB^KFTR$8jg&}Y>Z(JuBYY1f!x725g2YfDyqdR#Lh_txPLiCaT(u;ex&dpzM_j9JUR zSg-uoOk>fjyw-NZo#$sl(*16%3XZXWkExd~2fUO+h0=mjw>@GUEdqx*l8U}8yZ}uj z@yx44AZqwS8_Nyr(={2ORw?Fg4jCCj>yh!CilZ&<84w0}=+{p|tL{CMoS9c5JMhVP zWaCVW2n1euhQE%|J7SSx`XP^+Gk5~GXrl|gT;|_$B=A989^C(2`^Nk3bbbMFMEmIL z%j)vzO1ll}#H$52Z@weK))fJv#Zbx;j=<^scx_$gsacOH;ln!yW9d=PZ{crY9P^8> zQ&8xn_DgjSAo7WOw>2*|0ooAm8M*$g5NDl!JnOGXyCNjDG=_U z#KgPm9*s7bGVB4xX{PgClfObH9za=VISr#!$7ND8vB-6<+w;jDvQ?rbD3%AHT#WinONlR66CJBH8lSM zmvD<4!qs@l1uU~wr-xB&AnSgg9;ZUV6wrnz({#o6kTV14Y!Tl92wMK5~ZjDGU7 zYQg{{XzSwhG_^aN`J9?s1bFv^dVlZCo(VD7LUAy&p(RXrr7z8hQ2+Ff1*Lk_or4Co zEql4NzPyqq*D9WVb?Z*}z~{I~p*_Y=1zstLbyrm=v_p;DUn_jb?U4$y4( z?*$Hd!|H@u&$~~(ULYQ31dzat7im~i*r#$6qmCTv9kosTpTx~;du3?Pd@aNV5-@d% z%cGKPT~8?ZUuf6?rPb_`1kbWR2KLB;#eFc`n27(A9zcHs6_evW=! z(AV)3N23z;nzdu9^*r+&N1kBcsN}nL-$KYo{@qVp+ zO4(mnWi*i2SU4O;8`li0RJ{t6UL9^Dg7qB`)q5u>@WSY<`eiuQveF4L%{}OJb>3#j$98>tj2{IgYH?hFP{*eKSNqRs;oJ5ck7Tz(tBlRR{ATllrO7^kYZP*6oQ zW?=FpRcj3W=+LL2pXXp`e?Kzu!j>i#G80LOgo;42@|WWO?{Iz37Y_3 zq??lox{@)z^P!a&4VWqpXi^_vKjGbsnnQ z-w63+S|!x(o1CtX3X1lmA-no6ZuV1=2NudiN44w3p|!XjGj| zhL}6EjKd?tLHsfz&{$3J#WIJu1K|?W7fxgxG@|rXk&oTi?Q^%_{ahxSBvNl~`C5I4 z#6wkDY=N|o6{gf@O5&`t>gQB*pwas1P8GCX?Ne%-Hn?`YkS#elG42}EZNXOO{`1Wl zuEbzJt3koBxkE#fv0}80vaiF|alaHu%ecTcqc-u_F!KsU$5EQ4$Gv^pjW38V5N8Rc z^Ki%|M3;;B0ZGxW)1HPrXP9vw`+)XLiq4`~)4;U*K_!h$RDmB%(|!r{l|;C}{NpQf zZ~&=~7@%w4uHIgM*a*FRX*q5}?x`cWCj2mRk6@= zGv+!kL4SAm%P>tYlVmnwo5+T*-;N|lpNHp&I<0`b!|1fnqEkOs#1~45_ly{KMHtl= zudDaF$0sn)?8&1JxJ?;2`g&02fz5hhPTg+^yfJ*JLsvNF%Xmzk;f!n*} zS|*~&A<87Ebd0iP>f?h_!_Bz!2#3Ki`GHEx3r#>RKp=*a5{ zXyDdkTm9C=AfgiDpRz(?XT`_|u3-9=l>z%5aI%>ERW2_44*97fgS=6tXA9pUlw~DtX8$&=ze`+9g^Vy5sGhA*wq&w2kQQb@ z@Ec(he=bq$N*$FW&qbT1*%kv%9zrl)D#fxx#OkyAnqQ1}tfWvQ3EEyjlBWZg3=jB$_0#`Ljcs%3H1;|1%nP9eAN z?JMbDO^Z;KYr-fWdlJ;@uoS$_b}+4-JxVu2VtYff@ODp9nIe?o8DkB!N|S4!CQ z;9_!6U8*rIVgNiLQ5)X{eE6EEeb*}cT+Ca^`*})NGnLJ`TdA#wtA;Q3Nq5L(3Kudt z;{#UXq+s_C)i$Wm1i5_gwMsf--}#~9SXbTz0E35_+Nxp`Al3}wSUzVYIyM~gJ`%o7 zues>Pu5q_$Zk)RHW+s*?pmQ4l;2}LHte)Hte@XoKafGXQsw4XW@y><0Sqcafw&$iS zEaT7eg;SZ<=S>F-P&XkVPrS|Pxr~o;TCq|UzSdM{3MvcPj&?E#qthS}0;^M2(QNd2 zUDjP}g4KT~9|Ru#5zhA#BngPZSRR~<(XVRVQ@XMz{q|4mI;~kQ-9FPWt`3#Bz4Rj{P8R->8luP{40()m z4^O1E_(raupP%E#^`>a8S)Jg4835q@w&+_1WS@y>+DN9)W&k2KCE;8ipZ2Bdjl9Gz zkygPg=H?>~ziS;J4*Bp3I~A0g?Q{6JsL`jt(!~{~oQ1PKP?S1tcoJCNv%fwBMN9_d zTslGeI~C12e$AQ>^D?tPQz(qK(%;6X`jnQGI*>Y9g24|l9q^6{@TsaFtK9XL%vfCR z?Atr$3qg!UyElU?Z-Ax?k~(YgbZcK&EgopV%f7$K&-jr3eUg&+8m?btZTn#eGp~gY zSDbYPrR03{JZ9-C&YF$Dff1X@pW}?JG#R|sT2PdWBiIz3HEWuQ5YA1`RJ07Q3V-RR zS>{-YCnvafm&7PtNevAY`nHoU0=B7cVa`|2hDzP7a}iT8cV@Gu6e8vbH&EE_+lQ%+ z#}K4$>jXJrIGhoiCV94r{_VE<{hZ9eSzWPko%6%4N)n3c(wuoA7qyluOkd|JV%;qP z7yy@P?AF;BP53<>W+xdh_;s88#7`cvYN#K_;T!rri0U4IY0)yD#1dlvgzot1j1#AQJ_v4b zBI^&~EO5^2t%>nan=aX%6&j{=V<7zVOZtuc;lkzs?~*TUByrv@}qen@UGIG=olo0yU@ zQmp`k?g4~Mn1}8CMk6qxMwR9VOPeUQ*8DXS069ESS=3OE^6AO{u zsxD96K7!7KfwIzTV2ZwqD19Uji&6)a>KZOIGa)vZWq2Sl*R#{drgVv;D^L~d$RmZI z<3>a=V+(C);h7|R4r9j9V6}2qT2(e%%ECD8s+*A)1qD|I+DyYSh4tLLM<;mZxN=cM zL+Y0$CG%#r&96|^OJDvcW@vKN33$G zMHReGP6%sS)uOwX3O4ed2?~L~WMtk5-b6;RY4jHf7t)%y$!Q9jf{BR8VNZY1nHHzz(m}b4SX0;=KR+XFXX-Yclw#Kj( zd@bh;D$q2D=ikW}`$*mYwS-}YG4=QraY)}Uh@(6)$tu~QE=o#Hi;WY z+e1%E2((T-mNc1PzG|9V(yY4d@i^YfbJ4O$RL4!W{RzQkvtGl&|A!b{M7!0?)`4k! zpX>cM2|2YErymWpM7!w+Ids%W7Bt7{Q!XFVe-|rUvxDR>$=Fmg8|0DAxU1h9AJSCR zNx$hwtCb_CB6^D6s3}n^HQgFfF%cV-w-a{x0RY5hbOkoR`dwYrKJF9Y?4M{`C{nuA zpO}S`>jQ5DDDPyE;Eg@EXfmhmrc#Y2-uVw1?Df1mO zRC!Q&o&Vx$ZQ%?y8;RL4mc{dI@yv*)`O~2{O&6{ELyQmxUc%A8zTSreKobY=PdguvQ&Cr3 zcdmS7IVOv5wFEJlX*_B{FCWUQO@X{);^j!Bu zqZ9jU>H(JUZyUTylu=pM;Y{LHOxGCYx3`tslw<{DGqp-22d<(ooLb$y%j<$MQ<*WK zV{&N6h&T%{DzaXu_waEBRHhda5;Z%1=h&5`P-W^g6myxzG`{81RJVFrQ3c5%3in@KQmcZ> znR-v1?grQF%|%bhMwOFV22~X5jL92vNfS0aF6In3gyLukZ%nTUZ5YZFbXQv`qXS;= zbzk`-0T&_sN77X_9(7vT?`?&7WUKXj-4S zDP5(%oxR?`!PXU>Q<)VAw_7n9FZK8d=1Dc$C~JmQZ22RVhsvwA)f!2>dGn13;ZP&F z{tR0)s%hv^u+MNFwRcwQU1rNws&LJoe%}AH@SgF#US%aW>#qX=lh7m~UiHwg512&N z&M}keqGQ##rRJj2UrJ*u_i3k4K9R-SGb;5$Jb;v-NSyM4ShrofA_Fd&nb0fc1J_(( z;bjxXzeY29slG{A+15!^84XI~!z8bhnpzh~d_4hgzcxsPY%T6o%A7SCD6ezefN>er zciEZH)^@eX^w4@oOtcuqAgUX9a#a*s5C=kbryVKmSBJ5ff+nta1_ziz?A*hDJR2!5VDIpv7cEylyw*q{I zciFN1JatAgge0cHnnZs{445@!j3$&9}L@!6x zqB1u(7e<;F=M$*)lZ)@}NFF@%>&=!3aeK@?jRK@L<6ot*W%Fb`VzPf=p%~Ubr>$oF zOe9@YcMv(I<4k%N2VRuNmRHKZhVr4}w*zzyIOv2t;H|bv*Sq_qoB%nz=>Fxo-ES`B z6DM?kHO8`saFS>;O9JGB9Q|1Gmy`(C#4lO8Y#6LMMtk7`J!4eAn$1qq{yFr8bfQ_` zpRx2nq@>YF1kiLGTU-_PdmK-QmM8c8p^fziak5YC>hC|5kVmrTsnSXWo>&iMQi}}= z8?mDx1HTvNS?V{xd^IejE74y6e$Q!AmWv=KU1I$M%zg+?)n%3kJNi|OGW>RX6*Pwv$8a_U z_1`nS`TIB{s#+AO{l>>`WF`PH<`${1dieVdXWkNd5WKuZx%D?_vIV_Fd*TSoe36|EsSt z;+`jzR8sIOhYQh)B>86#Zhlgg(tG7W67l>QBN^_qbe%|C=FI1-N9(8!l|r4ex7XnE zjryQWV(e@(rU5CUwHt5l--jk8%uwHdz?Wp|T5(%etYl@*-FYQhv?9-|LU^T{oaj%X zwrukM{6CfO%Go!P|6Tr)(X*#{{@-PumhIbvzv=wB?nRR7|4-CDpUUF0|2H*BNv}m` zpVz-0%HM5yng5hhsrrX(vhpR*e+WhnG%Yzse*O9*)s>9Tsd73h4 zHb>9+ixuO~jsL?y*6pg(@d&Y!efmHji;80KO{ zvc0`MNonaC>isW&*p5+G&Wl!zCk6gz5VC90Yn`n7S#j|H=Y^7uP4?d+e*Ro+zz_F7 zL;O?uUwktpTNdlq_T`7OMz1a)|1iVo<*9$?=gg}o!8#`!>dRMoqOZ5xdvl`nR{nI> z`eO~__iMmAc$w$*ZG_>KG>?NnRflt*MyAP@P7N+CXSd!Obh~PUnX;d9Otm3jw2FR7 zW^k<9NwDsc@&G-QIo^6Vk&9wY&`&)s4Fe zf@R{dMK*PUi+s})hR<1+>mI7-kZWILkxh;B<`{21&g}G`v(Jh2I>f4Vy+DqW1Sbf4 z(mZ*@HC54By_l~MpNbDvZOc~LIo3=n52ajbwcmSsWj*nnh1P!|kg)V1Jhbq1Nv0tI z9(MZXU9>8rvZiQz_#v1o!5{s<>#tGg`mJG4{s?MEK2a(wRB47}M}sF-#)fZM4jxKNheJ_)z_ z`zREboc~lRZqb_Ht-wbnjRqVz1y7F2iP)hnF!aYAZ@0yifFYklu~dVvuU@U}CgWEx zrxM}Gc?FMg4@c*3(_=NkzimVBi;T0~$uo|2v3_#!9{H}RWMVYhK3UORml;*4asZC+ z&vNoURz6P^ub7;XL^7Q}#!aRAVa6fwqx%P4Z=V=p8-{$Z_vL-|M^e@)ZO-4y#c#0} zC?yDK@6C{fm+cIX=q9bFo{MPeqy+z-NU|A!Y|70aFU&@i!?X*e6ya8u}RTq0H7?wrR5e>J*+uiyzJ;@-WR#wDDVl8>4>*4rtyy_)jv9>vU7u$g>d$&cM`m9CI)qX)@IlLSho#%w9&Yl}t)$gDOkbY%*1wfS`m9`zs+b)t z%3XYY>q{gb3|6}5qVl&TppW`nb-C;V-j~nEe(BygHS&-|EyUfu%jtS*ia9ii{x~Zi zx&}5=sX^Ev>5mFDp!$!I-E;)oat5nVx3X0zrqc%+ZYxKF0d6imwH@1NjiJI2DpUScV`zl_aZBlc_hb&IS(yG*_xhw*u zkKNzoCIJF*ZV@yWoj|_jt&>!3HS=XwvVLw^fVhl-FM=|Q6rBM zg!Y9}b%CkFBQwY?Z{fad0FUwTeS)3o=7F)nv)!)NO=VnrjJ_Au-R%YEA}Rme5r>n{ zH}t0~U#Ml=@f3T~%*Sj*GzbeZiry3T0jMp zNh2gF=^YzFu`YpzdUN+1?q^+-d(=u#q%@p3q66{gbB+Yr79n99UHz54ukIM25{8dp z>NI%j55Z;bD3M%R1lj#{N!KXmXUd6`37Wcr#~bl-YVzZ zWmRqRL(3VYp43Ui$3U=cdO0BIb+$Ib8eG!Z7cRCijh=9`*?lQ?Dx60g?vk37zjgm@ zTn;4s#$?|LmtH$6)3I8$yPG(SYP5$s2~c4=Z4J@cXK0@k5BohOeqc-fUeoE)Ln0pd zJ$%30IiWqUJ$D>qFHVHC=8xq*k$2mcS3bsq|(I0 z>0AbbET7p82`coH7i9*u4ssE`DVQe}%an|D;qE;GC@S##7YV6B;w;UdYu!cc!azzx zYXq-lkEER`M?WL$YY(Pd2J_WXy+r{RHoddscy8dEgs#PYgIJ|yHs5vQI^j>$s=>5E z`i5yCn5+cIOZ%c{zm1pr;D-tfq2>dGjpd>=DSfb>RpI^D z+YPJ%tIDoibql>Bh~2-)?WmpiLhE)npHcW%e>U2`!J&K+K<`75#!E*XYwLyrXE2X{)Du@Be5pol={S5*bN}5&mlYL>aZq?Dnq2U4*;Q0#B7!ci{>n(~D?D*4aKK)(uq8+PD*D_Oq_l*-_>xTYLW;Ls$4&C(-#y^DWwvY+Ff_ zfH2DMn-dHbS>L6PA)8MQd`!>0ZB{9!qgZOS=8~X$?&smUvBgtQh)hSbi&I-JL~uU` zJJ;P|MbIbFZKzm5mStCrhSb~NaI6l%#j3I1Bh#mQqak~9%WxSYm; z2_907t|OVpZX6$cR&!DxvaOFTgC=N5+kF_lZ2NYkOz|lZ2~@Z7zKt+Afla_mek&8gZ5LTlL(+Xc7*Q?=2c9j*ejh?g#pY-U6TX2C1{G z#w^xHl+3m^T)ENFlzH1jegV$N`J~OGD6NKK=`^G#1*yul`a%bsjrZJlm z4taXcG@)WP-L-xt+U^ae&lPoK(()i&LU$;9J=A7O(kwr&u<{}O>kiRVjo6?Uo1(hd zQno;j-Q3a1<0#=ip{i73n5GYgSoekit_s!zD1-2K~U)u>F#C_ zX(Xf@q`NyuNonaGlrHJ6A*DgO8MyAY_gU*+?|N7l6IY$s`|PvN z*`Mo-{}J4Gdso^qLu+)1@8_w-o&=z+ngf@`VQbnQaxkLmKa{sjt zstJ^QG$7DRBk*M(k#3+C+DEcYC|U0*YrwJ8qlMMdo($FSoXBiW236h!1&0{Z$vdE9 zahgh9HR7Sq*~2epw>w)wlh7fv%B)J07@w@;7(Z7I2#Z{<3sffUVo$1e*Knn6HH>H> zmE1`YODOnNHG$J?Irh3Np%Wi=o@N5Zv_Jk3M6WN$@o{%)&nH|>m8mB)hN?s^&?g#M zi?Xy{LQEDd{b{u)Ee|JztUMw<{w>gMmlp*lKnF>7{!`!+Iw$)o22Arbjzw&C)+a!U2PlL?5`zhgqJ?ywF~d< zq@-@bi@otJsg1)w*}N*Cqfx4gVYXP!KiFj#@*+}gyAgusnhXfymkWH3k~OU@P8fDu zGneNpv!eKHMP_s)ZI}r%1@ut)kJK|O*0BfdjWwFs?%u80%l9?J-Z{I;J7M8F_#qdu#>Cs!Mh)%sBrpP8)`M$vUg^T z`N$%bGl=+8W_Kku&c$}{+xo7#F9MCPq=_WW3Ya%1tbia;hG>s5Gyuic87bO&vJ3=u zrWU2HJP!>ft-}f+zRHz;cC~D-@?(FK8=JEtKIv@T7^gYmx)Y0vs);t)wJFU9l-}** z!ArAP!QXN$0?^q%`Obx8F?}RAdMifg&iI}VI7EySbLeyk>bR@MzOA383WXk8#U~}T z7AVUMM-(10?EH1T6P_PwQvMmkKc-LQiKk_Mv;4T4Q&WUJ!yWf?%4)T&f@~LRp;(LTqRYeD@^qTd1*KIX9|i#4L?6@;7sy6+GX|d z?Vt7=ro{VU2|;d|w7xB@9&~3c{%$+Yu(l94@^ANlRR~_RMFquKQ%CD%5Vd-S}YAnGJ|*$l??rYj6_&z zJNr!GoimMBVH78;yV{Z;pW}L9AS|#A=6j8e`cKsH3MG7TdpF-SeI1kt()}NTMOe}8 zxidT@M4@xzj6~w zm1PRZGipY>o_+LYgA54hCeJYmIGHQLXYs9iFRKpgU)>9v5Kj;sQd^j08Gro1kgwtn5m9!84D(lHJ;5Ak zpg0Z(9;Vi9vHXmTS?d`SDRk@S5k9{aZE)#zHupb!HUT#5yj;I&{r=b44wn4K+1_BT z7Pvo4Zy75fi}7HTKKyLb;5Wifinb&){3gRG0kBp4;T^3C)Efv;1BN(FO7RExZ_~EKZo%bqD^vx8+3Wk|d zP3u-H^eAEjcIT|{fSPTGsY+`0GEq!M=EG%>hYqn7ikq5H)Fd|vyJJwu^C$MYcMGQG z_>(hs8Ym9Gyq|Wc?t~|0H`+w)Dk?SSu9& zbe$3Iu2!i^z-fOR!Q5X{S;Z-b2|9NnlM!+o6JUZ<`UWXrovcdDwSP^H-rK)U>j;1e1U2x_ zYGZ*GsC$aodpWYZga8rKg@}bZI(3$YukVELOw6lHwjzX2Pvz^Vw?F{b=N>brfYzL^ z7%mWtFD)MtMG{%HqDUVW_X8OfZO14Vqx96~se8RRaILeyU!N>PMY36V{1Rb$E#keM zamBT?I%3?}JJB)u9;KJoxZ*TB69xr^;8*B=lGW1Ex;!~|JXxPkb_ExmX}|Mjq4J6ymXVO|~+zWyGBucqXvI68Lg!^*|CET(t1cixcA z;b4CsC0|Xv)Wp+nrPV!}HJIjlrDsqz!SB99iS~4Ej`o-E%*}2OpOg%GhgWo#IX@|X zRdX5eei$tmYS=?CTD~^OXER=Q<+jLvZ7n!eEIDH|I-cE=jzw`n1SW9t3;(AkpQt>{ zO#ZdqHZwEA@Du!TyTD)X?Kcf!CGn|gdq(7RLA-wD-_p9;=g(fPgHl&{wXr`w$HPza zvv8=a=5K&gYV)R;m8f#b85W(fQ#IPQzf$AsP&6F9&y#kZZ{(k^;~zkO5)tUL-e1wd zteTlNhI0PK!i_bY2Pp#i4%;(jhtE-?NUqJnC`dU+g9eL|X_XSgt1kYS4(`Q?Jw8)y zdVygpKj7Aq#>9B%P5#+76f<+Uzd$(E{NZAyP%U_1+x__E(ER9PYKd&Mf^qZ3H*NM5 zb)m7^?=QOMdl%rqXrRV(=NOAZ zJKiC!jTuh{DXTWg7X2iHT}UJTPW6S;!VS;=m|CR7{<=|v)d;fGSt%l&XA}yfeUU9O zcKE_4zaWy&ZeAQrVajH& zl)1KItj5mBP-eDXn4hgnZ1wEo7Mbyh9i#^okxW<6OrTnb3)aS*-g|xeYMyDSx%_0G ze}Cri__`3?qIHWq;`lx+^2@ZVHGbshp4cDY7g-j+Zj#|GglO(mnBde=G0aHLLqb3? z<`_s+s_pR{HUYO#)QckCk1Bv-U%?hiwy3fmumfnk(SBe0LR-pQoon=fth2*3ua6U6?T+H|sgBVUDS2|-~{=~O+T_`L}piCdm3XURID}uD(M!H8i#(eg$-o_Nl zE8~N0V+!3)56l;pLj!vAl{{oZytK1@Yvoz~YgcDhdGfgX!Zvr0w+p{J(@ zPnfaZi2$ZwCq~)$({-U*#$jYVjfJs z=mJz?W!-PbdP>(M#r%r&!#QVotY3lYoi{pd=JdW>nrOU|Tzwz}506~(Fv+h0 zKBY-CB}`iC>7R1UVIzDv`&mIMq=V*-!P@4kh^5XCVWW-?3AM1C?IkvLBTM9WSP|Cuq1jWsFfxi``r=D8Bnx z5;Ksy%L+8N5ZyJ>R3C(*P-|gZ*MP%H(nCKsJbb)dJlviep_VK?D;2$V9v8;eMSbm5 zf3}C&wKGPU_F_UlAO?E? zJ}!6PESzy5HPpYN=KW~Ox_+{3lH$~|WA?J3G;_ks(w3S{)I*4cOb1eD33afz`(5Bw??ta10RfVTaA!=`>?sZW7FvIB!fmA+^hb=?uuj!CKOI-V zG0r}BgaebdqwTSWL_478?Sen~vNCT}J|ZG77V+$NZU)WSxHyKyl0#-5r+a1|pj4_u zwtNu)(KeVo$1s=+JJT&V2F9gJV>cW#v;^c4C$9NM#G6XuZ#)7aM{5^Qn-r`^IBS@~ z{0t!&U1@j|MucqcgduhdpFSIXN^D7uF*Fcw4zLl66Yqh3FDTDd zRxyB#HUz0IvCjc2I-L9L2uSyDLuLLOhV2;<Uj>d;0Kj!@Ju z|NM6JqfoP!R7_j;0B*ze-rRR+VPe{ezeWg{zp(AtxwzIh;Bmd(j&i;S$tr28$#ptp zOu%vZnwZwTdJUedaz{DazVBPijS~=wuro0;`|5npe&+$}*>Yn_5w&2As3+^%1o2A8 zF7VnAs8SHi4payc&i)W^D@ph~X>tH*N^MP@yU^R<3{O;8OOwT-Xh|qR#mRO^#_yi` zLNz3}IokoAtMCQD(@#b5kL27&QzFEOOz0>e9whta;3!@ASZsc64o0=&*NWenSJ>=g zORl1W=o5vqi$yE!12rzIJwJMI4V&|vk)ot6&>Va99S9m$}U?T`K<@t&xZWnoNqi*qvN zOV=1$jlcn$D(|r9CBdG=7{~SRT~V0ny<=l_fJBDym=r$84Vp+C7`tAw)vu4#HdI&- zeI|Vh)BPJwcmB?vR%^XIp>)*UEkWvjNrsNQnX?rA$A#((rYbWMud`j+d#KW*kEFi^ zKd{8qdN^JKb9Q0pPkoy-TMBO^M_kNUDSAt{eehx{!!7QXdMA;$*TW;KN5^*T+is8X ztryZ$*)0hvjt~Kxzw@$dvU*)1r8;edpP1i#L4?NZU!t7VgjWA!5A@#3cXerS0O+m# zW6zYdSr3*JqS$?y_oIYgga%?{&_+mj9s-5=aqV&$9Civd(9vfoIoy z$tDSt7x*2@iS$rc;03ouRNJDL!ZXrY>T>OVR1rRze_90fx2MrKFX#25QS?r=PhHl?P+^gKoGmH67Njz*jEZ3}iy3co(dP zgZfv???Po>2%WLD-TLD8zTX>o@z>jM`5Wy(q`C1}BZOROXrq5H;1P1yqXXtOpnobI zc=>(5|CbP1&tcwka0wY~31_o{3+H%nFy`d)*7ZvKZw6H){)?g@U?=E(fgPKmorwM> zs>`Ro;=DN~^?L5<+WT{B%=9-d2BzGazkc|+5bNs&S|?I5ydXv_wzMj9ugF_&&^=^j z$l;-@f?@cdnzSbz)~P+S67T;qY!cq0MN{o)^eE~A`>-T6%4H)R-# zHl^wq_{KkLJ8;4;(-~>XD<5YY=yU6)Y=Z2U-n$9xJHvHrBY6h#D~@}Md>^*pC+#bW zdTO*DZHtQF-uYl9=f<*cvi9a=A%0CMZYB60 zHEk+9neg6arr{GUm;@_#o>vRVhTz>2Q-0W&FHeFVLjLqT8K#6OV&4-=)Z+U-pGN%4 z0!STtI}OefqzGO}+FQR=^dDsH)>Yhd1t+e~@X}PZ51jKZ-3%+&3$^YERO;)dz|L5i zubv3BDA2u~#@1kkNH--8)%DoSB^Ol5NkIgFMgDoFs=}9I4AH%Nbj}?NJ?j@4Of^TN zB0by)`_%5(1pd=qsie(XMR;8%X=*27e8hXHk+frdVL5kbjd~HD^DYrvnBAXS$iX*6 zve)kFV2#B>ysXjUi8vm__%iZ>dP_5LIbWz;!17nMkQ*s45g693lZDtz<*Om%5hNr zWA(@zXJIf?|1b6J=-JAHKZBa+aG`{&+&g1og4kEc_ALq?AWZxDc=9QQgPPhQ5Re`6 z!>d(+&Vc^4A07KhCyn1!d4gkjFOpiodhl&n0zZvsi`?qV2}DDDEd3AZg4-WsLjXJ+ z2$-b|$YxX-2})4$r(qndYFGZ8?}zHrCEE0>$zFXR)I8SLk}h3i#AJTM>b{DJg|1e% zM?;)Y$QxaRBw_U7#HnAVO<&-2@=ja2&CE1wdv1C%-F4Jl^tK1VqwPaZwH74uqg$da zrjrUTF6v!;AlTeRuM|?;0=k;(D_k#K0r$=v&4?8Y?aj6Kt_a(o`LX7>=^JzkP zQ+oKMBMzs{pIi$7hL5wN8bAcoI%<~QWF9eu?VAcVc(1H0wySaVuJ%wBK?X9my0;Kl z5luJC&K~uFwLW=Mcow+w_>RF>c%2VVkye=Dxm(H``X&ZHhaIJI?BPNR63IDAf?k{h z1d-|G3%i+NUQFEc!uV8f=Xjd2AjE$=jI4Ju>CD-BWFp{4M*tpKNUyuOM|dO~@CI;d ze1fFX*wyD$(*854xuMw(`80nDmOxHz*f`~bfEk#8pgFK`@m9wkyecQiQ>2jSEM`i+ zG@QR#ohoegbWks~;gkV~vO&e9Nq;WB%r4zU7PhCxND#us6&BcBSG879eq%ZC&OIL_ ze`pB1)d&IlMo4KH@<|S7MZitkKDF)RYc8T_T8TkE&y1Ida}leR%kb0j`|eQQ zJuD9l2u$4AUh>8*GXAi<$Z#nmVHz)kAl&MLH^Xej5<#(@pUFtH?w2fDuBLSGsy_X) zcHQGkL24EJmFrG3kY+_X*BYEx-S%-jVe??nk&T+K$E3%^Va*8%MxBhw$$L{M(G##n z-!+#|X$T%xsKnQ$T^{<1o85&DLo-IHn}*sVHD_T>S|wuq0ga0n*BFeymim`2UQU81>=mpMCjmt z{1}jX0>^xti)tPbL?C??_>9q=s9XJ_ZL@Y*y8v>QTY-PRr-Ly8=r|RK5ZLn{q4SC# zp;zj8D%R~vF(|ZNmaTEzkCXBnLlGc|RLB-u9<)(Fk-#H%b!y?RYStZxBD&& z1a*W5W>o;@#9u#5zkWoUC=|6eRe(B1Pj$5w)*&%vDW8m>V-~M;%thdoN<-J_=XwnH zR>-6GyF!xu(DqbvP|6^Q&(N8;YEI;eil(Rdh+;Z5Q?{#P4ckZA(6$7KSva{47Buud{* zuoIm{$u{s(Z{{1z5?f|pg%7|?7xh{d+?Kpb0Wns#N3w)dMUjN3fWMfueQWb!ENgIi zK5>XdE9^w}Y+$3T`m}qJSxJ7lNiU- z#USvsWmLn6M(I)hf5ANVhUn3DZ$oW}f3@A2-JG*|7(~zfrFcFQiU$kq!)6SPx|f7O zeA2bFj58kPU-zPR1S@beeLS{XLkpDitdAZJk%0@fg_R3~DYS^LVtMQzcsTYxXp*KZ z8o5Gdu{J_N{|i;|6+Jn+NXID-`F1N5fqS%3AABj+8;9YOH-XunQ4w>w9y~IK08+`4 zBA!8`SN1$Ixmz8cQY`6_*(?-95(=hf9?ifI{R}GFFw{G`?zJql4;<{vZo{*Hleb!^ z75cvXf$nN)GHu`j?f9T!35!S|F;n{y>R2n(%ypZQf86637L=UA?Sb4JZMOEMP-gg6 z!E&JzlZ@0QC3D}n>`?AC4Kh0F!Ar$l?;|X;c|EZi`WH-A0@X>RqdxWK*yZCyip4dp z@h6)4vb7t-Ln)`PL}7KIrWOKK?iNbNDEhu{*o1|?NExxNCHuBVyZ{^ZXGuE-Yvx(S z=z3YY8WPu#cU*G-Id=Lb$!{w}-BMWo&+r@XfT-OQV5GajP| z?L&{=T1ygXyZ{L`z*fCY1(9&#MgG4NQG^RIw->Eg@N4`C#cfQPI|8G{mps7OUf<7t zGiL!2U!}yoy!1qggWlaP)A&BDx^De|^dKIHWSq8r8^Js5#Hu}TqGyJZ3wlP!a^xRf zCnkM!GkoI9?Lj6Kqm%GsDY_%4*U=^7R1M0N#781ns4Enf7ypxMH`H(r^i|Pv%KV({ zhSI|jU);4oh-mr5f?U_Lv-Qc_6Ri`%^0i7$SP-TN@2gUYUW9GWDa4{h(kK;wz|(t;X%paUxsdnr_a^TUsc}f8Mu8e(%g&df2B3bS9HN8!w!eNagLF zR@$E8%dd1?Fsd5p{`F1Y!JYz;0&KfxQxR7<)rcgxx1P!FwRbQ{LyTWNrT-2vgrDXw zx9c`$XNP6hrq5OLW-LFho8-h`BN@8olVZPJ2P@7N!p|}b>N`X$L8%Uro1>FqzP=VFR65H;KMvd0`}2xE#iI@r zj{?&R3Sa~MK0T!y;W9!G6NmZs>yZS1#s$ix$ z)Q4slaL_uS8E=BTF@do))ETxxBY!&xYk?Jsx0gzReH?O)=o=m$!Ye&mhr(64m}T!9 zol)7!7i2p3p&U)>%rlW~sSX;g9k*D=&Cecxm)XwLeQnoe+@_l#v%MV4y+0LYJpuk$ zuRDcUjA9peySqYFi^B&u_-Nz6wtdA&KaAH-59rqsm;*7jlN+gwM7GtwW{9yBQtT$c znPAw6%qWJzg|Av9O?#Z9bd+)*>ffW>oE#8^APJH+5_ky%XA2e7F0&I~(hj&1nRH-CkUgX5QW6RHH>US3+z25*Gw5usa(Bs1)r_F&>1 zA5XRxOh2b_01cMlpeftjnz*u%D8QPEO8sE=QoyQpHA9*I9h^1L1#$Yv^{A|eZM=(7 zK%qaW{D$B>7~?t3#OKa0Wu#i+Xa&U#Wj{-jwAQW0ZmOIk%QEN&$`H%BSucBcAa*HtSxnbq+o2HAny^c>cFFUiilvpSqMY z{T^G#;&r0u%io+PjNTCF=b=7ZxHR5*0cGC>Z6&;pIy8*lUV;eQJL~Pu(j}eVz!eQm z0mH@+HgLrp3V*R`b5oZ{hqe(7%UXnki++L#O(q0<{iRWwg`H`<(MB}@sY3Ssp#QbY zZ;l28%O>EQyExMo=Dbt}!M)FjJRA_6WplzZ*?^Ib^o`ji<7spK*n;aL(?g?qu5#~` zw~x81lF zug4Ogtj&Vl z-pBMH1PG$2Jy0<5AS}WF4DVS+!JOTAOgi=WUZiEmq)*qP1b#bMx|9gI2xLD{OHzDD z;UOnS+ng5(ys{uWhc;_sLl$Z+D;JXg5x)~W6SYkrwcqrBS!8| z?0$|Po`�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

##Fm@Nm`Z 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

vVV-`?s)y~Lu_9J6=O31KMV~Il; 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 diff --git a/plugins/misc/marketplace/README.md b/plugins/misc/marketplace/README.md index 37bb7e45427..101148c6feb 100644 --- a/plugins/misc/marketplace/README.md +++ b/plugins/misc/marketplace/README.md @@ -32,6 +32,7 @@ From the Hop install directory (or invoke the `hop` script by path — it alread ./hop marketplace install hop-tech-parquet ./hop marketplace install hop-engines-spark:2.19.0 --repo asf ./hop marketplace install hop-engines-beam +./hop marketplace install datavault # short name → discovered GAV + version ./hop marketplace list ./hop marketplace query parquet ./hop marketplace query engines @@ -40,11 +41,19 @@ From the Hop install directory (or invoke the `hop` script by path — it alread # Repositories (saved to ${HOP_CONFIG_FOLDER}/hop-config.json) ./hop marketplace repo list ./hop marketplace repo add --id local-nexus --url http://127.0.0.1:8081/repository/hop-plugins/ --primary +./hop marketplace repo add --id community --url https://nexus.example/repository/hop/ --browse +./hop marketplace repo import hop-marketplace-repo.yaml +./hop marketplace repo export community -o community-marketplace.yaml ./hop marketplace repo set-primary asf -./hop marketplace repo enable central -./hop marketplace repo disable local-nexus -./hop marketplace repo remove local-nexus -./hop marketplace repo reset-defaults # ASF primary + Central +./hop marketplace repo reset-defaults + +# Discovery: Apache optional catalog + every browse=true repo (live Nexus zip list) +# Default: ASCII table. --csv for scripts. --include-gav adds groupId:artifactId:version. +./hop marketplace query parquet +./hop marketplace query datavault +./hop marketplace query vault --repo community +./hop marketplace query datavault --include-gav +./hop marketplace query --csv > plugins.csv # Declarative environment (CI/CD / Docker) ./hop marketplace apply -f hop-env.yaml @@ -174,9 +183,34 @@ export HOP_MARKETPLACE_PASSWORD='…' Hop GUI → **Tools → Marketplace…**, or the main toolbar icon after **Save As…** (separator before it), opens the marketplace. The startup **Welcome** dialog also has a **Marketplace** topic (docs link, open dialog, install-all via `full-client-env.yaml`). -The dialog lists optional plugins from the registry. Choose the **primary repository**, -or **Manage…** to add/edit/remove/reorder repositories (same hop-config.json as the CLI). -Install uses the primary first, then fallbacks. +The **Plugins** tab lists Apache optionals plus a live zip list from every enabled +repository with **Browse** turned on (same as `marketplace query`). The **Repositories** +tab only manages endpoints (add/edit, Import/Export, primary, browse flag) — it does not +list plugins. Install uses the primary repository first, then fallbacks. + +## Company marketplace (shareable repo definition) + +Three steps: + +```bash +./hop marketplace repo import hop-marketplace-repo.yaml # browse: true +./hop marketplace query datavault # no special flags +./hop marketplace install datavault # resolves hop-datavault + version from repo +# or explicit: ./hop marketplace install org.apache.hop:hop-datavault:0.4.0-SNAPSHOT +``` + + +**How listing works** + +- Bundled Apache optional plugins: **version = running Hop version** (not absolute latest on ASF) +- Every enabled repo with **`browse: true`**: live Nexus search for `*.zip` (one row per artifact, latest plugin version, last updated) +- Optional YAML `plugins:` metadata **enriches** names/categories and can set: + - `minHopVersion` / `maxHopVersion` — hide if this Hop is outside the range (e.g. datavault needs ≥ 2.18.1) + - `version` — optional pin of the plugin artifact; otherwise latest from browse + +GUI **Plugins** tab uses the same discovery as `query`. + +Sample: `src/main/samples/hop-marketplace-repo.community.example.yaml` **Environment file** path + **Browse…** / **Edit…** / **Validate** / **Apply** manage declarative `hop-env.yaml` files. **Edit…** opens a tabbed editor (General, diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/NexusRepositoryBrowser.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/NexusRepositoryBrowser.java new file mode 100644 index 00000000000..de49c971e31 --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/NexusRepositoryBrowser.java @@ -0,0 +1,321 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.catalog; + +import java.net.URI; +import java.net.URLEncoder; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Base64; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import org.apache.commons.lang3.StringUtils; +import org.apache.hop.core.exception.HopException; +import org.apache.hop.core.json.HopJson; +import org.apache.hop.core.logging.ILogChannel; +import org.apache.hop.marketplace.config.MarketplaceRepository; +import org.apache.hop.marketplace.resolve.SnapshotVersions; + +/** + * Best-effort browse of a Sonatype Nexus 3 hosted/proxy Maven repository via REST search for {@code + * maven.extension=zip} assets. + */ +public final class NexusRepositoryBrowser { + + private NexusRepositoryBrowser() {} + + public static List browse( + MarketplaceRepository repository, String textFilter, ILogChannel log) throws HopException { + if (repository == null || StringUtils.isBlank(repository.getUrl())) { + return List.of(); + } + String repoName = extractRepositoryName(repository.getUrl()); + String nexusBase = extractNexusBase(repository.getUrl()); + if (StringUtils.isBlank(repoName) || StringUtils.isBlank(nexusBase)) { + throw new HopException( + "Cannot derive Nexus host/repository name from URL: " + repository.getUrl()); + } + + HttpClient client = + HttpClient.newBuilder() + .connectTimeout(Duration.ofSeconds(30)) + .followRedirects(HttpClient.Redirect.NORMAL) + .build(); + + // One row per groupId:artifactId — keep the latest plugin version (not every unique SNAPSHOT). + Map byGa = new LinkedHashMap<>(); + String continuation = null; + int pages = 0; + do { + pages++; + if (pages > 50) { + if (log != null) { + log.logBasic("Nexus search pagination stopped after 50 pages for " + repoName); + } + break; + } + StringBuilder q = new StringBuilder(); + q.append(nexusBase) + .append("/service/rest/v1/search?repository=") + .append(enc(repoName)) + .append("&format=maven2&maven.extension=zip"); + if (StringUtils.isNotBlank(repository.getGroupIdFilter())) { + q.append("&group=").append(enc(repository.getGroupIdFilter())); + } + if (StringUtils.isNotBlank(textFilter)) { + q.append("&name=").append(enc(textFilter.trim())); + } else if (StringUtils.isNotBlank(repository.getSearchQuery())) { + q.append("&name=").append(enc(repository.getSearchQuery().trim())); + } + if (StringUtils.isNotBlank(continuation)) { + q.append("&continuationToken=").append(enc(continuation)); + } + + String body = getText(client, q.toString(), repository); + Map json; + try { + json = HopJson.newMapper().readValue(body, Map.class); + } catch (Exception e) { + throw new HopException("Unable to parse Nexus search JSON from " + q, e); + } + Object items = json.get("items"); + if (items instanceof List list) { + for (Object item : list) { + if (!(item instanceof Map m)) { + continue; + } + String group = str(m.get("group")); + String name = str(m.get("name")); + String rawVersion = str(m.get("version")); + if (StringUtils.isAnyBlank(group, name, rawVersion)) { + continue; + } + // Nexus reports unique SNAPSHOT timestamps (1.0-20260721.105615-1); Maven layout uses + // base folder 1.0-SNAPSHOT/. Prefer the version folder from the zip asset path. + String zipAssetPath = extractZipAssetPath(m); + String version = SnapshotVersions.toBaseVersion(rawVersion, zipAssetPath); + if (!repository.isIncludeSnapshots() && SnapshotVersions.isSnapshot(version)) { + continue; + } + String gaKey = group.toLowerCase(Locale.ROOT) + ":" + name.toLowerCase(Locale.ROOT); + String lastUpdated = extractLastUpdated(m); + OptionalPluginInfo existing = byGa.get(gaKey); + if (existing != null && !isPreferable(version, lastUpdated, existing)) { + continue; + } + String path = + StringUtils.isNotBlank(zipAssetPath) + ? zipAssetPath.replaceFirst("^/+", "") + : mavenPath(group, name, version); + OptionalPluginInfo info = new OptionalPluginInfo(); + info.setGroupId(group); + info.setArtifactId(name); + info.setVersion(version); + info.setName(name); + info.setCategory("auto-discovered"); + info.setDescription(path); + info.setInstallPath(path); + info.setLastUpdated(lastUpdated); + info.setSource(repository.getId()); + byGa.put(gaKey, info); + } + } + Object token = json.get("continuationToken"); + continuation = + token == null || StringUtils.isBlank(String.valueOf(token)) + ? null + : String.valueOf(token); + } while (continuation != null); + + List out = new ArrayList<>(byGa.values()); + if (StringUtils.isNotBlank(textFilter) || StringUtils.isNotBlank(repository.getSearchQuery())) { + // client-side refine (server name= is only a partial match) + String needle = StringUtils.isNotBlank(textFilter) ? textFilter : repository.getSearchQuery(); + out = RemotePluginCatalog.filter(out, repository, needle); + } + return out; + } + + /** + * Prefer higher plugin version; if versions equal, prefer newer lastUpdated (unique SNAPSHOT + * builds collapsed to the same base version). + */ + static boolean isPreferable( + String candidateVersion, String candidateUpdated, OptionalPluginInfo existing) { + if (existing == null) { + return true; + } + int vc = VersionCompat.compare(candidateVersion, existing.getVersion()); + if (vc > 0) { + return true; + } + if (vc < 0) { + return false; + } + return isNewer(candidateUpdated, existing.getLastUpdated()); + } + + static String extractRepositoryName(String repositoryUrl) { + if (StringUtils.isBlank(repositoryUrl)) { + return null; + } + String u = repositoryUrl.trim(); + while (u.endsWith("/")) { + u = u.substring(0, u.length() - 1); + } + int idx = u.indexOf("/repository/"); + if (idx < 0) { + return null; + } + String rest = u.substring(idx + "/repository/".length()); + int slash = rest.indexOf('/'); + return slash < 0 ? rest : rest.substring(0, slash); + } + + static String extractNexusBase(String repositoryUrl) { + if (StringUtils.isBlank(repositoryUrl)) { + return null; + } + String u = repositoryUrl.trim(); + int idx = u.indexOf("/repository/"); + if (idx < 0) { + // already a host root? + while (u.endsWith("/")) { + u = u.substring(0, u.length() - 1); + } + return u; + } + return u.substring(0, idx); + } + + private static String getText(HttpClient client, String url, MarketplaceRepository repository) + throws HopException { + try { + HttpRequest.Builder b = + HttpRequest.newBuilder(URI.create(url)).timeout(Duration.ofSeconds(60)).GET(); + if (repository.hasCredentials()) { + String token = + Base64.getEncoder() + .encodeToString( + (repository.effectiveUsername() + ":" + repository.effectivePassword()) + .getBytes(StandardCharsets.UTF_8)); + b.header("Authorization", "Basic " + token); + } + HttpResponse response = client.send(b.build(), HttpResponse.BodyHandlers.ofString()); + if (response.statusCode() < 200 || response.statusCode() >= 300) { + throw new HopException("Nexus search failed HTTP " + response.statusCode() + " for " + url); + } + return response.body(); + } catch (HopException e) { + throw e; + } catch (Exception e) { + throw new HopException("Nexus search failed for " + url, e); + } + } + + private static String enc(String s) { + return URLEncoder.encode(s, StandardCharsets.UTF_8); + } + + private static String str(Object o) { + if (o == null) { + return null; + } + String s = String.valueOf(o).trim(); + return s.isEmpty() ? null : s; + } + + static String mavenPath(String group, String artifact, String version) { + return group.replace('.', '/') + "/" + artifact + "/" + version + "/"; + } + + /** + * Path of the first {@code .zip} asset (not checksum sidecars), relative to the repository root. + */ + static String extractZipAssetPath(Map item) { + Object assets = item.get("assets"); + if (!(assets instanceof List list)) { + return null; + } + for (Object o : list) { + if (!(o instanceof Map asset)) { + continue; + } + String path = str(asset.get("path")); + if (path == null) { + continue; + } + String lower = path.toLowerCase(Locale.ROOT); + if (lower.endsWith(".zip") + && !lower.endsWith(".zip.sha1") + && !lower.endsWith(".zip.md5") + && !lower.endsWith(".zip.sha256") + && !lower.endsWith(".zip.sha512")) { + return path; + } + } + return null; + } + + static String extractLastUpdated(Map item) { + Object assets = item.get("assets"); + if (assets instanceof List list && !list.isEmpty()) { + // Prefer zip asset lastModified when present + for (Object o : list) { + if (o instanceof Map asset) { + String path = str(asset.get("path")); + if (path != null && path.toLowerCase(Locale.ROOT).endsWith(".zip")) { + String lm = str(asset.get("lastModified")); + if (lm != null) { + return lm; + } + } + } + } + Object first = list.get(0); + if (first instanceof Map asset) { + String lm = str(asset.get("lastModified")); + if (lm != null) { + return lm; + } + } + } + String assetsUpdated = str(item.get("assetsUpdated")); + if (assetsUpdated != null) { + return assetsUpdated; + } + return str(item.get("lastModified")); + } + + /** Prefer non-blank newer lastUpdated strings (ISO-8601 sorts lexicographically). */ + static boolean isNewer(String candidate, String existing) { + if (StringUtils.isBlank(existing)) { + return true; + } + if (StringUtils.isBlank(candidate)) { + return false; + } + return candidate.compareTo(existing) > 0; + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginInfo.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginInfo.java index 866844c5edc..db5d1acac19 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginInfo.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/OptionalPluginInfo.java @@ -23,12 +23,32 @@ @Getter @Setter public class OptionalPluginInfo { + private String groupId; private String artifactId; + private String version; private String name; private String category; private String description; private String installPath; + /** Where this entry came from (e.g. {@code apache}, repository id, catalog URL). */ + private String source; + + /** Last modified time from remote repository (ISO-8601 or raw Nexus value), if known. */ + private String lastUpdated; + + /** + * Minimum Hop version this plugin supports (e.g. {@code 2.18.1}). When set, discovery hides the + * plugin if the running Hop version is older. + */ + private String minHopVersion; + + /** + * Optional maximum Hop version this plugin supports. When set, discovery hides the plugin if the + * running Hop version is newer. + */ + private String maxHopVersion; + public OptionalPluginInfo() { // Jackson / default } @@ -40,5 +60,6 @@ public OptionalPluginInfo( this.category = category; this.description = description; this.installPath = installPath; + this.source = "apache"; } } diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/PluginDiscovery.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/PluginDiscovery.java new file mode 100644 index 00000000000..b6fbdf81103 --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/PluginDiscovery.java @@ -0,0 +1,402 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.catalog; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; +import org.apache.hop.core.HopVersionProvider; +import org.apache.hop.core.exception.HopException; +import org.apache.hop.core.logging.ILogChannel; +import org.apache.hop.marketplace.config.MarketplaceConfig; +import org.apache.hop.marketplace.config.MarketplaceRepository; +import org.apache.hop.marketplace.resolve.MavenCoordinates; + +/** + * Discovers marketplace plugins for query / GUI / install coordinate resolution. + * + *

Always includes the bundled Apache optional catalog, plus a live listing of + * every enabled repository with {@code browse=true} (Nexus zip search). Optional plugin metadata + * embedded in the repository definition enriches live results; it is not a cache. + */ +public final class PluginDiscovery { + + private PluginDiscovery() {} + + /** + * Resolved install target: Maven coordinates plus an optional preferred repository id (from + * discovery {@code source}) tried first in the install fallback chain. + */ + public record InstallTarget(MavenCoordinates coordinates, String preferredRepoId) {} + + /** + * Full marketplace discovery: bundled Apache optional catalog plus every enabled repository with + * {@code browse=true} (live Nexus zip list or optional catalog URL). + * + * @param filter free-text filter (may be blank) + * @param repoId if non-blank, only that browse repository among remotes (Apache catalog still + * included) + */ + public static List query( + String filter, String repoId, MarketplaceConfig config, ILogChannel log) { + String hopVersion = resolveHopVersion(config); + Map byKey = new LinkedHashMap<>(); + + for (OptionalPluginInfo info : OptionalPluginCatalog.query(filter)) { + if (info == null) { + continue; + } + // Apache optional plugins track the running Hop line — not absolute repo . + if (StringUtils.isBlank(info.getVersion()) && StringUtils.isNotBlank(hopVersion)) { + info.setVersion(hopVersion); + } + if (StringUtils.isBlank(info.getSource())) { + info.setSource("apache"); + } + byKey.putIfAbsent(key(info), info); + } + + if (config != null && config.getRepositories() != null) { + for (MarketplaceRepository repo : config.getRepositories()) { + if (repo == null || !repo.isEnabled() || !repo.isBrowse()) { + continue; + } + if (StringUtils.isNotBlank(repoId) && !repoId.equals(repo.getId())) { + continue; + } + try { + for (OptionalPluginInfo info : discoverRepoLive(repo, filter, log)) { + if (info == null) { + continue; + } + if (!VersionCompat.isCompatibleWithHop(info, hopVersion)) { + continue; + } + byKey.putIfAbsent(key(info), info); + } + } catch (Exception e) { + if (log != null) { + log.logError( + "Marketplace discovery failed for repository '" + + repo.getId() + + "': " + + e.getMessage(), + e); + } + } + } + } + + return new ArrayList<>(byKey.values()); + } + + /** + * Resolve an install coordinate the same way users search with {@code marketplace query}. + * + *

+ */ + public static InstallTarget resolveInstall( + String spec, + String defaultGroupId, + String defaultVersion, + MarketplaceConfig config, + ILogChannel log) + throws HopException { + if (StringUtils.isBlank(spec)) { + throw new HopException("Plugin coordinate is empty"); + } + String trimmed = spec.trim(); + String[] parts = trimmed.split(":"); + if (parts.length > 3) { + throw new HopException( + "Invalid coordinate '" + + spec + + "'. Use artifactId, artifactId:version, or groupId:artifactId:version"); + } + if (parts.length == 3) { + return new InstallTarget(new MavenCoordinates(parts[0], parts[1], parts[2]), null); + } + + String token = parts[0]; + String userVersion = parts.length == 2 ? parts[1] : null; + + List matches = query(token, null, config, log); + OptionalPluginInfo chosen = pickInstallMatch(token, matches); + if (chosen == null) { + return new InstallTarget( + MavenCoordinates.parse(trimmed, defaultGroupId, defaultVersion), null); + } + + String groupId = + StringUtils.isNotBlank(chosen.getGroupId()) ? chosen.getGroupId() : defaultGroupId; + String artifactId = chosen.getArtifactId(); + String version; + if (StringUtils.isNotBlank(userVersion)) { + version = userVersion; + } else if (StringUtils.isNotBlank(chosen.getVersion())) { + version = chosen.getVersion(); + } else { + version = defaultVersion; + } + if (StringUtils.isBlank(version)) { + throw new HopException( + "No version for '" + + artifactId + + "'. Use artifactId:version or groupId:artifactId:version"); + } + + String preferredRepo = null; + if (StringUtils.isNotBlank(chosen.getSource()) + && !"apache".equalsIgnoreCase(chosen.getSource()) + && config != null + && config.findRepository(chosen.getSource()) != null) { + preferredRepo = chosen.getSource(); + } + + return new InstallTarget(new MavenCoordinates(groupId, artifactId, version), preferredRepo); + } + + /** + * Choose a single install target from discovery matches for {@code token} (artifact id or short + * name). Prefer exact artifact id, then unique artifact-id substring match, then unique overall + * match. Throws when multiple candidates remain. + */ + static OptionalPluginInfo pickInstallMatch(String token, List matches) + throws HopException { + if (matches == null || matches.isEmpty() || StringUtils.isBlank(token)) { + return null; + } + String needle = token.trim().toLowerCase(Locale.ROOT); + + List exactArtifact = new ArrayList<>(); + List artifactContains = new ArrayList<>(); + for (OptionalPluginInfo info : matches) { + if (info == null || StringUtils.isBlank(info.getArtifactId())) { + continue; + } + String aid = info.getArtifactId().toLowerCase(Locale.ROOT); + if (aid.equals(needle)) { + exactArtifact.add(info); + } else if (aid.contains(needle)) { + artifactContains.add(info); + } + } + + if (exactArtifact.size() == 1) { + return exactArtifact.get(0); + } + if (exactArtifact.size() > 1) { + // Same artifact from multiple sources/versions — prefer first (query order) + return exactArtifact.get(0); + } + if (artifactContains.size() == 1) { + return artifactContains.get(0); + } + if (artifactContains.size() > 1) { + throw ambiguous(token, artifactContains); + } + + // Description/name-only hits: allow only when unique + List withArtifact = + matches.stream() + .filter(i -> i != null && StringUtils.isNotBlank(i.getArtifactId())) + .collect(Collectors.toList()); + if (withArtifact.size() == 1) { + return withArtifact.get(0); + } + if (withArtifact.size() > 1) { + throw ambiguous(token, withArtifact); + } + return null; + } + + private static HopException ambiguous(String token, List candidates) { + String list = + candidates.stream() + .map( + i -> + " - " + + nullToEmpty(i.getGroupId()) + + ":" + + i.getArtifactId() + + ":" + + (StringUtils.isNotBlank(i.getVersion()) ? i.getVersion() : "?") + + (StringUtils.isNotBlank(i.getSource()) ? " [" + i.getSource() + "]" : "")) + .collect(Collectors.joining("\n")); + return new HopException( + "Ambiguous install target '" + + token + + "'. Matches:\n" + + list + + "\nUse a full artifactId or groupId:artifactId:version."); + } + + /** + * Live list for one repository: Nexus zip search (or catalog URL), enriched with any plugin + * metadata from the repository definition. + */ + public static List discoverRepoLive( + MarketplaceRepository repo, String filter, ILogChannel log) throws Exception { + if (repo == null) { + return List.of(); + } + + List live; + if (StringUtils.isNotBlank(repo.getCatalogUrl())) { + live = RemotePluginCatalog.load(repo); + live = RemotePluginCatalog.filter(live, repo, filter); + } else { + live = NexusRepositoryBrowser.browse(repo, filter, log); + } + + // If live listing failed empty but definition has explicit plugins, use those (not a cache — + // author-supplied list in the YAML). + if (live.isEmpty() && repo.getPlugins() != null && !repo.getPlugins().isEmpty()) { + return RemotePluginCatalog.filter(repo.getPlugins(), repo, filter); + } + + return enrichWithDefinitionMetadata(live, repo); + } + + /** + * Apply name/description/category/hop-range and optional version pin from definition plugins when + * artifact ids match (groupId optional on either side). + */ + static List enrichWithDefinitionMetadata( + List live, MarketplaceRepository repo) { + if (live == null + || live.isEmpty() + || repo.getPlugins() == null + || repo.getPlugins().isEmpty()) { + return live == null ? List.of() : live; + } + Map byGa = new LinkedHashMap<>(); + Map byArtifact = new LinkedHashMap<>(); + for (OptionalPluginInfo p : repo.getPlugins()) { + if (p == null || StringUtils.isBlank(p.getArtifactId())) { + continue; + } + byGa.putIfAbsent(artifactKey(p), p); + byArtifact.putIfAbsent(p.getArtifactId().toLowerCase(Locale.ROOT), p); + } + for (OptionalPluginInfo info : live) { + if (info == null || StringUtils.isBlank(info.getArtifactId())) { + continue; + } + OptionalPluginInfo m = byGa.get(artifactKey(info)); + if (m == null) { + m = byArtifact.get(info.getArtifactId().toLowerCase(Locale.ROOT)); + } + if (m == null) { + continue; + } + if (StringUtils.isNotBlank(m.getName()) + && (StringUtils.isBlank(info.getName()) || info.getName().equals(info.getArtifactId()))) { + info.setName(m.getName()); + } + if (StringUtils.isNotBlank(m.getDescription()) + && (StringUtils.isBlank(info.getDescription()) + || "auto-discovered".equals(info.getCategory()) + || looksLikeMavenPath(info.getDescription()))) { + if (!looksLikeMavenPath(m.getDescription())) { + info.setDescription(m.getDescription()); + } + } + // Prefer human category from YAML over Nexus auto-discovered + if (StringUtils.isNotBlank(m.getCategory()) + && (StringUtils.isBlank(info.getCategory()) + || "auto-discovered".equalsIgnoreCase(info.getCategory()) + || !"auto-discovered".equalsIgnoreCase(m.getCategory()))) { + if (!"auto-discovered".equalsIgnoreCase(m.getCategory()) + || StringUtils.isBlank(info.getCategory())) { + info.setCategory(m.getCategory()); + } + } + if (StringUtils.isNotBlank(m.getMinHopVersion())) { + info.setMinHopVersion(m.getMinHopVersion()); + } + if (StringUtils.isNotBlank(m.getMaxHopVersion())) { + info.setMaxHopVersion(m.getMaxHopVersion()); + } + // Optional pin of plugin artifact version from the shareable definition + if (StringUtils.isNotBlank(m.getVersion())) { + info.setVersion(m.getVersion()); + } + if (StringUtils.isBlank(info.getGroupId()) && StringUtils.isNotBlank(m.getGroupId())) { + info.setGroupId(m.getGroupId()); + } + } + return live; + } + + private static boolean looksLikeMavenPath(String s) { + return s != null && s.contains("/") && s.contains("."); + } + + static String artifactKey(OptionalPluginInfo info) { + String g = + StringUtils.isNotBlank(info.getGroupId()) + ? info.getGroupId().toLowerCase(Locale.ROOT) + : "org.apache.hop"; + return g + ":" + info.getArtifactId().toLowerCase(Locale.ROOT); + } + + private static String key(OptionalPluginInfo info) { + return nullToEmpty(info.getGroupId()) + + ":" + + nullToEmpty(info.getArtifactId()) + + ":" + + nullToEmpty(info.getVersion()) + + ":" + + nullToEmpty(info.getSource()); + } + + private static String nullToEmpty(String s) { + return s == null ? "" : s; + } + + /** + * Running Hop / marketplace default version — used for Apache optional plugin coordinates and + * minHopVersion checks. Mirrors {@code MarketplaceCommand.resolveDefaultVersion} without a + * circular dependency on the CLI class. + */ + static String resolveHopVersion(MarketplaceConfig config) { + if (config != null && StringUtils.isNotBlank(config.getDefaultVersion())) { + return config.getDefaultVersion(); + } + try { + String[] versions = new HopVersionProvider().getVersion(); + if (versions != null && versions.length > 0 && StringUtils.isNotBlank(versions[0])) { + return versions[0]; + } + } catch (Exception ignored) { + // fall through + } + return System.getProperty("hop.version", "2.19.0-SNAPSHOT"); + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/RemotePluginCatalog.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/RemotePluginCatalog.java new file mode 100644 index 00000000000..61dc658859c --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/RemotePluginCatalog.java @@ -0,0 +1,214 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.catalog; + +import java.io.InputStream; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import org.apache.commons.lang3.StringUtils; +import org.apache.hop.core.exception.HopException; +import org.apache.hop.core.json.HopJson; +import org.apache.hop.marketplace.config.MarketplaceRepository; +import org.yaml.snakeyaml.LoaderOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.SafeConstructor; + +/** Loads a remote or local hop-marketplace-catalog YAML/JSON. */ +public final class RemotePluginCatalog { + + private RemotePluginCatalog() {} + + public static List load(MarketplaceRepository repository) + throws HopException { + if (repository == null || StringUtils.isBlank(repository.getCatalogUrl())) { + return List.of(); + } + String url = repository.getCatalogUrl().trim(); + List plugins; + if (url.startsWith("http://") || url.startsWith("https://")) { + plugins = loadHttp(url); + } else { + plugins = loadFile(Path.of(url)); + } + String source = + StringUtils.isNotBlank(repository.getId()) ? repository.getId() : repository.displayName(); + for (OptionalPluginInfo p : plugins) { + if (p != null && StringUtils.isBlank(p.getSource())) { + p.setSource(source); + } + if (p != null && StringUtils.isBlank(p.getGroupId())) { + p.setGroupId("org.apache.hop"); + } + } + return filter(plugins, repository, null); + } + + public static List loadFile(Path file) throws HopException { + if (file == null || !Files.isRegularFile(file)) { + throw new HopException("Catalog file not found: " + file); + } + try (InputStream in = Files.newInputStream(file)) { + return parse(in, file.toString()); + } catch (Exception e) { + throw new HopException("Unable to read catalog: " + file, e); + } + } + + public static List loadHttp(String url) throws HopException { + try { + HttpClient client = + HttpClient.newBuilder() + .connectTimeout(Duration.ofSeconds(30)) + .followRedirects(HttpClient.Redirect.NORMAL) + .build(); + HttpRequest request = + HttpRequest.newBuilder(URI.create(url)).timeout(Duration.ofSeconds(60)).GET().build(); + HttpResponse response = + client.send(request, HttpResponse.BodyHandlers.ofInputStream()); + if (response.statusCode() < 200 || response.statusCode() >= 300) { + throw new HopException( + "Unable to download catalog from " + url + " (HTTP " + response.statusCode() + ")"); + } + try (InputStream in = response.body()) { + return parse(in, url); + } + } catch (HopException e) { + throw e; + } catch (Exception e) { + throw new HopException("Unable to download catalog from " + url, e); + } + } + + @SuppressWarnings("unchecked") + static List parse(InputStream in, String source) throws HopException { + try { + String lower = source == null ? "" : source.toLowerCase(Locale.ROOT); + Map root; + if (lower.endsWith(".json")) { + root = HopJson.newMapper().readValue(in, Map.class); + } else { + Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions())); + Object loaded = yaml.load(in); + if (!(loaded instanceof Map)) { + throw new HopException("Catalog root must be a mapping: " + source); + } + root = (Map) loaded; + } + Object pluginsNode = root.get("plugins"); + if (!(pluginsNode instanceof List list)) { + return List.of(); + } + List out = new ArrayList<>(); + for (Object item : list) { + if (!(item instanceof Map m)) { + continue; + } + OptionalPluginInfo info = new OptionalPluginInfo(); + info.setGroupId(str(m.get("groupId"))); + info.setArtifactId(str(m.get("artifactId"))); + info.setVersion(str(m.get("version"))); + info.setName(str(m.get("name"))); + info.setCategory(str(m.get("category"))); + info.setDescription(str(m.get("description"))); + info.setInstallPath(str(m.get("installPath"))); + info.setMinHopVersion(str(m.get("minHopVersion"))); + info.setMaxHopVersion(str(m.get("maxHopVersion"))); + info.setSource(str(m.get("source"))); + if (StringUtils.isNotBlank(info.getArtifactId())) { + out.add(info); + } + } + return out; + } catch (HopException e) { + throw e; + } catch (Exception e) { + throw new HopException("Unable to parse catalog: " + source, e); + } + } + + /** Apply repository filters and optional free-text filter. */ + public static List filter( + List plugins, MarketplaceRepository repository, String textFilter) { + if (plugins == null || plugins.isEmpty()) { + return List.of(); + } + String groupFilter = + repository != null ? StringUtils.trimToNull(repository.getGroupIdFilter()) : null; + boolean includeSnapshots = repository == null || repository.isIncludeSnapshots(); + String repoQuery = + repository != null ? StringUtils.trimToNull(repository.getSearchQuery()) : null; + String text = StringUtils.trimToNull(textFilter); + List out = new ArrayList<>(); + for (OptionalPluginInfo p : plugins) { + if (p == null || StringUtils.isBlank(p.getArtifactId())) { + continue; + } + if (groupFilter != null + && StringUtils.isNotBlank(p.getGroupId()) + && !groupFilter.equals(p.getGroupId())) { + continue; + } + if (!includeSnapshots + && p.getVersion() != null + && org.apache.hop.marketplace.resolve.SnapshotVersions.isSnapshot(p.getVersion())) { + continue; + } + if (repoQuery != null && !matchesText(p, repoQuery)) { + continue; + } + if (text != null && !matchesText(p, text)) { + continue; + } + out.add(p); + } + return out; + } + + static boolean matchesText(OptionalPluginInfo p, String needle) { + String n = needle.toLowerCase(Locale.ROOT); + return contains(p.getArtifactId(), n) + || contains(p.getName(), n) + || contains(p.getCategory(), n) + || contains(p.getDescription(), n) + || contains(p.getGroupId(), n) + || contains(p.getVersion(), n) + || contains(p.getInstallPath(), n) + || contains(p.getSource(), n); + } + + private static boolean contains(String value, String needleLower) { + return value != null && value.toLowerCase(Locale.ROOT).contains(needleLower); + } + + private static String str(Object o) { + if (o == null) { + return null; + } + String s = String.valueOf(o).trim(); + return s.isEmpty() ? null : s; + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/VersionCompat.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/VersionCompat.java new file mode 100644 index 00000000000..681fb3ec266 --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/catalog/VersionCompat.java @@ -0,0 +1,160 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.catalog; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.Locale; +import org.apache.commons.lang3.StringUtils; + +/** + * Hop / plugin version comparison and compatibility checks for marketplace discovery. + * + *

Lightweight Maven-like ordering: numeric segments, then qualifiers; {@code -SNAPSHOT} is + * treated as a pre-release of the same base version. + */ +public final class VersionCompat { + + private VersionCompat() {} + + /** + * Whether {@code info} may be offered on the given running Hop version. Blank min/max means no + * bound on that side. Missing hop version fails closed only when a bound is present. + */ + public static boolean isCompatibleWithHop(OptionalPluginInfo info, String hopVersion) { + if (info == null) { + return false; + } + String min = info.getMinHopVersion(); + String max = info.getMaxHopVersion(); + if (StringUtils.isBlank(min) && StringUtils.isBlank(max)) { + return true; + } + if (StringUtils.isBlank(hopVersion)) { + return false; + } + if (StringUtils.isNotBlank(min) && compare(hopVersion, min) < 0) { + return false; + } + if (StringUtils.isNotBlank(max) && compare(hopVersion, max) > 0) { + return false; + } + return true; + } + + /** + * @return negative if a < b, zero if equal, positive if a > b + */ + public static int compare(String a, String b) { + List pa = parse(a); + List pb = parse(b); + int n = Math.max(pa.size(), pb.size()); + for (int i = 0; i < n; i++) { + Object xa = i < pa.size() ? pa.get(i) : 0; + Object xb = i < pb.size() ? pb.get(i) : 0; + int c = comparePart(xa, xb); + if (c != 0) { + return c; + } + } + return 0; + } + + /** Highest version string in {@code versions}, or null if empty. */ + public static String latest(Collection versions) { + if (versions == null || versions.isEmpty()) { + return null; + } + return versions.stream() + .filter(StringUtils::isNotBlank) + .max(VersionCompat::compare) + .orElse(null); + } + + /** Comparator for plugin artifact versions (newest first). */ + public static Comparator newestFirst() { + return (a, b) -> compare(b, a); + } + + private static int comparePart(Object a, Object b) { + boolean aNum = a instanceof Integer; + boolean bNum = b instanceof Integer; + if (aNum && bNum) { + return Integer.compare((Integer) a, (Integer) b); + } + if (aNum) { + // numeric segment > qualifier (1.0 > 1.0-alpha) + return 1; + } + if (bNum) { + return -1; + } + String sa = String.valueOf(a).toLowerCase(Locale.ROOT); + String sb = String.valueOf(b).toLowerCase(Locale.ROOT); + // snapshot is older than release of same base when compared as qualifier after base + int rankA = qualifierRank(sa); + int rankB = qualifierRank(sb); + if (rankA != rankB) { + return Integer.compare(rankA, rankB); + } + return sa.compareTo(sb); + } + + private static int qualifierRank(String q) { + if ("snapshot".equals(q)) { + return -1; + } + if ("final".equals(q) || "ga".equals(q) || "release".equals(q) || q.isEmpty()) { + return 1; + } + return 0; + } + + static List parse(String version) { + List parts = new ArrayList<>(); + if (StringUtils.isBlank(version)) { + return parts; + } + String v = version.trim(); + // Split on . - and treat SNAPSHOT specially + StringBuilder buf = new StringBuilder(); + for (int i = 0; i <= v.length(); i++) { + char ch = i < v.length() ? v.charAt(i) : '.'; + if (ch == '.' || ch == '-' || i == v.length()) { + if (buf.length() > 0) { + String token = buf.toString(); + buf.setLength(0); + if (token.chars().allMatch(Character::isDigit)) { + try { + parts.add(Integer.parseInt(token)); + } catch (NumberFormatException e) { + parts.add(token.toLowerCase(Locale.ROOT)); + } + } else { + parts.add(token.toLowerCase(Locale.ROOT)); + } + } + } else { + buf.append(ch); + } + } + return parts; + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/CliTable.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/CliTable.java new file mode 100644 index 00000000000..4f0acd84490 --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/CliTable.java @@ -0,0 +1,169 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.command; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +/** Portable ASCII table and CSV printers for marketplace CLI output. */ +public final class CliTable { + + private CliTable() {} + + /** + * Print a bordered ASCII table. Column widths are the max of header and cell content (after + * optional truncation of individual cells by the caller). + */ + public static void printTable(PrintStream out, List headers, List> rows) { + if (headers == null || headers.isEmpty()) { + return; + } + int cols = headers.size(); + int[] widths = new int[cols]; + for (int c = 0; c < cols; c++) { + widths[c] = displayWidth(headers.get(c)); + } + if (rows != null) { + for (List row : rows) { + if (row == null) { + continue; + } + for (int c = 0; c < cols; c++) { + String cell = c < row.size() ? nullToEmpty(row.get(c)) : ""; + widths[c] = Math.max(widths[c], displayWidth(cell)); + } + } + } + + String separator = buildSeparator(widths); + out.println(separator); + out.println(buildRow(headers, widths)); + out.println(separator); + if (rows != null) { + for (List row : rows) { + if (row == null) { + continue; + } + List padded = new ArrayList<>(cols); + for (int c = 0; c < cols; c++) { + padded.add(c < row.size() ? nullToEmpty(row.get(c)) : ""); + } + out.println(buildRow(padded, widths)); + } + } + out.println(separator); + } + + /** Print CSV with a header row. Fields are quoted when needed (comma, quote, CR/LF). */ + public static void printCsv(PrintStream out, List headers, List> rows) { + if (headers == null || headers.isEmpty()) { + return; + } + out.println(toCsvLine(headers)); + if (rows == null) { + return; + } + int cols = headers.size(); + for (List row : rows) { + if (row == null) { + continue; + } + List cells = new ArrayList<>(cols); + for (int c = 0; c < cols; c++) { + cells.add(c < row.size() ? nullToEmpty(row.get(c)) : ""); + } + out.println(toCsvLine(cells)); + } + } + + static String toCsvLine(List fields) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < fields.size(); i++) { + if (i > 0) { + sb.append(','); + } + sb.append(escapeCsv(fields.get(i))); + } + return sb.toString(); + } + + static String escapeCsv(String value) { + String v = nullToEmpty(value); + boolean needsQuotes = + v.indexOf(',') >= 0 || v.indexOf('"') >= 0 || v.indexOf('\n') >= 0 || v.indexOf('\r') >= 0; + if (!needsQuotes) { + return v; + } + return '"' + v.replace("\"", "\"\"") + '"'; + } + + /** + * Truncate for display, appending {@code ...} when shortened. {@code maxLen} is the maximum + * output length including the ellipsis. + */ + public static String truncate(String value, int maxLen) { + String v = nullToEmpty(value).replace('\n', ' ').replace('\r', ' '); + if (maxLen <= 0 || v.length() <= maxLen) { + return v; + } + if (maxLen <= 3) { + return v.substring(0, maxLen); + } + return v.substring(0, maxLen - 3) + "..."; + } + + private static String buildSeparator(int[] widths) { + StringBuilder sb = new StringBuilder(); + sb.append('+'); + for (int w : widths) { + sb.append("-".repeat(w + 2)); + sb.append('+'); + } + return sb.toString(); + } + + private static String buildRow(List cells, int[] widths) { + StringBuilder sb = new StringBuilder(); + sb.append('|'); + for (int c = 0; c < widths.length; c++) { + String cell = c < cells.size() ? nullToEmpty(cells.get(c)) : ""; + sb.append(' '); + sb.append(padRight(cell, widths[c])); + sb.append(' '); + sb.append('|'); + } + return sb.toString(); + } + + private static String padRight(String s, int width) { + int pad = width - displayWidth(s); + if (pad <= 0) { + return s; + } + return s + " ".repeat(pad); + } + + private static int displayWidth(String s) { + return nullToEmpty(s).length(); + } + + private static String nullToEmpty(String s) { + return s == null ? "" : s; + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java index ab7bcce0443..0eaeca2ee2a 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/command/MarketplaceCommand.java @@ -20,6 +20,10 @@ import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import lombok.Getter; import lombok.Setter; @@ -27,6 +31,7 @@ import org.apache.hop.core.Const; import org.apache.hop.core.HopVersionProvider; import org.apache.hop.core.exception.HopException; +import org.apache.hop.core.json.HopJson; import org.apache.hop.core.logging.ILogChannel; import org.apache.hop.core.logging.LogChannel; import org.apache.hop.core.variables.IVariables; @@ -34,8 +39,10 @@ import org.apache.hop.hop.plugin.IHopCommand; import org.apache.hop.marketplace.catalog.OptionalPluginCatalog; import org.apache.hop.marketplace.catalog.OptionalPluginInfo; +import org.apache.hop.marketplace.catalog.PluginDiscovery; import org.apache.hop.marketplace.config.MarketplaceConfig; import org.apache.hop.marketplace.config.MarketplaceRepository; +import org.apache.hop.marketplace.config.MarketplaceRepositoryDefinition; import org.apache.hop.marketplace.env.EnvironmentApplier; import org.apache.hop.marketplace.env.EnvironmentDrift; import org.apache.hop.marketplace.env.HopEnvironmentLoader; @@ -125,19 +132,26 @@ void init(ILogChannel log, IVariables variables) { } } - @Command(name = "install", description = "Download and install a plugin zip by Maven coordinates") + @Command( + mixinStandardHelpOptions = true, + name = "install", + description = + "Download and install a plugin zip. Short names resolve via the same discovery as query" + + " (e.g. datavault → hop-datavault:0.4.0-SNAPSHOT from a browse repo).") static class InstallCommand extends MarketplaceSubCommand { @Parameters( index = "0", paramLabel = "COORDINATE", description = - "artifactId, artifactId:version, or groupId:artifactId:version (e.g. hop-tech-parquet)") + "Short name, artifactId, artifactId:version, or groupId:artifactId:version" + + " (e.g. datavault, hop-tech-parquet, hop-datavault:0.4.0-SNAPSHOT)") private String coordinate; @Option( names = {"--repo"}, description = - "Use only this repository id (skip fallback chain). Default: try primary then others.") + "Use only this repository id (skip fallback chain). Default: prefer discovery source," + + " then primary and other enabled repos.") private String repoId; @Override @@ -151,10 +165,25 @@ public void run() { // Activate any previously staged plugins first new PluginInstaller(log, hopHome, config).activateAllPending(); - MavenCoordinates gav = - MavenCoordinates.parse(coordinate, config.getGroupId(), resolveDefaultVersion(config)); + PluginDiscovery.InstallTarget target = + PluginDiscovery.resolveInstall( + coordinate, config.getGroupId(), resolveDefaultVersion(config), config, log); + MavenCoordinates gav = target.coordinates(); + if (StringUtils.isNotBlank(target.preferredRepoId()) && StringUtils.isBlank(repoId)) { + System.out.println( + "Resolved " + + coordinate + + " → " + + gav.gav() + + " (prefer repo '" + + target.preferredRepoId() + + "')"); + } else if (!coordinate.trim().equals(gav.artifactId()) || !coordinate.contains(":")) { + System.out.println("Resolved " + coordinate + " → " + gav.gav()); + } InstallReceipt receipt = - new PluginInstaller(log, hopHome, config).install(gav, true, repoId); + new PluginInstaller(log, hopHome, config) + .install(gav, true, repoId, target.preferredRepoId()); System.out.println( "Plugin " + gav.gav() @@ -176,6 +205,7 @@ public void run() { } @Command( + mixinStandardHelpOptions = true, name = "uninstall", description = "Remove a plugin previously installed via the marketplace") static class UninstallCommand extends MarketplaceSubCommand { @@ -196,7 +226,10 @@ public void run() { } } - @Command(name = "list", description = "List marketplace-installed plugins (receipts)") + @Command( + mixinStandardHelpOptions = true, + name = "list", + description = "List marketplace-installed plugins (receipts)") static class ListCommand extends MarketplaceSubCommand { @Override public void run() { @@ -212,8 +245,7 @@ public void run() { for (Path file : stream) { any = true; InstallReceipt receipt = - org.apache.hop.core.json.HopJson.newMapper() - .readValue(file.toFile(), InstallReceipt.class); + HopJson.newMapper().readValue(file.toFile(), InstallReceipt.class); System.out.printf( "%s %s:%s:%s%s%n", receipt.getArtifactId(), @@ -235,20 +267,40 @@ public void run() { } @Command( + mixinStandardHelpOptions = true, name = "query", description = - "Search the optional-plugin catalog (local registry). Filter is a case-insensitive" - + " substring over artifactId, name, category, description, and install path.") + "Search plugins: bundled Apache optional catalog plus every enabled repository with" + + " browse=true (live Nexus zip list). Filter is a case-insensitive substring." + + " Default output is an ASCII table; use --csv for machine-readable CSV.") static class QueryCommand extends MarketplaceSubCommand { + private static final int TABLE_DESCRIPTION_MAX = 56; + @Parameters( index = "0", arity = "0..1", paramLabel = "FILTER", description = - "Case-insensitive substring to match. Omit or use empty string to list all optional" - + " plugins.") + "Case-insensitive substring to match. Omit or use empty string to list matches.") private String filter; + @Option( + names = {"--repo"}, + description = + "Only include this repository id among browse-enabled remotes (Apache catalog still" + + " included).") + private String repoId; + + @Option( + names = {"--csv"}, + description = "Print results as CSV (header + rows) instead of an ASCII table") + private boolean csv; + + @Option( + names = {"--include-gav"}, + description = "Include a GAV (groupId:artifactId:version) column in the output") + private boolean includeGav; + @Override public void run() { try { @@ -258,27 +310,27 @@ public void run() { } catch (Exception ignored) { // installed status is optional } - java.util.List matches = OptionalPluginCatalog.query(filter); + MarketplaceConfig config = MarketplaceConfig.load(); + List matches = PluginDiscovery.query(filter, repoId, config, log); + + List headers = queryHeaders(includeGav); + List> rows = new ArrayList<>(); + for (OptionalPluginInfo info : matches) { + rows.add(queryRow(info, hopHome, includeGav, csv)); + } + + if (csv) { + // Always emit header so scripts get stable columns even when empty + CliTable.printCsv(System.out, headers, rows); + return; + } + if (matches.isEmpty()) { System.out.println( - "No optional plugins match filter: " - + (StringUtils.isBlank(filter) ? "(all)" : filter)); + "No plugins match filter: " + (StringUtils.isBlank(filter) ? "(all)" : filter)); return; } - for (OptionalPluginInfo info : matches) { - String installed = ""; - if (hopHome != null && OptionalPluginCatalog.isInstalledOnDisk(hopHome, info)) { - installed = " [installed]"; - } - System.out.printf( - "%-28s %-22s %-12s %s%s%n %s%n", - Const.NVL(info.getArtifactId(), ""), - Const.NVL(info.getName(), ""), - Const.NVL(info.getCategory(), ""), - Const.NVL(info.getInstallPath(), ""), - installed, - Const.NVL(info.getDescription(), "")); - } + CliTable.printTable(System.out, headers, rows); System.out.println(matches.size() + " plugin(s) matched."); } catch (Exception e) { System.err.println("ERROR: " + e.getMessage()); @@ -286,9 +338,54 @@ public void run() { new CommandLine(this), e.getMessage() == null ? "query failed" : e.getMessage(), e); } } + + static List queryHeaders(boolean includeGav) { + List headers = new ArrayList<>(); + headers.add("ARTIFACT"); + headers.add("VERSION"); + headers.add("CATEGORY"); + headers.add("SOURCE"); + if (includeGav) { + headers.add("GAV"); + } + headers.add("INSTALLED"); + headers.add("UPDATED"); + headers.add("DESCRIPTION"); + return headers; + } + + static List queryRow( + OptionalPluginInfo info, Path hopHome, boolean includeGav, boolean fullDescription) { + List row = new ArrayList<>(); + row.add(Const.NVL(info.getArtifactId(), "")); + row.add(Const.NVL(info.getVersion(), "")); + row.add(Const.NVL(info.getCategory(), "")); + row.add(Const.NVL(info.getSource(), "apache")); + if (includeGav) { + row.add(formatGav(info)); + } + boolean onDisk = hopHome != null && OptionalPluginCatalog.isInstalledOnDisk(hopHome, info); + row.add(onDisk ? "yes" : ""); + row.add(Const.NVL(info.getLastUpdated(), "")); + String description = Const.NVL(info.getDescription(), ""); + if (!fullDescription) { + description = CliTable.truncate(description, TABLE_DESCRIPTION_MAX); + } + row.add(description); + return row; + } + + static String formatGav(OptionalPluginInfo info) { + String group = + StringUtils.isNotBlank(info.getGroupId()) ? info.getGroupId() : "org.apache.hop"; + String artifact = Const.NVL(info.getArtifactId(), ""); + String version = StringUtils.isNotBlank(info.getVersion()) ? info.getVersion() : "?"; + return group + ":" + artifact + ":" + version; + } } @Command( + mixinStandardHelpOptions = true, name = "apply", description = "Install plugins and dependencies declared in hop-env.yaml (or .json). Optional --prune" @@ -333,6 +430,7 @@ public void run() { } @Command( + mixinStandardHelpOptions = true, name = "validate", description = "Check the local install against hop-env.yaml without installing. Exit code 1 on drift.") @@ -390,7 +488,7 @@ public void run() { private static void addExtraPlugins( Path hopHome, HopEnvironmentSpec env, EnvironmentDrift drift) throws Exception { - java.util.Set desired = new java.util.HashSet<>(); + Set desired = new HashSet<>(); if (env.getPlugins() != null) { for (HopEnvironmentSpec.PluginRef ref : env.getPlugins()) { if (ref.getArtifactId() != null) { @@ -415,6 +513,7 @@ private static void addExtraPlugins( } @Command( + mixinStandardHelpOptions = true, name = "repo", description = "Manage marketplace Maven repositories in hop-config.json", subcommands = { @@ -424,7 +523,9 @@ private static void addExtraPlugins( MarketplaceCommand.RepoSetPrimaryCommand.class, MarketplaceCommand.RepoEnableCommand.class, MarketplaceCommand.RepoDisableCommand.class, - MarketplaceCommand.RepoResetDefaultsCommand.class + MarketplaceCommand.RepoResetDefaultsCommand.class, + MarketplaceCommand.RepoExportCommand.class, + MarketplaceCommand.RepoImportCommand.class }) static class RepoCommand extends MarketplaceSubCommand { @Override @@ -434,23 +535,31 @@ public void run() { } } - @Command(name = "list", description = "List configured marketplace repositories") + @Command( + mixinStandardHelpOptions = true, + name = "list", + description = "List configured marketplace repositories") static class RepoListCommand extends MarketplaceSubCommand { @Override public void run() { MarketplaceConfig config = MarketplaceConfig.load(); - System.out.printf("%-8s %-10s %-12s %-20s %s%n", "PRIMARY", "ENABLED", "ID", "NAME", "URL"); + System.out.printf( + "%-8s %-10s %-8s %-14s %-20s %s%n", "PRIMARY", "ENABLED", "BROWSE", "ID", "NAME", "URL"); for (MarketplaceRepository repo : config.getRepositories()) { if (repo == null) { continue; } System.out.printf( - "%-8s %-10s %-12s %-20s %s%n", + "%-8s %-10s %-8s %-14s %-20s %s%n", repo.isPrimary() ? "*" : "", repo.isEnabled() ? "yes" : "no", + repo.isBrowse() ? "yes" : "no", Const.NVL(repo.getId(), ""), Const.NVL(repo.displayName(), ""), repo.normalizedUrl()); + if (StringUtils.isNotBlank(repo.getCatalogUrl())) { + System.out.println(" catalog: " + repo.getCatalogUrl()); + } } System.out.println(); System.out.println( @@ -461,7 +570,10 @@ public void run() { } } - @Command(name = "add", description = "Add a marketplace repository and save hop-config.json") + @Command( + mixinStandardHelpOptions = true, + name = "add", + description = "Add a marketplace repository and save hop-config.json") static class RepoAddCommand extends MarketplaceSubCommand { @Option( names = {"--id"}, @@ -495,6 +607,31 @@ static class RepoAddCommand extends MarketplaceSubCommand { description = "Optional Basic auth password (prefer env HOP_MARKETPLACE_PASSWORD)") private String password; + @Option( + names = {"--browse"}, + description = "Include this repository in marketplace query/GUI discovery") + private boolean browse; + + @Option( + names = {"--catalog-url"}, + description = "Optional hop-marketplace-catalog.yaml URL for discovery") + private String catalogUrl; + + @Option( + names = {"--search-query"}, + description = "Optional discovery filter for this repository") + private String searchQuery; + + @Option( + names = {"--group-id-filter"}, + description = "Optional Maven groupId filter for discovery") + private String groupIdFilter; + + @Option( + names = {"--no-snapshots"}, + description = "Hide SNAPSHOT versions in discovery for this repository") + private boolean noSnapshots; + @Override public void run() { try { @@ -503,6 +640,11 @@ public void run() { new MarketplaceRepository(id, StringUtils.isNotBlank(name) ? name : id, url, primary); repo.setUsername(username); repo.setPassword(password); + repo.setBrowse(browse); + repo.setCatalogUrl(catalogUrl); + repo.setSearchQuery(searchQuery); + repo.setGroupIdFilter(groupIdFilter); + repo.setIncludeSnapshots(!noSnapshots); config.addRepository(repo); config.save(); System.out.println( @@ -510,6 +652,7 @@ public void run() { + id + "'" + (primary ? " (primary)" : "") + + (browse ? " (browse)" : "") + " → " + repo.normalizedUrl()); } catch (Exception e) { @@ -520,7 +663,90 @@ public void run() { } } - @Command(name = "remove", description = "Remove a marketplace repository by id") + @Command( + mixinStandardHelpOptions = true, + name = "export", + description = + "Export a repository definition YAML/JSON (shareable; passwords omitted). For company" + + " marketplace onboarding.") + static class RepoExportCommand extends MarketplaceSubCommand { + @Parameters(index = "0", paramLabel = "ID", description = "Configured repository id") + private String id; + + @Option( + names = {"-o", "--output"}, + required = true, + description = "Output file (.yaml / .yml / .json)") + private String output; + + @Override + public void run() { + try { + MarketplaceConfig config = MarketplaceConfig.load(); + MarketplaceRepository repo = config.findRepository(id); + if (repo == null) { + throw new HopException("Unknown repository id: " + id); + } + Path out = Path.of(output); + MarketplaceRepositoryDefinition.save(out, repo); + System.out.println("Wrote repository definition: " + out.toAbsolutePath().normalize()); + } catch (Exception e) { + System.err.println("ERROR: " + e.getMessage()); + throw new CommandLine.ExecutionException( + new CommandLine(this), + e.getMessage() == null ? "repo export failed" : e.getMessage(), + e); + } + } + } + + @Command( + mixinStandardHelpOptions = true, + name = "import", + description = + "Import a hop-marketplace-repo.yaml (or URL) into hop-config.json. Upserts by repository" + + " id.") + static class RepoImportCommand extends MarketplaceSubCommand { + @Parameters( + index = "0", + paramLabel = "FILE_OR_URL", + description = "Path or https URL to hop-marketplace-repo.yaml") + private String fileOrUrl; + + @Option( + names = {"--primary"}, + description = "Make the imported repository primary") + private boolean primary; + + @Override + public void run() { + try { + MarketplaceRepository imported = MarketplaceRepositoryDefinition.loadFromUri(fileOrUrl); + MarketplaceConfig config = MarketplaceConfig.load(); + boolean existed = config.findRepository(imported.getId()) != null; + MarketplaceRepositoryDefinition.applyToConfig(config, imported, primary); + config.save(); + System.out.println( + (existed ? "Updated" : "Imported") + + " repository '" + + imported.getId() + + "' → " + + imported.normalizedUrl() + + (imported.isBrowse() ? " (browse enabled)" : "")); + } catch (Exception e) { + System.err.println("ERROR: " + e.getMessage()); + throw new CommandLine.ExecutionException( + new CommandLine(this), + e.getMessage() == null ? "repo import failed" : e.getMessage(), + e); + } + } + } + + @Command( + mixinStandardHelpOptions = true, + name = "remove", + description = "Remove a marketplace repository by id") static class RepoRemoveCommand extends MarketplaceSubCommand { @Parameters(index = "0", paramLabel = "ID", description = "Repository id") private String id; @@ -542,7 +768,10 @@ public void run() { } } - @Command(name = "set-primary", description = "Set the primary marketplace repository") + @Command( + mixinStandardHelpOptions = true, + name = "set-primary", + description = "Set the primary marketplace repository") static class RepoSetPrimaryCommand extends MarketplaceSubCommand { @Parameters(index = "0", paramLabel = "ID", description = "Repository id") private String id; @@ -564,7 +793,10 @@ public void run() { } } - @Command(name = "enable", description = "Enable a repository in the fallback chain") + @Command( + mixinStandardHelpOptions = true, + name = "enable", + description = "Enable a repository in the fallback chain") static class RepoEnableCommand extends MarketplaceSubCommand { @Parameters(index = "0", paramLabel = "ID") private String id; @@ -586,7 +818,10 @@ public void run() { } } - @Command(name = "disable", description = "Disable a repository (skip in fallback chain)") + @Command( + mixinStandardHelpOptions = true, + name = "disable", + description = "Disable a repository (skip in fallback chain)") static class RepoDisableCommand extends MarketplaceSubCommand { @Parameters(index = "0", paramLabel = "ID") private String id; @@ -609,6 +844,7 @@ public void run() { } @Command( + mixinStandardHelpOptions = true, name = "reset-defaults", description = "Reset repositories to ASF primary + Maven Central fallback") static class RepoResetDefaultsCommand extends MarketplaceSubCommand { diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java index 1d2925c1303..d97964f426f 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceConfig.java @@ -60,8 +60,6 @@ public class MarketplaceConfig { private boolean enabled = true; private String groupId = DEFAULT_GROUP_ID; private String defaultVersion; - private String searchApiUrl = "https://search.maven.org/solrsearch/select"; - private int cacheTtlHours = 24; private List repositories = new ArrayList<>(); public MarketplaceConfig() { diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java index fcd8bb8e791..648b92f8739 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepository.java @@ -17,9 +17,12 @@ package org.apache.hop.marketplace.config; +import java.util.ArrayList; +import java.util.List; import lombok.Getter; import lombok.Setter; import org.apache.commons.lang3.StringUtils; +import org.apache.hop.marketplace.catalog.OptionalPluginInfo; @Getter @Setter @@ -44,6 +47,44 @@ public class MarketplaceRepository { */ private String password; + /** + * When true, include this repository in {@code marketplace query} and the GUI Plugins tab (live + * Nexus zip list, or {@link #catalogUrl} if set). Default false so ASF/Central stay install-only + * endpoints. + */ + private boolean browse; + + /** + * Optional remote catalog index URL (YAML/JSON). Advanced only — prefer live Nexus zip listing + * when {@link #browse} is true. + */ + private String catalogUrl; + + /** + * Optional plugin metadata from a shareable repository definition (import/export). Used to enrich + * live discovery results (names, categories, descriptions) or as a fallback list if live browse + * returns nothing. Not a discovery cache — listing always prefers a live Nexus/catalog fetch. + */ + private List plugins = new ArrayList<>(); + + /** + * Optional search/filter string applied when browsing this repository (substring over GAV / + * catalog fields). Empty means no extra filter beyond {@link #groupIdFilter}. + */ + private String searchQuery; + + /** When false, SNAPSHOT versions are hidden from discovery results. Default true. */ + private boolean includeSnapshots = true; + + /** Optional Maven groupId restriction for discovery (e.g. {@code com.acme.hop}). */ + private String groupIdFilter; + + /** Optional human homepage for this marketplace (documentation only). */ + private String homepage; + + /** Optional human description (documentation / export). */ + private String description; + public MarketplaceRepository() { // Jackson } diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepositoryDefinition.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepositoryDefinition.java new file mode 100644 index 00000000000..625f923f0e4 --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/config/MarketplaceRepositoryDefinition.java @@ -0,0 +1,374 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.config; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Writer; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Duration; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import org.apache.commons.lang3.StringUtils; +import org.apache.hop.core.exception.HopException; +import org.apache.hop.core.json.HopJson; +import org.apache.hop.marketplace.catalog.OptionalPluginInfo; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.LoaderOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.SafeConstructor; + +/** + * Shareable Hop marketplace repository definition ({@code hop-marketplace-repo.yaml}). Passwords + * are never written on export. + */ +public final class MarketplaceRepositoryDefinition { + + public static final String KIND = "hop-marketplace-repository"; + public static final String SCHEMA_VERSION = "1.0"; + + private MarketplaceRepositoryDefinition() {} + + public static MarketplaceRepository load(Path file) throws HopException { + if (file == null || !Files.isRegularFile(file)) { + throw new HopException("Repository definition not found: " + file); + } + try (InputStream in = Files.newInputStream(file)) { + return parse(in, file.toString()); + } catch (IOException e) { + throw new HopException("Unable to read repository definition: " + file, e); + } + } + + public static MarketplaceRepository loadFromUri(String uriOrPath) throws HopException { + if (StringUtils.isBlank(uriOrPath)) { + throw new HopException("Repository definition path or URL is required"); + } + String s = uriOrPath.trim(); + if (s.startsWith("http://") || s.startsWith("https://")) { + return loadFromHttp(s); + } + return load(Path.of(s)); + } + + public static MarketplaceRepository loadFromHttp(String url) throws HopException { + try { + HttpClient client = + HttpClient.newBuilder() + .connectTimeout(Duration.ofSeconds(30)) + .followRedirects(HttpClient.Redirect.NORMAL) + .build(); + HttpRequest request = + HttpRequest.newBuilder(URI.create(url)).timeout(Duration.ofSeconds(60)).GET().build(); + HttpResponse response = + client.send(request, HttpResponse.BodyHandlers.ofInputStream()); + if (response.statusCode() < 200 || response.statusCode() >= 300) { + throw new HopException( + "Unable to download repository definition from " + + url + + " (HTTP " + + response.statusCode() + + ")"); + } + try (InputStream in = response.body()) { + return parse(in, url); + } + } catch (HopException e) { + throw e; + } catch (Exception e) { + throw new HopException("Unable to download repository definition from " + url, e); + } + } + + static MarketplaceRepository parse(InputStream in, String source) throws HopException { + try { + String name = source == null ? "" : source.toLowerCase(Locale.ROOT); + if (name.endsWith(".json")) { + Map map = HopJson.newMapper().readValue(in, Map.class); + return fromMap(map); + } + Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions())); + Object loaded = yaml.load(in); + if (!(loaded instanceof Map)) { + throw new HopException("Repository definition root must be a mapping: " + source); + } + return fromMap((Map) loaded); + } catch (HopException e) { + throw e; + } catch (Exception e) { + throw new HopException("Unable to parse repository definition: " + source, e); + } + } + + static MarketplaceRepository fromMap(Map map) throws HopException { + if (map == null) { + throw new HopException("Empty repository definition"); + } + Object kind = map.get("kind"); + if (kind != null && !KIND.equals(String.valueOf(kind).trim())) { + // allow missing kind for brevity + if (StringUtils.isNotBlank(String.valueOf(kind)) + && !String.valueOf(kind).contains("marketplace")) { + throw new HopException( + "Unexpected kind '" + kind + "' (expected " + KIND + " or omit kind)"); + } + } + MarketplaceRepository repo = new MarketplaceRepository(); + repo.setId(stringVal(map.get("id"))); + repo.setName(stringVal(map.get("name"))); + repo.setUrl(stringVal(map.get("url"))); + if (StringUtils.isBlank(repo.getId()) || StringUtils.isBlank(repo.getUrl())) { + throw new HopException("Repository definition requires id and url"); + } + if (StringUtils.isBlank(repo.getName())) { + repo.setName(repo.getId()); + } + repo.setPrimary(boolVal(map.get("primary"), false)); + repo.setEnabled(boolVal(map.get("enabled"), true)); + repo.setUsername(stringVal(map.get("username"))); + // password intentionally ignored on import unless present (discouraged) + String password = stringVal(map.get("password")); + if (StringUtils.isNotBlank(password)) { + repo.setPassword(password); + } + repo.setBrowse(boolVal(map.get("browse"), false)); + repo.setCatalogUrl(stringVal(map.get("catalogUrl"))); + repo.setSearchQuery(stringVal(map.get("searchQuery"))); + repo.setIncludeSnapshots(boolVal(map.get("includeSnapshots"), true)); + repo.setGroupIdFilter(stringVal(map.get("groupIdFilter"))); + repo.setHomepage(stringVal(map.get("homepage"))); + repo.setDescription(stringVal(map.get("description"))); + repo.setPlugins(parsePlugins(map.get("plugins"), repo.getId())); + return repo; + } + + static List parsePlugins(Object pluginsNode, String defaultSource) { + List out = new ArrayList<>(); + if (!(pluginsNode instanceof List list)) { + return out; + } + for (Object item : list) { + if (!(item instanceof Map m)) { + continue; + } + OptionalPluginInfo info = new OptionalPluginInfo(); + info.setGroupId(stringVal(m.get("groupId"))); + info.setArtifactId(stringVal(m.get("artifactId"))); + info.setVersion(stringVal(m.get("version"))); + info.setName(stringVal(m.get("name"))); + info.setCategory(stringVal(m.get("category"))); + info.setDescription(stringVal(m.get("description"))); + info.setInstallPath(stringVal(m.get("installPath"))); + info.setLastUpdated(stringVal(m.get("lastUpdated"))); + info.setMinHopVersion(stringVal(m.get("minHopVersion"))); + info.setMaxHopVersion(stringVal(m.get("maxHopVersion"))); + info.setSource(stringVal(m.get("source"))); + if (StringUtils.isBlank(info.getSource())) { + info.setSource(defaultSource); + } + if (StringUtils.isBlank(info.getCategory())) { + info.setCategory("auto-discovered"); + } + if (StringUtils.isBlank(info.getName())) { + info.setName(info.getArtifactId()); + } + if (StringUtils.isNotBlank(info.getArtifactId())) { + out.add(info); + } + } + return out; + } + + public static void save(Path file, MarketplaceRepository repo) throws HopException { + if (file == null) { + throw new HopException("Output path is required"); + } + if (repo == null) { + throw new HopException("Repository is required"); + } + try { + Path parent = file.getParent(); + if (parent != null) { + Files.createDirectories(parent); + } + Map map = toYamlMap(repo, false); + String name = file.getFileName().toString().toLowerCase(Locale.ROOT); + if (name.endsWith(".json")) { + HopJson.newMapper().writerWithDefaultPrettyPrinter().writeValue(file.toFile(), map); + return; + } + DumperOptions options = new DumperOptions(); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + options.setPrettyFlow(true); + options.setIndent(2); + Yaml yaml = new Yaml(options); + try (Writer writer = Files.newBufferedWriter(file, StandardCharsets.UTF_8)) { + writer.write("# Hop marketplace repository definition (shareable; no passwords)\n"); + yaml.dump(map, writer); + } + } catch (IOException e) { + throw new HopException("Unable to write repository definition: " + file, e); + } + } + + /** Map for export; passwords omitted unless {@code includePassword} is true. */ + public static Map toYamlMap(MarketplaceRepository repo, boolean includePassword) { + Map root = new LinkedHashMap<>(); + root.put("schemaVersion", SCHEMA_VERSION); + root.put("kind", KIND); + root.put("id", repo.getId()); + if (StringUtils.isNotBlank(repo.getName())) { + root.put("name", repo.getName()); + } + root.put("url", repo.getUrl()); + root.put("primary", repo.isPrimary()); + root.put("enabled", repo.isEnabled()); + if (StringUtils.isNotBlank(repo.getUsername())) { + root.put("username", repo.getUsername()); + } + if (includePassword && StringUtils.isNotBlank(repo.getPassword())) { + root.put("password", repo.getPassword()); + } + root.put("browse", repo.isBrowse()); + if (StringUtils.isNotBlank(repo.getCatalogUrl())) { + root.put("catalogUrl", repo.getCatalogUrl()); + } + if (StringUtils.isNotBlank(repo.getSearchQuery())) { + root.put("searchQuery", repo.getSearchQuery()); + } + root.put("includeSnapshots", repo.isIncludeSnapshots()); + if (StringUtils.isNotBlank(repo.getGroupIdFilter())) { + root.put("groupIdFilter", repo.getGroupIdFilter()); + } + if (StringUtils.isNotBlank(repo.getHomepage())) { + root.put("homepage", repo.getHomepage()); + } + if (StringUtils.isNotBlank(repo.getDescription())) { + root.put("description", repo.getDescription()); + } + if (repo.getPlugins() != null && !repo.getPlugins().isEmpty()) { + List> plugins = new ArrayList<>(); + for (OptionalPluginInfo p : repo.getPlugins()) { + if (p == null || StringUtils.isBlank(p.getArtifactId())) { + continue; + } + Map m = new LinkedHashMap<>(); + if (StringUtils.isNotBlank(p.getGroupId())) { + m.put("groupId", p.getGroupId()); + } + m.put("artifactId", p.getArtifactId()); + if (StringUtils.isNotBlank(p.getVersion())) { + m.put("version", p.getVersion()); + } + if (StringUtils.isNotBlank(p.getName())) { + m.put("name", p.getName()); + } + if (StringUtils.isNotBlank(p.getCategory())) { + m.put("category", p.getCategory()); + } + if (StringUtils.isNotBlank(p.getDescription())) { + m.put("description", p.getDescription()); + } + if (StringUtils.isNotBlank(p.getLastUpdated())) { + m.put("lastUpdated", p.getLastUpdated()); + } + if (StringUtils.isNotBlank(p.getInstallPath())) { + m.put("installPath", p.getInstallPath()); + } + if (StringUtils.isNotBlank(p.getMinHopVersion())) { + m.put("minHopVersion", p.getMinHopVersion()); + } + if (StringUtils.isNotBlank(p.getMaxHopVersion())) { + m.put("maxHopVersion", p.getMaxHopVersion()); + } + plugins.add(m); + } + if (!plugins.isEmpty()) { + root.put("plugins", plugins); + } + } + return root; + } + + public static void applyToConfig( + MarketplaceConfig config, MarketplaceRepository imported, boolean makePrimary) + throws HopException { + if (config == null || imported == null) { + throw new HopException("Config and repository are required"); + } + if (makePrimary) { + imported.setPrimary(true); + } + MarketplaceRepository existing = config.findRepository(imported.getId()); + if (existing == null) { + config.addRepository(imported); + } else { + // Upsert discovery + connection fields; keep password if import omitted it + existing.setName(imported.getName()); + existing.setUrl(imported.getUrl()); + existing.setEnabled(imported.isEnabled()); + if (imported.isPrimary() || makePrimary) { + config.setPrimary(existing.getId()); + } + if (StringUtils.isNotBlank(imported.getUsername())) { + existing.setUsername(imported.getUsername()); + } + if (StringUtils.isNotBlank(imported.getPassword())) { + existing.setPassword(imported.getPassword()); + } + existing.setBrowse(imported.isBrowse()); + existing.setCatalogUrl(imported.getCatalogUrl()); + existing.setSearchQuery(imported.getSearchQuery()); + existing.setIncludeSnapshots(imported.isIncludeSnapshots()); + existing.setGroupIdFilter(imported.getGroupIdFilter()); + existing.setHomepage(imported.getHomepage()); + existing.setDescription(imported.getDescription()); + if (imported.getPlugins() != null) { + existing.setPlugins(new ArrayList<>(imported.getPlugins())); + } + config.ensureValidPrimary(); + } + } + + private static String stringVal(Object o) { + if (o == null) { + return null; + } + String s = String.valueOf(o).trim(); + return s.isEmpty() ? null : s; + } + + private static boolean boolVal(Object o, boolean defaultValue) { + if (o == null) { + return defaultValue; + } + if (o instanceof Boolean b) { + return b; + } + return Boolean.parseBoolean(String.valueOf(o).trim()); + } +} diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java index 1f9effde7e4..2da895b9704 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceDialog.java @@ -28,8 +28,10 @@ import org.apache.hop.i18n.BaseMessages; import org.apache.hop.marketplace.catalog.OptionalPluginCatalog; import org.apache.hop.marketplace.catalog.OptionalPluginInfo; +import org.apache.hop.marketplace.catalog.PluginDiscovery; import org.apache.hop.marketplace.command.MarketplaceCommand; import org.apache.hop.marketplace.config.MarketplaceConfig; +import org.apache.hop.marketplace.config.MarketplaceRepository; import org.apache.hop.marketplace.env.EnvironmentApplier; import org.apache.hop.marketplace.install.HopHome; import org.apache.hop.marketplace.install.InstallReceipt; @@ -47,6 +49,9 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.events.ShellAdapter; +import org.eclipse.swt.events.ShellEvent; +import org.eclipse.swt.graphics.Cursor; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; @@ -73,7 +78,7 @@ public class MarketplaceDialog extends Dialog { private Label wStatus; private Path hopHome; private MarketplaceConfig config; - private boolean tableOptimized; + private MarketplaceRepositoriesPanel repositoriesPanel; public MarketplaceDialog(Shell parent) { super(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX); @@ -107,7 +112,8 @@ public void open() { // Shell-level Close only; Install/Uninstall/Refresh live on the Plugins tab. Button wClose = new Button(shell, SWT.PUSH); wClose.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.Close")); - wClose.addListener(SWT.Selection, e -> close()); + // shell.close() → ShellAdapter.shellClosed (single dirty check for button and window X) + wClose.addListener(SWT.Selection, e -> shell.close()); BaseTransformDialog.positionBottomButtons( shell, new Button[] {wClose}, PropsUi.getMargin(), null); @@ -131,11 +137,24 @@ public void open() { wTabFolder.setLayoutData(fdTabs); createPluginsTab(wTabFolder); - createEnvironmentTab(wTabFolder); createRepositoriesTab(wTabFolder); + createEnvironmentTab(wTabFolder); wTabFolder.setSelection(0); - refreshTable(); + shell.addShellListener( + new ShellAdapter() { + @Override + public void shellClosed(ShellEvent e) { + // X / Alt+F4 — same dirty prompt as Close button + if (!confirmClose()) { + e.doit = false; + } else { + props.setScreen(new WindowProperty(shell)); + } + } + }); + + refreshTable(false); BaseTransformDialog.setSize(shell); shell.open(); @@ -169,7 +188,7 @@ private void createPluginsTab(CTabFolder folder) { Button wRefresh = new Button(comp, SWT.PUSH); wRefresh.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Button.Refresh")); - wRefresh.addListener(SWT.Selection, e -> refreshTable()); + wRefresh.addListener(SWT.Selection, e -> refreshTable(true)); BaseTransformDialog.positionBottomButtons( comp, new Button[] {wInstall, wUninstall, wRefresh}, PropsUi.getMargin(), null); @@ -200,7 +219,7 @@ private void createPluginsTab(CTabFolder folder) { fdSearch.top = new FormAttachment(wlSearch, 0, SWT.CENTER); fdSearch.right = new FormAttachment(wClearSearch, -PropsUi.getMargin()); wSearch.setLayoutData(fdSearch); - wSearch.addListener(SWT.Modify, e -> refreshTable()); + wSearch.addListener(SWT.Modify, e -> refreshTable(false)); Label wSearchSep = new Label(comp, SWT.HORIZONTAL | SWT.SEPARATOR); FormData fdSearchSep = new FormData(); @@ -215,6 +234,11 @@ private void createPluginsTab(CTabFolder folder) { ColumnInfo.COLUMN_TYPE_TEXT, false, true), + new ColumnInfo( + BaseMessages.getString(PKG, "MarketplaceDialog.Column.Version"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), new ColumnInfo( BaseMessages.getString(PKG, "MarketplaceDialog.Column.Artifact"), ColumnInfo.COLUMN_TYPE_TEXT, @@ -225,6 +249,11 @@ private void createPluginsTab(CTabFolder folder) { ColumnInfo.COLUMN_TYPE_TEXT, false, true), + new ColumnInfo( + BaseMessages.getString(PKG, "MarketplaceDialog.Column.Repository"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), new ColumnInfo( BaseMessages.getString(PKG, "MarketplaceDialog.Column.Status"), ColumnInfo.COLUMN_TYPE_TEXT, @@ -311,7 +340,7 @@ private void createRepositoriesTab(CTabFolder folder) { tab.setControl(comp); // Full repository management UI (formerly a nested ManageRepositoriesDialog) - new MarketplaceRepositoriesPanel(comp, config); + repositoriesPanel = new MarketplaceRepositoriesPanel(comp, config); } private void clearSearch() { @@ -321,49 +350,132 @@ private void clearSearch() { } } - private void refreshTable() { - wTable.table.removeAll(); - // Filter only when more than 2 characters are typed (same as explorer/metadata search). - String searchText = wSearch != null ? wSearch.getText() : ""; - List plugins = - searchText != null && searchText.trim().length() > 2 - ? OptionalPluginCatalog.query(searchText) - : OptionalPluginCatalog.listWave1(); - for (OptionalPluginInfo info : plugins) { - // Column 0 is the (hidden) index column; data columns are 1-based. - TableItem item = new TableItem(wTable.table, SWT.NONE); - item.setText(1, Const.NVL(info.getName(), "")); - item.setText(2, Const.NVL(info.getArtifactId(), "")); - item.setText(3, Const.NVL(info.getCategory(), "")); - boolean onDisk = OptionalPluginCatalog.isInstalledOnDisk(hopHome, info); - InstallReceipt receipt = null; - try { - receipt = PluginInstaller.readReceipt(hopHome, info.getArtifactId()); - } catch (Exception e) { - log.logError("Unable to read receipt for " + info.getArtifactId(), e); + /** + * Reload the plugins list. + * + * @param userRefresh when true (Refresh button), prompt to save dirty repositories and show a + * wait cursor; search filter updates pass false. + */ + private void refreshTable(boolean userRefresh) { + if (userRefresh && !ensureRepositoriesSavedForRefresh()) { + return; + } + + Cursor waitCursor = null; + if (userRefresh && shell != null && !shell.isDisposed()) { + waitCursor = shell.getDisplay().getSystemCursor(SWT.CURSOR_WAIT); + shell.setCursor(waitCursor); + } + try { + // Keep shared in-memory config (after optional save/discard). Do not reload from disk on + // every search keystroke — that would drop unsaved repository edits. + if (repositoriesPanel != null) { + config = repositoriesPanel.getConfig(); } - String status; - if (onDisk && receipt != null) { - status = - BaseMessages.getString(PKG, "MarketplaceDialog.Status.Installed") - + " (" - + receipt.getVersion() - + ")"; - } else if (onDisk) { - status = BaseMessages.getString(PKG, "MarketplaceDialog.Status.Present"); - } else { - status = BaseMessages.getString(PKG, "MarketplaceDialog.Status.NotInstalled"); + wTable.table.removeAll(); + // Filter only when more than 2 characters are typed (same as explorer/metadata search). + String searchText = wSearch != null ? wSearch.getText() : ""; + String filter = + searchText != null && searchText.trim().length() > 2 ? searchText.trim() : null; + // Apache optional catalog + live list from every browse=true repository + List plugins = PluginDiscovery.query(filter, null, config, log); + for (OptionalPluginInfo info : plugins) { + // Column 0 is the (hidden) index column; data columns are 1-based. + TableItem item = new TableItem(wTable.table, SWT.NONE); + String name = Const.NVL(info.getName(), info.getArtifactId()); + item.setText(1, Const.NVL(name, "")); + item.setText(2, Const.NVL(info.getVersion(), "")); + item.setText(3, Const.NVL(info.getArtifactId(), "")); + item.setText(4, Const.NVL(info.getCategory(), "")); + item.setText(5, repositoryDisplayName(info.getSource())); + boolean onDisk = OptionalPluginCatalog.isInstalledOnDisk(hopHome, info); + InstallReceipt receipt = null; + try { + receipt = PluginInstaller.readReceipt(hopHome, info.getArtifactId()); + } catch (Exception e) { + log.logError("Unable to read receipt for " + info.getArtifactId(), e); + } + String status; + if (onDisk && receipt != null) { + status = + BaseMessages.getString(PKG, "MarketplaceDialog.Status.Installed") + + " (" + + receipt.getVersion() + + ")"; + } else if (onDisk) { + status = BaseMessages.getString(PKG, "MarketplaceDialog.Status.Present"); + } else { + status = BaseMessages.getString(PKG, "MarketplaceDialog.Status.NotInstalled"); + } + item.setText(6, status); + item.setText(7, Const.NVL(info.getDescription(), "")); + item.setData(info); } - item.setText(4, status); - item.setText(5, Const.NVL(info.getDescription(), "")); - item.setData(info); - } - if (!tableOptimized) { wTable.optimizeTableView(); - tableOptimized = true; + } finally { + if (userRefresh && shell != null && !shell.isDisposed()) { + shell.setCursor(null); + } } } + /** + * If repository edits are unsaved, ask the user to save before refreshing plugins (discovery uses + * the config that is saved / in memory). + * + * @return false if the user cancelled + */ + private boolean ensureRepositoriesSavedForRefresh() { + if (repositoriesPanel == null || !repositoriesPanel.isDirty()) { + return true; + } + MessageBox box = new MessageBox(shell, SWT.YES | SWT.NO | SWT.CANCEL | SWT.ICON_WARNING); + box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.ReposDirty.Header")); + box.setMessage(BaseMessages.getString(PKG, "MarketplaceDialog.ReposDirty.Refresh.Message")); + int answer = box.open(); + if (answer == SWT.CANCEL) { + return false; + } + if (answer == SWT.YES) { + return repositoriesPanel.saveChanges(false); + } + // No — discard in-memory edits and reload hop-config so refresh matches disk + try { + MarketplaceConfig loaded = MarketplaceConfig.load(); + config = loaded; + repositoriesPanel.setConfig(loaded); + return true; + } catch (Exception e) { + new ErrorDialog( + shell, + BaseMessages.getString(PKG, "MarketplaceDialog.Error.Header"), + BaseMessages.getString(PKG, "MarketplaceDialog.ReposDirty.Reload.Error"), + e); + return false; + } + } + + /** + * @return true if the dialog may close (saved, discarded, or clean) + */ + private boolean confirmClose() { + if (repositoriesPanel == null || !repositoriesPanel.isDirty()) { + return true; + } + MessageBox box = new MessageBox(shell, SWT.YES | SWT.NO | SWT.CANCEL | SWT.ICON_WARNING); + box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.ReposDirty.Header")); + box.setMessage(BaseMessages.getString(PKG, "MarketplaceDialog.ReposDirty.Close.Message")); + int answer = box.open(); + if (answer == SWT.CANCEL) { + return false; + } + if (answer == SWT.YES) { + return repositoriesPanel.saveChanges(false); + } + // No — discard + return true; + } + private OptionalPluginInfo selected() { TableItem[] items = wTable.table.getSelection(); if (items == null || items.length == 0) { @@ -372,27 +484,56 @@ private OptionalPluginInfo selected() { return (OptionalPluginInfo) items[0].getData(); } + /** + * Human-readable origin for a discovery hit: repository display name when {@code source} is a + * known repo id, otherwise the source string (e.g. {@code apache}). + */ + private String repositoryDisplayName(String source) { + if (StringUtils.isBlank(source)) { + return ""; + } + if ("apache".equalsIgnoreCase(source)) { + return BaseMessages.getString(PKG, "MarketplaceDialog.Repository.Apache"); + } + if (config != null) { + MarketplaceRepository repo = config.findRepository(source); + if (repo != null) { + return Const.NVL(repo.displayName(), source); + } + } + return source; + } + private void installSelected() { OptionalPluginInfo info = selected(); if (info == null) { return; } try { - // Re-read repo URL in case config changed - config = MarketplaceConfig.load(); - String version = MarketplaceCommand.resolveDefaultVersion(config); - MavenCoordinates coords = - new MavenCoordinates(config.getGroupId(), info.getArtifactId(), version); + if (repositoriesPanel != null) { + config = repositoriesPanel.getConfig(); + } + String groupId = + StringUtils.isNotBlank(info.getGroupId()) ? info.getGroupId() : config.getGroupId(); + String version = + StringUtils.isNotBlank(info.getVersion()) + ? info.getVersion() + : MarketplaceCommand.resolveDefaultVersion(config); + MavenCoordinates coords = new MavenCoordinates(groupId, info.getArtifactId(), version); + String preferredRepo = + StringUtils.isNotBlank(info.getSource()) && !"apache".equalsIgnoreCase(info.getSource()) + ? info.getSource() + : null; wStatus.setText( BaseMessages.getString(PKG, "MarketplaceDialog.Status.Installing", coords.gav())); shell.update(); - new PluginInstaller(log, hopHome, config).install(coords, true); + new PluginInstaller(log, hopHome, config).install(coords, true, null, preferredRepo); MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION); box.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Install.Done.Header")); box.setMessage( BaseMessages.getString(PKG, "MarketplaceDialog.Install.Done.Message", coords.gav())); box.open(); - refreshTable(); + refreshTable(false); wStatus.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Status.RestartHint")); } catch (Exception e) { new ErrorDialog( @@ -428,7 +569,7 @@ private void uninstallSelected() { return; } new PluginUninstaller(log, hopHome).uninstall(info.getArtifactId()); - refreshTable(); + refreshTable(false); wStatus.setText(BaseMessages.getString(PKG, "MarketplaceDialog.Status.RestartHint")); } catch (Exception e) { new ErrorDialog( @@ -438,9 +579,4 @@ private void uninstallSelected() { e); } } - - private void close() { - props.setScreen(new WindowProperty(shell)); - shell.dispose(); - } } diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceRepositoriesPanel.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceRepositoriesPanel.java index c4960d3063f..824db2adeec 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceRepositoriesPanel.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/gui/MarketplaceRepositoriesPanel.java @@ -17,15 +17,19 @@ package org.apache.hop.marketplace.gui; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.StringUtils; import org.apache.hop.core.Const; import org.apache.hop.core.variables.Variables; import org.apache.hop.i18n.BaseMessages; +import org.apache.hop.marketplace.catalog.OptionalPluginInfo; import org.apache.hop.marketplace.config.MarketplaceConfig; import org.apache.hop.marketplace.config.MarketplaceRepository; +import org.apache.hop.marketplace.config.MarketplaceRepositoryDefinition; import org.apache.hop.ui.core.PropsUi; +import org.apache.hop.ui.core.dialog.BaseDialog; import org.apache.hop.ui.core.dialog.ErrorDialog; import org.apache.hop.ui.core.dialog.MessageBox; import org.apache.hop.ui.core.gui.WindowProperty; @@ -33,6 +37,8 @@ import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; @@ -47,14 +53,18 @@ /** * Marketplace repository list editor hosted as a panel (e.g. Marketplace dialog Repositories tab). * Settings are saved to hop-config.json via {@link MarketplaceConfig#save()}. + * + *

Plugin metadata for a repository is edited in the Add/Edit repository dialog (Plugin metadata + * tab). Import/Export shareable hop-marketplace-repo YAML definitions from this panel. */ public class MarketplaceRepositoriesPanel { private static final Class PKG = MarketplaceGuiPlugin.class; - private final MarketplaceConfig config; + private MarketplaceConfig config; private final Shell shell; private final TableView wTable; + private boolean dirty; /** * Build the repositories UI into {@code parent} (must use {@link FormLayout}). @@ -66,6 +76,7 @@ public MarketplaceRepositoriesPanel(Composite parent, MarketplaceConfig config) PropsUi props = PropsUi.getInstance(); this.config = config; this.shell = parent.getShell(); + this.dirty = false; Label wlHelp = new Label(parent, SWT.LEFT | SWT.WRAP); PropsUi.setLook(wlHelp); @@ -76,50 +87,31 @@ public MarketplaceRepositoriesPanel(Composite parent, MarketplaceConfig config) fdlHelp.right = new FormAttachment(100, 0); wlHelp.setLayoutData(fdlHelp); - Label wHelpSep = new Label(parent, SWT.HORIZONTAL | SWT.SEPARATOR); - FormData fdHelpSep = new FormData(); - fdHelpSep.left = new FormAttachment(0, 0); - fdHelpSep.right = new FormAttachment(100, 0); - fdHelpSep.top = new FormAttachment(wlHelp, PropsUi.getMargin()); - wHelpSep.setLayoutData(fdHelpSep); - - Button wSave = new Button(parent, SWT.PUSH); - wSave.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Save")); + Button wSave = createRightButton(parent, "ManageRepositoriesDialog.Button.Save"); wSave.addListener(SWT.Selection, e -> save()); - - Button wReset = new Button(parent, SWT.PUSH); - wReset.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.ResetDefaults")); + Button wReset = createRightButton(parent, "ManageRepositoriesDialog.Button.ResetDefaults"); wReset.addListener(SWT.Selection, e -> resetDefaults()); - - Button wRemove = new Button(parent, SWT.PUSH); - wRemove.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Remove")); + Button wDown = createRightButton(parent, "ManageRepositoriesDialog.Button.MoveDown"); + wDown.addListener(SWT.Selection, e -> moveSelected(1)); + Button wUp = createRightButton(parent, "ManageRepositoriesDialog.Button.MoveUp"); + wUp.addListener(SWT.Selection, e -> moveSelected(-1)); + Button wPrimary = createRightButton(parent, "ManageRepositoriesDialog.Button.SetPrimary"); + wPrimary.addListener(SWT.Selection, e -> setPrimarySelected()); + Button wExport = createRightButton(parent, "ManageRepositoriesDialog.Button.Export"); + wExport.addListener(SWT.Selection, e -> exportDefinition()); + Button wImport = createRightButton(parent, "ManageRepositoriesDialog.Button.Import"); + wImport.addListener(SWT.Selection, e -> importDefinition()); + Button wRemove = createRightButton(parent, "ManageRepositoriesDialog.Button.Remove"); wRemove.addListener(SWT.Selection, e -> removeSelected()); - - Button wEdit = new Button(parent, SWT.PUSH); - wEdit.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Edit")); + Button wEdit = createRightButton(parent, "ManageRepositoriesDialog.Button.Edit"); wEdit.addListener(SWT.Selection, e -> editSelected()); - - Button wAdd = new Button(parent, SWT.PUSH); - wAdd.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Add")); + Button wAdd = createRightButton(parent, "ManageRepositoriesDialog.Button.Add"); wAdd.addListener(SWT.Selection, e -> addRepository()); - Button wPrimary = new Button(parent, SWT.PUSH); - wPrimary.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.SetPrimary")); - wPrimary.addListener(SWT.Selection, e -> setPrimarySelected()); - - Button wUp = new Button(parent, SWT.PUSH); - wUp.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.MoveUp")); - wUp.addListener(SWT.Selection, e -> moveSelected(-1)); - - Button wDown = new Button(parent, SWT.PUSH); - wDown.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.MoveDown")); - wDown.addListener(SWT.Selection, e -> moveSelected(1)); - - BaseTransformDialog.positionBottomButtons( - parent, - new Button[] {wAdd, wEdit, wRemove, wPrimary, wUp, wDown, wReset, wSave}, - PropsUi.getMargin(), - wlHelp); + Button[] rightButtons = { + wAdd, wEdit, wRemove, wImport, wExport, wPrimary, wUp, wDown, wReset, wSave + }; + layoutRightButtons(rightButtons, wlHelp); ColumnInfo[] columns = { new ColumnInfo( @@ -132,6 +124,11 @@ public MarketplaceRepositoriesPanel(Composite parent, MarketplaceConfig config) ColumnInfo.COLUMN_TYPE_TEXT, false, true), + new ColumnInfo( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Browse"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + true), new ColumnInfo( BaseMessages.getString(PKG, "ManageRepositoriesDialog.Column.Id"), ColumnInfo.COLUMN_TYPE_TEXT, @@ -165,17 +162,84 @@ public MarketplaceRepositoriesPanel(Composite parent, MarketplaceConfig config) props, false); PropsUi.setLook(wTable); - FormData fdTable = new FormData(); fdTable.left = new FormAttachment(0, 0); - fdTable.top = new FormAttachment(wSave, PropsUi.getMargin()); - fdTable.right = new FormAttachment(100, 0); + fdTable.top = new FormAttachment(wlHelp, PropsUi.getMargin() * 2); + fdTable.right = new FormAttachment(wAdd, -PropsUi.getMargin()); fdTable.bottom = new FormAttachment(100, 0); wTable.setLayoutData(fdTable); refreshTable(); } + private static Button createRightButton(Composite parent, String messageKey) { + Button b = new Button(parent, SWT.PUSH); + b.setText(BaseMessages.getString(PKG, messageKey)); + PropsUi.setLook(b); + return b; + } + + private void layoutRightButtons(Button[] buttons, Label wlHelp) { + int margin = PropsUi.getMargin(); + int maxW = 80; + for (Button b : buttons) { + maxW = Math.max(maxW, b.computeSize(SWT.DEFAULT, SWT.DEFAULT).x); + } + Button prev = null; + for (Button b : buttons) { + FormData fd = new FormData(); + fd.right = new FormAttachment(100, 0); + fd.left = new FormAttachment(100, -maxW - 8); + if (prev == null) { + fd.top = new FormAttachment(wlHelp, margin * 2); + } else { + fd.top = new FormAttachment(prev, margin); + } + b.setLayoutData(fd); + prev = b; + } + } + + public boolean isDirty() { + return dirty; + } + + public boolean saveChanges(boolean showSuccessDialog) { + try { + config.ensureValidPrimary(); + config.save(); + dirty = false; + if (showSuccessDialog) { + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION); + box.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Save.Done.Header")); + box.setMessage(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Save.Done.Message")); + box.open(); + } + return true; + } catch (Exception e) { + new ErrorDialog( + shell, + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Error.Header"), + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Error.Save"), + e); + return false; + } + } + + public void setConfig(MarketplaceConfig config) { + this.config = config; + this.dirty = false; + refreshTable(); + } + + public MarketplaceConfig getConfig() { + return config; + } + + private void markDirty() { + dirty = true; + } + private void refreshTable() { wTable.table.removeAll(); if (config.getRepositories() == null) { @@ -189,11 +253,12 @@ private void refreshTable() { TableItem item = new TableItem(wTable.table, SWT.NONE); item.setText(1, repo.isPrimary() ? "*" : ""); item.setText(2, repo.isEnabled() ? "Y" : "N"); - item.setText(3, Const.NVL(repo.getId(), "")); - item.setText(4, Const.NVL(repo.displayName(), "")); - item.setText(5, Const.NVL(repo.getUrl(), "")); + item.setText(3, repo.isBrowse() ? "Y" : "N"); + item.setText(4, Const.NVL(repo.getId(), "")); + item.setText(5, Const.NVL(repo.displayName(), "")); + item.setText(6, Const.NVL(repo.getUrl(), "")); item.setText( - 6, repo.hasCredentials() || StringUtils.isNotBlank(repo.getUsername()) ? "Y" : ""); + 7, repo.hasCredentials() || StringUtils.isNotBlank(repo.getUsername()) ? "Y" : ""); item.setData(repo); } wTable.optimizeTableView(); @@ -216,7 +281,9 @@ private void addRepository() { if (editRepository(repo, true)) { try { config.addRepository(repo); + markDirty(); refreshTable(); + selectRepoId(repo.getId()); } catch (Exception e) { new ErrorDialog( shell, @@ -234,12 +301,32 @@ private void editSelected() { } if (editRepository(repo, false)) { config.ensureValidPrimary(); + markDirty(); refreshTable(); + selectRepoId(repo.getId()); } } + private void selectRepoId(String id) { + if (StringUtils.isBlank(id) || config.getRepositories() == null) { + return; + } + for (int i = 0; i < wTable.table.getItemCount(); i++) { + MarketplaceRepository r = (MarketplaceRepository) wTable.table.getItem(i).getData(); + if (r != null && id.equals(r.getId())) { + wTable.table.setSelection(i); + break; + } + } + } + + /** + * Add/Edit repository dialog: General connection fields + Plugin metadata table (for this repo + * only). Mutations applied only on OK. + */ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { - Shell dialog = new Shell(shell, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE); + Shell dialog = new Shell(shell, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX); + PropsUi props = PropsUi.getInstance(); PropsUi.setLook(dialog); dialog.setText( BaseMessages.getString( @@ -252,10 +339,35 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { layout.marginHeight = PropsUi.getFormMargin(); dialog.setLayout(layout); - int middle = PropsUi.getInstance().getMiddlePct(); + int middle = props.getMiddlePct(); int margin = PropsUi.getMargin(); - Label wlId = new Label(dialog, SWT.RIGHT); + final boolean[] ok = {false}; + + Button wOk = new Button(dialog, SWT.PUSH); + wOk.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Ok")); + Button wCancel = new Button(dialog, SWT.PUSH); + wCancel.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Cancel")); + BaseTransformDialog.positionBottomButtons(dialog, new Button[] {wOk, wCancel}, margin, null); + + CTabFolder tabs = new CTabFolder(dialog, SWT.BORDER); + PropsUi.setLook(tabs); + FormData fdTabs = new FormData(); + fdTabs.left = new FormAttachment(0, 0); + fdTabs.top = new FormAttachment(0, 0); + fdTabs.right = new FormAttachment(100, 0); + fdTabs.bottom = new FormAttachment(wOk, -margin); + tabs.setLayoutData(fdTabs); + + // ----- General ----- + CTabItem generalTab = new CTabItem(tabs, SWT.NONE); + generalTab.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Tab.General")); + Composite general = new Composite(tabs, SWT.NONE); + PropsUi.setLook(general); + general.setLayout(new FormLayout()); + generalTab.setControl(general); + + Label wlId = new Label(general, SWT.RIGHT); PropsUi.setLook(wlId); wlId.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Id")); FormData fdlId = new FormData(); @@ -263,7 +375,7 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { fdlId.top = new FormAttachment(0, margin); fdlId.right = new FormAttachment(middle, -margin); wlId.setLayoutData(fdlId); - Text wId = new Text(dialog, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + Text wId = new Text(general, SWT.SINGLE | SWT.LEFT | SWT.BORDER); PropsUi.setLook(wId); wId.setText(Const.NVL(repo.getId(), "")); wId.setEditable(isNew); @@ -273,7 +385,7 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { fdId.right = new FormAttachment(100, 0); wId.setLayoutData(fdId); - Label wlName = new Label(dialog, SWT.RIGHT); + Label wlName = new Label(general, SWT.RIGHT); PropsUi.setLook(wlName); wlName.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Name")); FormData fdlName = new FormData(); @@ -281,7 +393,7 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { fdlName.top = new FormAttachment(wId, margin); fdlName.right = new FormAttachment(middle, -margin); wlName.setLayoutData(fdlName); - Text wName = new Text(dialog, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + Text wName = new Text(general, SWT.SINGLE | SWT.LEFT | SWT.BORDER); PropsUi.setLook(wName); wName.setText(Const.NVL(repo.getName(), "")); FormData fdName = new FormData(); @@ -290,7 +402,7 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { fdName.right = new FormAttachment(100, 0); wName.setLayoutData(fdName); - Label wlUrl = new Label(dialog, SWT.RIGHT); + Label wlUrl = new Label(general, SWT.RIGHT); PropsUi.setLook(wlUrl); wlUrl.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Url")); FormData fdlUrl = new FormData(); @@ -298,7 +410,7 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { fdlUrl.top = new FormAttachment(wName, margin); fdlUrl.right = new FormAttachment(middle, -margin); wlUrl.setLayoutData(fdlUrl); - Text wUrl = new Text(dialog, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + Text wUrl = new Text(general, SWT.SINGLE | SWT.LEFT | SWT.BORDER); PropsUi.setLook(wUrl); wUrl.setText(Const.NVL(repo.getUrl(), "")); FormData fdUrl = new FormData(); @@ -307,7 +419,7 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { fdUrl.right = new FormAttachment(100, 0); wUrl.setLayoutData(fdUrl); - Label wlUser = new Label(dialog, SWT.RIGHT); + Label wlUser = new Label(general, SWT.RIGHT); PropsUi.setLook(wlUser); wlUser.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Username")); FormData fdlUser = new FormData(); @@ -315,7 +427,7 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { fdlUser.top = new FormAttachment(wUrl, margin); fdlUser.right = new FormAttachment(middle, -margin); wlUser.setLayoutData(fdlUser); - Text wUser = new Text(dialog, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + Text wUser = new Text(general, SWT.SINGLE | SWT.LEFT | SWT.BORDER); PropsUi.setLook(wUser); wUser.setText(Const.NVL(repo.getUsername(), "")); FormData fdUser = new FormData(); @@ -324,7 +436,7 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { fdUser.right = new FormAttachment(100, 0); wUser.setLayoutData(fdUser); - Label wlPass = new Label(dialog, SWT.RIGHT); + Label wlPass = new Label(general, SWT.RIGHT); PropsUi.setLook(wlPass); wlPass.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Password")); FormData fdlPass = new FormData(); @@ -332,7 +444,7 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { fdlPass.top = new FormAttachment(wUser, margin); fdlPass.right = new FormAttachment(middle, -margin); wlPass.setLayoutData(fdlPass); - Text wPass = new Text(dialog, SWT.SINGLE | SWT.LEFT | SWT.BORDER | SWT.PASSWORD); + Text wPass = new Text(general, SWT.SINGLE | SWT.LEFT | SWT.BORDER | SWT.PASSWORD); PropsUi.setLook(wPass); FormData fdPass = new FormData(); fdPass.left = new FormAttachment(middle, margin); @@ -340,7 +452,7 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { fdPass.right = new FormAttachment(100, 0); wPass.setLayoutData(fdPass); - Button wEnabled = new Button(dialog, SWT.CHECK); + Button wEnabled = new Button(general, SWT.CHECK); PropsUi.setLook(wEnabled); wEnabled.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Enabled")); wEnabled.setSelection(repo.isEnabled()); @@ -349,7 +461,7 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { fdEnabled.top = new FormAttachment(wPass, margin); wEnabled.setLayoutData(fdEnabled); - Button wPrimary = new Button(dialog, SWT.CHECK); + Button wPrimary = new Button(general, SWT.CHECK); PropsUi.setLook(wPrimary); wPrimary.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Primary")); wPrimary.setSelection(repo.isPrimary()); @@ -358,9 +470,203 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { fdPrimary.top = new FormAttachment(wEnabled, margin); wPrimary.setLayoutData(fdPrimary); - final boolean[] ok = {false}; - Button wOk = new Button(dialog, SWT.PUSH); - wOk.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Ok")); + Button wBrowse = new Button(general, SWT.CHECK); + PropsUi.setLook(wBrowse); + wBrowse.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Browse")); + wBrowse.setToolTipText( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.Browse.Tooltip")); + wBrowse.setSelection(repo.isBrowse()); + FormData fdBrowse = new FormData(); + fdBrowse.left = new FormAttachment(middle, margin); + fdBrowse.top = new FormAttachment(wPrimary, margin); + wBrowse.setLayoutData(fdBrowse); + + Label wlCatalog = new Label(general, SWT.RIGHT); + PropsUi.setLook(wlCatalog); + wlCatalog.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.CatalogUrl")); + FormData fdlCatalog = new FormData(); + fdlCatalog.left = new FormAttachment(0, 0); + fdlCatalog.top = new FormAttachment(wBrowse, margin); + fdlCatalog.right = new FormAttachment(middle, -margin); + wlCatalog.setLayoutData(fdlCatalog); + Text wCatalog = new Text(general, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + PropsUi.setLook(wCatalog); + wCatalog.setText(Const.NVL(repo.getCatalogUrl(), "")); + FormData fdCatalog = new FormData(); + fdCatalog.left = new FormAttachment(middle, margin); + fdCatalog.top = new FormAttachment(wlCatalog, 0, SWT.CENTER); + fdCatalog.right = new FormAttachment(100, 0); + wCatalog.setLayoutData(fdCatalog); + + Label wlSearch = new Label(general, SWT.RIGHT); + PropsUi.setLook(wlSearch); + wlSearch.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.SearchQuery")); + FormData fdlSearch = new FormData(); + fdlSearch.left = new FormAttachment(0, 0); + fdlSearch.top = new FormAttachment(wCatalog, margin); + fdlSearch.right = new FormAttachment(middle, -margin); + wlSearch.setLayoutData(fdlSearch); + Text wSearch = new Text(general, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + PropsUi.setLook(wSearch); + wSearch.setText(Const.NVL(repo.getSearchQuery(), "")); + FormData fdSearch = new FormData(); + fdSearch.left = new FormAttachment(middle, margin); + fdSearch.top = new FormAttachment(wlSearch, 0, SWT.CENTER); + fdSearch.right = new FormAttachment(100, 0); + wSearch.setLayoutData(fdSearch); + + Label wlGroup = new Label(general, SWT.RIGHT); + PropsUi.setLook(wlGroup); + wlGroup.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.GroupIdFilter")); + FormData fdlGroup = new FormData(); + fdlGroup.left = new FormAttachment(0, 0); + fdlGroup.top = new FormAttachment(wSearch, margin); + fdlGroup.right = new FormAttachment(middle, -margin); + wlGroup.setLayoutData(fdlGroup); + Text wGroup = new Text(general, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + PropsUi.setLook(wGroup); + wGroup.setText(Const.NVL(repo.getGroupIdFilter(), "")); + FormData fdGroup = new FormData(); + fdGroup.left = new FormAttachment(middle, margin); + fdGroup.top = new FormAttachment(wlGroup, 0, SWT.CENTER); + fdGroup.right = new FormAttachment(100, 0); + wGroup.setLayoutData(fdGroup); + + Button wSnapshots = new Button(general, SWT.CHECK); + PropsUi.setLook(wSnapshots); + wSnapshots.setText( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Edit.IncludeSnapshots")); + wSnapshots.setSelection(repo.isIncludeSnapshots()); + FormData fdSnapshots = new FormData(); + fdSnapshots.left = new FormAttachment(middle, margin); + fdSnapshots.top = new FormAttachment(wGroup, margin); + wSnapshots.setLayoutData(fdSnapshots); + + // ----- Plugin metadata ----- + CTabItem metaTab = new CTabItem(tabs, SWT.NONE); + metaTab.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Tab.PluginMetadata")); + Composite meta = new Composite(tabs, SWT.NONE); + PropsUi.setLook(meta); + meta.setLayout(new FormLayout()); + metaTab.setControl(meta); + + Label wlMetaHelp = new Label(meta, SWT.LEFT | SWT.WRAP); + PropsUi.setLook(wlMetaHelp); + wlMetaHelp.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Plugins.Hint")); + FormData fdlMetaHelp = new FormData(); + fdlMetaHelp.left = new FormAttachment(0, 0); + fdlMetaHelp.top = new FormAttachment(0, 0); + fdlMetaHelp.right = new FormAttachment(100, 0); + wlMetaHelp.setLayoutData(fdlMetaHelp); + + Button wAddPlugin = new Button(meta, SWT.PUSH); + wAddPlugin.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.AddPlugin")); + Button wRemovePlugin = new Button(meta, SWT.PUSH); + wRemovePlugin.setText( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.RemovePlugin")); + BaseTransformDialog.positionBottomButtons( + meta, new Button[] {wAddPlugin, wRemovePlugin}, margin, null); + + ColumnInfo[] pluginCols = { + new ColumnInfo( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Plugins.Column.Group"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + false), + new ColumnInfo( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Plugins.Column.Artifact"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + false), + new ColumnInfo( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Plugins.Column.Version"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + false), + new ColumnInfo( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Plugins.Column.Name"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + false), + new ColumnInfo( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Plugins.Column.Category"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + false), + new ColumnInfo( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Plugins.Column.Description"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + false), + new ColumnInfo( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Plugins.Column.MinHop"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + false), + new ColumnInfo( + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Plugins.Column.MaxHop"), + ColumnInfo.COLUMN_TYPE_TEXT, + false, + false), + }; + TableView wPluginsTable = + new TableView( + Variables.getADefaultVariableSpace(), + meta, + SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI | SWT.V_SCROLL, + pluginCols, + 1, + true, + null, + props, + true); + PropsUi.setLook(wPluginsTable); + FormData fdPlugins = new FormData(); + fdPlugins.left = new FormAttachment(0, 0); + fdPlugins.top = new FormAttachment(wlMetaHelp, margin); + fdPlugins.right = new FormAttachment(100, 0); + fdPlugins.bottom = new FormAttachment(wAddPlugin, -margin); + wPluginsTable.setLayoutData(fdPlugins); + + // Load existing plugins into the table (do not mutate repo until OK) + if (repo.getPlugins() != null) { + for (OptionalPluginInfo p : repo.getPlugins()) { + if (p == null) { + continue; + } + TableItem item = new TableItem(wPluginsTable.table, SWT.NONE); + item.setText(1, Const.NVL(p.getGroupId(), "")); + item.setText(2, Const.NVL(p.getArtifactId(), "")); + item.setText(3, Const.NVL(p.getVersion(), "")); + item.setText(4, Const.NVL(p.getName(), "")); + item.setText(5, Const.NVL(p.getCategory(), "")); + item.setText(6, Const.NVL(p.getDescription(), "")); + item.setText(7, Const.NVL(p.getMinHopVersion(), "")); + item.setText(8, Const.NVL(p.getMaxHopVersion(), "")); + } + } + wPluginsTable.optimizeTableView(); + + wAddPlugin.addListener( + SWT.Selection, + e -> { + TableItem item = new TableItem(wPluginsTable.table, SWT.NONE); + item.setText(1, "org.apache.hop"); + item.setText(5, "Community"); + wPluginsTable.optimizeTableView(); + }); + wRemovePlugin.addListener( + SWT.Selection, + e -> { + int[] indices = wPluginsTable.table.getSelectionIndices(); + if (indices == null || indices.length == 0) { + return; + } + for (int i = indices.length - 1; i >= 0; i--) { + wPluginsTable.table.remove(indices[i]); + } + }); + wOk.addListener( SWT.Selection, e -> { @@ -380,17 +686,24 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { } repo.setEnabled(wEnabled.getSelection()); repo.setPrimary(wPrimary.getSelection()); + repo.setBrowse(wBrowse.getSelection()); + repo.setCatalogUrl(StringUtils.trimToNull(wCatalog.getText())); + repo.setSearchQuery(StringUtils.trimToNull(wSearch.getText())); + repo.setGroupIdFilter(StringUtils.trimToNull(wGroup.getText())); + repo.setIncludeSnapshots(wSnapshots.getSelection()); + repo.setPlugins(readPluginsFromTable(wPluginsTable, repo.getId())); ok[0] = true; PropsUi.getInstance().setScreen(new WindowProperty(dialog)); dialog.dispose(); }); - Button wCancel = new Button(dialog, SWT.PUSH); - wCancel.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Button.Cancel")); wCancel.addListener(SWT.Selection, e -> dialog.dispose()); - BaseTransformDialog.positionBottomButtons( - dialog, new Button[] {wOk, wCancel}, margin, wPrimary); + tabs.setSelection(0); BaseTransformDialog.setSize(dialog); + // Prefer a taller default so the metadata table is usable + if (dialog.getSize().y < 480) { + dialog.setSize(Math.max(dialog.getSize().x, 640), 520); + } dialog.open(); Display display = shell.getDisplay(); while (!dialog.isDisposed()) { @@ -408,6 +721,29 @@ private boolean editRepository(MarketplaceRepository repo, boolean isNew) { return ok[0]; } + private static List readPluginsFromTable(TableView table, String repoId) { + List plugins = new ArrayList<>(); + for (int i = 0; i < table.table.getItemCount(); i++) { + TableItem item = table.table.getItem(i); + String artifact = item.getText(2).trim(); + if (StringUtils.isBlank(artifact)) { + continue; + } + OptionalPluginInfo p = new OptionalPluginInfo(); + p.setGroupId(StringUtils.trimToNull(item.getText(1))); + p.setArtifactId(artifact); + p.setVersion(StringUtils.trimToNull(item.getText(3))); + p.setName(StringUtils.trimToNull(item.getText(4))); + p.setCategory(StringUtils.trimToNull(item.getText(5))); + p.setDescription(StringUtils.trimToNull(item.getText(6))); + p.setMinHopVersion(StringUtils.trimToNull(item.getText(7))); + p.setMaxHopVersion(StringUtils.trimToNull(item.getText(8))); + p.setSource(repoId); + plugins.add(p); + } + return plugins; + } + private void removeSelected() { MarketplaceRepository repo = selected(); if (repo == null) { @@ -415,6 +751,7 @@ private void removeSelected() { } try { config.removeRepository(repo.getId()); + markDirty(); refreshTable(); } catch (Exception e) { new ErrorDialog( @@ -425,6 +762,85 @@ private void removeSelected() { } } + private void importDefinition() { + try { + String path = + BaseDialog.presentFileDialog( + false, + shell, + new String[] {"*.yaml;*.yml;*.json", "*.*"}, + new String[] { + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Filter.RepoDef"), + BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Filter.All") + }, + false); + if (StringUtils.isBlank(path)) { + return; + } + MarketplaceRepository imported = MarketplaceRepositoryDefinition.load(Path.of(path.trim())); + MarketplaceRepositoryDefinition.applyToConfig(config, imported, false); + markDirty(); + refreshTable(); + selectRepoId(imported.getId()); + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION); + box.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Import.Done.Header")); + box.setMessage( + BaseMessages.getString( + PKG, "ManageRepositoriesDialog.Import.Done.Message", imported.getId())); + box.open(); + } catch (Exception e) { + new ErrorDialog( + shell, + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Error.Header"), + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Import.Error"), + e); + } + } + + private void exportDefinition() { + MarketplaceRepository repo = selected(); + if (repo == null) { + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_WARNING); + box.setMessage(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Export.Select")); + box.open(); + return; + } + try { + String path = + BaseDialog.presentFileDialog( + true, + shell, + new String[] {"*.yaml;*.yml", "*.json", "*.*"}, + new String[] { + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Filter.Yaml"), + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Filter.Json"), + BaseMessages.getString(PKG, "MarketplaceDialog.EnvFile.Filter.All") + }, + false); + if (StringUtils.isBlank(path)) { + return; + } + Path out = Path.of(path.trim()); + String name = out.getFileName().toString().toLowerCase(); + if (!name.endsWith(".yaml") && !name.endsWith(".yml") && !name.endsWith(".json")) { + out = out.resolveSibling(out.getFileName().toString() + ".yaml"); + } + MarketplaceRepositoryDefinition.save(out, repo); + MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION); + box.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Export.Done.Header")); + box.setMessage( + BaseMessages.getString( + PKG, "ManageRepositoriesDialog.Export.Done.Message", out.toString())); + box.open(); + } catch (Exception e) { + new ErrorDialog( + shell, + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Error.Header"), + BaseMessages.getString(PKG, "ManageRepositoriesDialog.Export.Error"), + e); + } + } + private void setPrimarySelected() { MarketplaceRepository repo = selected(); if (repo == null) { @@ -432,7 +848,9 @@ private void setPrimarySelected() { } try { config.setPrimary(repo.getId()); + markDirty(); refreshTable(); + selectRepoId(repo.getId()); } catch (Exception e) { new ErrorDialog( shell, @@ -455,6 +873,7 @@ private void moveSelected(int delta) { } list.remove(idx); list.add(target, repo); + markDirty(); refreshTable(); wTable.table.setSelection(target); } @@ -467,23 +886,11 @@ private void resetDefaults() { return; } config.setRepositories(new ArrayList<>(MarketplaceConfig.defaultRepositories())); + markDirty(); refreshTable(); } private void save() { - try { - config.ensureValidPrimary(); - config.save(); - MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION); - box.setText(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Save.Done.Header")); - box.setMessage(BaseMessages.getString(PKG, "ManageRepositoriesDialog.Save.Done.Message")); - box.open(); - } catch (Exception e) { - new ErrorDialog( - shell, - BaseMessages.getString(PKG, "ManageRepositoriesDialog.Error.Header"), - BaseMessages.getString(PKG, "ManageRepositoriesDialog.Error.Save"), - e); - } + saveChanges(true); } } diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java index ea0de0aa113..e8410b1c7d7 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/install/PluginInstaller.java @@ -79,7 +79,7 @@ public PluginInstaller(ILogChannel log, Path hopHome, MarketplaceConfig config) */ public InstallReceipt install(MavenCoordinates coordinates, boolean activateImmediately) throws HopException { - return install(coordinates, activateImmediately, null); + return install(coordinates, activateImmediately, null, null); } /** @@ -88,11 +88,25 @@ public InstallReceipt install(MavenCoordinates coordinates, boolean activateImme public InstallReceipt install( MavenCoordinates coordinates, boolean activateImmediately, String forceRepoId) throws HopException { + return install(coordinates, activateImmediately, forceRepoId, null); + } + + /** + * @param forceRepoId when non-blank, only that repository is used (no fallback chain) + * @param preferredRepoId when non-blank and force is blank, try this repository first then the + * normal fallback chain (used when discovery knows the source repo) + */ + public InstallReceipt install( + MavenCoordinates coordinates, + boolean activateImmediately, + String forceRepoId, + String preferredRepoId) + throws HopException { Path downloadDir = hopHome.resolve(STAGING_DIR).resolve(".download"); Path zipFile = downloadDir.resolve(coordinates.artifactId() + "-" + coordinates.version() + ".zip"); try { - List repos = resolveRepositories(forceRepoId); + List repos = resolveRepositories(forceRepoId, preferredRepoId); MarketplaceRepository used = null; List errors = new ArrayList<>(); for (MarketplaceRepository repo : repos) { @@ -154,7 +168,8 @@ public InstallReceipt install( } } - private List resolveRepositories(String forceRepoId) throws HopException { + private List resolveRepositories( + String forceRepoId, String preferredRepoId) throws HopException { if (StringUtils.isNotBlank(forceRepoId)) { MarketplaceRepository forced = config.findRepository(forceRepoId); if (forced == null) { @@ -165,7 +180,21 @@ private List resolveRepositories(String forceRepoId) thro } return List.of(forced); } - return config.orderedRepositories(); + List ordered = new ArrayList<>(config.orderedRepositories()); + if (StringUtils.isNotBlank(preferredRepoId)) { + MarketplaceRepository preferred = null; + for (int i = 0; i < ordered.size(); i++) { + MarketplaceRepository r = ordered.get(i); + if (r != null && preferredRepoId.equals(r.getId())) { + preferred = ordered.remove(i); + break; + } + } + if (preferred != null) { + ordered.add(0, preferred); + } + } + return ordered; } /** Activate all staged plugins (startup hook). */ diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java index 7e3594ea075..56247c27735 100644 --- a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/MavenRepositoryClient.java @@ -136,16 +136,33 @@ public void downloadArtifact( } /** - * For release versions: {@code g/a/v/a-v.zip}. For {@code *-SNAPSHOT}, resolve the unique - * timestamped file name from {@code maven-metadata.xml} (as deployed by Maven / Nexus). + * For release versions: {@code g/a/v/a-v.zip}. For {@code *-SNAPSHOT} (including unique + * timestamped forms like {@code 1.0.0-20260721.105615-1} from Nexus search), resolve the unique + * file name from {@code maven-metadata.xml} under the base SNAPSHOT directory. */ String resolveZipRelativePath(MarketplaceRepository repository, MavenCoordinates coordinates) throws HopException { - String version = coordinates.version(); + String version = SnapshotVersions.toBaseVersion(coordinates.version()); if (version == null || !version.endsWith("-SNAPSHOT")) { return coordinates.zipRepositoryPath(); } + // When the caller already passed a unique SNAPSHOT, place that file under the base folder + // without requiring metadata (Nexus search already named the asset). + if (SnapshotVersions.isUniqueSnapshot(coordinates.version())) { + String groupPath = coordinates.groupId().replace('.', '/'); + return groupPath + + "/" + + coordinates.artifactId() + + "/" + + version + + "/" + + coordinates.artifactId() + + "-" + + coordinates.version().trim() + + ".zip"; + } + String groupPath = coordinates.groupId().replace('.', '/'); String metadataPath = groupPath + "/" + coordinates.artifactId() + "/" + version + "/maven-metadata.xml"; @@ -157,7 +174,16 @@ String resolveZipRelativePath(MarketplaceRepository repository, MavenCoordinates // Fall back to non-unique name (some repos allow it) log.logBasic( "Could not parse SNAPSHOT zip from maven-metadata.xml; trying non-unique file name"); - return coordinates.zipRepositoryPath(); + return groupPath + + "/" + + coordinates.artifactId() + + "/" + + version + + "/" + + coordinates.artifactId() + + "-" + + version + + ".zip"; } return groupPath + "/" diff --git a/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/SnapshotVersions.java b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/SnapshotVersions.java new file mode 100644 index 00000000000..65a916695b3 --- /dev/null +++ b/plugins/misc/marketplace/src/main/java/org/apache/hop/marketplace/resolve/SnapshotVersions.java @@ -0,0 +1,107 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.resolve; + +import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.apache.commons.lang3.StringUtils; + +/** + * Maven SNAPSHOT helpers. Nexus search often reports the unique version ({@code + * 1.0.0-20260721.105615-1}) while repository layout stores files under the base folder ({@code + * 1.0.0-SNAPSHOT/}). + */ +public final class SnapshotVersions { + + /** Unique timestamped SNAPSHOT: {@code base-yyyyMMdd.HHmmss-buildNumber}. */ + private static final Pattern UNIQUE_SNAPSHOT = Pattern.compile("^(.*)-(\\d{8}\\.\\d{6})-(\\d+)$"); + + private SnapshotVersions() {} + + /** True for {@code *-SNAPSHOT} or unique timestamped SNAPSHOT versions. */ + public static boolean isSnapshot(String version) { + if (StringUtils.isBlank(version)) { + return false; + } + return version.endsWith("-SNAPSHOT") || isUniqueSnapshot(version); + } + + /** True for {@code 1.0.0-20260721.105615-1} style unique versions. */ + public static boolean isUniqueSnapshot(String version) { + return StringUtils.isNotBlank(version) && UNIQUE_SNAPSHOT.matcher(version.trim()).matches(); + } + + /** + * Map unique SNAPSHOT versions to base {@code *-SNAPSHOT} used in Maven repository directories. + * Leaves release and already-base SNAPSHOT versions unchanged. + */ + public static String toBaseVersion(String version) { + if (StringUtils.isBlank(version)) { + return version; + } + String v = version.trim(); + if (v.endsWith("-SNAPSHOT")) { + return v; + } + Matcher m = UNIQUE_SNAPSHOT.matcher(v); + if (m.matches()) { + return m.group(1) + "-SNAPSHOT"; + } + return v; + } + + /** + * Prefer the version folder from a Maven asset path (e.g. {@code /g/a/0.4.0-SNAPSHOT/a-....zip}), + * else {@link #toBaseVersion(String)}. + */ + public static String toBaseVersion(String version, String mavenAssetPath) { + String fromPath = versionFolderFromPath(mavenAssetPath); + if (StringUtils.isNotBlank(fromPath)) { + return fromPath; + } + return toBaseVersion(version); + } + + /** + * Extract the version directory from a repository-relative path such as {@code + * org/apache/hop/hop-datavault/0.4.0-SNAPSHOT/hop-datavault-….zip}. + */ + public static String versionFolderFromPath(String path) { + if (StringUtils.isBlank(path)) { + return null; + } + String p = path.trim(); + while (p.startsWith("/")) { + p = p.substring(1); + } + while (p.endsWith("/")) { + p = p.substring(0, p.length() - 1); + } + String[] parts = p.split("/"); + if (parts.length < 2) { + return null; + } + // …/artifactId/version/filename + return parts[parts.length - 2]; + } + + public static boolean containsSnapshotKeyword(String version) { + return version != null && version.toUpperCase(Locale.ROOT).contains("SNAPSHOT"); + } +} diff --git a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties index 612232d7daf..fbfe263eb56 100644 --- a/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties +++ b/plugins/misc/marketplace/src/main/resources/org/apache/hop/marketplace/gui/messages/messages_en_US.properties @@ -37,10 +37,13 @@ MarketplaceDialog.Tab.Repositories=Repositories MarketplaceDialog.Repository.Label=Primary repository MarketplaceDialog.Repository.SetPrimary.Error=Could not set primary repository MarketplaceDialog.Column.Name=Name +MarketplaceDialog.Column.Version=Version MarketplaceDialog.Column.Artifact=Artifact MarketplaceDialog.Column.Category=Category +MarketplaceDialog.Column.Repository=Repository MarketplaceDialog.Column.Status=Status MarketplaceDialog.Column.Description=Description +MarketplaceDialog.Repository.Apache=Apache (optional catalog) MarketplaceDialog.Search.Label=Search MarketplaceDialog.Search.Placeholder=Type 3+ characters to filter plugins… MarketplaceDialog.Search.Clear=Clear search filter @@ -48,6 +51,10 @@ MarketplaceDialog.Button.Install=Install MarketplaceDialog.Button.Uninstall=Uninstall MarketplaceDialog.Button.Refresh=Refresh MarketplaceDialog.Button.Close=Close +MarketplaceDialog.ReposDirty.Header=Unsaved repository changes +MarketplaceDialog.ReposDirty.Close.Message=Repository settings were changed but not saved to hop-config.\n\nSave changes before closing? +MarketplaceDialog.ReposDirty.Refresh.Message=Repository settings were changed but not saved.\nPlugin discovery uses the saved configuration.\n\nSave changes before refreshing the plugin list? +MarketplaceDialog.ReposDirty.Reload.Error=Could not reload marketplace configuration from hop-config MarketplaceDialog.Button.ManageRepos=Manage… MarketplaceDialog.Button.BrowseEnv=Browse… MarketplaceDialog.Button.EditEnv=Edit… @@ -99,14 +106,17 @@ MarketplaceDialog.Apply.Done.Message=Applied:\n{0}\n\nPlease restart Hop so new MarketplaceDialog.Apply.Error=Failed to apply the environment file ManageRepositoriesDialog.Shell.Title=Marketplace repositories -ManageRepositoriesDialog.Help=The primary repository is tried first. The other enabled repositories are fallbacks. \nDefaults: Apache Repository (repository.apache.org) then Maven Central. \nSettings are saved to hop-config.json under '${HOP_CONFIG_FOLDER}'. +ManageRepositoriesDialog.Help=Primary repo is tried first for installs; other enabled repos are fallbacks. Enable Browse to list zips live on the Plugins tab.\nImport/Export shareable repository YAML. Edit connection fields and plugin metadata (name, category, version pin, Hop range) via Add/Edit repository.\nDefaults: Apache Repository then Maven Central. Settings: hop-config.json under '${HOP_CONFIG_FOLDER}'. ManageRepositoriesDialog.Column.Primary=Primary ManageRepositoriesDialog.Column.Enabled=Enabled +ManageRepositoriesDialog.Column.Browse=Browse ManageRepositoriesDialog.Column.Id=Id ManageRepositoriesDialog.Column.Name=Name ManageRepositoriesDialog.Column.Url=URL ManageRepositoriesDialog.Column.Auth=Auth ManageRepositoriesDialog.Button.Add=Add +ManageRepositoriesDialog.Button.Import=Import… +ManageRepositoriesDialog.Button.Export=Export… ManageRepositoriesDialog.Button.Edit=Edit ManageRepositoriesDialog.Button.Remove=Remove ManageRepositoriesDialog.Button.SetPrimary=Set primary @@ -131,8 +141,36 @@ ManageRepositoriesDialog.Edit.Username=Username ManageRepositoriesDialog.Edit.Password=Password ManageRepositoriesDialog.Edit.Enabled=Enabled (use in fallback chain) ManageRepositoriesDialog.Edit.Primary=Primary (tried first) +ManageRepositoriesDialog.Edit.Browse=Browse (list zips in query / Plugins tab) +ManageRepositoriesDialog.Edit.Browse.Tooltip=When enabled, marketplace query and the Plugins tab always include a live list of *.zip artifacts from this repository (Nexus search). Optional catalog URL overrides live search. +ManageRepositoriesDialog.Edit.CatalogUrl=Catalog URL +ManageRepositoriesDialog.Edit.SearchQuery=Search query +ManageRepositoriesDialog.Edit.GroupIdFilter=Group ID filter +ManageRepositoriesDialog.Edit.IncludeSnapshots=Include SNAPSHOT versions in discovery ManageRepositoriesDialog.Edit.IdUrlRequired=Id and URL are required. - +ManageRepositoriesDialog.Filter.RepoDef=Repository definitions (*.yaml, *.yml, *.json) +ManageRepositoriesDialog.Filter.Yaml=YAML (*.yaml, *.yml) +ManageRepositoriesDialog.Filter.Json=JSON (*.json) +ManageRepositoriesDialog.Import.Done.Header=Repository imported +ManageRepositoriesDialog.Import.Done.Message=Imported/updated repository ''{0}''. Click Save to persist hop-config. +ManageRepositoriesDialog.Import.Error=Could not import repository definition +ManageRepositoriesDialog.Export.Select=Select a repository row to export. +ManageRepositoriesDialog.Export.Done.Header=Repository exported +ManageRepositoriesDialog.Export.Done.Message=Wrote:\n{0} +ManageRepositoriesDialog.Export.Error=Could not export repository definition +ManageRepositoriesDialog.Edit.Tab.General=General +ManageRepositoriesDialog.Tab.PluginMetadata=Plugin metadata +ManageRepositoriesDialog.Plugins.Hint=Optional metadata for plugins from this repository (enriches live browse: name, category, version pin, min/max Hop version). Applied when you click OK. +ManageRepositoriesDialog.Plugins.Column.Group=Group ID +ManageRepositoriesDialog.Plugins.Column.Artifact=Artifact ID +ManageRepositoriesDialog.Plugins.Column.Version=Version pin +ManageRepositoriesDialog.Plugins.Column.Name=Name +ManageRepositoriesDialog.Plugins.Column.Category=Category +ManageRepositoriesDialog.Plugins.Column.Description=Description +ManageRepositoriesDialog.Plugins.Column.MinHop=Min Hop version +ManageRepositoriesDialog.Plugins.Column.MaxHop=Max Hop version +ManageRepositoriesDialog.Button.AddPlugin=Add plugin +ManageRepositoriesDialog.Button.RemovePlugin=Remove plugin HopEnvironmentDialog.Shell.Title=Marketplace environment — {0} HopEnvironmentDialog.Untitled=Untitled HopEnvironmentDialog.Button.New=New diff --git a/plugins/misc/marketplace/src/main/samples/hop-marketplace-catalog.example.yaml b/plugins/misc/marketplace/src/main/samples/hop-marketplace-catalog.example.yaml new file mode 100644 index 00000000000..06344a96e87 --- /dev/null +++ b/plugins/misc/marketplace/src/main/samples/hop-marketplace-catalog.example.yaml @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Example remote catalog for marketplace discovery (host next to your Maven repo). +# Point catalogUrl in hop-marketplace-repo.yaml at this file's public URL. +# +schemaVersion: "1.0" +kind: hop-marketplace-catalog +repositoryId: data-hopper-community +plugins: + - groupId: org.apache.hop + artifactId: hop-datavault + version: 0.4.0-SNAPSHOT + name: Data Vault + category: Community + description: Data Vault modeling transforms for Apache Hop diff --git a/plugins/misc/marketplace/src/main/samples/hop-marketplace-repo.community.example.yaml b/plugins/misc/marketplace/src/main/samples/hop-marketplace-repo.community.example.yaml new file mode 100644 index 00000000000..6ad308be367 --- /dev/null +++ b/plugins/misc/marketplace/src/main/samples/hop-marketplace-repo.community.example.yaml @@ -0,0 +1,40 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Shareable marketplace repository definition. +# +# ./hop marketplace repo import this-file.yaml +# ./hop marketplace query datavault +# ./hop marketplace install org.apache.hop:hop-datavault:0.4.0-SNAPSHOT +# +# browse: true → Hop lists *.zip from this Nexus repo live (no cache, no refresh). +# Optional plugins: metadata below only enriches display when present. +# +schemaVersion: "1.0" +kind: hop-marketplace-repository + +id: data-hopper-community +name: Data Hopper Community Plugins +url: https://repository.data-hopper.com/repository/hop-community-plugins/ +primary: false +enabled: true +browse: true +includeSnapshots: true + +# Optional metadata (enriches live Nexus list; not a cache) +# minHopVersion: only show when the running Hop is >= this version +# version: optional pin of the plugin artifact (else latest from browse) +plugins: + - groupId: org.apache.hop + artifactId: hop-datavault + version: 0.4.0-SNAPSHOT + minHopVersion: "2.18.1" + name: Data Vault + category: Community + description: Data Vault transforms for Hop diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/PluginDiscoveryEnrichTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/PluginDiscoveryEnrichTest.java new file mode 100644 index 00000000000..5f2a358fa23 --- /dev/null +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/PluginDiscoveryEnrichTest.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.catalog; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.List; +import org.apache.hop.marketplace.config.MarketplaceRepository; +import org.junit.jupiter.api.Test; + +class PluginDiscoveryEnrichTest { + + @Test + void enrichCategoryAndNameFromYamlWithoutGroupId() { + OptionalPluginInfo live = new OptionalPluginInfo(); + live.setGroupId("org.apache.hop"); + live.setArtifactId("hop-datavault"); + live.setVersion("0.4.0-SNAPSHOT"); + live.setName("hop-datavault"); + live.setCategory("auto-discovered"); + live.setDescription("org/apache/hop/hop-datavault/0.4.0-SNAPSHOT/..."); + + OptionalPluginInfo meta = new OptionalPluginInfo(); + // no groupId — common in hand-written YAML + meta.setArtifactId("hop-datavault"); + meta.setName("Data Vault"); + meta.setCategory("Community"); + meta.setDescription("Data Vault transforms for Hop"); + meta.setMinHopVersion("2.18.1"); + meta.setVersion("0.4.0-SNAPSHOT"); + + MarketplaceRepository repo = new MarketplaceRepository("community", "https://example/repo/"); + repo.setPlugins(new ArrayList<>(List.of(meta))); + + List out = + PluginDiscovery.enrichWithDefinitionMetadata(List.of(live), repo); + assertEquals(1, out.size()); + assertEquals("Community", out.get(0).getCategory()); + assertEquals("Data Vault", out.get(0).getName()); + assertEquals("Data Vault transforms for Hop", out.get(0).getDescription()); + assertEquals("2.18.1", out.get(0).getMinHopVersion()); + } + + @Test + void enrichMatchesOnFullGa() { + OptionalPluginInfo live = new OptionalPluginInfo(); + live.setGroupId("org.apache.hop"); + live.setArtifactId("hop-datavault"); + live.setCategory("auto-discovered"); + live.setName("hop-datavault"); + + OptionalPluginInfo meta = new OptionalPluginInfo(); + meta.setGroupId("org.apache.hop"); + meta.setArtifactId("hop-datavault"); + meta.setCategory("Community"); + meta.setName("Data Vault"); + + MarketplaceRepository repo = new MarketplaceRepository("c", "https://x/"); + repo.setPlugins(List.of(meta)); + + PluginDiscovery.enrichWithDefinitionMetadata(List.of(live), repo); + assertEquals("Community", live.getCategory()); + assertEquals("Data Vault", live.getName()); + } +} diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/PluginDiscoveryResolveInstallTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/PluginDiscoveryResolveInstallTest.java new file mode 100644 index 00000000000..1606d447743 --- /dev/null +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/PluginDiscoveryResolveInstallTest.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.catalog; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import org.apache.hop.core.exception.HopException; +import org.junit.jupiter.api.Test; + +class PluginDiscoveryResolveInstallTest { + + @Test + void pickExactArtifactId() throws Exception { + OptionalPluginInfo a = plugin("hop-datavault", "0.4.0-SNAPSHOT", "community"); + OptionalPluginInfo b = plugin("hop-other", "1.0", "community"); + OptionalPluginInfo chosen = PluginDiscovery.pickInstallMatch("hop-datavault", List.of(a, b)); + assertEquals("hop-datavault", chosen.getArtifactId()); + assertEquals("0.4.0-SNAPSHOT", chosen.getVersion()); + } + + @Test + void pickShortNameSubstringOnArtifact() throws Exception { + OptionalPluginInfo a = plugin("hop-datavault", "0.4.0-SNAPSHOT", "data-hopper-community"); + OptionalPluginInfo chosen = PluginDiscovery.pickInstallMatch("datavault", List.of(a)); + assertEquals("hop-datavault", chosen.getArtifactId()); + } + + @Test + void ambiguousShortNameThrows() { + OptionalPluginInfo a = plugin("hop-datavault", "0.4.0-SNAPSHOT", "c1"); + OptionalPluginInfo b = plugin("hop-datavault-ui", "1.0", "c1"); + HopException ex = + assertThrows( + HopException.class, () -> PluginDiscovery.pickInstallMatch("datavault", List.of(a, b))); + assertTrue(ex.getMessage().toLowerCase().contains("ambiguous")); + } + + @Test + void fullGavSkipsDiscovery() throws Exception { + PluginDiscovery.InstallTarget target = + PluginDiscovery.resolveInstall( + "org.example:foo:9.9.9", "org.apache.hop", "2.19.0-SNAPSHOT", null, null); + assertEquals("org.example:foo:9.9.9", target.coordinates().gav()); + assertNull(target.preferredRepoId()); + } + + @Test + void unknownNameFallsBackToLiteralParse() throws Exception { + PluginDiscovery.InstallTarget target = + PluginDiscovery.resolveInstall( + "totally-unknown-plugin", "org.apache.hop", "2.19.0-SNAPSHOT", null, null); + assertEquals( + "org.apache.hop:totally-unknown-plugin:2.19.0-SNAPSHOT", target.coordinates().gav()); + } + + private static OptionalPluginInfo plugin(String artifactId, String version, String source) { + OptionalPluginInfo info = new OptionalPluginInfo(); + info.setGroupId("org.apache.hop"); + info.setArtifactId(artifactId); + info.setVersion(version); + info.setSource(source); + return info; + } +} diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/RemotePluginCatalogTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/RemotePluginCatalogTest.java new file mode 100644 index 00000000000..c223a05c4a4 --- /dev/null +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/RemotePluginCatalogTest.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.catalog; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import org.apache.hop.marketplace.config.MarketplaceRepository; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +class RemotePluginCatalogTest { + + @TempDir Path tempDir; + + @Test + void loadYamlCatalogAndFilter() throws Exception { + Path file = tempDir.resolve("catalog.yaml"); + Files.writeString( + file, + """ + schemaVersion: "1.0" + kind: hop-marketplace-catalog + plugins: + - groupId: org.apache.hop + artifactId: hop-datavault + version: 0.4.0-SNAPSHOT + name: Data Vault + category: Community + description: DV transforms + - groupId: com.example + artifactId: other + version: 1.0.0 + name: Other + """, + StandardCharsets.UTF_8); + + MarketplaceRepository repo = new MarketplaceRepository(); + repo.setId("community"); + repo.setCatalogUrl(file.toString()); + repo.setGroupIdFilter("org.apache.hop"); + repo.setIncludeSnapshots(true); + + List all = RemotePluginCatalog.load(repo); + assertEquals(1, all.size()); + assertEquals("hop-datavault", all.get(0).getArtifactId()); + assertEquals("community", all.get(0).getSource()); + + List filtered = RemotePluginCatalog.filter(all, repo, "vault"); + assertEquals(1, filtered.size()); + + repo.setIncludeSnapshots(false); + assertTrue(RemotePluginCatalog.filter(all, repo, null).isEmpty()); + } + + @Test + void nexusUrlParsing() { + assertEquals( + "hop-community-plugins", + NexusRepositoryBrowser.extractRepositoryName( + "https://repository.data-hopper.com/repository/hop-community-plugins/")); + assertEquals( + "https://repository.data-hopper.com", + NexusRepositoryBrowser.extractNexusBase( + "https://repository.data-hopper.com/repository/hop-community-plugins/")); + } +} diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/VersionCompatTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/VersionCompatTest.java new file mode 100644 index 00000000000..e0b50568ba8 --- /dev/null +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/catalog/VersionCompatTest.java @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.catalog; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import org.junit.jupiter.api.Test; + +class VersionCompatTest { + + @Test + void compareNumericAndSnapshot() { + assertTrue(VersionCompat.compare("2.19.0", "2.18.1") > 0); + assertTrue(VersionCompat.compare("2.18.1", "2.19.0-SNAPSHOT") < 0); + assertTrue(VersionCompat.compare("0.4.0-SNAPSHOT", "0.3.0") > 0); + assertEquals(0, VersionCompat.compare("2.19.0-SNAPSHOT", "2.19.0-SNAPSHOT")); + } + + @Test + void latestPicksHighest() { + assertEquals( + "0.4.0-SNAPSHOT", VersionCompat.latest(List.of("0.3.0", "0.4.0-SNAPSHOT", "0.2.0"))); + } + + @Test + void minHopVersionFilter() { + OptionalPluginInfo info = new OptionalPluginInfo(); + info.setArtifactId("hop-datavault"); + info.setMinHopVersion("2.18.1"); + assertTrue(VersionCompat.isCompatibleWithHop(info, "2.19.0-SNAPSHOT")); + assertTrue(VersionCompat.isCompatibleWithHop(info, "2.18.1")); + assertFalse(VersionCompat.isCompatibleWithHop(info, "2.17.0")); + } + + @Test + void maxHopVersionFilter() { + OptionalPluginInfo info = new OptionalPluginInfo(); + info.setMaxHopVersion("2.19.0"); + assertTrue(VersionCompat.isCompatibleWithHop(info, "2.18.0")); + assertFalse(VersionCompat.isCompatibleWithHop(info, "2.20.0")); + } + + @Test + void noBoundsAlwaysCompatible() { + OptionalPluginInfo info = new OptionalPluginInfo(); + info.setArtifactId("auto"); + assertTrue(VersionCompat.isCompatibleWithHop(info, "2.19.0")); + assertTrue(VersionCompat.isCompatibleWithHop(info, null)); + } + + @Test + void nexusPreferableHigherVersion() { + OptionalPluginInfo existing = new OptionalPluginInfo(); + existing.setVersion("0.3.0"); + existing.setLastUpdated("2026-01-01T00:00:00Z"); + assertTrue( + NexusRepositoryBrowser.isPreferable("0.4.0-SNAPSHOT", "2026-07-21T14:00:00Z", existing)); + assertFalse(NexusRepositoryBrowser.isPreferable("0.2.0", "2026-07-21T14:00:00Z", existing)); + } + + @Test + void nexusPreferableSameVersionNewerTimestamp() { + OptionalPluginInfo existing = new OptionalPluginInfo(); + existing.setVersion("0.4.0-SNAPSHOT"); + existing.setLastUpdated("2026-07-21T10:56:17Z"); + assertTrue( + NexusRepositoryBrowser.isPreferable("0.4.0-SNAPSHOT", "2026-07-21T14:42:59Z", existing)); + } +} diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/command/CliTableTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/command/CliTableTest.java new file mode 100644 index 00000000000..d0c72f6ed45 --- /dev/null +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/command/CliTableTest.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.command; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; +import java.util.List; +import org.junit.jupiter.api.Test; + +class CliTableTest { + + @Test + void printTableBordersAlign() { + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + PrintStream out = new PrintStream(buf, true, StandardCharsets.UTF_8); + CliTable.printTable(out, List.of("A", "BB"), List.of(List.of("1", "22"), List.of("xx", "y"))); + String text = buf.toString(StandardCharsets.UTF_8); + String[] lines = text.split("\\R"); + assertTrue(lines.length >= 5); + assertTrue(lines[0].startsWith("+")); + assertTrue(lines[0].endsWith("+")); + assertEquals(lines[0], lines[2]); + assertEquals(lines[0], lines[lines.length - 1]); + assertTrue(lines[1].startsWith("|")); + assertTrue(lines[1].contains("A")); + assertTrue(lines[1].contains("BB")); + } + + @Test + void csvEscapesCommaAndQuotes() { + assertEquals("plain", CliTable.escapeCsv("plain")); + assertEquals("\"a,b\"", CliTable.escapeCsv("a,b")); + assertEquals("\"say \"\"hi\"\"\"", CliTable.escapeCsv("say \"hi\"")); + assertEquals("\"a\nb\"", CliTable.escapeCsv("a\nb")); + } + + @Test + void printCsvHeaderOnlyWhenEmpty() { + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + PrintStream out = new PrintStream(buf, true, StandardCharsets.UTF_8); + CliTable.printCsv(out, List.of("artifact", "version"), List.of()); + String text = buf.toString(StandardCharsets.UTF_8).trim(); + assertEquals("artifact,version", text); + } + + @Test + void printCsvRows() { + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + PrintStream out = new PrintStream(buf, true, StandardCharsets.UTF_8); + CliTable.printCsv(out, List.of("artifact", "desc"), List.of(List.of("hop-x", "hello, world"))); + String text = buf.toString(StandardCharsets.UTF_8).trim(); + String[] lines = text.split("\\R"); + assertEquals(2, lines.length); + assertEquals("artifact,desc", lines[0]); + assertEquals("hop-x,\"hello, world\"", lines[1]); + } + + @Test + void truncateDescription() { + assertEquals("short", CliTable.truncate("short", 56)); + assertEquals("abcdefghij...", CliTable.truncate("abcdefghijklmnopqrstuvwxyz", 13)); + assertFalse(CliTable.truncate("line\nbreak", 20).contains("\n")); + } + + @Test + void queryHeadersOptionalGav() { + List without = MarketplaceCommand.QueryCommand.queryHeaders(false); + assertFalse(without.contains("GAV")); + assertTrue(without.contains("ARTIFACT")); + List with = MarketplaceCommand.QueryCommand.queryHeaders(true); + assertTrue(with.contains("GAV")); + assertEquals(without.size() + 1, with.size()); + } +} diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/config/MarketplaceRepositoryDefinitionTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/config/MarketplaceRepositoryDefinitionTest.java new file mode 100644 index 00000000000..8c728dff598 --- /dev/null +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/config/MarketplaceRepositoryDefinitionTest.java @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.config; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.file.Files; +import java.nio.file.Path; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +class MarketplaceRepositoryDefinitionTest { + + @TempDir Path tempDir; + + @Test + void exportImportRoundTripOmitsPassword() throws Exception { + MarketplaceRepository repo = new MarketplaceRepository(); + repo.setId("community"); + repo.setName("Community"); + repo.setUrl("https://repository.example/repository/hop/"); + repo.setBrowse(true); + repo.setCatalogUrl("https://repository.example/catalog.yaml"); + repo.setIncludeSnapshots(true); + repo.setGroupIdFilter("com.example"); + repo.setSearchQuery("vault"); + repo.setPassword("secret"); + + Path file = tempDir.resolve("def.yaml"); + MarketplaceRepositoryDefinition.save(file, repo); + String text = Files.readString(file); + assertFalse(text.contains("secret")); + assertTrue(text.contains("browse: true")); + + MarketplaceRepository loaded = MarketplaceRepositoryDefinition.load(file); + assertEquals("community", loaded.getId()); + assertEquals("https://repository.example/repository/hop/", loaded.getUrl()); + assertTrue(loaded.isBrowse()); + assertEquals("https://repository.example/catalog.yaml", loaded.getCatalogUrl()); + assertEquals("com.example", loaded.getGroupIdFilter()); + assertEquals("vault", loaded.getSearchQuery()); + assertNull(loaded.getPassword()); + } + + @Test + void applyToConfigUpserts() throws Exception { + MarketplaceConfig config = new MarketplaceConfig(); + MarketplaceRepository first = new MarketplaceRepository("community", "https://a.example/r/"); + first.setBrowse(false); + config.addRepository(first); + + MarketplaceRepository imported = new MarketplaceRepository(); + imported.setId("community"); + imported.setUrl("https://b.example/r/"); + imported.setBrowse(true); + imported.setCatalogUrl("https://b.example/c.yaml"); + MarketplaceRepositoryDefinition.applyToConfig(config, imported, false); + + MarketplaceRepository found = config.findRepository("community"); + assertEquals("https://b.example/r/", found.getUrl()); + assertTrue(found.isBrowse()); + assertEquals("https://b.example/c.yaml", found.getCatalogUrl()); + } + + @Test + void importExportsEmbeddedPlugins() throws Exception { + Path file = tempDir.resolve("with-plugins.yaml"); + Files.writeString( + file, + """ + kind: hop-marketplace-repository + id: community + url: https://repository.example/repository/hop/ + browse: true + plugins: + - groupId: org.apache.hop + artifactId: hop-datavault + version: 0.4.0-SNAPSHOT + minHopVersion: "2.18.1" + category: auto-discovered + description: org/apache/hop/hop-datavault/0.4.0-SNAPSHOT/ + lastUpdated: "2026-07-21T12:00:00.000+00:00" + """); + + MarketplaceRepository loaded = MarketplaceRepositoryDefinition.load(file); + assertEquals(1, loaded.getPlugins().size()); + assertEquals("hop-datavault", loaded.getPlugins().get(0).getArtifactId()); + assertEquals("auto-discovered", loaded.getPlugins().get(0).getCategory()); + assertEquals("2.18.1", loaded.getPlugins().get(0).getMinHopVersion()); + + Path out = tempDir.resolve("out.yaml"); + MarketplaceRepositoryDefinition.save(out, loaded); + String saved = Files.readString(out); + assertTrue(saved.contains("hop-datavault")); + assertTrue(saved.contains("minHopVersion")); + } +} diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/resolve/MavenRepositoryClientSnapshotTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/resolve/MavenRepositoryClientSnapshotTest.java index 4ac9c418899..18d6c1f93bd 100644 --- a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/resolve/MavenRepositoryClientSnapshotTest.java +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/resolve/MavenRepositoryClientSnapshotTest.java @@ -20,6 +20,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; +import org.apache.hop.marketplace.config.MarketplaceRepository; import org.junit.jupiter.api.Test; class MavenRepositoryClientSnapshotTest { @@ -76,4 +77,18 @@ void parseSnapshotFromTimestampOnly() { void emptyMetadata() { assertNull(MavenRepositoryClient.parseSnapshotZipValue("", "a", "1-SNAPSHOT")); } + + @Test + void uniqueSnapshotUsesBaseDirectory() throws Exception { + MavenRepositoryClient client = new MavenRepositoryClient(null); + MarketplaceRepository repo = + new MarketplaceRepository("x", "https://example.com/repository/hop/"); + String path = + client.resolveZipRelativePath( + repo, + new MavenCoordinates("org.apache.hop", "hop-datavault", "0.4.0-20260721.105615-1")); + assertEquals( + "org/apache/hop/hop-datavault/0.4.0-SNAPSHOT/hop-datavault-0.4.0-20260721.105615-1.zip", + path); + } } diff --git a/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/resolve/SnapshotVersionsTest.java b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/resolve/SnapshotVersionsTest.java new file mode 100644 index 00000000000..3c8a6dba4ba --- /dev/null +++ b/plugins/misc/marketplace/src/test/java/org/apache/hop/marketplace/resolve/SnapshotVersionsTest.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.marketplace.resolve; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class SnapshotVersionsTest { + + @Test + void uniqueToBase() { + assertEquals("0.4.0-SNAPSHOT", SnapshotVersions.toBaseVersion("0.4.0-20260721.105615-1")); + assertEquals("2.19.0-SNAPSHOT", SnapshotVersions.toBaseVersion("2.19.0-20260719.204953-1")); + } + + @Test + void alreadyBaseOrRelease() { + assertEquals("0.4.0-SNAPSHOT", SnapshotVersions.toBaseVersion("0.4.0-SNAPSHOT")); + assertEquals("1.2.3", SnapshotVersions.toBaseVersion("1.2.3")); + } + + @Test + void preferPathFolder() { + assertEquals( + "0.4.0-SNAPSHOT", + SnapshotVersions.toBaseVersion( + "0.4.0-20260721.105615-1", + "/org/apache/hop/hop-datavault/0.4.0-SNAPSHOT/hop-datavault-0.4.0-20260721.105615-1.zip")); + } + + @Test + void isSnapshotFlags() { + assertTrue(SnapshotVersions.isSnapshot("0.4.0-SNAPSHOT")); + assertTrue(SnapshotVersions.isSnapshot("0.4.0-20260721.105615-1")); + assertTrue(SnapshotVersions.isUniqueSnapshot("0.4.0-20260721.105615-1")); + assertFalse(SnapshotVersions.isUniqueSnapshot("0.4.0-SNAPSHOT")); + assertFalse(SnapshotVersions.isSnapshot("1.0.0")); + } + + @Test + void versionFolderFromPath() { + assertEquals( + "0.4.0-SNAPSHOT", + SnapshotVersions.versionFolderFromPath( + "/org/apache/hop/hop-datavault/0.4.0-SNAPSHOT/hop-datavault-0.4.0-20260721.105615-1.zip")); + } +}