Skip to content

Commit 3057b1e

Browse files
committed
Add CacheRefreshReason to telemetry and metadata
1 parent 5259675 commit 3057b1e

File tree

7 files changed

+67
-39
lines changed

7 files changed

+67
-39
lines changed

msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/AcquireTokenSilentSupplier.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ AuthenticationResult execute() throws Exception {
5757

5858
shouldRefresh = shouldRefresh(silentRequest.parameters(), res);
5959

60-
if (shouldRefresh || clientApplication.serviceBundle().getServerSideTelemetry().getCurrentRequest().cacheInfo() == CacheTelemetry.REFRESH_REFRESH_IN.telemetryValue) {
60+
if (shouldRefresh) {
6161
if (!StringHelper.isBlank(res.refreshToken())) {
6262
//There are certain scenarios where the cached authority may differ from the client app's authority,
6363
// such as when a request is instance aware. Unless overridden by SilentParameters.authorityUrl, the
@@ -66,7 +66,8 @@ AuthenticationResult execute() throws Exception {
6666
requestAuthority = Authority.createAuthority(new URL(requestAuthority.authority().replace(requestAuthority.host(),
6767
res.account().environment())));
6868
}
69-
res = makeRefreshRequest(res, requestAuthority);
69+
70+
res = makeRefreshRequest(res, requestAuthority, clientApplication.serviceBundle().getServerSideTelemetry().getCurrentRequest().cacheInfo());
7071
} else {
7172
res = null;
7273
}
@@ -81,13 +82,17 @@ AuthenticationResult execute() throws Exception {
8182
return res;
8283
}
8384

84-
private AuthenticationResult makeRefreshRequest(AuthenticationResult cachedResult, Authority requestAuthority) throws Exception {
85+
private AuthenticationResult makeRefreshRequest(AuthenticationResult cachedResult, Authority requestAuthority, CacheRefreshReason refreshReason) throws Exception {
86+
8587
RefreshTokenRequest refreshTokenRequest = new RefreshTokenRequest(
8688
RefreshTokenParameters.builder(silentRequest.parameters().scopes(), cachedResult.refreshToken()).build(),
8789
silentRequest.application(),
8890
silentRequest.requestContext(),
8991
silentRequest);
9092

93+
//The ServiceBundle will have a new CurrentRequest object when the RefreshTokenRequest is made, so the telemetry value needs to be set again
94+
setCacheTelemetry(refreshReason);
95+
9196
AcquireTokenByAuthorizationGrantSupplier acquireTokenByAuthorisationGrantSupplier =
9297
new AcquireTokenByAuthorizationGrantSupplier(clientApplication, refreshTokenRequest, requestAuthority);
9398

@@ -101,7 +106,7 @@ private AuthenticationResult makeRefreshRequest(AuthenticationResult cachedResul
101106
} catch (MsalServiceException ex) {
102107
//If the token refresh attempt threw a MsalServiceException but the refresh attempt was done
103108
// only because of refreshOn, then simply return the existing cached token rather than throw an exception
104-
if (clientApplication.serviceBundle().getServerSideTelemetry().getCurrentRequest().cacheInfo() == CacheTelemetry.REFRESH_REFRESH_IN.telemetryValue) {
109+
if (refreshReason == CacheRefreshReason.PROACTIVE_REFRESH) {
105110
return cachedResult;
106111
}
107112
throw ex;
@@ -113,15 +118,15 @@ private boolean shouldRefresh(SilentParameters parameters, AuthenticationResult
113118

114119
//If forceRefresh is true, no reason to check any other option
115120
if (parameters.forceRefresh()) {
116-
setCacheTelemetry(CacheTelemetry.REFRESH_FORCE_REFRESH.telemetryValue);
121+
setCacheTelemetry(CacheRefreshReason.FORCE_REFRESH);
117122
log.debug("Refreshing access token because forceRefresh parameter is true.");
118123
return true;
119124
}
120125

121126
//If the request contains claims then the token should be refreshed, to ensure that the returned token has the correct claims
122127
// Note: these are the types of claims found in (for example) a claims challenge, and do not include client capabilities
123128
if (parameters.claims() != null) {
124-
setCacheTelemetry(CacheTelemetry.REFRESH_FORCE_REFRESH.telemetryValue);
129+
setCacheTelemetry(CacheRefreshReason.FORCE_REFRESH);
125130
log.debug("Refreshing access token because the claims parameter is not null.");
126131
return true;
127132
}
@@ -130,7 +135,7 @@ private boolean shouldRefresh(SilentParameters parameters, AuthenticationResult
130135

131136
//If the access token is expired or within 5 minutes of becoming expired, refresh it
132137
if (!StringHelper.isBlank(cachedResult.accessToken()) && cachedResult.expiresOn() < (currTimeStampSec + ACCESS_TOKEN_EXPIRE_BUFFER_IN_SEC)) {
133-
setCacheTelemetry(CacheTelemetry.REFRESH_ACCESS_TOKEN_EXPIRED.telemetryValue);
138+
setCacheTelemetry(CacheRefreshReason.EXPIRED);
134139
log.debug("Refreshing access token because it is expired.");
135140
return true;
136141
}
@@ -139,22 +144,22 @@ private boolean shouldRefresh(SilentParameters parameters, AuthenticationResult
139144
if (!StringHelper.isBlank(cachedResult.accessToken()) &&
140145
cachedResult.refreshOn() != null && cachedResult.refreshOn() > 0 &&
141146
cachedResult.refreshOn() < currTimeStampSec && cachedResult.expiresOn() >= (currTimeStampSec + ACCESS_TOKEN_EXPIRE_BUFFER_IN_SEC)){
142-
setCacheTelemetry(CacheTelemetry.REFRESH_REFRESH_IN.telemetryValue);
147+
setCacheTelemetry(CacheRefreshReason.PROACTIVE_REFRESH);
143148
log.debug("Attempting to refresh access token because it is after the refreshOn time.");
144149
return true;
145150
}
146151

147152
//If there is a refresh token but no access token, we should use the refresh token to get the access token
148153
if (StringHelper.isBlank(cachedResult.accessToken()) && !StringHelper.isBlank(cachedResult.refreshToken())) {
149-
setCacheTelemetry(CacheTelemetry.REFRESH_NO_ACCESS_TOKEN.telemetryValue);
154+
setCacheTelemetry(CacheRefreshReason.NO_CACHED_ACCESS_TOKEN);
150155
log.debug("Refreshing access token because it was missing from the cache.");
151156
return true;
152157
}
153158

154159
return false;
155160
}
156161

157-
private void setCacheTelemetry(int cacheInfoValue){
162+
private void setCacheTelemetry(CacheRefreshReason cacheInfoValue){
158163
clientApplication.serviceBundle().getServerSideTelemetry().getCurrentRequest().cacheInfo(cacheInfoValue);
159164
}
160165
}

msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/AuthenticationResultMetadata.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,19 @@
2020
@Builder
2121
public class AuthenticationResultMetadata implements Serializable {
2222

23+
/**
24+
* The source of the tokens in the {@link AuthenticationResult}, see {@link TokenSource} for possible values
25+
*/
2326
private TokenSource tokenSource;
27+
28+
/**
29+
* When the token should be proactively refreshed. May be null or 0 if proactive refresh is not used
30+
*/
2431
private Long refreshOn;
32+
33+
/**
34+
* Specifies the reason for refreshing a token, see {@link CacheRefreshReason} for possible values.Will be {@link CacheRefreshReason#NOT_APPLICABLE} if the token was not refreshed
35+
*/
36+
@Builder.Default
37+
private CacheRefreshReason cacheRefreshReason = CacheRefreshReason.NOT_APPLICABLE;
2538
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.microsoft.aad.msal4j;
5+
6+
/**
7+
* Specifies the reason for fetching the access token from the identity provider when using {@link AbstractClientApplicationBase#acquireTokenSilently(SilentParameters)}
8+
*/
9+
public enum CacheRefreshReason {
10+
/**
11+
* Token did not need to be refreshed, or was retrieved in a non-silent call
12+
*/
13+
NOT_APPLICABLE(0),
14+
/**
15+
* Silent call was made with the force refresh option
16+
*/
17+
FORCE_REFRESH(1),
18+
/**
19+
* Access token was missing from the cache, but a valid refresh token was used to retrieve a new access token
20+
*/
21+
NO_CACHED_ACCESS_TOKEN(2),
22+
/**
23+
* Cached access token was expired and successfully refreshed
24+
*/
25+
EXPIRED(3),
26+
/**
27+
* Cached access token was not expired but was after the 'refresh_in' value, and was proactively refreshed before the expiration date
28+
*/
29+
PROACTIVE_REFRESH(4);
30+
31+
final int telemetryValue;
32+
33+
CacheRefreshReason(int telemetryValue) {
34+
this.telemetryValue = telemetryValue;
35+
}
36+
}

msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/CacheTelemetry.java

Lines changed: 0 additions & 26 deletions
This file was deleted.

msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/CurrentRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class CurrentRequest {
1414
private final PublicApi publicApi;
1515

1616
@Setter
17-
private int cacheInfo = -1;
17+
private CacheRefreshReason cacheInfo = CacheRefreshReason.NOT_APPLICABLE;
1818

1919
@Setter
2020
private String regionUsed = StringHelper.EMPTY_STRING;

msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/ServerSideTelemetry.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ private synchronized String buildCurrentRequestHeader() {
6767
String currentRequestHeader = SCHEMA_VERSION + SCHEMA_PIPE_DELIMITER +
6868
currentRequest.publicApi().getApiId() +
6969
SCHEMA_COMMA_DELIMITER +
70-
(currentRequest.cacheInfo() == -1 ? "" : currentRequest.cacheInfo()) +
70+
currentRequest.cacheInfo().telemetryValue +
7171
SCHEMA_COMMA_DELIMITER +
7272
currentRequest.regionUsed() +
7373
SCHEMA_COMMA_DELIMITER +

msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/SilentRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class SilentRequest extends MsalRequest {
3232

3333
if (parameters.forceRefresh()) {
3434
application.serviceBundle().getServerSideTelemetry().getCurrentRequest().cacheInfo(
35-
CacheTelemetry.REFRESH_FORCE_REFRESH.telemetryValue);
35+
CacheRefreshReason.FORCE_REFRESH);
3636
}
3737
}
3838
}

0 commit comments

Comments
 (0)