microsoftgraph / microsoftgraph/msgraph-sdk-java
Microsoft Graph - Error executing the request
还没有人认领这个 Issue。
- 主要语言
- Java
- 星标
- 444
- 派生
- 154
- 平均合并
- 18 小时 28 分钟
- 30 天内合并 PR
- 4
描述
Using version 3.0.0 i implemented batch because our app was being throttled and now i am randomly getting socket errors... it works few times then errors few times etc... How can i fix my error?
Error:
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.content.BatchRequest.post(BatchRequest.java:60)
at com.company.myapp.microsoftgraph.MicrosoftGraphClient.getUserCalendarFreeSlots(MicrosoftGraphClient.java:205)
at com.company.myapp.service.DataCacheService.getAvailability(DataCacheService.java:192)
at com.company.myapp.service.DataCacheService.refreshAvailability(DataCacheService.java:178)
at com.company.myapp.service.DataCacheService.refreshAvailabilityWithLocks(DataCacheService.java:90)
at com.company.myapp.service.DataCacheRefresher.refreshAvailabilityCache(DataCacheRefresher.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:503)
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(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:826)
Caused by: java.net.SocketTimeoutException: timeout
at okio.SocketAsyncTimeout.newTimeoutException(JvmOkio.kt:143)
at okio.AsyncTimeout.access$newTimeoutException(AsyncTimeout.kt:162)
at okio.AsyncTimeout$source$1.read(AsyncTimeout.kt:335)
at okio.RealBufferedSource.indexOf(RealBufferedSource.kt:427)
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.kt:320)
at okhttp3.internal.http1.HeadersReader.readLine(HeadersReader.kt:29)
at okhttp3.internal.http1.Http1ExchangeCodec.readResponseHeaders(Http1ExchangeCodec.kt:178)
at okhttp3.internal.connection.Exchange.readResponseHeaders(Exchange.kt:106)
at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.kt:79)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:34)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at com.microsoft.graph.httpcore.RedirectHandler.intercept(RedirectHandler.java:137)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at com.microsoft.graph.httpcore.RetryHandler.intercept(RetryHandler.java:176)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at com.microsoft.graph.httpcore.AuthenticationHandler.intercept(AuthenticationHandler.java:59)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at com.microsoft.graph.httpcore.TelemetryHandler.intercept(TelemetryHandler.java:69)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154)
at com.microsoft.graph.http.CoreHttpProvider.sendRequestInternal(CoreHttpProvider.java:385)
... 22 more
Caused by: javax.net.ssl.SSLException: Socket closed
at sun.security.ssl.Alert.createSSLException(Alert.java:127)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:331)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:274)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:269)
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1572)
at sun.security.ssl.SSLSocketImpl.access$400(SSLSocketImpl.java:73)
at sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:982)
at okio.InputStreamSource.read(JvmOkio.kt:90)
at okio.AsyncTimeout$source$1.read(AsyncTimeout.kt:129)
... 48 more
Caused by: java.net.SocketException: Socket closed
at java.net.SocketInputStream.read(SocketInputStream.java:204)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:464)
at sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:68)
at sun.security.ssl.SSLSocketImpl.readApplicationRecord(SSLSocketImpl.java:1350)
at sun.security.ssl.SSLSocketImpl.access$300(SSLSocketImpl.java:73)
at sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:966)
... 50 more
Config:
@Configuration
public class GraphClientConfig {
@Value("${microsoft.graph.tenantId}") private String tenantId;
@Value("${microsoft.graph.clientId}") private String clientId;
@Value("${microsoft.graph.clientSecret}") private String clientSecret;
@Value("${microsoft.graph.authority}") private String authority;
@Value("${microsoft.graph.scopes}") private List<String> scopes;
@Bean
public ClientSecretCredential graphClientAuthProvider() {
ClientSecretCredential clientSecretCredential = new ClientSecretCredentialBuilder()
.clientId(clientId)
.clientSecret(clientSecret)
.tenantId(tenantId)
.build();
return clientSecretCredential;
}
@Bean
public GraphServiceClient graphClient() {
TokenCredentialAuthProvider authProvider = new TokenCredentialAuthProvider(scopes, graphClientAuthProvider());
GraphServiceClient<?> graphClient = GraphServiceClient.builder().authenticationProvider(authProvider).buildClient();
return graphClient;
}
}
MicrosoftGraphClient
@Component
public class MicrosoftGraphClient<IHttpRequest> {
private static Logger logger = LoggerFactory.getLogger(MicrosoftGraphClient.class);
private static final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
public static final String timeZone="Central Europe Standard Time";
@Autowired GraphServiceClient graphClient;
@Value("${microsoft.graph.defaultUserId}") private String defaultUserId;
public List<CalendarAvailabilityView> getUserCalendarFreeSlots(String userid, List<String> calendarIds, LocalDate startDate, LocalDate endDate){
logger.info("getUserCalendarFreeSlots()");
if (userid == null)
userid=defaultUserId;
StopWatch sw = new StopWatch("getUserCalendarFreeSlots");
LinkedList<Option> requestOptions = new LinkedList<Option>();
requestOptions.add(new HeaderOption("Prefer", "outlook.timezone=\""+timeZone+"\""));
requestOptions.add(new HeaderOption("Content-Type", "application/json"));
LocalDateTime startDateTime = LocalDateTime.of(startDate, LocalTime.of(0, 0));
LocalDateTime endDateTime = LocalDateTime.of(endDate, LocalTime.of(23, 59));
// calculate dates between
List<LocalDate> dates = new ArrayList<> ();
for (LocalDate d = startDate; !d.isAfter(endDate); d = d.plusDays(1)) {
dates.add(d);
}
DateTimeTimeZone startTime = new DateTimeTimeZone();
startTime.dateTime = dtf.format(startDateTime);
startTime.timeZone = timeZone;
DateTimeTimeZone endTime = new DateTimeTimeZone();
endTime.dateTime = dtf.format(endDateTime);
endTime.timeZone = timeZone;
int availabilityViewInterval = 30;
List<List<String>> partitions = Lists.partition(calendarIds, 5);
List<CalendarAvailabilityView> availability = new ArrayList<CalendarAvailabilityView>();
CalendarGetScheduleCollectionRequest request = null;
CalendarGetScheduleParameterSet req = null;
for (List<String> schedulesList: partitions) {
BatchRequestContent batchRequestContent = new BatchRequestContent();
logger.info("reading partition: "+StringUtils.join(schedulesList, ", "));
sw.start("get data");
req = CalendarGetScheduleParameterSet.newBuilder()
.withSchedules(schedulesList)
.withEndTime(endTime)
.withStartTime(startTime)
.withAvailabilityViewInterval(availabilityViewInterval).build();
request = graphClient.users()
.byId(userid).calendar().getSchedule(req)
.buildRequest(requestOptions);
String requestId = batchRequestContent.addBatchRequestStep(request, HttpMethod.POST, req);
BatchResponseContent batchResponseContent = graphClient.batch()
.buildRequest()
.post(batchRequestContent);
CalendarGetScheduleCollectionResponse response = new CalendarGetScheduleCollectionResponse();
ISerializer serializer = graphClient.getSerializer();
JsonObject obj = batchResponseContent.getResponseById(requestId).body.getAsJsonObject();
// Populate CalendarGetScheduleCollectionResponse
if (obj.has("value")) {
JsonArray scheduleItems = obj.getAsJsonArray("value");
List<ScheduleInformation> scheduleInformationList = new ArrayList<>();
for (JsonElement item : scheduleItems) {
ScheduleInformation info = serializer.deserializeObject(item.toString(), ScheduleInformation.class);
scheduleInformationList.add(info);
}
response.value = scheduleInformationList;
}
CalendarGetScheduleCollectionPage page = request.buildFromResponse(response);
List<ScheduleInformation> objects = new ArrayList<>();
objects.addAll(page.getCurrentPage());
CalendarGetScheduleCollectionRequestBuilder builder = page.getNextPage();
while (builder != null) {
request = builder.buildRequest();
page = request.post();
objects.addAll(page.getCurrentPage());
builder = page.getNextPage();
}
sw.stop();
if (objects != null && objects.size() > 0) {
for (ScheduleInformation si: objects) {
String availabilityView = si.availabilityView;
WorkingHours workingHours =si.workingHours;
if (availabilityView != null) {
CalendarAvailabilityView calav=new CalendarAvailabilityView();
calav.setAvailabilityView(availabilityView);
calav.setIdCalendar(si.scheduleId);
calav.setWorkingHours(convert(workingHours));
calav.setDates(dates);
availability.add(calav);
}
}
}
}
logger.info(sw.prettyPrint());
return availability;
}
private Map<String, WorkingHour> convert(WorkingHours wh) {
Map<String, WorkingHour> workingHoursMap = new LinkedHashMap<String, WorkingHour>();
if (wh==null)
return null;
//List<com.microsoft.graph.models.generated.DayOfWeek> daysOfWeek = wh.daysOfWeek;
List<com.microsoft.graph.models.DayOfWeek> daysOfWeek = wh.daysOfWeek;
for (com.microsoft.graph.models.DayOfWeek dow: daysOfWeek) {
WorkingHour workingHour = new WorkingHour();
TimeOfDay endTime = wh.endTime;
workingHour.setEndTime(LocalTime.of(endTime.getHour(), endTime.getMinute()));
TimeOfDay startTime = wh.startTime;
workingHour.setStartTime(LocalTime.of(startTime.getHour(), startTime.getMinute()));
workingHoursMap.put(dow.name().toUpperCase(), workingHour);
}
return workingHoursMap;
}
}
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
从 MicrosoftGraphClient.getUserCalendarFreeSlots 和 BatchRequest.post 调用开始,然后通过 CoreHttpProvider.sendRequestInternal 跟踪报告的故障。重现间歇性 batch request,并比较 timeout 和 socket-closed 情况;当原因已定位到 SDK 请求路径或所提供客户端的使用方式时,即视为完成。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- java
- 领域
- api
- Issue 类型
- 缺陷
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 活跃度
- 停滞
- 描述清晰度
- 需要澄清
- 新手友好度
- 20/100