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 2e6eaaeb38 NIFI-11926: Added proxy handling in Azure Storage
Credentials Services
2e6eaaeb38 is described below
commit 2e6eaaeb38c2166a06f7876740968230af81f7f5
Author: Peter Turcsanyi <[email protected]>
AuthorDate: Mon Aug 7 16:44:23 2023 +0200
NIFI-11926: Added proxy handling in Azure Storage Credentials Services
Added Proxy Configuration Service property in
AzureStorageCredentialsControllerService_v12 and
ADLSCredentialsControllerService used by Service Principal and Managed Identity
authentication modes.
This closes #7590
Signed-off-by: David Handermann <[email protected]>
---
.../storage/utils/BlobServiceClientFactory.java | 7 ++
.../utils/DataLakeServiceClientFactory.java | 8 ++
.../storage/ADLSCredentialsControllerService.java | 7 +-
...ureStorageCredentialsControllerService_v12.java | 15 ++-
.../azure/storage/ADLSCredentialsDetails.java | 28 ++++-
.../AzureStorageCredentialsDetails_v12.java | 35 ++++--
.../services/azure/util/ProxyOptionsUtils.java | 55 ++++++++
.../services/azure/util/ProxyOptionsUtilsTest.java | 140 +++++++++++++++++++++
8 files changed, 277 insertions(+), 18 deletions(-)
diff --git
a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/storage/utils/BlobServiceClientFactory.java
b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/storage/utils/BlobServiceClientFactory.java
index b5a354b145..12e49c93dd 100644
---
a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/storage/utils/BlobServiceClientFactory.java
+++
b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/storage/utils/BlobServiceClientFactory.java
@@ -19,6 +19,7 @@ package org.apache.nifi.processors.azure.storage.utils;
import com.azure.core.credential.AzureSasCredential;
import com.azure.core.credential.TokenCredential;
import com.azure.core.http.ProxyOptions;
+import com.azure.core.http.netty.NettyAsyncHttpClientBuilder;
import com.azure.core.util.ClientOptions;
import com.azure.core.util.HttpClientOptions;
import com.azure.identity.ClientSecretCredentialBuilder;
@@ -59,6 +60,9 @@ public class BlobServiceClientFactory extends
AbstractStorageClientFactory<Azure
case MANAGED_IDENTITY:
clientBuilder.credential(new ManagedIdentityCredentialBuilder()
.clientId(credentialsDetails.getManagedIdentityClientId())
+ .httpClient(new NettyAsyncHttpClientBuilder()
+ .proxy(credentialsDetails.getProxyOptions())
+ .build())
.build());
break;
case SERVICE_PRINCIPAL:
@@ -66,6 +70,9 @@ public class BlobServiceClientFactory extends
AbstractStorageClientFactory<Azure
.tenantId(credentialsDetails.getServicePrincipalTenantId())
.clientId(credentialsDetails.getServicePrincipalClientId())
.clientSecret(credentialsDetails.getServicePrincipalClientSecret())
+ .httpClient(new NettyAsyncHttpClientBuilder()
+ .proxy(credentialsDetails.getProxyOptions())
+ .build())
.build());
break;
case ACCESS_TOKEN:
diff --git
a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/storage/utils/DataLakeServiceClientFactory.java
b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/storage/utils/DataLakeServiceClientFactory.java
index 51ee6ff9b3..fb43393dcc 100644
---
a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/storage/utils/DataLakeServiceClientFactory.java
+++
b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/storage/utils/DataLakeServiceClientFactory.java
@@ -19,6 +19,7 @@ package org.apache.nifi.processors.azure.storage.utils;
import com.azure.core.credential.AccessToken;
import com.azure.core.credential.TokenCredential;
import com.azure.core.http.ProxyOptions;
+import com.azure.core.http.netty.NettyAsyncHttpClientBuilder;
import com.azure.core.util.ClientOptions;
import com.azure.core.util.HttpClientOptions;
import com.azure.identity.ClientSecretCredential;
@@ -50,6 +51,7 @@ public class DataLakeServiceClientFactory extends
AbstractStorageClientFactory<A
final String servicePrincipalTenantId =
credentialsDetails.getServicePrincipalTenantId();
final String servicePrincipalClientId =
credentialsDetails.getServicePrincipalClientId();
final String servicePrincipalClientSecret =
credentialsDetails.getServicePrincipalClientSecret();
+ final ProxyOptions credentialProxyOptions =
credentialsDetails.getProxyOptions();
final String endpoint = String.format("https://%s.%s", accountName,
endpointSuffix);
@@ -67,6 +69,9 @@ public class DataLakeServiceClientFactory extends
AbstractStorageClientFactory<A
} else if (useManagedIdentity) {
final ManagedIdentityCredential misCredential = new
ManagedIdentityCredentialBuilder()
.clientId(managedIdentityClientId)
+ .httpClient(new NettyAsyncHttpClientBuilder()
+ .proxy(credentialProxyOptions)
+ .build())
.build();
dataLakeServiceClientBuilder.credential(misCredential);
} else if (StringUtils.isNoneBlank(servicePrincipalTenantId,
servicePrincipalClientId, servicePrincipalClientSecret)) {
@@ -74,6 +79,9 @@ public class DataLakeServiceClientFactory extends
AbstractStorageClientFactory<A
.tenantId(servicePrincipalTenantId)
.clientId(servicePrincipalClientId)
.clientSecret(servicePrincipalClientSecret)
+ .httpClient(new NettyAsyncHttpClientBuilder()
+ .proxy(credentialProxyOptions)
+ .build())
.build();
dataLakeServiceClientBuilder.credential(credential);
} else {
diff --git
a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsControllerService.java
b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsControllerService.java
index b075322862..c7c408be7f 100644
---
a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsControllerService.java
+++
b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsControllerService.java
@@ -83,6 +83,8 @@ public class ADLSCredentialsControllerService extends
AbstractControllerService
public static final PropertyDescriptor SERVICE_PRINCIPAL_CLIENT_SECRET =
AzureStorageUtils.SERVICE_PRINCIPAL_CLIENT_SECRET;
+ public static final PropertyDescriptor PROXY_CONFIGURATION_SERVICE =
AzureStorageUtils.PROXY_CONFIGURATION_SERVICE;
+
private static final List<PropertyDescriptor> PROPERTIES =
Collections.unmodifiableList(Arrays.asList(
ACCOUNT_NAME,
ENDPOINT_SUFFIX,
@@ -92,7 +94,8 @@ public class ADLSCredentialsControllerService extends
AbstractControllerService
MANAGED_IDENTITY_CLIENT_ID,
SERVICE_PRINCIPAL_TENANT_ID,
SERVICE_PRINCIPAL_CLIENT_ID,
- SERVICE_PRINCIPAL_CLIENT_SECRET
+ SERVICE_PRINCIPAL_CLIENT_SECRET,
+ PROXY_CONFIGURATION_SERVICE
));
private ConfigurationContext context;
@@ -184,6 +187,8 @@ public class ADLSCredentialsControllerService extends
AbstractControllerService
setValue(credentialsBuilder, SERVICE_PRINCIPAL_CLIENT_ID,
PropertyValue::getValue,
ADLSCredentialsDetails.Builder::setServicePrincipalClientId, attributes);
setValue(credentialsBuilder, SERVICE_PRINCIPAL_CLIENT_SECRET,
PropertyValue::getValue,
ADLSCredentialsDetails.Builder::setServicePrincipalClientSecret, attributes);
+
credentialsBuilder.setProxyOptions(AzureStorageUtils.getProxyOptions(context));
+
return credentialsBuilder.build();
}
diff --git
a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/AzureStorageCredentialsControllerService_v12.java
b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/AzureStorageCredentialsControllerService_v12.java
index ff63b1538f..79278dc6c0 100644
---
a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/AzureStorageCredentialsControllerService_v12.java
+++
b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/AzureStorageCredentialsControllerService_v12.java
@@ -16,6 +16,7 @@
*/
package org.apache.nifi.services.azure.storage;
+import com.azure.core.http.ProxyOptions;
import org.apache.nifi.annotation.documentation.CapabilityDescription;
import org.apache.nifi.annotation.documentation.Tags;
import org.apache.nifi.annotation.lifecycle.OnEnabled;
@@ -109,6 +110,11 @@ public class AzureStorageCredentialsControllerService_v12
extends AbstractContro
.dependsOn(CREDENTIALS_TYPE,
AzureStorageCredentialsType.SERVICE_PRINCIPAL.getAllowableValue())
.build();
+ public static final PropertyDescriptor PROXY_CONFIGURATION_SERVICE = new
PropertyDescriptor.Builder()
+
.fromPropertyDescriptor(AzureStorageUtils.PROXY_CONFIGURATION_SERVICE)
+ .dependsOn(CREDENTIALS_TYPE,
AzureStorageCredentialsType.SERVICE_PRINCIPAL.getAllowableValue(),
AzureStorageCredentialsType.MANAGED_IDENTITY.getAllowableValue())
+ .build();
+
private static final List<PropertyDescriptor> PROPERTIES =
Collections.unmodifiableList(Arrays.asList(
ACCOUNT_NAME,
ENDPOINT_SUFFIX,
@@ -118,7 +124,8 @@ public class AzureStorageCredentialsControllerService_v12
extends AbstractContro
MANAGED_IDENTITY_CLIENT_ID,
SERVICE_PRINCIPAL_TENANT_ID,
SERVICE_PRINCIPAL_CLIENT_ID,
- SERVICE_PRINCIPAL_CLIENT_SECRET
+ SERVICE_PRINCIPAL_CLIENT_SECRET,
+ PROXY_CONFIGURATION_SERVICE
));
private ConfigurationContext context;
@@ -138,6 +145,7 @@ public class AzureStorageCredentialsControllerService_v12
extends AbstractContro
String accountName = context.getProperty(ACCOUNT_NAME).getValue();
String endpointSuffix =
context.getProperty(ENDPOINT_SUFFIX).getValue();
AzureStorageCredentialsType credentialsType =
AzureStorageCredentialsType.valueOf(context.getProperty(CREDENTIALS_TYPE).getValue());
+ ProxyOptions proxyOptions = AzureStorageUtils.getProxyOptions(context);
switch (credentialsType) {
case ACCOUNT_KEY:
@@ -148,12 +156,13 @@ public class AzureStorageCredentialsControllerService_v12
extends AbstractContro
return
AzureStorageCredentialsDetails_v12.createWithSasToken(accountName,
endpointSuffix, sasToken);
case MANAGED_IDENTITY:
String managedIdentityClientId =
context.getProperty(MANAGED_IDENTITY_CLIENT_ID).getValue();
- return
AzureStorageCredentialsDetails_v12.createWithManagedIdentity(accountName,
endpointSuffix, managedIdentityClientId);
+ return
AzureStorageCredentialsDetails_v12.createWithManagedIdentity(accountName,
endpointSuffix, managedIdentityClientId, proxyOptions);
case SERVICE_PRINCIPAL:
String servicePrincipalTenantId =
context.getProperty(SERVICE_PRINCIPAL_TENANT_ID).getValue();
String servicePrincipalClientId =
context.getProperty(SERVICE_PRINCIPAL_CLIENT_ID).getValue();
String servicePrincipalClientSecret =
context.getProperty(SERVICE_PRINCIPAL_CLIENT_SECRET).getValue();
- return
AzureStorageCredentialsDetails_v12.createWithServicePrincipal(accountName,
endpointSuffix, servicePrincipalTenantId, servicePrincipalClientId,
servicePrincipalClientSecret);
+ return
AzureStorageCredentialsDetails_v12.createWithServicePrincipal(accountName,
endpointSuffix,
+ servicePrincipalTenantId, servicePrincipalClientId,
servicePrincipalClientSecret, proxyOptions);
default:
throw new IllegalArgumentException("Unhandled credentials
type: " + credentialsType);
}
diff --git
a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsDetails.java
b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsDetails.java
index 0a831161e5..671d659c3f 100644
---
a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsDetails.java
+++
b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsDetails.java
@@ -17,9 +17,13 @@
package org.apache.nifi.services.azure.storage;
import com.azure.core.credential.AccessToken;
+import com.azure.core.http.ProxyOptions;
import java.util.Objects;
+import static
org.apache.nifi.services.azure.util.ProxyOptionsUtils.equalsProxyOptions;
+import static
org.apache.nifi.services.azure.util.ProxyOptionsUtils.hashCodeProxyOptions;
+
public class ADLSCredentialsDetails {
private final String accountName;
@@ -36,6 +40,8 @@ public class ADLSCredentialsDetails {
private final String servicePrincipalClientId;
private final String servicePrincipalClientSecret;
+ private final ProxyOptions proxyOptions;
+
public ADLSCredentialsDetails(
String accountName,
String accountKey,
@@ -46,7 +52,8 @@ public class ADLSCredentialsDetails {
String managedIdentityClientId,
String servicePrincipalTenantId,
String servicePrincipalClientId,
- String servicePrincipalClientSecret
+ String servicePrincipalClientSecret,
+ ProxyOptions proxyOptions
) {
this.accountName = accountName;
this.accountKey = accountKey;
@@ -58,6 +65,7 @@ public class ADLSCredentialsDetails {
this.servicePrincipalTenantId = servicePrincipalTenantId;
this.servicePrincipalClientId = servicePrincipalClientId;
this.servicePrincipalClientSecret = servicePrincipalClientSecret;
+ this.proxyOptions = proxyOptions;
}
public String getAccountName() {
@@ -100,6 +108,10 @@ public class ADLSCredentialsDetails {
return servicePrincipalClientSecret;
}
+ public ProxyOptions getProxyOptions() {
+ return proxyOptions;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -120,7 +132,8 @@ public class ADLSCredentialsDetails {
&& Objects.equals(managedIdentityClientId,
that.managedIdentityClientId)
&& Objects.equals(servicePrincipalTenantId,
that.servicePrincipalTenantId)
&& Objects.equals(servicePrincipalClientId,
that.servicePrincipalClientId)
- && Objects.equals(servicePrincipalClientSecret,
that.servicePrincipalClientSecret);
+ && Objects.equals(servicePrincipalClientSecret,
that.servicePrincipalClientSecret)
+ && equalsProxyOptions(proxyOptions, that.proxyOptions);
}
@Override
@@ -135,7 +148,8 @@ public class ADLSCredentialsDetails {
managedIdentityClientId,
servicePrincipalTenantId,
servicePrincipalClientId,
- servicePrincipalClientSecret
+ servicePrincipalClientSecret,
+ hashCodeProxyOptions(proxyOptions)
);
}
@@ -150,6 +164,7 @@ public class ADLSCredentialsDetails {
private String servicePrincipalTenantId;
private String servicePrincipalClientId;
private String servicePrincipalClientSecret;
+ private ProxyOptions proxyOptions;
private Builder() {}
@@ -207,9 +222,14 @@ public class ADLSCredentialsDetails {
return this;
}
+ public Builder setProxyOptions(ProxyOptions proxyOptions) {
+ this.proxyOptions = proxyOptions;
+ return this;
+ }
+
public ADLSCredentialsDetails build() {
return new ADLSCredentialsDetails(accountName, accountKey,
sasToken, endpointSuffix, accessToken, useManagedIdentity,
managedIdentityClientId,
- servicePrincipalTenantId, servicePrincipalClientId,
servicePrincipalClientSecret);
+ servicePrincipalTenantId, servicePrincipalClientId,
servicePrincipalClientSecret, proxyOptions);
}
}
}
diff --git
a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/storage/AzureStorageCredentialsDetails_v12.java
b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/storage/AzureStorageCredentialsDetails_v12.java
index 68457256d6..ee28670f9c 100644
---
a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/storage/AzureStorageCredentialsDetails_v12.java
+++
b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/storage/AzureStorageCredentialsDetails_v12.java
@@ -17,9 +17,13 @@
package org.apache.nifi.services.azure.storage;
import com.azure.core.credential.AccessToken;
+import com.azure.core.http.ProxyOptions;
import java.util.Objects;
+import static
org.apache.nifi.services.azure.util.ProxyOptionsUtils.equalsProxyOptions;
+import static
org.apache.nifi.services.azure.util.ProxyOptionsUtils.hashCodeProxyOptions;
+
public class AzureStorageCredentialsDetails_v12 {
private final String accountName;
@@ -32,10 +36,11 @@ public class AzureStorageCredentialsDetails_v12 {
private final String servicePrincipalClientId;
private final String servicePrincipalClientSecret;
private final AccessToken accessToken;
+ private final ProxyOptions proxyOptions;
private AzureStorageCredentialsDetails_v12(
String accountName, String endpointSuffix,
AzureStorageCredentialsType credentialsType, String accountKey, String
sasToken, String managedIdentityClientId,
- String servicePrincipalTenantId, String servicePrincipalClientId,
String servicePrincipalClientSecret, AccessToken accessToken) {
+ String servicePrincipalTenantId, String servicePrincipalClientId,
String servicePrincipalClientSecret, AccessToken accessToken, ProxyOptions
proxyOptions) {
this.accountName = accountName;
this.endpointSuffix = endpointSuffix;
this.credentialsType = credentialsType;
@@ -46,6 +51,7 @@ public class AzureStorageCredentialsDetails_v12 {
this.servicePrincipalClientId = servicePrincipalClientId;
this.servicePrincipalClientSecret = servicePrincipalClientSecret;
this.accessToken = accessToken;
+ this.proxyOptions = proxyOptions;
}
public String getAccountName() {
@@ -88,6 +94,10 @@ public class AzureStorageCredentialsDetails_v12 {
return accessToken;
}
+ public ProxyOptions getProxyOptions() {
+ return proxyOptions;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -108,7 +118,8 @@ public class AzureStorageCredentialsDetails_v12 {
&& Objects.equals(servicePrincipalTenantId,
that.servicePrincipalTenantId)
&& Objects.equals(servicePrincipalClientId,
that.servicePrincipalClientId)
&& Objects.equals(servicePrincipalClientSecret,
that.servicePrincipalClientSecret)
- && Objects.equals(accessToken, that.accessToken);
+ && Objects.equals(accessToken, that.accessToken)
+ && equalsProxyOptions(proxyOptions, that.proxyOptions);
}
@Override
@@ -123,7 +134,8 @@ public class AzureStorageCredentialsDetails_v12 {
servicePrincipalTenantId,
servicePrincipalClientId,
servicePrincipalClientSecret,
- accessToken
+ accessToken,
+ hashCodeProxyOptions(proxyOptions)
);
}
@@ -131,21 +143,23 @@ public class AzureStorageCredentialsDetails_v12 {
String accountName,
String endpointSuffix,
String accountKey) {
- return new AzureStorageCredentialsDetails_v12(accountName,
endpointSuffix, AzureStorageCredentialsType.ACCOUNT_KEY, accountKey, null,
null, null, null, null, null);
+ return new AzureStorageCredentialsDetails_v12(accountName,
endpointSuffix, AzureStorageCredentialsType.ACCOUNT_KEY, accountKey, null,
null, null, null, null, null, null);
}
public static AzureStorageCredentialsDetails_v12 createWithSasToken(
String accountName,
String endpointSuffix,
String sasToken) {
- return new AzureStorageCredentialsDetails_v12(accountName,
endpointSuffix, AzureStorageCredentialsType.SAS_TOKEN, null, sasToken, null,
null, null, null, null);
+ return new AzureStorageCredentialsDetails_v12(accountName,
endpointSuffix, AzureStorageCredentialsType.SAS_TOKEN, null, sasToken, null,
null, null, null, null, null);
}
public static AzureStorageCredentialsDetails_v12 createWithManagedIdentity(
String accountName,
String endpointSuffix,
- String managedIdentityClientId) {
- return new AzureStorageCredentialsDetails_v12(accountName,
endpointSuffix, AzureStorageCredentialsType.MANAGED_IDENTITY, null, null,
managedIdentityClientId, null, null, null, null);
+ String managedIdentityClientId,
+ ProxyOptions proxyOptions) {
+ return new AzureStorageCredentialsDetails_v12(accountName,
endpointSuffix, AzureStorageCredentialsType.MANAGED_IDENTITY, null, null,
managedIdentityClientId,
+ null, null, null, null, proxyOptions);
}
public static AzureStorageCredentialsDetails_v12
createWithServicePrincipal(
@@ -153,15 +167,16 @@ public class AzureStorageCredentialsDetails_v12 {
String endpointSuffix,
String servicePrincipalTenantId,
String servicePrincipalClientId,
- String servicePrincipalClientSecret) {
+ String servicePrincipalClientSecret,
+ ProxyOptions proxyOptions) {
return new AzureStorageCredentialsDetails_v12(accountName,
endpointSuffix, AzureStorageCredentialsType.SERVICE_PRINCIPAL, null, null, null,
- servicePrincipalTenantId, servicePrincipalClientId,
servicePrincipalClientSecret, null);
+ servicePrincipalTenantId, servicePrincipalClientId,
servicePrincipalClientSecret, null, proxyOptions);
}
public static AzureStorageCredentialsDetails_v12 createWithAccessToken(
String accountName,
String endpointSuffix,
AccessToken accessToken) {
- return new AzureStorageCredentialsDetails_v12(accountName,
endpointSuffix, AzureStorageCredentialsType.ACCESS_TOKEN, null, null, null,
null, null, null, accessToken);
+ return new AzureStorageCredentialsDetails_v12(accountName,
endpointSuffix, AzureStorageCredentialsType.ACCESS_TOKEN, null, null, null,
null, null, null, accessToken, null);
}
}
diff --git
a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/util/ProxyOptionsUtils.java
b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/util/ProxyOptionsUtils.java
new file mode 100644
index 0000000000..449a6025a3
--- /dev/null
+++
b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/util/ProxyOptionsUtils.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.nifi.services.azure.util;
+
+import com.azure.core.http.ProxyOptions;
+
+import java.util.Objects;
+
+/**
+ * Utility class implementing equals and hashCode methods for {@link
com.azure.core.http.ProxyOptions}.
+ */
+public final class ProxyOptionsUtils {
+
+ private ProxyOptionsUtils() {}
+
+ public static boolean equalsProxyOptions(final ProxyOptions proxyOptions1,
final ProxyOptions proxyOptions2) {
+ if (proxyOptions1 == null || proxyOptions2 == null) {
+ return proxyOptions1 == proxyOptions2;
+ } else {
+ return proxyOptions1.getType() == proxyOptions2.getType()
+ && Objects.equals(proxyOptions1.getAddress(),
proxyOptions2.getAddress())
+ && Objects.equals(proxyOptions1.getUsername(),
proxyOptions2.getUsername())
+ && Objects.equals(proxyOptions1.getPassword(),
proxyOptions2.getPassword())
+ && Objects.equals(proxyOptions1.getNonProxyHosts(),
proxyOptions2.getNonProxyHosts());
+ }
+ }
+
+ public static int hashCodeProxyOptions(final ProxyOptions proxyOptions) {
+ if (proxyOptions == null) {
+ return 0;
+ } else {
+ return Objects.hash(
+ proxyOptions.getType(),
+ proxyOptions.getAddress(),
+ proxyOptions.getUsername(),
+ proxyOptions.getPassword(),
+ proxyOptions.getNonProxyHosts()
+ );
+ }
+ }
+}
diff --git
a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/test/java/org/apache/nifi/services/azure/util/ProxyOptionsUtilsTest.java
b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/test/java/org/apache/nifi/services/azure/util/ProxyOptionsUtilsTest.java
new file mode 100644
index 0000000000..db9f72cb76
--- /dev/null
+++
b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/test/java/org/apache/nifi/services/azure/util/ProxyOptionsUtilsTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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.nifi.services.azure.util;
+
+import com.azure.core.http.ProxyOptions;
+import org.junit.jupiter.api.Test;
+
+import java.net.InetSocketAddress;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class ProxyOptionsUtilsTest {
+
+ private static final String DEFAULT_IP_ADDRESS = "192.168.0.1";
+ private static final int DEFAULT_PORT = 8080;
+ private static final String DEFAULT_USERNAME = "nifi";
+ private static final String DEFAULT_PASSWORD = "password";
+
+ private final ProxyOptions proxyOptions1 = createDefaultProxyOptions();
+
+ @Test
+ void testEquals() {
+ final ProxyOptions proxyOptions2 = createDefaultProxyOptions();
+
+ assertNotEquals(proxyOptions1, proxyOptions2);
+ assertTrue(ProxyOptionsUtils.equalsProxyOptions(proxyOptions1,
proxyOptions2));
+ }
+
+ @Test
+ void testEqualsDifferentIpAddress() {
+ final ProxyOptions proxyOptions2 = new
ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("192.168.0.2",
DEFAULT_PORT));
+
+ assertFalse(ProxyOptionsUtils.equalsProxyOptions(proxyOptions1,
proxyOptions2));
+ }
+
+ @Test
+ void testEqualsDifferentPort() {
+ final ProxyOptions proxyOptions2 = new
ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress(DEFAULT_IP_ADDRESS,
8081));
+
+ assertFalse(ProxyOptionsUtils.equalsProxyOptions(proxyOptions1,
proxyOptions2));
+ }
+
+ @Test
+ void testEqualsDifferentUsername() {
+ final ProxyOptions proxyOptions2 = createDefaultProxyOptions();
+ proxyOptions2.setCredentials("nifi1", DEFAULT_PASSWORD);
+
+ assertFalse(ProxyOptionsUtils.equalsProxyOptions(proxyOptions1,
proxyOptions2));
+ }
+
+ @Test
+ void testEqualsDifferentPassword() {
+ final ProxyOptions proxyOptions2 = createDefaultProxyOptions();
+ proxyOptions2.setCredentials(DEFAULT_USERNAME, "password1");
+
+ assertFalse(ProxyOptionsUtils.equalsProxyOptions(proxyOptions1,
proxyOptions2));
+ }
+
+ @Test
+ void testEqualsThisNull() {
+ assertFalse(ProxyOptionsUtils.equalsProxyOptions(null, proxyOptions1));
+ }
+
+ @Test
+ void testEqualsThatNull() {
+ assertFalse(ProxyOptionsUtils.equalsProxyOptions(proxyOptions1, null));
+ }
+
+ @Test
+ void testEqualsBothNull() {
+ assertTrue(ProxyOptionsUtils.equalsProxyOptions(null, null));
+ }
+
+ @Test
+ void testHashCode() {
+ final ProxyOptions proxyOptions2 = createDefaultProxyOptions();
+
+ assertNotEquals(proxyOptions1.hashCode(), proxyOptions2.hashCode());
+ assertEquals(ProxyOptionsUtils.hashCodeProxyOptions(proxyOptions1),
ProxyOptionsUtils.hashCodeProxyOptions(proxyOptions2));
+ }
+
+ @Test
+ void testHashCodeDifferentIpAddress() {
+ final ProxyOptions proxyOptions2 = new
ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("192.168.0.2",
DEFAULT_PORT));
+
+ assertNotEquals(ProxyOptionsUtils.hashCodeProxyOptions(proxyOptions1),
ProxyOptionsUtils.hashCodeProxyOptions(proxyOptions2));
+ }
+
+ @Test
+ void testHashCodeDifferentPort() {
+ final ProxyOptions proxyOptions2 = new
ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress(DEFAULT_IP_ADDRESS,
8081));
+
+ assertNotEquals(ProxyOptionsUtils.hashCodeProxyOptions(proxyOptions1),
ProxyOptionsUtils.hashCodeProxyOptions(proxyOptions2));
+ }
+
+ @Test
+ void testHashCodeDifferentUsername() {
+ final ProxyOptions proxyOptions2 = createDefaultProxyOptions();
+ proxyOptions2.setCredentials("nifi1", DEFAULT_PASSWORD);
+
+ assertNotEquals(ProxyOptionsUtils.hashCodeProxyOptions(proxyOptions1),
ProxyOptionsUtils.hashCodeProxyOptions(proxyOptions2));
+ }
+
+ @Test
+ void testHashCodeDifferentPassword() {
+ final ProxyOptions proxyOptions2 = createDefaultProxyOptions();
+ proxyOptions2.setCredentials(DEFAULT_USERNAME, "password1");
+
+ assertNotEquals(ProxyOptionsUtils.hashCodeProxyOptions(proxyOptions1),
ProxyOptionsUtils.hashCodeProxyOptions(proxyOptions2));
+ }
+
+ @Test
+ void testHashCodeNull() {
+ assertEquals(0, ProxyOptionsUtils.hashCodeProxyOptions(null));
+ }
+
+ private ProxyOptions createDefaultProxyOptions() {
+ final ProxyOptions proxyOptions = new
ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress(DEFAULT_IP_ADDRESS,
DEFAULT_PORT));
+ proxyOptions.setCredentials(DEFAULT_USERNAME, DEFAULT_PASSWORD);
+
+ return proxyOptions;
+ }
+}