Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persistence token cache for Mac & Linux with new MSAL ext #9188

Merged
merged 55 commits into from
May 4, 2020
Merged
Show file tree
Hide file tree
Changes from 49 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
898a02f
Depend on msal persistence extension
jianghaolu Mar 17, 2020
132c01a
Initial draft of shared token cache for Mac and Linux
jianghaolu Mar 18, 2020
3c03443
Clean up
jianghaolu Mar 18, 2020
49acab7
Add msal ext to module-info
jianghaolu Mar 18, 2020
f50d8b7
Wrap MSAL error and fix module-info
jianghaolu Mar 18, 2020
4e4c467
checkstyle
jianghaolu Mar 18, 2020
fca0133
Fix spotbugs and naming
jianghaolu Mar 18, 2020
571b44c
Fix default azure credential test
jianghaolu Mar 23, 2020
e2c5dc3
Add initial perf test
jianghaolu Apr 1, 2020
dd341e7
more perf testing work
jianghaolu Apr 3, 2020
7cba579
Move default to identity client options
jianghaolu Apr 6, 2020
600fc6b
Fix array access in identity client options
jianghaolu Apr 7, 2020
1c53b24
Fix libsecret on Windows
jianghaolu Apr 7, 2020
3539779
Remove shared token cache configurations
jianghaolu Apr 7, 2020
80bb671
Clean up
jianghaolu Apr 7, 2020
b289411
Merge branch 'master' of github.com:Azure/azure-sdk-for-java into per…
jianghaolu Apr 7, 2020
a83c9ab
Fix tests
jianghaolu Apr 7, 2020
52e11f6
Fix versions
jianghaolu Apr 7, 2020
5a79873
Fix versions
jianghaolu Apr 7, 2020
bfcf3b3
Add version again
jianghaolu Apr 8, 2020
3660848
Lazy initialize pub client
jianghaolu Apr 8, 2020
8c5606a
Merge branch 'master' of github.com:Azure/azure-sdk-for-java into per…
jianghaolu Apr 8, 2020
435a4f2
Defer Mono.fromFuture()
jianghaolu Apr 8, 2020
4ad8ef8
Merge branch 'master' of github.com:Azure/azure-sdk-for-java into per…
jianghaolu Apr 8, 2020
5ac9807
Checkstyle
jianghaolu Apr 8, 2020
0b48bbb
Merge branch 'master' of github.com:Azure/azure-sdk-for-java into per…
jianghaolu Apr 13, 2020
f8245f0
Fix in perf test
jianghaolu Apr 14, 2020
e8d572a
Merge branch 'persistence' of github.com:jianghaolu/azure-sdk-for-jav…
jianghaolu Apr 14, 2020
ed6b013
Merge branch 'master' of github.com:Azure/azure-sdk-for-java into per…
jianghaolu Apr 20, 2020
1472726
Does not throw except SharedTokenCacheCredential
jianghaolu Apr 21, 2020
1cc8254
Fix merge error
jianghaolu Apr 21, 2020
6b1e50d
x-include-update
jianghaolu Apr 21, 2020
3a16cad
Minor change in public client creation
jianghaolu Apr 22, 2020
db0eb37
Checkstyle
jianghaolu Apr 22, 2020
775568f
Revert persistent cache demo
jianghaolu Apr 22, 2020
006b191
Align Linux default settings with MSAL.NET tests
jianghaolu Apr 22, 2020
eb9c615
Fix readme and use expandable enum
jianghaolu Apr 23, 2020
abfbea9
Merge branch 'persistence' of github.com:jianghaolu/azure-sdk-for-jav…
jianghaolu Apr 25, 2020
233ce5c
Disable shared token cache by default
jianghaolu Apr 29, 2020
a0b1725
Allow enabling on select builders
jianghaolu Apr 29, 2020
77c8a59
Wrap exceptions in ClientAuthenticationExceptions when Msal fails
jianghaolu Apr 29, 2020
7c7045c
Merge branch 'master' of github.com:Azure/azure-sdk-for-java into per…
jianghaolu Apr 29, 2020
ed8e722
Address spotbugs
jianghaolu Apr 29, 2020
09718dd
Clean up and address Alan's review
jianghaolu Apr 29, 2020
806539a
Merge error message
jianghaolu Apr 29, 2020
066d413
CI says IdentityClient doesn't compile
jianghaolu Apr 29, 2020
6cc8c1b
Checkstyle: indentation
jianghaolu Apr 29, 2020
d5c4662
Update shared token cache look up with master
jianghaolu Apr 30, 2020
0bf3f76
Address Connie's feedback
jianghaolu May 1, 2020
b337b93
address feedback
g2vinay May 1, 2020
4e1d1a0
Merge branch 'master' of github.com:Azure/azure-sdk-for-java into per…
jianghaolu May 3, 2020
5b4e878
Merge branch 'master' of github.com:Azure/azure-sdk-for-java into per…
jianghaolu May 4, 2020
25d2a63
Fix shared token cache and error handling
jianghaolu May 4, 2020
e3a405d
Use getPublicClientApplication()
jianghaolu May 4, 2020
3dff1f3
Undo changes in key vault
jianghaolu May 4, 2020
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
1 change: 1 addition & 0 deletions eng/versioning/external_dependencies.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ com.microsoft.azure:azure-mgmt-search;1.24.1
com.microsoft.azure:azure-mgmt-storage;1.3.0
com.microsoft.azure:azure-storage;8.0.0
com.microsoft.azure:msal4j;1.3.0
com.microsoft.azure:msal4j-persistence-extension;0.1
com.sun.activation:jakarta.activation;1.2.1
io.opentelemetry:opentelemetry-api;0.2.4
io.opentelemetry:opentelemetry-sdk;0.2.4
Expand Down
1 change: 1 addition & 0 deletions eng/versioning/version_client.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ com.azure:azure-cosmos-benchmark;4.0.1-beta.1;4.0.1-beta.1
com.azure:azure-data-appconfiguration;1.1.1;1.2.0-beta.1
com.azure:azure-e2e;1.0.0-beta.1;1.0.0-beta.1
com.azure:azure-identity;1.0.5;1.1.0-beta.4
com.azure:azure-identity-perf;1.0.0-beta.1;1.0.0-beta.1
com.azure:azure-messaging-eventhubs;5.0.3;5.1.0-beta.1
com.azure:azure-messaging-eventhubs-checkpointstore-blob;1.0.3;1.1.0-beta.1
com.azure:azure-messaging-servicebus;7.0.0-beta.1;7.0.0-beta.2
Expand Down
32 changes: 32 additions & 0 deletions sdk/identity/azure-identity-perf/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Azure Identity Performance test client library for Java

Represents Performance tests for Azure Identity SDK for Java.

## Getting started

### Prerequisites

- Java Development Kit (JDK) with version 8 or above

### Adding the package to your product


## Key concepts


## Examples

## Troubleshooting

## Next steps

## Contributing

If you would like to become an active contributor to this project please follow the instructions provided in [Microsoft
Azure Projects Contribution Guidelines](http://azure.github.io/guidelines.html).

1. Fork it
1. Create your feature branch (`git checkout -b my-new-feature`)
1. Commit your changes (`git commit -am 'Add some feature'`)
1. Push to the branch (`git push origin my-new-feature`)
1. Create new Pull Request
68 changes: 68 additions & 0 deletions sdk/identity/azure-identity-perf/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<parent>
<groupId>com.azure</groupId>
<artifactId>azure-client-sdk-parent</artifactId>
<version>1.7.0</version> <!-- {x-version-update;com.azure:azure-client-sdk-parent;current} -->
<relativePath>../../../pom.client.xml</relativePath>
</parent>

<modelVersion>4.0.0</modelVersion>

<groupId>com.azure</groupId>
<artifactId>azure-identity-perf</artifactId>
<version>1.0.0-beta.1</version> <!-- {x-version-update;com.azure:azure-identity-perf;current} -->
<packaging>jar</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.1.0-beta.4</version> <!-- {x-version-update;com.azure:azure-identity;current} -->
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>perf-test-core</artifactId>
<version>1.0.0-beta.1</version> <!-- {x-version-update;com.azure:perf-test-core;current} -->
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.2.0</version> <!-- {x-version-update;org.apache.maven.plugins:maven-assembly-plugin;external_dependency} -->
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>
com.azure.identity.perf.App
</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.identity.perf;

import com.azure.perf.test.core.PerfStressProgram;

/**
* Runs the Identity performance tests.
*
* Test scenarios:
* 1. Read cache from a single process
* 2. Read cache from multiple processes
* 3. Write cache from a single process
* 4. Write cache from multiple processes
*
* <p>To run from command line. Package the project into a jar with dependencies via mvn clean package.
* Then run the program via java -jar 'compiled-jar-with-dependencies-path' </p>
*
* <p> To run from IDE, set all the required environment variables in IntelliJ via Run -&gt; EditConfigurations section.
* Then run the App's main method via IDE.</p>
*/
public class App {
public static void main(String[] args) {
Class<?>[] testClasses;

try {
testClasses = new Class<?>[] {
Class.forName("com.azure.identity.perf.ReadCache"),
Class.forName("com.azure.identity.perf.WriteCache"),
};
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}

PerfStressProgram.run(testClasses, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.identity.perf;

import com.azure.identity.SharedTokenCacheCredential;
import com.azure.identity.SharedTokenCacheCredentialBuilder;
import com.azure.identity.perf.core.ServiceTest;
import com.azure.perf.test.core.PerfStressOptions;
import reactor.core.publisher.Mono;

public class ReadCache extends ServiceTest<PerfStressOptions> {
private final SharedTokenCacheCredential credential;

public ReadCache(PerfStressOptions options) {
super(options);
credential = new SharedTokenCacheCredentialBuilder()
.clientId(CLI_CLIENT_ID)
.build();
}

// Perform the API call to be tested here
@Override
public void run() {
credential.getToken(ARM_TOKEN_REQUEST_CONTEXT).block();
}

@Override
public Mono<Void> runAsync() {
return credential.getToken(ARM_TOKEN_REQUEST_CONTEXT).then();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.identity.perf;

import com.azure.identity.SharedTokenCacheCredential;
import com.azure.identity.SharedTokenCacheCredentialBuilder;
import com.azure.identity.perf.core.ServiceTest;
import com.azure.perf.test.core.PerfStressOptions;
import reactor.core.publisher.Mono;

import java.time.Duration;

public class WriteCache extends ServiceTest<PerfStressOptions> {
private final SharedTokenCacheCredential credential;

public WriteCache(PerfStressOptions options) {
super(options);
credential = new SharedTokenCacheCredentialBuilder()
.clientId(CLI_CLIENT_ID)
.tokenRefreshOffset(Duration.ofMinutes(60))
.build();
}

// Perform the API call to be tested here
@Override
public void run() {
credential.getToken(ARM_TOKEN_REQUEST_CONTEXT).block();
}

@Override
public Mono<Void> runAsync() {
return credential.getToken(ARM_TOKEN_REQUEST_CONTEXT).then();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.identity.perf.core;

import com.azure.core.credential.TokenRequestContext;
import com.azure.identity.InteractiveBrowserCredential;
import com.azure.identity.InteractiveBrowserCredentialBuilder;
import com.azure.perf.test.core.PerfStressOptions;
import com.azure.perf.test.core.PerfStressTest;
import reactor.core.publisher.Mono;

public abstract class ServiceTest<TOptions extends PerfStressOptions> extends PerfStressTest<TOptions> {
protected static final String CLI_CLIENT_ID = "04b07795-8ddb-461a-bbee-02f9e1bf7b46";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need them to be static ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

protected static final TokenRequestContext ARM_TOKEN_REQUEST_CONTEXT = new TokenRequestContext()
.addScopes("https://management.azure.com/.default");

private InteractiveBrowserCredential interactiveBrowserCredential = new InteractiveBrowserCredentialBuilder()
.port(8765)
.clientId(CLI_CLIENT_ID)
.build();

public ServiceTest(TOptions options) {
super(options);
}

@Override
public Mono<Void> globalSetupAsync() {
// Populate the token cache for tests
return super.globalSetupAsync()
.then(interactiveBrowserCredential.getToken(ARM_TOKEN_REQUEST_CONTEXT))
.then();
}
}
6 changes: 6 additions & 0 deletions sdk/identity/azure-identity/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
<artifactId>msal4j</artifactId>
<version>1.3.0</version> <!-- {x-version-update;com.microsoft.azure:msal4j;external_dependency} -->
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>msal4j-persistence-extension</artifactId>
<version>0.1</version> <!-- {x-version-update;com.microsoft.azure:msal4j-persistence-extension;external_dependency} -->
</dependency>
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>oauth2-oidc-sdk</artifactId>
Expand Down Expand Up @@ -107,6 +112,7 @@
<includes>
<include>com.azure:*</include>
<include>com.microsoft.azure:msal4j:[1.3.0]</include> <!-- {x-include-update;com.microsoft.azure:msal4j;external_dependency} -->
<include>com.microsoft.azure:msal4j-persistence-extension:[0.1]</include> <!-- {x-include-update;com.microsoft.azure:msal4j-persistence-extension;external_dependency} -->
<include>com.nimbusds:oauth2-oidc-sdk:[6.14]</include> <!-- {x-include-update;com.nimbusds:oauth2-oidc-sdk;external_dependency} -->
<include>net.java.dev.jna:jna-platform:[5.4.0]</include> <!-- {x-include-update;net.java.dev.jna:jna-platform;external_dependency} -->
<include>org.nanohttpd:nanohttpd:[2.3.1]</include> <!-- {x-include-update;org.nanohttpd:nanohttpd;external_dependency} -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public class AuthorizationCodeCredential implements TokenCredential {
public Mono<AccessToken> getToken(TokenRequestContext request) {
return Mono.defer(() -> {
if (cachedToken.get() != null) {
return identityClient.authenticateWithUserRefreshToken(request, cachedToken.get())
return identityClient.authenticateWithMsalAccount(request, cachedToken.get().getAccount())
.onErrorResume(t -> Mono.empty());
} else {
return Mono.empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,31 @@ public AuthorizationCodeCredentialBuilder redirectUrl(String redirectUrl) {
return this;
}

/**
* Sets whether to use an unprotected file specified by <code>cacheFileLocation()</code> instead of
* Gnome keyring on Linux. This is false by default.
*
* @param allowUnencryptedCache whether to use an unprotected file for cache storage.
*
* @return An updated instance of this builder with the unprotected token cache setting set as specified.
*/
public AuthorizationCodeCredentialBuilder allowUnencryptedCache(boolean allowUnencryptedCache) {
this.identityClientOptions.allowUnencryptedCache(allowUnencryptedCache);
return this;
}

/**
* Sets whether to enable using the shared token cache. This is disabled by default.
*
* @param enabled whether to enabled using the shared token cache.
*
* @return An updated instance of this builder with if the shared token cache enabled specified.
*/
public AuthorizationCodeCredentialBuilder enableSharedTokenCache(boolean enabled) {
this.identityClientOptions.enableSharedTokenCache(enabled);
return this;
}

/**
* Creates a new {@link AuthorizationCodeCredential} with the current configurations.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class DeviceCodeCredential implements TokenCredential {
public Mono<AccessToken> getToken(TokenRequestContext request) {
return Mono.defer(() -> {
if (cachedToken.get() != null) {
return identityClient.authenticateWithUserRefreshToken(request, cachedToken.get())
return identityClient.authenticateWithMsalAccount(request, cachedToken.get().getAccount())
.onErrorResume(t -> Mono.empty());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you want this to resume on an error and return an empty Mono? I'd expect the error to be propagated downstream and allow downstream subscribers to do with that error what they will. In globalSetupAsync this is call is chained with .then(), so it would hide the error.

There are similar instances in other credentials below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it should be probably be handled downstream - it's out of the scope of this PR but I can see if it can be done with minimal footprint

} else {
return Mono.empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,31 @@ public DeviceCodeCredentialBuilder challengeConsumer(
return this;
}

/**
* Sets whether to use an unprotected file specified by <code>cacheFileLocation()</code> instead of
* Gnome keyring on Linux. This is false by default.
*
* @param allowUnencryptedCache whether to use an unprotected file for cache storage.
*
* @return An updated instance of this builder with the unprotected token cache setting set as specified.
*/
public DeviceCodeCredentialBuilder allowUnencryptedCache(boolean allowUnencryptedCache) {
this.identityClientOptions.allowUnencryptedCache(allowUnencryptedCache);
return this;
}

/**
* Sets whether to enable using the shared token cache. This is disabled by default.
*
* @param enabled whether to enabled using the shared token cache.
*
* @return An updated instance of this builder with if the shared token cache enabled specified.
*/
public DeviceCodeCredentialBuilder enableSharedTokenCache(boolean enabled) {
jianghaolu marked this conversation as resolved.
Show resolved Hide resolved
this.identityClientOptions.enableSharedTokenCache(enabled);
return this;
}

/**
* Creates a new {@link DeviceCodeCredential} with the current configurations.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public class InteractiveBrowserCredential implements TokenCredential {
public Mono<AccessToken> getToken(TokenRequestContext request) {
return Mono.defer(() -> {
if (cachedToken.get() != null) {
return identityClient.authenticateWithUserRefreshToken(request, cachedToken.get())
return identityClient.authenticateWithMsalAccount(request, cachedToken.get().getAccount())
.onErrorResume(t -> Mono.empty());
} else {
return Mono.empty();
Expand Down
Loading