lordgamez commented on a change in pull request #1178:
URL: https://github.com/apache/nifi-minifi-cpp/pull/1178#discussion_r719206363
##########
File path:
extensions/azure/controllerservices/AzureStorageCredentialsService.cpp
##########
@@ -22,53 +22,69 @@
#include "core/Resource.h"
-namespace org {
-namespace apache {
-namespace nifi {
-namespace minifi {
-namespace azure {
-namespace controllers {
+namespace org::apache::nifi::minifi::azure::controllers {
const core::Property AzureStorageCredentialsService::StorageAccountName(
core::PropertyBuilder::createProperty("Storage Account Name")
->withDescription("The storage account name.")
+ ->supportsExpressionLanguage(true)
->build());
const core::Property AzureStorageCredentialsService::StorageAccountKey(
core::PropertyBuilder::createProperty("Storage Account Key")
->withDescription("The storage account key. This is an admin-like
password providing access to every container in this account. "
"It is recommended one uses Shared Access Signature
(SAS) token instead for fine-grained control with policies.")
+ ->supportsExpressionLanguage(true)
->build());
const core::Property AzureStorageCredentialsService::SASToken(
core::PropertyBuilder::createProperty("SAS Token")
- ->withDescription("Shared Access Signature token. Specify either SAS
Token (recommended) or Account Key.")
+ ->withDescription("Shared Access Signature token. Specify either SAS
Token (recommended) or Account Key together with Storage Account Key if Managed
Identity is not used.")
+ ->supportsExpressionLanguage(true)
->build());
const core::Property
AzureStorageCredentialsService::CommonStorageAccountEndpointSuffix(
core::PropertyBuilder::createProperty("Common Storage Account Endpoint
Suffix")
->withDescription("Storage accounts in public Azure always use a common
FQDN suffix. Override this endpoint suffix with a "
"different suffix in certain circumstances (like Azure
Stack or non-public Azure regions).")
+ ->supportsExpressionLanguage(true)
->build());
const core::Property AzureStorageCredentialsService::ConnectionString(
core::PropertyBuilder::createProperty("Connection String")
- ->withDescription("Connection string used to connect to Azure Storage
service. This overrides all other set credential properties.")
+ ->withDescription("Connection string used to connect to Azure Storage
service. This overrides all other set credential properties if Managed Identity
is not used.")
+ ->supportsExpressionLanguage(true)
+ ->build());
+const core::Property
AzureStorageCredentialsService::UseManagedIdentityCredentials(
+ core::PropertyBuilder::createProperty("Use Managed Identity Credentials")
+ ->withDescription("If true Managed Identity credentials will be used
together with the Storage Account Name for authentication.")
+ ->isRequired(true)
+ ->withDefaultValue<bool>(false)
->build());
void AzureStorageCredentialsService::initialize() {
- setSupportedProperties({StorageAccountName, StorageAccountKey, SASToken,
CommonStorageAccountEndpointSuffix, ConnectionString});
+ setSupportedProperties({StorageAccountName, StorageAccountKey, SASToken,
CommonStorageAccountEndpointSuffix, ConnectionString,
UseManagedIdentityCredentials});
}
void AzureStorageCredentialsService::onEnable() {
- getProperty(StorageAccountName.getName(), credentials_.storage_account_name);
- getProperty(StorageAccountKey.getName(), credentials_.storage_account_key);
- getProperty(SASToken.getName(), credentials_.sas_token);
- getProperty(CommonStorageAccountEndpointSuffix.getName(),
credentials_.endpoint_suffix);
- getProperty(ConnectionString.getName(), credentials_.connection_string);
+ std::string value;
+ if (getProperty(StorageAccountName.getName(), value)) {
Review comment:
You are right, I'm not sure why it was used in AWS controller service
and also documented that way. I removed all signs of expression language
support for controller services in 184b900f78ed72755f3d0e1876cc69d694da7a9e
##########
File path: extensions/azure/storage/AzureStorageCredentials.h
##########
@@ -21,53 +21,31 @@
#include <string>
-#include "utils/StringUtils.h"
-
-namespace org {
-namespace apache {
-namespace nifi {
-namespace minifi {
-namespace azure {
-namespace storage {
-
-struct AzureStorageCredentials {
- std::string storage_account_name;
- std::string storage_account_key;
- std::string sas_token;
- std::string endpoint_suffix;
- std::string connection_string;
-
- std::string getConnectionString() const {
- if (!connection_string.empty()) {
- return connection_string;
- }
-
- if (storage_account_name.empty() || (storage_account_key.empty() &&
sas_token.empty())) {
- return "";
- }
-
- std::string credentials;
- credentials += "AccountName=" + storage_account_name;
-
- if (!storage_account_key.empty()) {
- credentials += ";AccountKey=" + storage_account_key;
- }
-
- if (!sas_token.empty()) {
- credentials += ";SharedAccessSignature=" + (sas_token[0] == '?' ?
sas_token.substr(1) : sas_token);
- }
-
- if (!endpoint_suffix.empty()) {
- credentials += ";EndpointSuffix=" + endpoint_suffix;
- }
-
- return credentials;
- }
+namespace org::apache::nifi::minifi::azure::storage {
+
+class AzureStorageCredentials {
+ public:
+ void setStorageAccountName(const std::string& storage_account_name);
+ void setStorageAccountKey(const std::string& storage_account_key);
+ void setSasToken(const std::string& sas_token);
+ void setEndpontSuffix(const std::string& endpoint_suffix);
+ void setConnectionString(const std::string& connection_string);
+ void setUseManagedIdentityCredentials(bool use_managed_identity_credentials);
+
+ std::string getStorageAccountName() const;
+ std::string getEndpointSuffix() const;
+ bool getUseManagedIdentityCredentials() const;
+ std::string buildConnectionString() const;
+
+ bool operator==(const AzureStorageCredentials& other);
Review comment:
Updated in 184b900f78ed72755f3d0e1876cc69d694da7a9e
##########
File path: extensions/azure/processors/PutAzureBlobStorage.cpp
##########
@@ -138,38 +149,80 @@ void PutAzureBlobStorage::onSchedule(const
std::shared_ptr<core::ProcessContext>
logger_->log_info("Using storage account name and SAS token for
authentication");
}
-std::string PutAzureBlobStorage::getAzureConnectionStringFromProperties(
+storage::AzureStorageCredentials
PutAzureBlobStorage::getAzureCredentialsFromProperties(
const std::shared_ptr<core::ProcessContext> &context,
- const std::shared_ptr<core::FlowFile> &flow_file) {
+ const std::shared_ptr<core::FlowFile> &flow_file) const {
storage::AzureStorageCredentials credentials;
- context->getProperty(StorageAccountName, credentials.storage_account_name,
flow_file);
- context->getProperty(StorageAccountKey, credentials.storage_account_key,
flow_file);
- context->getProperty(SASToken, credentials.sas_token, flow_file);
- context->getProperty(CommonStorageAccountEndpointSuffix,
credentials.endpoint_suffix, flow_file);
- context->getProperty(ConnectionString, credentials.connection_string,
flow_file);
- return credentials.getConnectionString();
+ std::string value;
+ if (context->getProperty(StorageAccountName, value, flow_file)) {
+ credentials.setStorageAccountName(value);
+ }
+ if (context->getProperty(StorageAccountKey, value, flow_file)) {
+ credentials.setStorageAccountKey(value);
+ }
+ if (context->getProperty(SASToken, value, flow_file)) {
+ credentials.setSasToken(value);
+ }
+ if (context->getProperty(CommonStorageAccountEndpointSuffix, value,
flow_file)) {
+ credentials.setEndpontSuffix(value);
+ }
+ if (context->getProperty(ConnectionString, value, flow_file)) {
+ credentials.setConnectionString(value);
+ }
+
credentials.setUseManagedIdentityCredentials(use_managed_identity_credentials_);
+ return credentials;
}
-void PutAzureBlobStorage::createAzureStorageClient(const std::string
&connection_string, const std::string &container_name) {
- // When used in multithreaded environment make sure to use the
azure_storage_mutex_ to lock the wrapper so the
- // client is not reset with different configuration while another thread is
using it.
- if (blob_storage_wrapper_ == nullptr) {
- blob_storage_wrapper_ =
std::make_unique<storage::AzureBlobStorage>(connection_string, container_name);
- return;
+std::optional<storage::PutAzureBlobStorageParameters>
PutAzureBlobStorage::buildAzureBlobStorageParameters(
+ const std::shared_ptr<core::ProcessContext> &context,
+ const std::shared_ptr<core::FlowFile> &flow_file) {
+ storage::PutAzureBlobStorageParameters params;
+ auto credentials = getCredentials(context, flow_file);
+ if (!credentials) {
+ logger_->log_error("No valid credentials are set!");
+ return std::nullopt;
+ }
+
+ params.credentials = *credentials;
+
+ if (!context->getProperty(ContainerName, params.container_name, flow_file)
|| params.container_name.empty()) {
+ logger_->log_error("Container Name is invalid or empty!");
+ return std::nullopt;
}
- blob_storage_wrapper_->resetClientIfNeeded(connection_string,
container_name);
+ context->getProperty(Blob, params.blob_name, flow_file);
+ if (params.blob_name.empty() && (!flow_file->getAttribute("filename",
params.blob_name) || params.blob_name.empty())) {
+ logger_->log_error("Blob is not set and default 'filename' attribute could
not be found!");
+ return std::nullopt;
+ }
+
+ return params;
}
-std::string PutAzureBlobStorage::getConnectionString(
+std::optional<storage::AzureStorageCredentials>
PutAzureBlobStorage::getCredentials(
const std::shared_ptr<core::ProcessContext> &context,
const std::shared_ptr<core::FlowFile> &flow_file) const {
- auto connection_string = getAzureConnectionStringFromProperties(context,
flow_file);
- if (!connection_string.empty()) {
- return connection_string;
+ auto credentialsValid = [](const storage::AzureStorageCredentials&
credentials) {
Review comment:
Added in 184b900f78ed72755f3d0e1876cc69d694da7a9e
##########
File path: extensions/azure/storage/AzureBlobStorage.cpp
##########
@@ -23,61 +23,39 @@
#include <memory>
#include <utility>
-namespace org {
-namespace apache {
-namespace nifi {
-namespace minifi {
-namespace azure {
-namespace storage {
+#include "azure/identity.hpp"
+#include "AzureBlobStorageClient.h"
-AzureBlobStorage::AzureBlobStorage(std::string connection_string, std::string
container_name)
- : BlobStorage(std::move(connection_string), std::move(container_name))
- ,
container_client_(std::make_unique<Azure::Storage::Blobs::BlobContainerClient>(
-
Azure::Storage::Blobs::BlobContainerClient::CreateFromConnectionString(connection_string_,
container_name_))) {
-}
+namespace org::apache::nifi::minifi::azure::storage {
-void AzureBlobStorage::resetClientIfNeeded(const std::string
&connection_string, const std::string &container_name) {
- if (connection_string == connection_string_ && container_name_ ==
container_name) {
- logger_->log_debug("Client credentials have not changed, no need to reset
client");
- return;
- }
- connection_string_ = connection_string;
- container_name_ = container_name;
- logger_->log_debug("Client has been reset with new credentials");
- container_client_ =
std::make_unique<Azure::Storage::Blobs::BlobContainerClient>(Azure::Storage::Blobs::BlobContainerClient::CreateFromConnectionString(connection_string,
container_name));
+AzureBlobStorage::AzureBlobStorage(std::unique_ptr<BlobStorageClient>
blob_storage_client)
+ : blob_storage_client_(blob_storage_client ? std::move(blob_storage_client)
: std::make_unique<AzureBlobStorageClient>()) {
Review comment:
Added in 184b900f78ed72755f3d0e1876cc69d694da7a9e
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]