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;
+    }
+}

Reply via email to