microsoftgraph / microsoftgraph/msgraph-sdk-java

Microsoft Graph - Error executing the request

Open
#2,159 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Needs: Attention :wave: type:legacy-version
Dominant language
Java
Stars
444
Forks
154
Avg merge
18h 28m
Merged PRs (30d)
4

Description

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;
    }
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at MicrosoftGraphClient.getUserCalendarFreeSlots and the BatchRequest.post call, then trace the reported failure through CoreHttpProvider.sendRequestInternal. Reproduce the intermittent batch request and compare the timeout and socket-closed cases; done means the cause is isolated to the SDK request path or the supplied client usage.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.