I have recently upgraded my application to :
- Spring Boot: 2.4.4
- microsoft-graph: 3.0.0
While upgrading the application i have followed the upgrade guide.
I'm retrieving the group members using below code:
public void getGroupMembersWithDevices(final IGroup group) {
List<IUser> users = this.userService.getAllUsersWithDevices();
List<IUser> groupUsers = new ArrayList<>();
DirectoryObjectCollectionWithReferencesPage directoryObjectCollectionWithReferencesPage = this.graphClient
.getGraphServiceClient()
.groups(group.getGroupId().toString())
.members()
.buildRequest()
.select("Id")
.top(999)
.get();
while (directoryObjectCollectionWithReferencesPage != null) {
final List<DirectoryObject> directoryObjects = directoryObjectCollectionWithReferencesPage.getCurrentPage();
List<IUser> usersWithDevices = users.stream().filter(
one -> directoryObjects.stream().anyMatch(two -> UUID.fromString(two.id).equals(one.getUserId())))
.collect(Collectors.toList());
if (usersWithDevices.size() > 0) {
groupUsers.addAll(usersWithDevices);
users.removeAll(usersWithDevices);
}
final DirectoryObjectCollectionWithReferencesRequestBuilder nextPage =
directoryObjectCollectionWithReferencesPage.getNextPage();
if (nextPage == null) {
break;
} else {
directoryObjectCollectionWithReferencesPage = nextPage.buildRequest().get();
}
}
group.setUsers(groupUsers.stream().collect(Collectors.toSet()));
}
IUser
and IDevice
are custom models created.
The end goal is to get all the users with devices who are not part of any specified Group. Hence we have first fetched all the users with devices (no errors) and then crosschecked the same against group members.
However, after upgrading the application to I have started getting errors. I have tried rerunning this in production and keep getting the same error at different intervals.
com.microsoft.graph.core.ClientException: Error executing the request
at com.microsoft.graph.http.CoreHttpProvider.sendRequestInternal(CoreHttpProvider.java:388)
at com.microsoft.graph.http.CoreHttpProvider.send(CoreHttpProvider.java:214)
at com.microsoft.graph.http.CoreHttpProvider.send(CoreHttpProvider.java:191)
at com.microsoft.graph.http.BaseCollectionRequest.send(BaseCollectionRequest.java:102)
at com.microsoft.graph.http.BaseEntityCollectionRequest.get(BaseEntityCollectionRequest.java:78)
at com.app.intune.util.GroupUtil.getGroupMembersWithDevices(GroupUtil.java:128)
at com.app.intune.ScheduleInventory.scheduleGetInventory(ScheduleInventory.java:85)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:95)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.security.ssl.InputRecord.readFully(Unknown Source)
at sun.security.ssl.InputRecord.read(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at sun.security.ssl.AppInputStream.read(Unknown Source)
at okio.Okio$2.read(Okio.java:140)
at okio.AsyncTimeout$2.read(AsyncTimeout.java:237)
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:358)
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:230)
at okhttp3.internal.http1.Http1ExchangeCodec.readHeaderLine(Http1ExchangeCodec.java:242)
at okhttp3.internal.http1.Http1ExchangeCodec.readResponseHeaders(Http1ExchangeCodec.java:213)
at okhttp3.internal.connection.Exchange.readResponseHeaders(Exchange.java:115)
at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:94)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:43)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:94)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:88)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at com.microsoft.graph.httpcore.RedirectHandler.intercept(RedirectHandler.java:137)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at com.microsoft.graph.httpcore.RetryHandler.intercept(RetryHandler.java:176)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at com.microsoft.graph.httpcore.AuthenticationHandler.intercept(AuthenticationHandler.java:59)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at com.microsoft.graph.httpcore.TelemetryHandler.intercept(TelemetryHandler.java:69)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:229)
at okhttp3.RealCall.execute(RealCall.java:81)
at com.microsoft.graph.http.CoreHttpProvider.sendRequestInternal(CoreHttpProvider.java:385)
... 20 more
Update 1:
Class created below for creating graph client and setting up proxy:
import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.azure.core.http.ProxyOptions;
import com.azure.core.http.netty.NettyAsyncHttpClientBuilder;
import com.azure.identity.ClientSecretCredential;
import com.azure.identity.ClientSecretCredentialBuilder;
import com.microsoft.graph.authentication.TokenCredentialAuthProvider;
import com.microsoft.graph.requests.GraphServiceClient;
@Component
public class GraphClient {
private String clientId;
private String clientSecret;
private List<String> scopes;
private String tenantId;
@Autowired
BasicConfiguration configuration;
@Autowired
IntuneConfig intuneConfig;
@PostConstruct
public void init() {
this.clientId = this.configuration.getClientId();
this.clientSecret = this.configuration.getSecretKey();
this.scopes = Arrays.asList(this.configuration.getScope());
this.tenantId = this.configuration.getTenant();
}
@SuppressWarnings({ "rawtypes" })
public GraphServiceClient getGraphServiceClient() {
final ClientSecretCredential clientSecretCredential = new ClientSecretCredentialBuilder()
.clientId(this.clientId).clientSecret(this.clientSecret).tenantId(this.tenantId)
.httpClient(
new NettyAsyncHttpClientBuilder()
.proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress(
this.intuneConfig.getProxyHost(), this.intuneConfig.getProxyPort())))
.build())
.build();
final TokenCredentialAuthProvider tokenCredentialAuthProvider = new TokenCredentialAuthProvider(this.scopes,
clientSecretCredential);
final GraphServiceClient graphClient = GraphServiceClient.builder()
.authenticationProvider(tokenCredentialAuthProvider).buildClient();
return graphClient;
}
}
Update 2: Updated GraphClient class to retrieve instance of GraphServiceClient. The instance is created just once.
import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.azure.core.http.ProxyOptions;
import com.azure.core.http.netty.NettyAsyncHttpClientBuilder;
import com.azure.identity.ClientSecretCredential;
import com.azure.identity.ClientSecretCredentialBuilder;
import com.microsoft.graph.authentication.TokenCredentialAuthProvider;
import com.microsoft.graph.requests.GraphServiceClient;
@Component
public class GraphClient {
private String clientId;
private String clientSecret;
private List<String> scopes;
private String tenantId;
@SuppressWarnings("rawtypes")
private static GraphServiceClient graphClient;
@Autowired
BasicConfiguration configuration;
@Autowired
IntuneConfig intuneConfig;
@PostConstruct
public void init() {
this.clientId = this.configuration.getClientId();
this.clientSecret = this.configuration.getSecretKey();
this.scopes = Arrays.asList(this.configuration.getScope());
this.tenantId = this.configuration.getTenant();
}
@SuppressWarnings({ "rawtypes" })
public GraphServiceClient getGraphServiceClient() {
if (GraphClient.graphClient == null) {
final ClientSecretCredential clientSecretCredential = new ClientSecretCredentialBuilder()
.clientId(this.clientId).clientSecret(this.clientSecret).tenantId(this.tenantId)
.httpClient(
new NettyAsyncHttpClientBuilder()
.proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress(
this.intuneConfig.getProxyHost(), this.intuneConfig.getProxyPort())))
.build())
.build();
final TokenCredentialAuthProvider tokenCredentialAuthProvider = new TokenCredentialAuthProvider(this.scopes,
clientSecretCredential);
final GraphServiceClient client = GraphServiceClient.builder()
.authenticationProvider(tokenCredentialAuthProvider).buildClient();
GraphClient.graphClient = client;
}
return GraphClient.graphClient;
}
}