Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
b1a32af
MLE-28021 Merge main to develop, bump to 2.2-SNAPSHOT
rjrudin Mar 18, 2026
7b3511d
Merge pull request #616 from marklogic/feature/temp-main
rjrudin Mar 18, 2026
c241250
MLE-28021 Bumping Netty to latest patch version
rjrudin Apr 1, 2026
3463c60
MLE-28021 Small docs fix
rjrudin Mar 18, 2026
429627b
MLE-12345 - Clarifying the use of connectionString with Basic authent…
BillFarber Apr 8, 2026
b1aac14
Merge pull request #622 from BillFarber/develop
BillFarber Apr 8, 2026
038ebe0
PDP-1182: Remove per-repo pr-workflow.yaml
SameeraPriyathamTadikonda Apr 9, 2026
7e8d48e
Merge pull request #626 from marklogic/PDP-1182-remove-pr-workflow-fr…
GAdityaVarma Apr 9, 2026
b5b6240
MLE-28702 Using bucket-scoped keys for S3
rjrudin Apr 23, 2026
6c02667
MLE-28702 Adding hidden prop for generic write options
rjrudin Apr 23, 2026
42396c4
MLE-28770 Added S3 anonymous access support
rjrudin Apr 24, 2026
1c1bac7
MLE-12345 abort copy command only when --output-abort-on-write-failur…
jteh May 5, 2026
bbd6f74
MLE-29542 Bumping netty, bouncycastle, and log4j dependencies
rjrudin May 12, 2026
203fa2b
MLE-28770 Adjusting version for S3 anonymous access support
rjrudin May 12, 2026
755d3a9
MLE-29542 Specifying version for thrift
rjrudin May 12, 2026
c0ffb4c
MLE-29542 Using top-level config for thrift dependency
rjrudin May 12, 2026
cff8783
MLE-29542 Added default implementations for new API methods
rjrudin May 18, 2026
70050b2
Bumped to 3.1.1
rjrudin May 12, 2026
a3c68db
Merge branch 'main' into release/2.1.1
rjrudin May 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,15 +198,15 @@ are all synonyms):

./gradlew shadowJar

This will produce an assembly jar at `./flux-cli/build/libs/marklogic-flux-2.1-SNAPSHOT-all.jar`.
This will produce an assembly jar at `./flux-cli/build/libs/marklogic-flux-2.2-SNAPSHOT-all.jar`.
Comment thread
rjrudin marked this conversation as resolved.

You can now run any CLI command via spark-submit. This is an example of previewing an import of files - change the value
of `--path`, as an absolute path is needed, and of course change the value of `--master` to match that of your Spark
cluster:

```
$SPARK_HOME/bin/spark-submit --class com.marklogic.flux.spark.Submit \
--master spark://NYWHYC3G0W:7077 flux-cli/build/libs/marklogic-flux-2.1-SNAPSHOT-all.jar \
--master spark://NYWHYC3G0W:7077 flux-cli/build/libs/marklogic-flux-2.2-SNAPSHOT-all.jar \
Comment thread
rjrudin marked this conversation as resolved.
import-files --path /Users/rudin/workspace/flux/flux-cli/src/test/resources/mixed-files \
--connection-string "admin:admin@localhost:8000" \
--preview 5 --preview-drop content
Expand All @@ -223,7 +223,7 @@ to something you can access):
$SPARK_HOME/bin/spark-submit --class com.marklogic.flux.spark.Submit \
--packages org.apache.hadoop:hadoop-aws:3.3.4,org.apache.hadoop:hadoop-client:3.3.4 \
--master spark://NYWHYC3G0W:7077 \
flux-cli/build/libs/marklogic-flux-2.1-SNAPSHOT-all.jar \
flux-cli/build/libs/marklogic-flux-2.2-SNAPSHOT-all.jar \
Comment thread
rjrudin marked this conversation as resolved.
import-files --path "s3a://changeme/" \
--connection-string "admin:admin@localhost:8000" \
--s3-add-credentials \
Expand Down
6,648 changes: 2,317 additions & 4,331 deletions NOTICE.txt

Large diffs are not rendered by default.

15 changes: 11 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ subprojects {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
// Defining this rule for io.netty here so that it affects both flux-cli and flux-embedding-model-azure-open-ai.
if (details.requested.group.equals("io.netty") and (details.requested.version.startsWith("4.1.") || details.requested.version.startsWith("4.2."))) {
details.useVersion "4.2.10.Final"
details.useVersion "4.2.13.Final"
details.because "Forcing Spark 4.1.x to use latest to minimize CVEs; this also forces azure-open-ai to use latest to avoid conflicts."
}

if (details.requested.group.equals("org.apache.logging.log4j") && details.requested.version.equals("2.24.3")) {
details.useVersion "2.25.3"
details.because "Forces Spark 4.1.x to use log4j 2.25.3 to address this CVE - https://nvd.nist.gov/vuln/detail/CVE-2025-68161 ."
if (details.requested.group.equals("org.apache.logging.log4j") && details.requested.version.startsWith("2.24")) {
details.useVersion "2.26.0"
details.because "Forces Spark 4.1.x to use latest log4j 2.x to eliminate CVEs."
}

if (details.requested.group.startsWith("com.fasterxml.jackson")) {
Expand All @@ -69,6 +69,13 @@ subprojects {
}
details.because "Force Jackson to 2.21.x to align with Java Client 8.1.0."
}

if (details.requested.group.equals("org.apache.thrift") && details.requested.name.equals("libthrift")) {
// This is being done solely for Black Duck's sake, as it seems to be having trouble recognizing that the
// internal snapshot build of the MarkLogic Spark connector is already using version 0.23.0.
details.useVersion "0.23.0"
details.because "Forces Spark 4.1.x to use the latest libthrift, which is needed to avoid CVEs."
}
}
}

Expand Down
11 changes: 6 additions & 5 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Or if you are using Gradle, add the following to your `build.gradle` file:

```
dependencies {
implementation "com.marklogic:flux-api:2.0.0"
implementation "com.marklogic:flux-api:2.1.1"
}
```

Expand Down Expand Up @@ -106,12 +106,13 @@ The `com.marklogic.flux.api.Flux` class is the entry point to the Flux API. This
with each Flux CLI command.

Each method in the `Flux` class returns a subclass of the `com.marklogic.flux.api.Executor` interface. Each instance of
`Executor` has two methods for specifying a connection to MarkLogic:
`Executor` has three methods for specifying a connection to MarkLogic:

- `connectionString(String)` allows you to specify a connection to MarkLogic via a connection string, which requires
the user of `basic` or `digest` authentication.
the use of `digest` authentication.
- `connectionStringBasic(String)` allows you to specify a connection string and force `basic` authentication.
- `connection(Consumer<ConnectionOptions>)` allows you to specify a Java lambda expression for configuring the necessary
options on the given `com.marklogic.flux.api.ConnectionOptions` object.
options on the given `com.marklogic.flux.api.ConnectionOptions` object.

Each subclass of `Executor` has `from` and `to` methods for specifying options that control where data is read from and
control where data is written to. Similar to the `connection` method above, all `from` and `to` methods allow you to
Expand Down Expand Up @@ -160,7 +161,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath "com.marklogic:flux-api:2.0.0"
classpath "com.marklogic:flux-api:2.1.1"
}
}
```
Expand Down
3 changes: 3 additions & 0 deletions docs/common-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ password of `sp@r:k`, you would use the following string:

--connection-string user:sp%40r%3Ak@host:8000

When using `--connection-string`, Flux defaults to digest authentication. If your app server requires basic
authentication, also include `--auth-type basic`.

For other authentication mechanisms, you must use the `--host` and `--port` options to define the host and port for
your MarkLogic app server.

Expand Down
3 changes: 3 additions & 0 deletions docs/export/specifying-path.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ can specify a profile via the `AWS_PROFILE` environment variable. See the
[AWS documentation on configuration and credential files](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html)
for more information.

**Anonymous authentication** - As of Flux 2.1.1, you can use `--s3-anonymous` to access public S3 buckets that do not
require authentication.

### Configuring the S3 connection

When running Flux within AWS and accessing an S3 bucket in a different region, you may need to configure the S3
Expand Down
3 changes: 3 additions & 0 deletions docs/import/import-files/selecting-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ can specify a profile via the `AWS_PROFILE` environment variable. See the
[AWS documentation on configuration and credential files](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html)
for more information.

**Anonymous authentication** - As of Flux 2.1.1, you can use `--s3-anonymous` to access public S3 buckets that do not
require authentication.

### Configuring the S3 connection

When running Flux within AWS and accessing an S3 bucket in a different region, you may need to configure the S3
Expand Down
6 changes: 3 additions & 3 deletions docs/spark-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Flux integrates with [spark-submit](https://spark.apache.org/docs/latest/submitt
submit a Flux command invocation to a remote Spark cluster. Every Flux command is a Spark application, and thus every
Flux command, along with all of its option, can be invoked via `spark-submit`.

To use Flux with `spark-submit`, first download the `marklogic-flux-2.1.0-all.jar` file from the
To use Flux with `spark-submit`, first download the `marklogic-flux-2.1.1-all.jar` file from the
[GitHub release page](https://github.com/marklogic/flux/releases). This jar file includes Flux and all of
its dependencies, excluding those of Spark itself, which will be provided via the Spark cluster that you connect to
via `spark-submit`.
Expand All @@ -51,7 +51,7 @@ The following shows a notional example of running the Flux `import-files` comman
```
$SPARK_HOME/bin/spark-submit --class com.marklogic.flux.spark.Submit \
--master spark://changeme:7077 \
marklogic-flux-2.1.0-all.jar \
marklogic-flux-2.1.1-all.jar \
import-files \
--path path/to/data \
--connection-string user:password@host:8000 \
Expand All @@ -62,7 +62,7 @@ $SPARK_HOME/bin/spark-submit --class com.marklogic.flux.spark.Submit \
```
$SPARK_HOME\bin\spark-submit --class com.marklogic.flux.spark.Submit ^
--master spark://changeme:7077 ^
marklogic-flux-2.1.0-all.jar ^
marklogic-flux-2.1.1-all.jar ^
import-files ^
--path path/to/data ^
--connection-string user:password@host:8000 ^
Expand Down
6 changes: 3 additions & 3 deletions examples/client-project/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ buildscript {
mavenLocal()
}
dependencies {
classpath "com.marklogic:flux-api:2.0.0"
classpath "com.marklogic:flux-api:2.1.1"
}
}

Expand All @@ -30,8 +30,8 @@ repositories {
}

dependencies {
implementation "com.marklogic:flux-api:2.0.0"
implementation "com.marklogic:flux-embedding-model-minilm:2.0.0"
implementation "com.marklogic:flux-api:2.1.1"
implementation "com.marklogic:flux-embedding-model-minilm:2.1.1"
}

/**
Expand Down
16 changes: 16 additions & 0 deletions flux-cli/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ dependencies {
implementation("org.eclipse.jetty:jetty-util-ajax:9.4.58.v20250814") {
because "Bumping to latest 9.x to eliminate CVEs; this is brought in by hadoop-azure."
}
implementation("org.bouncycastle:bcprov-jdk18on:1.84") {
because "Bumping to latest 1.x to eliminate CVEs; this is a transitive dependency of Tika."
}
implementation("org.bouncycastle:bcjmail-jdk18on:1.84") {
because "Bumping to latest 1.x to eliminate CVEs; this is a transitive dependency of Tika."
}
testImplementation("org.assertj:assertj-core:3.27.7") {
because "Resolves CVE https://nvd.nist.gov/vuln/detail/CVE-2026-24400"
}
Expand Down Expand Up @@ -350,6 +356,16 @@ publishing {
}
}
repositories {
if (project.hasProperty("ghToken")) {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/rjrudin/flux")
Comment thread
rjrudin marked this conversation as resolved.
credentials {
username = ghActor
password = ghToken
Comment on lines +359 to +365
}
}
}
maven {
if (project.hasProperty("mavenUser")) {
credentials {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2024-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
* Copyright (c) 2024-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
*/
package com.marklogic.flux.api;

Expand All @@ -23,6 +23,14 @@ public interface CustomExportWriteOptions {
*/
CustomExportWriteOptions s3UseProfile();

/**
* @since 2.1.1
*/
default CustomExportWriteOptions s3AnonymousAccess() {
// Default implementation for backwards compatibility.
throw new UnsupportedOperationException("S3 anonymous access is not supported in this implementation");
}

CustomExportWriteOptions s3AccessKeyId(String accessKeyId);

CustomExportWriteOptions s3SecretAccessKey(String secretAccessKey);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2024-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
* Copyright (c) 2024-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
*/
package com.marklogic.flux.api;

Expand All @@ -25,6 +25,14 @@ interface CustomReadOptions {
*/
CustomReadOptions s3UseProfile();

/**
* @since 2.1.1
*/
default CustomReadOptions s3AnonymousAccess() {
// Default implementation for backwards compatibility.
throw new UnsupportedOperationException("S3 anonymous access is not supported in this implementation");
}

CustomReadOptions s3AccessKeyId(String accessKeyId);

CustomReadOptions s3SecretAccessKey(String secretAccessKey);
Expand Down
14 changes: 13 additions & 1 deletion flux-cli/src/main/java/com/marklogic/flux/api/Executor.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2024-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
* Copyright (c) 2024-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
*/
package com.marklogic.flux.api;

Expand Down Expand Up @@ -42,6 +42,18 @@ public interface Executor<T extends Executor> {
*/
T connectionString(String connectionString);

/**
* Convenience for configuring a MarkLogic connection via a connection string and forcing basic authentication.
*
* @param connectionString Defines a connection to MarkLogic via "user:password@host:port/optionalDatabaseName".
* @return instance of this executor
* @since 2.1.1
*/
default T connectionStringBasic(String connectionString) {
// Default implementation for backwards compatibility.
return connectionString(connectionString);
}

Comment on lines +53 to +56
/**
* Limit the number of records read from the executor's data source.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2024-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
* Copyright (c) 2024-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
*/
package com.marklogic.flux.api;

Expand Down Expand Up @@ -30,6 +30,14 @@ interface WriteGenericFilesOptions {
*/
WriteGenericFilesOptions s3UseProfile();

/**
* @since 2.1.1
*/
default WriteGenericFilesOptions s3AnonymousAccess() {
// Default implementation for backwards compatibility.
throw new UnsupportedOperationException("S3 anonymous access is not supported in this implementation");
}

WriteGenericFilesOptions s3AccessKeyId(String accessKeyId);

WriteGenericFilesOptions s3SecretAccessKey(String secretAccessKey);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2024-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
* Copyright (c) 2024-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
*/
package com.marklogic.flux.api;

Expand All @@ -24,6 +24,14 @@ public interface ReadFilesOptions<T extends ReadFilesOptions> {
*/
T s3UseProfile();

/**
* @since 2.1.1
*/
default T s3AnonymousAccess() {
// Default implementation for backwards compatibility.
throw new UnsupportedOperationException("S3 anonymous access is not supported in this implementation");
}

T s3AccessKeyId(String accessKeyId);

T s3SecretAccessKey(String secretAccessKey);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2024-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
* Copyright (c) 2024-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
*/
package com.marklogic.flux.api;

Expand All @@ -20,6 +20,14 @@ public interface WriteFilesOptions<T extends WriteFilesOptions> {
*/
T s3UseProfile();

/**
* @since 2.1.1
*/
default T s3AnonymousAccess() {
// Default implementation for backwards compatibility.
throw new UnsupportedOperationException("S3 anonymous access is not supported in this implementation");
}

T s3Endpoint(String endpoint);

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/*
* Copyright (c) 2024-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
* Copyright (c) 2024-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
*/
package com.marklogic.flux.impl;

import com.marklogic.flux.api.AuthenticationType;
import com.marklogic.flux.api.Executor;
import com.marklogic.flux.api.FluxException;
import com.marklogic.spark.ConnectorException;
Expand Down Expand Up @@ -222,6 +223,13 @@ public T connectionString(String connectionString) {
return (T) this;
}

@Override
public T connectionStringBasic(String connectionString) {
getConnectionParams().authenticationType(AuthenticationType.BASIC);
getConnectionParams().connectionString(connectionString);
return (T) this;
}

@Override
public T limit(int limit) {
commonParams.setLimit(limit);
Expand All @@ -248,7 +256,8 @@ protected final String applyCloudStorageParams(Configuration conf, CloudStorageP
* each path if necessary based on the Azure Storage parameters.
*/
protected final List<String> applyCloudStorageParams(Configuration conf, CloudStorageParams params, List<String> paths) {
applyCloudStorageParams(conf, params);
params.getS3Params().addToHadoopConfiguration(conf, paths);
params.getAzureStorageParams().addToHadoopConfiguration(conf);
List<String> transformedPaths = params.getAzureStorageParams().transformPathsIfNecessary(paths);
if (logger.isInfoEnabled()) {
if (transformedPaths.size() == 1) {
Expand Down
Loading
Loading