DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Commonly Occurring Errors in Microsoft Graph Integrations and How To Troubleshoot Them (Part 4)
  • Optimizing Java Applications: Parallel Processing and Result Aggregation Techniques
  • How To Create a Stub in 5 Minutes
  • Coordinating Threads Using CountDownLatch

Trending

  • AWS to Azure Migration: A Cloudy Journey of Challenges and Triumphs
  • Memory Leak Due to Time-Taking finalize() Method
  • Developers Beware: Slopsquatting and Vibe Coding Can Increase Risk of AI-Powered Attacks
  • Infrastructure as Code (IaC) Beyond the Basics
  1. DZone
  2. Software Design and Architecture
  3. Integration
  4. Commonly Occurring Errors in Microsoft Graph Integrations and How to Troubleshoot Them (Part 3)

Commonly Occurring Errors in Microsoft Graph Integrations and How to Troubleshoot Them (Part 3)

This third article explains common integration errors that may be seen in the transition from EWS to Microsoft Graph as to the resource type To Do Tasks.

By 
Constantin Kwiatkowski user avatar
Constantin Kwiatkowski
·
Updated Jan. 25, 23 · Tutorial
Likes (2)
Comment
Save
Tweet
Share
5.0K Views

Join the DZone community and get the full member experience.

Join For Free

Unlike the first and second articles of the series, this article not only covers case studies related to To Do Tasks, but also discusses what happened to To Do Tasks in the last months of 2022 regarding the accessibility via the MS Graph API v1.0.

Types of Accessibility

Types of Accessibility

Source: Microsoft Documentation

There are two types to access a protected resource via the MS Graph API’s. The delegated access and the app-only access. What does it mean? 

Assume there is an application A that uses delegated access, and the resource owner must consent to or deny your application request. Application A acts on behalf of a signed-in user. 

Assume there is an application B that uses app-only access. No authorization from the resource owner is required. Application B acts only as the application’s own identity.

Let’s take a closer look at these two types.

Type 1—Delegated Access

The client application A accesses the resource on behalf of the user. This type of access requires delegated permissions. To make the request, the client and user must be authorized interdependently. The client application A must have the correct delegated permissions (and must also be granted). Regarding user permission, the authorization relies on the privileges the user has been granted for them to access the resource. 

Type 2—App-Only Access 

The client application B acts on its own with no user signed in. There are many scenarios to use application access, such as automation. Most of these applications run as background services or daemons. Unlike application A, apps like B use app roles instead of delegated scopes to define permissions. For app-only access, the client application B must have the correct app roles of the resource it’s calling to access the data. 

Recent Changes of the Accessibility of To Do Tasks via the MS Graph API v1.0

The resource type To Do Tasks was introduced in August 2020 for MS Graph Beta and in October 2020 for Microsoft Graph v1.0 (production environment). At that time, app-only access to To Do Tasks via the MS Graph API v1.0 was not possible.

At the last Microsoft Build conference in 2022, the MS Graph developers announced this feature will be available by September 2022. According to the change notes of the MS Graph Java SDK 5.25.0, To Do Tasks was now available within the Java SDK. But, still, at that time, app-only access was not possible (according to the Microsoft documentation and my own tests in May.)

V.5.25.0

It should take more than six months until accessibility of To Do Tasks via the MS Graph v1.0 at the application level was possible. Finally, with the changes in December 2022, Microsoft has also released the long-requested feature. Unfortunately, the Microsoft documentation is not updated yet or there is no other remark in the change notes about this very important feature.

Attach Files to To Do Tasks

Assume there is an application B that uses app-only access. That means no authorization from the resource owner is required. Further, a To Do task T was already created and has the ID taskID.

According to Microsoft documentation, only attachments up to 25MB can be uploaded and attached to To Do tasks. Attachments up to 3MB in size can be uploaded with a single POST call. The following example shows how to create such a call within the Java SDK:

Java
 
final String primaryUser = "office365userEmail"; 
final String taskID = "taskID";

final GraphServiceClient<Request> graphClient = GraphServiceClient
                        .builder()
                        .authenticationProvider(getAuthenticationProvider())
                        .buildClient();

String defaultTodoTaskListId = getDefaultTodoTaskListId();

final AttachmentBase attachmentBase = graphService
      .getGraphServiceClient()
      .users(primaryUser)
      .todo()
      .lists(defaultTodoTaskListId)
      .tasks(taskID)
      .attachments()
      .buildRequest()
      .post(getAttachment());


After creating the client graphClient, the application must create a call to get the ID number of the To Do Task List that contains the To Do task T. In this case, it is the default To Do task list. The following code shows how to create such a call (getDefaultTodoTaskListId()):

Java
 
Objects.requireNonNull(service
                    .getGraphServiceClient()
                    .users(primeryID)
                    .todo()
                    .lists()
                    .buildRequest()
                    .get())
                    .getCurrentPage()
                    .stream()
                    .filter(e -> e.wellknownListName == WellknownListName.DEFAULT_LIST)
                    .findFirst()
                    .ifPresent(todoTaskList -> defaultTodoTaskListId = todoTaskList.id);


As parameter of the POST request (getAttachment()), we paste an object of the type TaskFileAttachment.

Java
 
TaskFileAttachment attachmentBase = new TaskFileAttachment();
attachmentBase.name = attachment.getFilename();
attachmentBase.contentBytes = attachment.getContent();
attachmentBase.contentType = attachment.getMimeType();


For attachments between 3MB and 25MB, similar to the way how to upload large attachments for events (check my first article), we alson create an upload session and upload these attachments piece by piece via multiple PUT calls. Let us consider the following example: 

Java
 
final String primaryUser = "office365userEmail"; 
final String taskID = "taskID";
String defaultTodoTaskListId = getDefaultTodoTaskListId();

final GraphServiceClient<Request> graphClient = GraphServiceClient
                        .builder()
                        .authenticationProvider(getAuthenticationProvider())
                        .buildClient();

final File file = File.createTempFile("testFile", "txt"); 
FileUtils.writeByteArrayToFile(file, "testContent".getBytes());
InputStream fileStream = new FileInputStream(file);

final AttachmentInfo attachmentInfo = new AttachmentInfo();
attachmentInfo.attachmentType = AttachmentType.FILE;
attachmentInfo.name = file.getName();
attachmentInfo.size = file.getTotalSpace();

final AttachmentBaseCreateUploadSessionParameterSet attachmentBaseCreateUploadSessionParameterSet =
                AttachmentBaseCreateUploadSessionParameterSet
                .newBuilder()
                .withAttachmentInfo(attachmentInfo)
                .build();

final UploadSession uploadSession = graphService.getGraphServiceClient()
                .users(primaryUser)
                .todo()
                .lists(defaultTodoTaskListId)
                .tasks(taskID)
                .attachments()
                .createUploadSession(attachmentBaseCreateUploadSessionParameterSet)
                .buildRequest()
                .post();

uploadSession.uploadUrl = uploadSession.uploadUrl + "/content";

// Called after each slice of the file is uploaded
final IProgressCallback callback =
                (current, max) -> log.info("Uploaded {} bytes of {} total bytes", current, max);

final LargeFileUploadTask<AttachmentInfo> uploadTask =
               new LargeFileUploadTask<>(uploadSession, graphService.getGraphServiceClient(),
                fileStream, file.length(), AttachmentInfo.class);

// upload (default: chunkSize is 5 MB)
uploadTask.upload(0, null, callback);


The example is very simple and self-explanatory and is not really different from the way large attachments are uploaded for events. First, we create a upload sesssion uploadSession via a POST request. A possible response to the POST request could look as follows:

HTTP
 
HTTP/1.1 200 OK
Content-Type: application/json

{
    "@odata.context": "https://graph.microsoft.com/beta/$metadata#microsoft.graph.uploadSession",
    "uploadUrl": "https://graph.microsoft.com/beta/users/6f9a2a92-8527-4d64-837e-b5312852f36d/todo/lists/AAMDiFkfh=/tasks/AAMkADliMm=/attachmentSessions/AAMkADliMm=",
    "expirationDateTime": "2022-06-09T10:45:27.4324526Z",
    "nextExpectedRanges": [
        "0-"
    ]
}


As a response to the POST request, you get an upload link uploadURL, which can be used to upload the attachment. Be aware, you have to extend the upload URL uploadURL with the keyword “content.” If not, you will receive a return code 404, the attachment session can’t be found. In the final step, we use multiple PUT calls to upload the attachment.

In both cases, MS Events and MS To Do Tasks, we create an upload session and use multiple PUT calls to upload large attachments. But, there are still differences. 

  • Size of file: For events, you can upload attachments with a maximum size of 150 MB. For tasks, you only can upload files of a maximum size of 25 MB.
  • Upload URL: For events, you upload the attachment via a Outlook API. For tasks, you upload the attachment via an MS Graph API and you must extend the upload URL with “content.”

Unlike events, you won’t see an issue, such as if you upload an attachment to a task since the upload is carried out via an MS Graph API:

 
401 : Unauthorized upon request. com.microsoft.graph.core.ClientException: 
Error code: InvalidAudienceForResource Error message: 
The audience claim value is invalid for current resource. 
Audience claim is 'https://graph.microsoft.com/', request url is 
'https://outlook.office.com/api/v2.0/Users...'.


Conclusion

From the perspective of a developer, in the future, I hope to see Microsoft invest more attention and a better way to upload large attachements.

By now, you should have a better understanding of the common integration errors that may be seen in the transition from EWS to Microsoft Graph as to the resource type To Do Tasks. I hope this article was informative and useful. 

API Java (programming language) Task (computing) Microsoft Outlook Microsoft Windows Microsoft Windows SDK POST (HTTP)

Opinions expressed by DZone contributors are their own.

Related

  • Commonly Occurring Errors in Microsoft Graph Integrations and How To Troubleshoot Them (Part 4)
  • Optimizing Java Applications: Parallel Processing and Result Aggregation Techniques
  • How To Create a Stub in 5 Minutes
  • Coordinating Threads Using CountDownLatch

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: