Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ namespace Azure { namespace Core { namespace Credentials {
*
*/
std::string TenantId;

/**
* @brief Use credentials cache.
*
*/
bool CacheCredentials = true;
};

/**
Expand Down
9 changes: 8 additions & 1 deletion sdk/core/perf/inc/azure/perf/base_test.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,14 @@ namespace Azure { namespace Perf {
*
* @param proxy A test-proxy server url.
*/
void SetTestProxy(std::string const& proxy) { m_proxy = proxy; }
void SetTestProxy(std::string const& proxy)
{
if (!proxy.empty())
{
m_isInsecureEnabled = true;
m_proxy = proxy;
}
}

/**
* @brief Set the performance test to run insecure.
Expand Down
8 changes: 7 additions & 1 deletion sdk/core/perf/inc/azure/perf/dynamic_test_options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,18 @@ namespace Azure { namespace Perf {
class TestOptions {
private:
argagg::parser_results m_results;
bool m_skipInitial = true;

public:
/**
* @brief Create the test options component from the command line parsed results.
*
* @param results The command line parsed results.
*/
explicit TestOptions(argagg::parser_results results) : m_results(results) {}
explicit TestOptions(argagg::parser_results results, bool skipInitial = true)
: m_results(results), m_skipInitial(skipInitial)
{
}

/**
* @brief Get the option value from the option name. If the option is not found, it returns \p
Expand Down Expand Up @@ -72,5 +76,7 @@ namespace Azure { namespace Perf {
{
return m_results[optionName].as<T>();
}

bool ShouldSkipInitial() { return m_skipInitial; }
};
}} // namespace Azure::Perf
4 changes: 4 additions & 0 deletions sdk/core/perf/src/arg_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ Azure::Perf::GlobalTestOptions Azure::Perf::Program::ArgParser::Parse(
options.TestProxies.push_back(proxy);
}
}
if (parsedArgs["TestProxy"])
{
options.TestProxies.push_back(parsedArgs["TestProxy"].as<std::string>());
}

return options;
}
11 changes: 7 additions & 4 deletions sdk/core/perf/src/base_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ namespace Azure { namespace Perf {
#if defined(BUILD_CURL_HTTP_TRANSPORT_ADAPTER)
Azure::Core::Http::CurlTransportOptions curlOptions;
curlOptions.SslVerifyPeer = false;
curlOptions.SslOptions.AllowFailedCrlRetrieval = true;
clientOptions.Transport.Transport
= std::make_shared<Azure::Core::Http::CurlTransport>(curlOptions);
#elif defined(BUILD_TRANSPORT_WINHTTP_ADAPTER)
Expand All @@ -137,7 +138,6 @@ namespace Azure { namespace Perf {

void BaseTest::PostSetUp()
{

if (!m_proxy.empty())
{
Azure::Core::_internal::ClientOptions clientOp;
Expand All @@ -148,10 +148,13 @@ namespace Azure { namespace Perf {
Azure::Core::Http::_internal::HttpPipeline pipeline(
clientOp, "PerfFw", "na", std::move(policiesRe), std::move(policiesOp));
Azure::Core::Context ctx;

// Make one call to Run() before starting recording, to avoid capturing one-time setup
// like authorization requests.
this->Run(ctx);
if (!m_options.ShouldSkipInitial())
{
this->Run(ctx);
}

// Send start-record call
{
Expand Down Expand Up @@ -192,7 +195,7 @@ namespace Azure { namespace Perf {
Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Post, startPlayback);
request.SetHeader("x-recording-id", m_recordId);
auto response = pipeline.Send(request, ctx);

auto const& headers = response->GetHeaders();
auto findHeader = std::find_if(
headers.begin(),
Expand Down
11 changes: 8 additions & 3 deletions sdk/core/perf/src/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,14 @@ std::vector<Azure::Perf::TestOption> Azure::Perf::GlobalTestOptions::GetOptionMe
[Option("sync", HelpText = "Runs sync version of test")] -- Not supported
[Option('w', "warmup", Default = 5, HelpText = "Duration of warmup in seconds")]
[Option('x', "proxy", Default = "", HelpText = "Proxy server")]
[Option("test-proxy", HelpText = "URI of TestProxy Server")]
*/
return {
{"Duration",
{"-d", "--duration"},
"Duration of the test in seconds. Default to 10 seconds.",
1},
{"help", {"-h", "--help"}, "Display help information.", 0},
{"Host", {"--host"}, "Host to redirect HTTP requests. No redirection by default.", 1},
{"Insecure", {"--insecure"}, "Allow untrusted SSL certs. Default to false.", 0},
{"Iterations",
Expand All @@ -83,8 +85,11 @@ std::vector<Azure::Perf::TestOption> Azure::Perf::GlobalTestOptions::GetOptionMe
1},
{"Port", {"--port"}, "Port to redirect HTTP requests. Default to no redirection.", 1},
{"Rate", {"-r", "--rate"}, "Target throughput (ops/sec). Default to no throughput.", 1},
{"Warmup", {"-w", "--warmup"}, "Duration of warmup in seconds. Default to 5 seconds.", 1},

{"Sync", {"-y", "--sync"}, "Runs sync version of test, not implemented", 0},
{"TestProxies", {"-x", "--test-proxies"}, "URIs of TestProxy Servers (separated by ';')", 1},
{"help", {"-h", "--help"}, "Display help information.", 0},
{"Sync", {"-y", "--sync"}, "Runs sync version of test, not implemented", 0}};
{"TestProxy", {"--test-proxy"}, "URI of TestProxy Server", 1},
{"Warmup", {"-w", "--warmup"}, "Duration of warmup in seconds. Default to 5 seconds.", 1},
};

}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ namespace Azure { namespace Identity { namespace _detail {
// Gets item from cache, or creates it, puts into cache, and returns.
std::shared_ptr<CacheValue> GetOrCreateValue(
CacheKey const& key,
DateTime::duration minimumExpiration) const;
DateTime::duration minimumExpiration,
bool useCaching) const;

public:
TokenCache() = default;
Expand All @@ -91,14 +92,15 @@ namespace Azure { namespace Identity { namespace _detail {
* @param minimumExpiration Minimum token lifetime for the cached value to be returned.
* @param getNewToken Function to get the new token for the given \p scopeString, in case when
* cache does not have it, or if its remaining lifetime is less than \p minimumExpiration.
*
* @param useCaching If set to false, the token will not be cached.
* @return Authentication token.
*
*/
Core::Credentials::AccessToken GetToken(
std::string const& scopeString,
std::string const& tenantId,
DateTime::duration minimumExpiration,
std::function<Core::Credentials::AccessToken()> const& getNewToken) const;
std::function<Core::Credentials::AccessToken()> const& getNewToken,
bool useCaching = true) const;
};
}}} // namespace Azure::Identity::_detail
43 changes: 24 additions & 19 deletions sdk/identity/azure-identity/src/client_secret_credential.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,23 +82,28 @@ AccessToken ClientSecretCredential::GetToken(
// when they are being executed. They are not supposed to keep a reference to lambda argument to
// call it later. Therefore, any capture made here will outlive the possible time frame when the
// lambda might get called.
return m_tokenCache.GetToken(scopesStr, tenantId, tokenRequestContext.MinimumExpiration, [&]() {
return m_tokenCredentialImpl->GetToken(context, [&]() {
auto body = m_requestBody;

if (!scopesStr.empty())
{
body += "&scope=" + scopesStr;
}

auto const requestUrl = m_clientCredentialCore.GetRequestUrl(tenantId);

auto request
= std::make_unique<TokenCredentialImpl::TokenRequest>(HttpMethod::Post, requestUrl, body);

request->HttpRequest.SetHeader("Host", requestUrl.GetHost());

return request;
});
});
return m_tokenCache.GetToken(
scopesStr,
tenantId,
tokenRequestContext.MinimumExpiration,
[&]() {
return m_tokenCredentialImpl->GetToken(context, [&]() {
auto body = m_requestBody;

if (!scopesStr.empty())
{
body += "&scope=" + scopesStr;
}

auto const requestUrl = m_clientCredentialCore.GetRequestUrl(tenantId);

auto request = std::make_unique<TokenCredentialImpl::TokenRequest>(
HttpMethod::Post, requestUrl, body);

request->HttpRequest.SetHeader("Host", requestUrl.GetHost());

return request;
});
},
tokenRequestContext.CacheCredentials);
}
14 changes: 11 additions & 3 deletions sdk/identity/azure-identity/src/token_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,15 @@ template <typename T> bool ShouldCleanUpCacheFromExpiredItems(T cacheSize);

std::shared_ptr<TokenCache::CacheValue> TokenCache::GetOrCreateValue(
CacheKey const& key,
DateTime::duration minimumExpiration) const
DateTime::duration minimumExpiration,
bool useCaching) const
{
// not using caching, return new value;
if (!useCaching)
{
return std::make_shared<CacheValue>();
}

{
std::shared_lock<std::shared_timed_mutex> cacheReadLock(m_cacheMutex);

Expand Down Expand Up @@ -88,9 +95,10 @@ AccessToken TokenCache::GetToken(
std::string const& scopeString,
std::string const& tenantId,
DateTime::duration minimumExpiration,
std::function<AccessToken()> const& getNewToken) const
std::function<AccessToken()> const& getNewToken,
bool useCaching) const
{
auto const item = GetOrCreateValue({scopeString, tenantId}, minimumExpiration);
auto const item = GetOrCreateValue({scopeString, tenantId}, minimumExpiration, useCaching);

{
std::shared_lock<std::shared_timed_mutex> itemReadLock(item->ElementMutex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ namespace Azure { namespace Identity { namespace Test {
m_clientId = m_options.GetMandatoryOption<std::string>("ClientId");
m_secret = m_options.GetMandatoryOption<std::string>("Secret");
m_tokenRequestContext.Scopes.push_back(m_options.GetMandatoryOption<std::string>("Scope"));
m_tokenRequestContext.CacheCredentials = m_options.GetOptionOrDefault<bool>("Cache", false);
m_credential = std::make_unique<Azure::Identity::ClientSecretCredential>(
m_tenantId,
m_clientId,
Expand Down Expand Up @@ -76,7 +77,8 @@ namespace Azure { namespace Identity { namespace Test {
{"TenantId", {"--tenantId"}, "The tenant Id for the authentication.", 1, true},
{"ClientId", {"--clientId"}, "The client Id for the authentication.", 1, true},
{"Secret", {"--secret"}, "The secret for authentication.", 1, true, true},
{"Scope", {"--scope"}, "One scope to request access to.", 1, true}};
{"Scope", {"--scope"}, "One scope to request access to.", 1, true},
{"Cache", {"--cache"}, "Use credential cache.", 1, false}};
}

/**
Expand Down