This is an automated email from the ASF dual-hosted git repository.
exceptionfactory pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new 19d8ff0bac NIFI-13987 Add SSL Context Service in
GitHubFlowRegistryClient and GitLabFlowRegistryClient (#10788)
19d8ff0bac is described below
commit 19d8ff0bac77e0c06cceada178b4874e62c3d6b3
Author: Pierre Villard <[email protected]>
AuthorDate: Tue Jan 20 19:52:16 2026 +0100
NIFI-13987 Add SSL Context Service in GitHubFlowRegistryClient and
GitLabFlowRegistryClient (#10788)
Signed-off-by: David Handermann <[email protected]>
---
.../nifi-git-flow-registry/pom.xml | 5 ++++
.../flow/git/AbstractGitFlowRegistryClient.java | 9 +++++++
.../nifi/github/GitHubFlowRegistryClient.java | 2 ++
.../apache/nifi/github/GitHubRepositoryClient.java | 17 ++++++++++++
.../nifi/gitlab/GitLabFlowRegistryClient.java | 2 ++
.../apache/nifi/gitlab/GitLabRepositoryClient.java | 31 +++++++++++++++++++++-
6 files changed, 65 insertions(+), 1 deletion(-)
diff --git
a/nifi-extension-bundles/nifi-extension-utils/nifi-git-flow-registry/pom.xml
b/nifi-extension-bundles/nifi-extension-utils/nifi-git-flow-registry/pom.xml
index 293ac5de84..3bbeae47c5 100644
--- a/nifi-extension-bundles/nifi-extension-utils/nifi-git-flow-registry/pom.xml
+++ b/nifi-extension-bundles/nifi-extension-utils/nifi-git-flow-registry/pom.xml
@@ -28,6 +28,11 @@
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jakarta-xmlbind-annotations</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-ssl-context-service-api</artifactId>
+ <version>2.8.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-mock</artifactId>
diff --git
a/nifi-extension-bundles/nifi-extension-utils/nifi-git-flow-registry/src/main/java/org/apache/nifi/registry/flow/git/AbstractGitFlowRegistryClient.java
b/nifi-extension-bundles/nifi-extension-utils/nifi-git-flow-registry/src/main/java/org/apache/nifi/registry/flow/git/AbstractGitFlowRegistryClient.java
index bd98772ab3..96e8e87753 100644
---
a/nifi-extension-bundles/nifi-extension-utils/nifi-git-flow-registry/src/main/java/org/apache/nifi/registry/flow/git/AbstractGitFlowRegistryClient.java
+++
b/nifi-extension-bundles/nifi-extension-utils/nifi-git-flow-registry/src/main/java/org/apache/nifi/registry/flow/git/AbstractGitFlowRegistryClient.java
@@ -56,6 +56,7 @@ import
org.apache.nifi.registry.flow.git.client.GitCreateContentRequest;
import org.apache.nifi.registry.flow.git.client.GitRepositoryClient;
import org.apache.nifi.registry.flow.git.serialize.FlowSnapshotSerializer;
import
org.apache.nifi.registry.flow.git.serialize.JacksonFlowSnapshotSerializer;
+import org.apache.nifi.ssl.SSLContextProvider;
import org.apache.nifi.util.StringUtils;
import java.io.IOException;
@@ -111,6 +112,13 @@ public abstract class AbstractGitFlowRegistryClient
extends AbstractFlowRegistry
.required(true)
.build();
+ public static final PropertyDescriptor SSL_CONTEXT_SERVICE = new
PropertyDescriptor.Builder()
+ .name("SSL Context Service")
+ .description("SSL Context Service provides trusted certificates
and client certificates for TLS communication.")
+ .required(false)
+ .identifiesControllerService(SSLContextProvider.class)
+ .build();
+
static final String DEFAULT_BUCKET_NAME = "default";
static final String DEFAULT_BUCKET_KEEP_FILE_PATH = DEFAULT_BUCKET_NAME +
"/.keep";
static final String DEFAULT_BUCKET_KEEP_FILE_CONTENT = "Do Not Delete";
@@ -140,6 +148,7 @@ public abstract class AbstractGitFlowRegistryClient extends
AbstractFlowRegistry
combinedPropertyDescriptors.add(REPOSITORY_PATH);
combinedPropertyDescriptors.add(DIRECTORY_FILTER_EXCLUDE);
combinedPropertyDescriptors.add(PARAMETER_CONTEXT_VALUES);
+ combinedPropertyDescriptors.add(SSL_CONTEXT_SERVICE);
propertyDescriptors =
Collections.unmodifiableList(combinedPropertyDescriptors);
flowSnapshotSerializer = createFlowSnapshotSerializer();
diff --git
a/nifi-extension-bundles/nifi-github-bundle/nifi-github-extensions/src/main/java/org/apache/nifi/github/GitHubFlowRegistryClient.java
b/nifi-extension-bundles/nifi-github-bundle/nifi-github-extensions/src/main/java/org/apache/nifi/github/GitHubFlowRegistryClient.java
index d1063564cb..da085231eb 100644
---
a/nifi-extension-bundles/nifi-github-bundle/nifi-github-extensions/src/main/java/org/apache/nifi/github/GitHubFlowRegistryClient.java
+++
b/nifi-extension-bundles/nifi-github-bundle/nifi-github-extensions/src/main/java/org/apache/nifi/github/GitHubFlowRegistryClient.java
@@ -26,6 +26,7 @@ import
org.apache.nifi.registry.flow.FlowRegistryClientConfigurationContext;
import org.apache.nifi.registry.flow.FlowRegistryException;
import org.apache.nifi.registry.flow.git.AbstractGitFlowRegistryClient;
import org.apache.nifi.registry.flow.git.client.GitRepositoryClient;
+import org.apache.nifi.ssl.SSLContextProvider;
import java.io.IOException;
import java.util.List;
@@ -125,6 +126,7 @@ public class GitHubFlowRegistryClient extends
AbstractGitFlowRegistryClient {
.repoOwner(context.getProperty(REPOSITORY_OWNER).getValue())
.repoName(context.getProperty(REPOSITORY_NAME).getValue())
.repoPath(context.getProperty(REPOSITORY_PATH).getValue())
+
.sslContext(context.getProperty(SSL_CONTEXT_SERVICE).asControllerService(SSLContextProvider.class))
.build();
}
diff --git
a/nifi-extension-bundles/nifi-github-bundle/nifi-github-extensions/src/main/java/org/apache/nifi/github/GitHubRepositoryClient.java
b/nifi-extension-bundles/nifi-github-bundle/nifi-github-extensions/src/main/java/org/apache/nifi/github/GitHubRepositoryClient.java
index f4ef6a0fe4..f428d47679 100644
---
a/nifi-extension-bundles/nifi-github-bundle/nifi-github-extensions/src/main/java/org/apache/nifi/github/GitHubRepositoryClient.java
+++
b/nifi-extension-bundles/nifi-github-bundle/nifi-github-extensions/src/main/java/org/apache/nifi/github/GitHubRepositoryClient.java
@@ -26,6 +26,7 @@ import org.apache.nifi.registry.flow.FlowRegistryException;
import org.apache.nifi.registry.flow.git.client.GitCommit;
import org.apache.nifi.registry.flow.git.client.GitCreateContentRequest;
import org.apache.nifi.registry.flow.git.client.GitRepositoryClient;
+import org.apache.nifi.ssl.SSLContextProvider;
import org.kohsuke.github.GHCommit;
import org.kohsuke.github.GHContent;
import org.kohsuke.github.GHContentUpdateResponse;
@@ -41,11 +42,13 @@ import org.kohsuke.github.PagedIterator;
import org.kohsuke.github.authorization.AppInstallationAuthorizationProvider;
import org.kohsuke.github.authorization.AuthorizationProvider;
import org.kohsuke.github.connector.GitHubConnectorResponse;
+import org.kohsuke.github.extras.HttpClientGitHubConnector;
import org.kohsuke.github.extras.authorization.JWTTokenProvider;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.net.http.HttpClient;
import java.security.PrivateKey;
import java.time.Instant;
import java.util.ArrayList;
@@ -118,6 +121,14 @@ public class GitHubRepositoryClient implements
GitRepositoryClient {
}
});
+ // Configure HttpClient connector with SSL context if provided
+ if (builder.sslContextProvider != null) {
+ final HttpClient httpClient = HttpClient.newBuilder()
+ .sslContext(builder.sslContextProvider.createContext())
+ .build();
+ gitHubBuilder.withConnector(new
HttpClientGitHubConnector(httpClient));
+ }
+
gitHub = gitHubBuilder.build();
final String fullRepoName = repoOwner + "/" + repoName;
@@ -511,6 +522,7 @@ public class GitHubRepositoryClient implements
GitRepositoryClient {
private String appPrivateKey;
private String appId;
private ComponentLog logger;
+ private SSLContextProvider sslContextProvider;
public Builder apiUrl(final String apiUrl) {
this.apiUrl = apiUrl;
@@ -556,6 +568,11 @@ public class GitHubRepositoryClient implements
GitRepositoryClient {
return this;
}
+ public Builder sslContext(final SSLContextProvider sslContextProvider)
{
+ this.sslContextProvider = sslContextProvider;
+ return this;
+ }
+
public GitHubRepositoryClient build() throws IOException,
FlowRegistryException {
return new GitHubRepositoryClient(this);
}
diff --git
a/nifi-extension-bundles/nifi-gitlab-bundle/nifi-gitlab-extensions/src/main/java/org/apache/nifi/gitlab/GitLabFlowRegistryClient.java
b/nifi-extension-bundles/nifi-gitlab-bundle/nifi-gitlab-extensions/src/main/java/org/apache/nifi/gitlab/GitLabFlowRegistryClient.java
index 800aaf41a9..20af7b1a38 100644
---
a/nifi-extension-bundles/nifi-gitlab-bundle/nifi-gitlab-extensions/src/main/java/org/apache/nifi/gitlab/GitLabFlowRegistryClient.java
+++
b/nifi-extension-bundles/nifi-gitlab-bundle/nifi-gitlab-extensions/src/main/java/org/apache/nifi/gitlab/GitLabFlowRegistryClient.java
@@ -25,6 +25,7 @@ import
org.apache.nifi.registry.flow.FlowRegistryClientConfigurationContext;
import org.apache.nifi.registry.flow.FlowRegistryException;
import org.apache.nifi.registry.flow.git.AbstractGitFlowRegistryClient;
import org.apache.nifi.registry.flow.git.client.GitRepositoryClient;
+import org.apache.nifi.ssl.SSLContextProvider;
import org.gitlab4j.api.GitLabApi;
import java.util.List;
@@ -141,6 +142,7 @@ public class GitLabFlowRegistryClient extends
AbstractGitFlowRegistryClient {
.authToken(context.getProperty(ACCESS_TOKEN).evaluateAttributeExpressions().getValue())
.connectTimeout(context.getProperty(CONNECT_TIMEOUT).asTimePeriod(TimeUnit.MILLISECONDS).intValue())
.readTimeout(context.getProperty(READ_TIMEOUT).asTimePeriod(TimeUnit.MILLISECONDS).intValue())
+
.sslContext(context.getProperty(SSL_CONTEXT_SERVICE).asControllerService(SSLContextProvider.class))
.build();
}
}
diff --git
a/nifi-extension-bundles/nifi-gitlab-bundle/nifi-gitlab-extensions/src/main/java/org/apache/nifi/gitlab/GitLabRepositoryClient.java
b/nifi-extension-bundles/nifi-gitlab-bundle/nifi-gitlab-extensions/src/main/java/org/apache/nifi/gitlab/GitLabRepositoryClient.java
index c9fdf43a93..f63ac57424 100644
---
a/nifi-extension-bundles/nifi-gitlab-bundle/nifi-gitlab-extensions/src/main/java/org/apache/nifi/gitlab/GitLabRepositoryClient.java
+++
b/nifi-extension-bundles/nifi-gitlab-bundle/nifi-gitlab-extensions/src/main/java/org/apache/nifi/gitlab/GitLabRepositoryClient.java
@@ -27,6 +27,7 @@ import org.apache.nifi.registry.flow.FlowRegistryException;
import org.apache.nifi.registry.flow.git.client.GitCommit;
import org.apache.nifi.registry.flow.git.client.GitCreateContentRequest;
import org.apache.nifi.registry.flow.git.client.GitRepositoryClient;
+import org.apache.nifi.ssl.SSLContextProvider;
import org.gitlab4j.api.CommitsApi;
import org.gitlab4j.api.GitLabApi;
import org.gitlab4j.api.GitLabApiException;
@@ -43,6 +44,7 @@ import org.gitlab4j.api.models.RepositoryFile;
import org.gitlab4j.api.models.TreeItem;
import org.gitlab4j.models.Constants;
import org.gitlab4j.models.Constants.Encoding;
+import org.glassfish.jersey.client.ClientProperties;
import java.io.IOException;
import java.io.InputStream;
@@ -52,12 +54,17 @@ import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Base64;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.function.Supplier;
import java.util.stream.Collectors;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
/**
* Implementation of {@link GitRepositoryClient} for GitLab.
@@ -88,6 +95,7 @@ public class GitLabRepositoryClient implements
GitRepositoryClient {
private final int connectTimeout;
private final int readTimeout;
+ private final SSLContextProvider sslContextProvider;
private final GitLabApi gitLab;
private final boolean canRead;
@@ -110,8 +118,17 @@ public class GitLabRepositoryClient implements
GitRepositoryClient {
connectTimeout = builder.connectTimeout;
readTimeout = builder.readTimeout;
+ sslContextProvider = builder.sslContextProvider;
+
+ // Configure client properties for SSL context if provided
+ final Map<String, Object> clientConfigProperties = new HashMap<>();
+ if (sslContextProvider != null) {
+ // Jersey client property for SSL context supplier
+ final Supplier<SSLContext> sslContextSupplier = () ->
sslContextProvider.createContext();
+ clientConfigProperties.put(ClientProperties.SSL_CONTEXT_SUPPLIER,
sslContextSupplier);
+ }
- gitLab = new GitLabApi(apiVersion, apiUrl, tokenType, authToken);
+ gitLab = new GitLabApi(apiVersion, apiUrl, tokenType, authToken, null,
clientConfigProperties);
gitLab.setRequestTimeout(builder.connectTimeout, builder.readTimeout);
gitLab.setDefaultPerPage(DEFAULT_ITEMS_PER_PAGE);
@@ -378,6 +395,12 @@ public class GitLabRepositoryClient implements
GitRepositoryClient {
connection.setRequestProperty(PRIVATE_TOKEN_HEADER,
gitLab.getAuthToken());
connection.setConnectTimeout(connectTimeout);
connection.setReadTimeout(readTimeout);
+
+ // Configure SSL context for HTTPS connections
+ if (sslContextProvider != null && connection instanceof
HttpsURLConnection httpsConnection) {
+
httpsConnection.setSSLSocketFactory(sslContextProvider.createContext().getSocketFactory());
+ }
+
return connection;
}
@@ -455,6 +478,7 @@ public class GitLabRepositoryClient implements
GitRepositoryClient {
private int connectTimeout;
private int readTimeout;
private ComponentLog logger;
+ private SSLContextProvider sslContextProvider;
public Builder clientId(final String clientId) {
this.clientId = clientId;
@@ -511,6 +535,11 @@ public class GitLabRepositoryClient implements
GitRepositoryClient {
return this;
}
+ public Builder sslContext(final SSLContextProvider sslContextProvider)
{
+ this.sslContextProvider = sslContextProvider;
+ return this;
+ }
+
public GitLabRepositoryClient build() throws FlowRegistryException {
return new GitLabRepositoryClient(this);
}