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
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

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
  • How to Perform Custom Error Handling With ANTLR
  • Data Quality: A Novel Perspective for 2025
  • Unlocking AI Coding Assistants: Generate Unit Tests
  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.1K 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
Oops! Something Went Wrong

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:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!