├── android
├── .gitignore
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── lint-baseline.xml
├── lint.xml
├── settings.gradle
├── AndroidManifest.xml
├── gradle.properties
├── build.gradle
└── gradlew.bat
├── java-8
├── .gitignore
├── gradle.properties
├── settings.gradle
└── build.gradle
├── .release-please-manifest.json
├── .github
├── CODEOWNERS
├── release-please.yml
├── ISSUE_TEMPLATE
│ ├── 03-blank-issue.md
│ ├── config.yml
│ ├── 02-sdk-feature-request.yml
│ └── 01-sdk-bug.yml
├── workflows
│ ├── auto-merge-dependabot.yml
│ ├── api-level-lint.yml
│ ├── gradle-build.yml
│ ├── release-please-gha.yml
│ ├── conflicting-pr-label.yml
│ ├── sonarcloud.yml
│ ├── codeql-analysis.yml
│ └── project-auto-add.yml
├── PULL_REQUEST_TEMPLATE.md
├── dependabot.yml
└── policies
│ ├── resourceManagement.yml
│ └── msgraph-sdk-java-core-branch-protection.yml
├── .vscode
└── settings.json
├── .editorconfig
├── devx.yml
├── gradle
├── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
└── dependencies.gradle
├── settings.gradle
├── src
├── main
│ └── java
│ │ └── com
│ │ └── microsoft
│ │ └── graph
│ │ └── core
│ │ ├── models
│ │ ├── IProgressCallback.java
│ │ ├── EncryptedContentBearer.java
│ │ ├── UploadResult.java
│ │ ├── EncryptableSubscription.java
│ │ ├── DiscoverUrlAdapter.java
│ │ ├── IUploadSession.java
│ │ └── BatchRequestStep.java
│ │ ├── exceptions
│ │ └── ClientException.java
│ │ ├── requests
│ │ ├── IBaseClient.java
│ │ ├── FeatureTracker.java
│ │ ├── FeatureFlag.java
│ │ ├── upload
│ │ │ ├── UploadSessionRequestBuilder.java
│ │ │ ├── UploadSliceRequestBuilder.java
│ │ │ └── UploadResponseHandler.java
│ │ ├── options
│ │ │ └── GraphClientOption.java
│ │ ├── BatchRequestBuilder.java
│ │ ├── middleware
│ │ │ └── GraphTelemetryHandler.java
│ │ └── ResponseBodyHandler.java
│ │ ├── content
│ │ ├── KeyedBatchResponseContent.java
│ │ └── BatchResponseContentCollection.java
│ │ ├── tasks
│ │ └── PageIteratorBuilder.java
│ │ └── authentication
│ │ ├── AzureIdentityAuthenticationProvider.java
│ │ └── AzureIdentityAccessTokenProvider.java
└── test
│ └── java
│ └── com
│ └── microsoft
│ └── graph
│ └── core
│ ├── requests
│ ├── upload
│ │ ├── UploadSessionTest.java
│ │ └── UploadSliceRequestTest.java
│ ├── FeatureTrackerTest.java
│ ├── MockResponseHandler.java
│ ├── BatchRequestBuilderTest.java
│ └── middleware
│ │ └── GraphTelemetryHandlerTest.java
│ ├── testModels
│ ├── TestBodyType.java
│ ├── TestChangeType.java
│ ├── TestLifecycleEventType.java
│ ├── TestAttendee.java
│ ├── TestEventsResponse.java
│ ├── TestChatMessage.java
│ ├── TestEventsDeltaResponse.java
│ ├── TestDrive.java
│ ├── TestDriveItem.java
│ ├── TestNoteBook.java
│ ├── TestEmailAddress.java
│ ├── TestRecipient.java
│ ├── TestDateTimeTimeZone.java
│ ├── TestItemBody.java
│ ├── BaseCollectionPaginationCountResponse.java
│ ├── TestEvent.java
│ ├── TestUser.java
│ └── TestResourceData.java
│ ├── BaseClient.java
│ └── models
│ └── TokenValidableTests.java
├── .gitignore
├── CODE_OF_CONDUCT.md
├── release-please-config.json
├── LICENSE
├── scripts
├── decodeAndWrite.ps1
├── getLatestVersion.ps1
└── validatePackageContents.ps1
├── THIRD PARTY NOTICES
├── gradle.properties
├── pom.xml
├── SECURITY.md
├── gradlew.bat
├── CONTRIBUTING.md
├── spotBugsExcludeFilter.xml
└── README.md
/android/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | build
--------------------------------------------------------------------------------
/java-8/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | build/
3 |
--------------------------------------------------------------------------------
/.release-please-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | ".": "3.6.5"
3 | }
4 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @microsoftgraph/msgraph-devx-java-write
2 |
--------------------------------------------------------------------------------
/java-8/gradle.properties:
--------------------------------------------------------------------------------
1 | mavenArtifactId = msgraph-sdk-java-core
2 |
--------------------------------------------------------------------------------
/java-8/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'msgraph-sdk-java-core'
2 |
--------------------------------------------------------------------------------
/.github/release-please.yml:
--------------------------------------------------------------------------------
1 | manifest: true
2 | primaryBranch: main
3 | handleGHRelease: true
4 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "java.configuration.updateBuildConfiguration": "automatic"
3 | }
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.java]
2 | indent_style = space
3 | indent_size = 4
4 | insert_final_newline = true
5 | trim_trailing_whitespace = true
--------------------------------------------------------------------------------
/devx.yml:
--------------------------------------------------------------------------------
1 | languages:
2 | - java
3 | extensions:
4 | services:
5 | - Microsoft Graph
6 | dependencyFile: /gradle/dependencies.gradle
7 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/msgraph-sdk-java-core/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/msgraph-sdk-java-core/HEAD/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/03-blank-issue.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Blank issue
3 | about: Something that doesn't fit the other categories
4 | title: ''
5 | labels: ["status:waiting-for-triage"]
6 | assignees: ''
7 |
8 | ---
9 |
--------------------------------------------------------------------------------
/android/lint-baseline.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/android/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This file was generated by the Gradle 'init' task.
3 | *
4 | * The settings file is used to specify which projects to include in your build.
5 | *
6 | * Detailed information about configuring a multi-project build in Gradle can be found
7 | * in the user manual at https://docs.gradle.org/6.6/userguide/multi_project_builds.html
8 | */
9 |
10 | rootProject.name = 'msgraph-sdk-java-core'
11 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This file was generated by the Gradle 'init' task.
3 | *
4 | * The settings file is used to specify which projects to include in your build.
5 | *
6 | * Detailed information about configuring a multi-project build in Gradle can be found
7 | * in the user manual at https://docs.gradle.org/6.6/userguide/multi_project_builds.html
8 | */
9 |
10 | rootProject.name = 'msgraph-sdk-java-core'
11 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/models/IProgressCallback.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.models;
2 |
3 | /**
4 | * Defines how to return progress status from a request.
5 | */
6 | @FunctionalInterface
7 | public interface IProgressCallback {
8 |
9 | /**
10 | * How progress updates are handled for this callback
11 | *
12 | * @param current the current amount of progress
13 | * @param max the max amount of progress
14 | */
15 | void report(final long current, final long max);
16 | }
17 |
--------------------------------------------------------------------------------
/java-8/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | // Apply the java-library plugin to add support for Java Library
3 | id 'java-library'
4 | id 'eclipse'
5 | }
6 |
7 | repositories {
8 | mavenCentral()
9 | }
10 |
11 | sourceSets {
12 | main {
13 | java {
14 | srcDirs = ['../src']
15 | exclude 'test/**'
16 | }
17 | }
18 | }
19 |
20 | java {
21 | toolchain {
22 | languageVersion = JavaLanguageVersion.of(8)
23 | }
24 | withSourcesJar()
25 | }
26 |
27 | apply from: "../gradle/dependencies.gradle"
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.ear
17 | *.zip
18 | *.tar.gz
19 | *.rar
20 |
21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
22 | hs_err_pid*
23 | /.gradle/
24 | /build/
25 | /bin/
26 |
27 | #Eclipse
28 | .project
29 | .classpath
30 | .settings
31 |
32 | # IntelliJ
33 | *.iml
34 | .idea/
35 |
36 | # Maven
37 | /target/
38 | local.properties
39 | *.gpg
40 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Microsoft Open Source Code of Conduct
2 |
3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
4 |
5 | Resources:
6 |
7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
10 | - Employees can reach out at [aka.ms/opensource/moderation-support](https://aka.ms/opensource/moderation-support)
11 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: true
2 | contact_links:
3 | - name: Question on use of graph sdk
4 | url: https://github.com/microsoftgraph/msgraph-sdk-java/discussions
5 | about: Please add your question in the discussions section of the repo
6 | - name: Question on use of kiota
7 | url: https://github.com/microsoft/kiota/discussions
8 | about: Please add your question in the discussions section of the repo
9 | - name: Question or Feature Request for the MS Graph API?
10 | url: https://aka.ms/msgraphsupport
11 | about: Report an issue or limitation with the MS Graph service APIs
12 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/models/EncryptedContentBearer.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.models;
2 |
3 | /**
4 | * Contains Decryptable content
5 | * @param The type of the decryptable content
6 | */
7 | public interface EncryptedContentBearer {
8 |
9 | /**
10 | * Sets encrypted content
11 | * @param encryptedContent encrypted content
12 | */
13 | public void setEncryptedContent(T encryptedContent);
14 |
15 | /**
16 | * Return encrypted content
17 | * @return encrypted content
18 | */
19 | public T getEncryptedContent();
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/requests/upload/UploadSessionTest.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.requests.upload;
2 |
3 | import static org.junit.jupiter.api.Assertions.assertNull;
4 |
5 | import java.util.List;
6 |
7 | import org.junit.jupiter.api.Test;
8 |
9 | import com.microsoft.graph.core.models.UploadSession;
10 |
11 | class UploadSessionTest {
12 | @Test
13 | void getNextExpectedRangesDoesNotFailOnDefault()
14 | {
15 | final UploadSession uploadSession = new UploadSession();
16 | final List result = uploadSession.getNextExpectedRanges();
17 | assertNull(result);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/exceptions/ClientException.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.exceptions;
2 |
3 | import jakarta.annotation.Nonnull;
4 |
5 | /**
6 | * Graph client exception wrapper.
7 | */
8 | public class ClientException extends Exception {
9 | /**
10 | * Constructor for a ClientException
11 | * @param message The exception message.
12 | * @param cause The possible inner exception causing this exception.
13 | */
14 | public ClientException(@Nonnull String message, @Nonnull Throwable cause) {
15 | super(message, cause);
16 | }
17 | /***
18 | * Constructor for a ClientException
19 | * @param message The exception message.
20 | */
21 | public ClientException(@Nonnull String message) {
22 | super(message);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/requests/IBaseClient.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.requests;
2 |
3 | import com.microsoft.kiota.RequestAdapter;
4 |
5 | import jakarta.annotation.Nonnull;
6 |
7 | /**
8 | * The default client interface
9 | */
10 | public interface IBaseClient {
11 | /**
12 | * Method to set the RequestAdapter property
13 | * @param requestAdapter specifies the desired RequestAdapter
14 | */
15 | void setRequestAdapter(@Nonnull RequestAdapter requestAdapter);
16 | /**
17 | * Returns the current RequestAdapter for sending requests
18 | * @return the RequestAdapter currently in use
19 | */
20 | @Nonnull
21 | RequestAdapter getRequestAdapter();
22 | /**
23 | * Gets the BatchRequestBuilder
24 | * @return the BatchRequestBuilder instance
25 | */
26 | @Nonnull
27 | BatchRequestBuilder getBatchRequestBuilder();
28 | }
29 |
--------------------------------------------------------------------------------
/android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
16 |
17 |
23 |
--------------------------------------------------------------------------------
/.github/workflows/auto-merge-dependabot.yml:
--------------------------------------------------------------------------------
1 | name: Auto-merge dependabot updates
2 |
3 | on:
4 | pull_request:
5 | branches: [ main ]
6 |
7 | permissions:
8 | pull-requests: write
9 | contents: write
10 |
11 | jobs:
12 |
13 | dependabot-merge:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | if: ${{ github.actor == 'dependabot[bot]' }}
18 |
19 | steps:
20 | - name: Dependabot metadata
21 | id: metadata
22 | uses: dependabot/fetch-metadata@v2.4.0
23 | with:
24 | github-token: "${{ secrets.GITHUB_TOKEN }}"
25 |
26 | - name: Enable auto-merge for Dependabot PRs
27 | # Only if version bump is not a major version change
28 | if: ${{steps.metadata.outputs.update-type != 'version-update:semver-major'}}
29 | run: gh pr merge --auto --merge "$PR_URL"
30 | env:
31 | PR_URL: ${{github.event.pull_request.html_url}}
32 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
33 |
--------------------------------------------------------------------------------
/release-please-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "bootstrap-sha": "e4d7342b47cc665d8137b046ed985bf7b7d76441",
3 | "exclude-paths": [
4 | ".git",
5 | ".idea",
6 | ".github",
7 | ".vscode"
8 | ],
9 | "release-type": "simple",
10 | "include-component-in-tag": false,
11 | "include-v-in-tag": true,
12 | "packages": {
13 | ".": {
14 | "package-name": "com.microsoft.graph.microsoft-graph-core",
15 | "changelog-path": "CHANGELOG.md",
16 | "extra-files": [
17 | "gradle.properties",
18 | "README.md",
19 | "src/main/java/com/microsoft/graph/core/CoreConstants.java",
20 | {
21 | "type": "xml",
22 | "path": "pom.xml",
23 | "xpath": "//project/version"
24 | }
25 | ]
26 | }
27 | },
28 | "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
29 | }
30 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 | Fixes #
12 |
13 |
14 | ### Changes proposed in this pull request
15 | -
16 |
17 |
18 | ### Other links
19 | -
20 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/testModels/TestBodyType.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.testModels;
2 |
3 | import com.microsoft.kiota.serialization.ValuedEnum;
4 | import jakarta.annotation.Nonnull;
5 | import jakarta.annotation.Nullable;
6 |
7 | import java.util.Objects;
8 |
9 | public enum TestBodyType implements ValuedEnum {
10 | Text("Text"),
11 | Html("Html");
12 | public final String value;
13 |
14 | TestBodyType(@Nonnull final String value) {
15 | this.value = value;
16 | }
17 |
18 | @Nonnull
19 | @Override
20 | public String getValue() {
21 | return this.value;
22 | }
23 |
24 | @Nullable public static TestBodyType forValue(@Nullable final String searchValue) {
25 | Objects.requireNonNull(searchValue);
26 | switch(searchValue) {
27 | case "Text": return Text;
28 | case "Html": return Html;
29 | default: return null;
30 | }
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/testModels/TestChangeType.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.testModels;
2 |
3 | import com.microsoft.kiota.serialization.ValuedEnum;
4 | import java.util.Objects;
5 |
6 | public enum TestChangeType implements ValuedEnum {
7 | Created("created"),
8 | Updated("updated"),
9 | Deleted("deleted");
10 | public final String value;
11 | TestChangeType(final String value) {
12 | this.value = value;
13 | }
14 | @jakarta.annotation.Nonnull
15 | public String getValue() { return this.value; }
16 | @jakarta.annotation.Nullable
17 | public static TestChangeType forValue(@jakarta.annotation.Nonnull final String searchValue) {
18 | Objects.requireNonNull(searchValue);
19 | switch(searchValue) {
20 | case "created": return Created;
21 | case "updated": return Updated;
22 | case "deleted": return Deleted;
23 | default: return null;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/requests/FeatureTrackerTest.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.requests;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import static org.junit.jupiter.api.Assertions.assertEquals;
6 |
7 | class FeatureTrackerTest {
8 | @Test
9 | void setFeatureUsageTest() {
10 | FeatureTracker featureTracker = new FeatureTracker();
11 | featureTracker.setFeatureUsage(FeatureFlag.AUTH_HANDLER_FLAG);
12 | featureTracker.setFeatureUsage(FeatureFlag.REDIRECT_HANDLER_FLAG);
13 | assertEquals("5", featureTracker.getSerializedFeatureUsage());
14 | }
15 | @Test
16 | void getSerializedFeatureUsageTest() {
17 | FeatureTracker featureTracker = new FeatureTracker();
18 | featureTracker.setFeatureUsage(FeatureFlag.AUTH_HANDLER_FLAG);
19 | featureTracker.setFeatureUsage(FeatureFlag.REDIRECT_HANDLER_FLAG);
20 | featureTracker.setFeatureUsage(FeatureFlag.RETRY_HANDLER_FLAG);
21 | assertEquals("7", featureTracker.getSerializedFeatureUsage());
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/content/KeyedBatchResponseContent.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.content;
2 |
3 | import jakarta.annotation.Nonnull;
4 | import java.util.HashSet;
5 | import java.util.Set;
6 |
7 | /**
8 | * A model to map id Keys to requests within a BatchResponseContent object.
9 | */
10 | public class KeyedBatchResponseContent {
11 | /**
12 | * The ids of the requests that were batched together.
13 | */
14 | @Nonnull
15 | protected HashSet keys;
16 | /**
17 | * The BatchResponseContent object paired to the keys.
18 | */
19 | @Nonnull
20 | protected BatchResponseContent response;
21 | /**
22 | * Instantiates a new Keyed batch response content.
23 | * @param keys the ids of the requests that were batched together.
24 | * @param response the BatchResponseContent object to add to the collection.
25 | */
26 | public KeyedBatchResponseContent(@Nonnull Set keys, @Nonnull BatchResponseContent response) {
27 | this.keys = new HashSet<>(keys);
28 | this.response = response;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/testModels/TestLifecycleEventType.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.testModels;
2 |
3 | import com.microsoft.kiota.serialization.ValuedEnum;
4 | import java.util.Objects;
5 |
6 | public enum TestLifecycleEventType implements ValuedEnum {
7 | Missed("missed"),
8 | SubscriptionRemoved("subscriptionRemoved"),
9 | ReauthorizationRequired("reauthorizationRequired");
10 | public final String value;
11 | TestLifecycleEventType(final String value) {
12 | this.value = value;
13 | }
14 | @jakarta.annotation.Nonnull
15 | public String getValue() { return this.value; }
16 | @jakarta.annotation.Nullable
17 | public static TestLifecycleEventType forValue(@jakarta.annotation.Nonnull final String searchValue) {
18 | Objects.requireNonNull(searchValue);
19 | switch(searchValue) {
20 | case "missed": return Missed;
21 | case "subscriptionRemoved": return SubscriptionRemoved;
22 | case "reauthorizationRequired": return ReauthorizationRequired;
23 | default: return null;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Microsoft Graph
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/models/UploadResult.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.models;
2 |
3 | import jakarta.annotation.Nullable;
4 |
5 | import java.net.URI;
6 |
7 | /**
8 | * Model containing the information from an upload response.
9 | * @param The type of item contained in the response.
10 | */
11 | public class UploadResult {
12 | /**
13 | * Default constructor.
14 | */
15 | public UploadResult() {
16 | //Default constructor
17 | }
18 | /** The UploadSession containing information about the created upload session. */
19 | @Nullable
20 | public IUploadSession uploadSession;
21 | /** The uploaded item, once upload has completed. */
22 | @Nullable
23 | public T itemResponse;
24 | /** The uploaded item location, once upload has completed. */
25 | @Nullable
26 | public URI location;
27 | /**
28 | * Status of the request.
29 | * @return A boolean dictating whether the upload has been fully completed.
30 | */
31 | public boolean isUploadSuccessful() {
32 | return (this.itemResponse != null) || (this.location != null);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/.github/workflows/api-level-lint.yml:
--------------------------------------------------------------------------------
1 | name: "Checks the SDK only using APIs from the targeted API level"
2 |
3 | on:
4 | workflow_dispatch:
5 | push:
6 | branches: [main, support/2.x.x]
7 | pull_request:
8 | branches: [main, support/2.x.x]
9 |
10 | jobs:
11 | lint-api-level:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v5
15 | - uses: actions/setup-java@v5
16 | with:
17 | distribution: 'temurin'
18 | java-version: 21
19 | cache: gradle
20 | - name: Setup Android SDK
21 | uses: android-actions/setup-android@v3.2.2
22 | - name: Add execution right to the script
23 | run: chmod +x gradlew
24 | working-directory: ./android
25 | - name: Build SDK with Android project configuration
26 | id: lint
27 | run: ./gradlew --no-daemon build
28 | working-directory: ./android
29 | - name: Upload linting results
30 | if: failure() && steps.lint.outcome == 'failure'
31 | uses: actions/upload-artifact@v4
32 | with:
33 | name: lint-report
34 | path: ./android/build/reports
35 |
36 |
--------------------------------------------------------------------------------
/scripts/decodeAndWrite.ps1:
--------------------------------------------------------------------------------
1 | # Copyright (c) Microsoft Corporation. All rights reserved.
2 | # Licensed under the MIT License.
3 |
4 | <#
5 | .Synopsis
6 | Decode the encoded string and write it to a local file.
7 | .Description
8 | Recieves an encoded string value and decodes it using base64.
9 | Write the new decoded string to a local file for later consumption.
10 | .Parameter encodedValue
11 | The encoded string we wish to decode.
12 | .Parameter outputPath
13 | The file path that we wish to write the decoded value to.
14 | #>
15 |
16 | Param(
17 | [string]$encodedValue ,
18 | [string]$outputPath
19 | )
20 |
21 | if($outputPath -eq "" -or $null -eq $outputPath) {
22 | Write-Output "Value of Variable: outputPath is Null or Empty. Exiting."
23 | Exit
24 | }
25 | if($encodedValue -eq "" -or $null -eq $encodedValue) {
26 | Write-Output "Value of Variable: encodedValue is Null of Empty. Exiting."
27 | Exit
28 | }
29 |
30 | $decodedValue = [System.Convert]::FromBase64String($encodedValue)
31 | $targetFullPath = Join-Path $PWD -ChildPath $outputPath
32 | [System.IO.File]::WriteAllBytes($targetFullPath, $decodedValue)
33 |
--------------------------------------------------------------------------------
/.github/workflows/gradle-build.yml:
--------------------------------------------------------------------------------
1 | name: Java CI with Gradle
2 |
3 | on:
4 | pull_request:
5 | branches: [main, support/2.x.x]
6 | workflow_dispatch:
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v5
13 | - name: Set up JDK
14 | uses: actions/setup-java@v5
15 | with:
16 | java-version: 21
17 | distribution: 'temurin'
18 | cache: gradle
19 | - name: Grant execute permission for gradlew
20 | run: chmod +x gradlew
21 | - name: Build with Gradle
22 | run: ./gradlew build
23 | - name: Build with Java 8
24 | working-directory: ./java-8
25 | run: .././gradlew build
26 | - name: Upload a Build Artifact
27 | uses: actions/upload-artifact@v4
28 | with:
29 | name: drop
30 | path: |
31 | **/libs/*
32 | build/generated-pom.xml
33 | build/generated-pom.xml.asc
34 | build.gradle
35 | gradlew
36 | gradlew.bat
37 | settings.gradle
38 | gradle.properties
39 | **/gradle/**
40 | Scripts/**
41 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/testModels/TestAttendee.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.testModels;
2 |
3 | import com.microsoft.kiota.serialization.AdditionalDataHolder;
4 | import com.microsoft.kiota.serialization.Parsable;
5 | import com.microsoft.kiota.serialization.ParseNode;
6 | import com.microsoft.kiota.serialization.SerializationWriter;
7 |
8 | import jakarta.annotation.Nonnull;
9 | import java.util.Map;
10 |
11 | public class TestAttendee extends TestRecipient implements Parsable, AdditionalDataHolder {
12 | public TestAttendee() {
13 | this.ODataType = "microsoft.graph.attendee";
14 | }
15 |
16 | @Override
17 | public void serialize(@Nonnull SerializationWriter writer) {
18 | super.serialize(writer);
19 | writer.writeAdditionalData(this.additionalData);
20 | }
21 |
22 | public static TestAttendee createFromDiscriminatorValue(ParseNode parseNode) {
23 | if (parseNode == null) {
24 | throw new IllegalArgumentException("The parseNode parameter cannot be null.");
25 | }
26 | return new TestAttendee();
27 | }
28 |
29 | @Nonnull
30 | @Override
31 | public Map getAdditionalData() {
32 | return this.additionalData;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/02-sdk-feature-request.yml:
--------------------------------------------------------------------------------
1 | name: SDK Feature request
2 | description: Request a new feature on the SDK
3 | labels: ["type:feature", "status:waiting-for-triage"]
4 | body:
5 | - type: markdown
6 | attributes:
7 | value: |
8 | **Thank you for taking the time to fill out this feature request form!**
9 | 💥Please search to see if an issue already exists for the feature you are requesting.
10 | - type: textarea
11 | attributes:
12 | label: Is your feature request related to a problem? Please describe the problem.
13 | description: A clear and concise description of what the problem is.
14 | placeholder: I am trying to do [...] but [...]
15 | validations:
16 | required: false
17 | - type: textarea
18 | attributes:
19 | label: Describe the solution you'd like.
20 | description: |
21 | A clear and concise description of what you want to happen. Include any alternative solutions you've considered.
22 | validations:
23 | required: true
24 | - type: textarea
25 | attributes:
26 | label: Additional context?
27 | description: |
28 | Add any other context or screenshots about the feature request here.
29 | validations:
30 | required: false
31 |
--------------------------------------------------------------------------------
/THIRD PARTY NOTICES:
--------------------------------------------------------------------------------
1 | This file is based on or incorporates material from the projects listed below
2 | (Third Party IP). The original copyright notice and the license under which
3 | Microsoft received such Third Party IP, are set forth below. Such licenses and
4 | notices are provided for informational purposes only. Microsoft licenses the
5 | Third Party IP to you under the licensing terms for the Microsoft product.
6 | Microsoft reserves all other rights not expressly granted under this agreement,
7 | whether by implication, estoppel or otherwise.
8 |
9 | Gson
10 | Copyright 2008-2011 Google Inc.
11 |
12 | Provided for Informational Purposes Only
13 |
14 | Apache 2.0 License
15 |
16 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
17 | this file except in compliance with the License. You may obtain a copy of the
18 | License at http://www.apache.org/licenses/LICENSE-2.0
19 |
20 | THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
21 | ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
22 | WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
23 | MERCHANTABLITY OR NON-INFRINGEMENT.
24 |
25 | See the Apache Version 2.0 License for specific language governing permissions
26 | and limitations under the License.
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/requests/FeatureTracker.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.requests;
2 |
3 |
4 | import jakarta.annotation.Nonnull;
5 |
6 | /**
7 | * Manages and tracks the flags for tasks and handlers.
8 | */
9 | public class FeatureTracker {
10 | /**
11 | * Default constructor
12 | */
13 | public FeatureTracker() {
14 | //Default constructor
15 | }
16 |
17 | private int featureUsage = FeatureFlag.NONE_FLAG;
18 | /**
19 | * Sets a numeric representation of the SDK feature usage
20 | * @param flag a numeric representation of the SDK feature usage
21 | */
22 | public void setFeatureUsage(@Nonnull int flag) {
23 |
24 | featureUsage = featureUsage | flag;
25 | }
26 | /**
27 | * Gets a numeric representation of the SDK feature usage
28 | * @return a numeric representation of the SDK feature usage
29 | */
30 | public int getFeatureUsage() {
31 | return featureUsage;
32 | }
33 |
34 | /**
35 | * Gets a serialized representation of the SDK feature usage.
36 | * @return a serialized representation of the SDK feature usage
37 | */
38 | @Nonnull
39 | public String getSerializedFeatureUsage() {
40 | return Integer.toHexString(featureUsage);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: gradle
4 | directories:
5 | - "/"
6 | - "/java-8"
7 | schedule:
8 | interval: daily
9 | time: "09:00" # 9am UTC
10 | open-pull-requests-limit: 10
11 | groups:
12 | kiota-dependencies:
13 | patterns:
14 | - "*kiota*"
15 | junit-dependencies:
16 | patterns:
17 | - "*junit*"
18 | open-telemetry:
19 | patterns:
20 | - "*opentelemetry*"
21 | - package-ecosystem: gradle
22 | directory: "/android"
23 | schedule:
24 | interval: daily
25 | time: "10:00" # 10am UTC. After core dependencies are updated to prevent duplicates.
26 | open-pull-requests-limit: 10
27 | groups:
28 | kiota-dependencies:
29 | patterns:
30 | - "*kiota*"
31 | junit-dependencies:
32 | patterns:
33 | - "*junit*"
34 | open-telemetry:
35 | patterns:
36 | - "*opentelemetry*"
37 | - package-ecosystem: maven
38 | directory: "/"
39 | schedule:
40 | interval: daily
41 | open-pull-requests-limit: 10
42 | groups:
43 | kiota-dependencies:
44 | patterns:
45 | - "*kiota*"
46 | junit-dependencies:
47 | patterns:
48 | - "*junit*"
49 | open-telemetry:
50 | patterns:
51 | - "*opentelemetry*"
52 | - package-ecosystem: github-actions
53 | directory: "/"
54 | schedule:
55 | interval: daily
56 | open-pull-requests-limit: 10
57 |
--------------------------------------------------------------------------------
/.github/workflows/release-please-gha.yml:
--------------------------------------------------------------------------------
1 | ## -----------------------------------------------------------------------------
2 | # Copyright (c) Microsoft Corporation. All rights reserved.
3 | # Licensed under the MIT License. See LICENSE.txt in the project root for license information.
4 | ## -----------------------------------------------------------------------------
5 | #
6 | # Summary:
7 | # This GitHub Actions workflow automates the release process using Release Please.
8 | # It triggers on pushes to the main branch, generates a GitHub App token using organization
9 | # variables and secrets, and then runs the release-please-action to manage versioning and changelogs.
10 |
11 | name: Release Please
12 |
13 | on:
14 | push:
15 | branches:
16 | - main
17 |
18 | jobs:
19 | release:
20 | runs-on: ubuntu-latest
21 | steps:
22 | - uses: actions/checkout@v5
23 |
24 | - name: Generate GitHub App token
25 | id: app-token
26 | uses: actions/create-github-app-token@v2
27 | with:
28 | app-id: ${{ vars.RELEASE_PLEASE_TOKEN_PROVIDER_APP_ID }}
29 | private-key: ${{ secrets.RELEASE_PLEASE_TOKEN_PROVIDER_PEM }}
30 |
31 | - name: Release Please
32 | uses: googleapis/release-please-action@v4
33 | with:
34 | token: ${{ steps.app-token.outputs.token }}
35 | config-file: release-please-config.json
36 | manifest-file: .release-please-manifest.json
--------------------------------------------------------------------------------
/scripts/getLatestVersion.ps1:
--------------------------------------------------------------------------------
1 | # Copyright (c) Microsoft Corporation. All rights reserved.
2 | # Licensed under the MIT License.
3 |
4 | <#
5 | .Synopsis
6 | Retrieve the latest version of the library
7 | .Description
8 | Retrieves the latest version specified in the Gradle.Properties file
9 | Uses the retrieved values to update the environment variable VERSION_STRING
10 | .Parameter propertiesPath
11 | The path pointing to the gradle.properties file.
12 | #>
13 |
14 | Param(
15 | [string]$propertiesPath
16 | )
17 |
18 | #Retrieve the current version from the Gradle.Properties file given the specified path
19 | if($propertiesPath -eq "" -or $null -eq $propertiesPath) {
20 | $propertiesPath = Join-Path -Path $PSScriptRoot -ChildPath "../gradle.properties"
21 | }
22 | $file = get-item $propertiesPath
23 | $findVersions = $file | Select-String -Pattern "mavenMajorVersion" -Context 0,2
24 | $content = Get-Content $propertiesPath
25 |
26 | $lineNumber = $findVersions.LineNumber - 1
27 | $versionIndex = $content[$lineNumber].IndexOf("=")
28 | $versionIndex += 2 # skipping =[space]
29 | $majorVersion = $content[$lineNumber].Substring($versionIndex)
30 | $lineNumber++
31 | $minorVersion = $content[$lineNumber].Substring($versionIndex)
32 | $lineNumber++
33 | $patchVersion = $content[$lineNumber].Substring($versionIndex)
34 | $version = "$majorVersion.$minorVersion.$patchVersion"
35 |
36 | #Set Task output to create tag
37 | Write-Output "::set-output name=tag::v${version}"
--------------------------------------------------------------------------------
/.github/workflows/conflicting-pr-label.yml:
--------------------------------------------------------------------------------
1 | # This is a basic workflow to help you get started with Actions
2 |
3 | name: PullRequestConflicting
4 |
5 | # Controls when the action will run. Triggers the workflow on push or pull request
6 | # events but only for the main branch
7 | on:
8 | workflow_dispatch:
9 | push:
10 | branches: [main, support/2.x.x]
11 | pull_request:
12 | types: [synchronize]
13 | branches: [main, support/2.x.x]
14 |
15 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel
16 | jobs:
17 | # This workflow contains a single job called "build"
18 | build:
19 | # The type of runner that the job will run on
20 | runs-on: ubuntu-latest
21 |
22 | # Steps represent a sequence of tasks that will be executed as part of the job
23 | steps:
24 | - name: check if prs are dirty
25 | uses: eps1lon/actions-label-merge-conflict@releases/2.x
26 | if: env.LABELING_TOKEN != '' && env.LABELING_TOKEN != null
27 | id: check
28 | with:
29 | dirtyLabel: "conflicting"
30 | repoToken: "${{ secrets.GITHUB_TOKEN }}"
31 | continueOnMissingPermissions: true
32 | commentOnDirty: 'This pull request has conflicting changes, the author must resolve the conflicts before this pull request can be merged.'
33 | commentOnClean: 'Conflicts have been resolved. A maintainer will take a look shortly.'
34 | env:
35 | LABELING_TOKEN: ${{secrets.GITHUB_TOKEN }}
36 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE users:
4 | # Settings specified in this file will override any Gradle settings
5 | # configured through the IDE.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | # The size of the library demands a large amount of RAM to build. Increase as necessary if you get GC errors
21 | ## linux requires 10G, OSX requires 11G
22 | org.gradle.jvmargs=-Xmx2g
23 | org.gradle.parallel=true
24 | org.gradle.caching=true
25 |
26 | mavenGroupId = com.microsoft.graph
27 | mavenArtifactId = microsoft-graph-core
28 | mavenMajorVersion = 3
29 | mavenMinorVersion = 1
30 | mavenPatchVersion = 0
31 | mavenArtifactSuffix =
32 |
33 |
34 | #enable mavenCentralPublishingEnabled to publish to maven central
35 | mavenCentralSnapshotArtifactSuffix = -SNAPSHOT
36 | mavenCentralPublishingEnabled=false
37 |
--------------------------------------------------------------------------------
/gradle/dependencies.gradle:
--------------------------------------------------------------------------------
1 | dependencies {
2 | // Use JUnit test framework
3 | testImplementation 'org.junit.jupiter:junit-jupiter:5.13.4'
4 | testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
5 | testImplementation 'org.mockito:mockito-core:5.19.0'
6 | testImplementation 'io.opentelemetry:opentelemetry-api:1.54.0'
7 | testImplementation 'io.opentelemetry:opentelemetry-context:1.54.0'
8 | testImplementation 'io.github.std-uritemplate:std-uritemplate:1.0.6'
9 | implementation 'com.google.code.gson:gson:2.13.2'
10 |
11 | implementation 'jakarta.annotation:jakarta.annotation-api:2.1.1'
12 |
13 | implementation 'io.jsonwebtoken:jjwt-api:0.13.0'
14 | runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.13.0'
15 | runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.13.0'
16 | implementation 'com.auth0:jwks-rsa:0.23.0'
17 |
18 | api 'com.squareup.okhttp3:okhttp:4.12.0'
19 | api 'com.azure:azure-core:1.56.1'
20 |
21 | api 'com.microsoft.kiota:microsoft-kiota-abstractions:1.8.10'
22 | api 'com.microsoft.kiota:microsoft-kiota-authentication-azure:1.8.10'
23 | implementation 'com.microsoft.kiota:microsoft-kiota-http-okHttp:1.8.10'
24 | implementation 'com.microsoft.kiota:microsoft-kiota-serialization-json:1.8.10'
25 | implementation 'com.microsoft.kiota:microsoft-kiota-serialization-text:1.8.10'
26 | implementation 'com.microsoft.kiota:microsoft-kiota-serialization-form:1.8.10'
27 | implementation 'com.microsoft.kiota:microsoft-kiota-serialization-multipart:1.8.10'
28 | }
29 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE users:
4 | # Settings specified in this file will override any Gradle settings
5 | # configured through the IDE.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | # The size of the library demands a large amount of RAM to build. Increase as necessary if you get GC errors
21 | ## linux requires 10G, OSX requires 11G
22 | org.gradle.jvmargs=-Xmx2g
23 |
24 | mavenGroupId = com.microsoft.graph
25 | mavenArtifactId = microsoft-graph-core
26 | # x-release-please-start-major
27 | mavenMajorVersion = 3
28 | # x-release-please-end
29 | # x-release-please-start-minor
30 | mavenMinorVersion = 6
31 | # x-release-please-end
32 | # x-release-please-start-patch
33 | mavenPatchVersion = 5
34 | # x-release-please-end
35 | mavenArtifactSuffix =
36 |
37 | #enable mavenCentralPublishingEnabled to publish to maven central
38 | mavenCentralSnapshotArtifactSuffix = -SNAPSHOT
39 | mavenCentralPublishingEnabled=false
40 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/models/EncryptableSubscription.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.models;
2 |
3 | import java.security.cert.CertificateEncodingException;
4 | import java.security.cert.X509Certificate;
5 | import java.util.Base64;
6 | import java.util.Objects;
7 |
8 | import jakarta.annotation.Nonnull;
9 | import jakarta.annotation.Nullable;
10 |
11 | /**
12 | * EncryptableSubscription interface
13 | */
14 | public interface EncryptableSubscription {
15 |
16 | /**
17 | * Sets the encryption certificate
18 | * @param certificate Base-64 encoded certificate to be used by Microsoft Graph to encrypt resource data
19 | */
20 | public void setEncryptionCertificate(@Nullable final String certificate);
21 |
22 | /**
23 | * Returns the encryption certificate
24 | * @return encryption certificate
25 | */
26 | public @Nullable String getEncryptionCertificate();
27 |
28 | /**
29 | * Converts an X.509 Certificate object to Base-64 string and adds to the encryptableSubscription provided
30 | * @param subscription encryptable subscription
31 | * @param certificate X.509 Certificate
32 | * @throws CertificateEncodingException if the certificate cannot be encoded
33 | */
34 | public static void addPublicEncryptionCertificate(@Nonnull final EncryptableSubscription subscription, @Nonnull final X509Certificate certificate) throws CertificateEncodingException {
35 | Objects.requireNonNull(subscription);
36 | Objects.requireNonNull(certificate);
37 | subscription.setEncryptionCertificate(
38 | Base64.getEncoder().encodeToString(certificate.getEncoded())
39 | );
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | gradlePluginPortal()
5 | }
6 |
7 | dependencies {
8 | classpath "com.gradle:gradle-enterprise-gradle-plugin:3.19.2"
9 | classpath "com.android.tools.build:gradle:8.13.0"
10 | classpath "com.github.ben-manes:gradle-versions-plugin:0.52.0"
11 | }
12 | }
13 |
14 | repositories {
15 | google()
16 | gradlePluginPortal()
17 | mavenCentral()
18 | }
19 |
20 | apply plugin: "com.android.library"
21 | apply plugin: "com.github.ben-manes.versions"
22 |
23 | android {
24 | namespace "com.microsoft.graph"
25 |
26 | compileSdkVersion 36
27 |
28 | defaultConfig {
29 | versionCode 1
30 | versionName "1.0"
31 | minSdkVersion 26
32 | targetSdkVersion 36
33 | }
34 |
35 | buildTypes {
36 | release {
37 | minifyEnabled false
38 | }
39 | }
40 |
41 | compileOptions {
42 | sourceCompatibility JavaVersion.VERSION_1_8
43 | targetCompatibility JavaVersion.VERSION_1_8
44 | }
45 |
46 | lint {
47 | baseline = file("lint-baseline.xml")
48 | }
49 |
50 | lintOptions {
51 | textOutput "stdout"
52 | checkAllWarnings true
53 | warningsAsErrors true
54 | lintConfig file("lint.xml")
55 | }
56 |
57 | sourceSets {
58 | main {
59 | java.srcDirs = ['../src/main/java']
60 | res.srcDirs = ['../src/main/java']
61 | manifest.srcFile 'AndroidManifest.xml'
62 | }
63 | androidTest {
64 | setRoot '../src/test'
65 | }
66 | }
67 | }
68 |
69 | apply from: "../gradle/dependencies.gradle"
70 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/requests/MockResponseHandler.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.requests;
2 |
3 | import java.io.IOException;
4 |
5 | import okhttp3.Interceptor;
6 | import okhttp3.MediaType;
7 | import okhttp3.Protocol;
8 | import okhttp3.Response;
9 | import okhttp3.ResponseBody;
10 | import okio.Buffer;
11 |
12 | class MockResponseHandler implements Interceptor {
13 |
14 | private int statusCode;
15 |
16 | public MockResponseHandler(int statusCode) {
17 | this.statusCode = statusCode;
18 | }
19 |
20 | public MockResponseHandler() {
21 | this.statusCode = 200;
22 | }
23 |
24 | @Override
25 | public Response intercept(Chain chain) throws IOException {
26 | final var request = chain.request();
27 | final var requestBody = request.body();
28 | if (request != null && requestBody != null) {
29 | final var buffer = new Buffer();
30 | requestBody.writeTo(buffer);
31 | return new Response.Builder()
32 | .code(this.statusCode)
33 | .message("OK")
34 | .protocol(Protocol.HTTP_1_1)
35 | .request(request)
36 | .body(
37 | ResponseBody.create(
38 | buffer.readByteArray(), MediaType.parse("application/json")))
39 | .build();
40 | }
41 | return new Response.Builder()
42 | .code(this.statusCode)
43 | .message("OK")
44 | .protocol(Protocol.HTTP_1_1)
45 | .request(request)
46 | .body(ResponseBody.create("", MediaType.parse("application/json")))
47 | .build();
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/testModels/TestEventsResponse.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.testModels;
2 |
3 |
4 | import com.microsoft.kiota.serialization.AdditionalDataHolder;
5 | import com.microsoft.kiota.serialization.Parsable;
6 | import com.microsoft.kiota.serialization.ParseNode;
7 | import com.microsoft.kiota.serialization.SerializationWriter;
8 |
9 | import jakarta.annotation.Nonnull;
10 | import java.util.HashMap;
11 | import java.util.List;
12 | import java.util.Map;
13 | import java.util.Objects;
14 | import java.util.function.Consumer;
15 |
16 | public class TestEventsResponse extends BaseCollectionPaginationCountResponse {
17 | public List value;
18 |
19 | public TestEventsResponse() {
20 | super();
21 | }
22 |
23 | public List getValue() {
24 | return value;
25 | }
26 |
27 | public void setValue(List value) {
28 | this.value = value;
29 | }
30 | @Nonnull
31 | public Map> getFieldDeserializers() {
32 | final HashMap> deserializerMap = new HashMap>(super.getFieldDeserializers());
33 | deserializerMap.put("value", (n) -> { this.setValue(n.getCollectionOfObjectValues(TestEventItem::createFromDiscriminatorValue)); });
34 | return deserializerMap;
35 | }
36 |
37 | public void serialize(@Nonnull SerializationWriter writer) {
38 | Objects.requireNonNull(writer);
39 | super.serialize(writer);
40 | writer.writeCollectionOfObjectValues("value", getValue());
41 | }
42 |
43 | public static TestEventsResponse createFromDiscriminatorValue(ParseNode parseNode) {
44 | Objects.requireNonNull(parseNode);
45 | return new TestEventsResponse();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/.github/workflows/sonarcloud.yml:
--------------------------------------------------------------------------------
1 | name: Static analysis with SonarCloud
2 | on:
3 | workflow_dispatch:
4 | push:
5 | branches: [main, support/2.x.x]
6 | pull_request:
7 | types: [opened, synchronize, reopened]
8 |
9 | env:
10 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
11 |
12 | jobs:
13 | checksecret:
14 | name: check if SONAR_TOKEN is set in github secrets
15 | runs-on: ubuntu-latest
16 | outputs:
17 | is_SONAR_TOKEN_set: ${{ steps.checksecret_job.outputs.is_SONAR_TOKEN_set }}
18 | steps:
19 | - name: Check whether unity activation requests should be done
20 | id: checksecret_job
21 | run: |
22 | echo "is_SONAR_TOKEN_set=${{ env.SONAR_TOKEN != '' }}" >> $GITHUB_OUTPUT
23 | build:
24 | needs: [checksecret]
25 | if: needs.checksecret.outputs.is_SONAR_TOKEN_set == 'true'
26 | name: Build
27 | runs-on: ubuntu-latest
28 | steps:
29 | - uses: actions/checkout@v5
30 | with:
31 | fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
32 | - name: Set up JDK
33 | uses: actions/setup-java@v5
34 | with:
35 | java-version: 21
36 | distribution: 'temurin'
37 | cache: gradle
38 | - name: Cache SonarCloud packages
39 | uses: actions/cache@v4
40 | with:
41 | path: ~/.sonar/cache
42 | key: ${{ runner.os }}-sonar
43 | restore-keys: ${{ runner.os }}-sonar
44 | - name: Cache Gradle packages
45 | uses: actions/cache@v4
46 | with:
47 | path: ~/.gradle/caches
48 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
49 | restore-keys: ${{ runner.os }}-gradle
50 | - name: Build and analyze
51 | env:
52 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
53 | run: ./gradlew build sonarqube --info
54 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/models/DiscoverUrlAdapter.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.models;
2 |
3 | import java.net.MalformedURLException;
4 | import java.net.URI;
5 | import java.net.URISyntaxException;
6 | import java.security.Key;
7 | import java.util.Objects;
8 |
9 | import org.slf4j.LoggerFactory;
10 |
11 | import com.auth0.jwk.Jwk;
12 | import com.auth0.jwk.JwkProvider;
13 | import com.auth0.jwk.UrlJwkProvider;
14 |
15 | import io.jsonwebtoken.JweHeader;
16 | import io.jsonwebtoken.JwsHeader;
17 | import io.jsonwebtoken.LocatorAdapter;
18 | import jakarta.annotation.Nonnull;
19 | import jakarta.annotation.Nullable;
20 |
21 | /**
22 | * DiscoverUrlAdapter class
23 | */
24 | public class DiscoverUrlAdapter extends LocatorAdapter {
25 |
26 | /**
27 | * Key store
28 | */
29 | private final JwkProvider keyStore;
30 |
31 | /**
32 | * Constructor
33 | * @param keyDiscoveryUrl the JWKS endpoint to use to retrieve signing keys
34 | * @throws URISyntaxException if uri is invalid
35 | * @throws MalformedURLException if url is invalid
36 | */
37 | public DiscoverUrlAdapter(@Nonnull final String keyDiscoveryUrl)
38 | throws URISyntaxException, MalformedURLException {
39 | this.keyStore =
40 | new UrlJwkProvider(new URI(Objects.requireNonNull(keyDiscoveryUrl)).toURL());
41 | }
42 |
43 | @Override
44 | protected @Nullable Key locate(@Nonnull JwsHeader header) {
45 | Objects.requireNonNull(header);
46 | try {
47 | String keyId = header.getKeyId();
48 | Jwk publicKey = keyStore.get(keyId);
49 | return publicKey.getPublicKey();
50 | } catch (final Exception e) {
51 | throw new IllegalArgumentException("Could not locate key", e);
52 | }
53 | }
54 |
55 | @Override
56 | protected @Nullable Key locate(@Nonnull JweHeader header) {
57 | return null;
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/requests/FeatureFlag.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.requests;
2 |
3 | /**
4 | * The class which holds the values of each feature flag.
5 | * Values are set such that they translate seamlessly to base 2.
6 | */
7 | public final class FeatureFlag {
8 | private FeatureFlag(){}
9 | /** The value of the None flag, 0.*/
10 | public static final int NONE_FLAG = 0;
11 | /** The value of the Redirect Handler flag, 1. */
12 | public static final int REDIRECT_HANDLER_FLAG = 1;
13 | /** The value of the Retry Handler flag, 10. */
14 | public static final int RETRY_HANDLER_FLAG = 2;
15 | /** The value of the Auth Handler flag, 100. */
16 | public static final int AUTH_HANDLER_FLAG = 4;
17 | /** The value of the Default Http flag, 1000. */
18 | public static final int DEFAULT_HTTP_FLAG = 8;
19 | /** The value of the Logging Handler flag, 10000. */
20 | public static final int LOGGING_HANDLER_FLAG = 16;
21 | /** The value of the Service Discovery flag, 100000. */
22 | public static final int SERVICE_DISCOVERY_FLAG = 32;
23 | /** The value of the Compression Handler flag, 1000000. */
24 | public static final int COMPRESSION_HANDLER_FLAG = 64;
25 | /** The value of the Connection Pool flag, 10000000. */
26 | public static final int CONNECTION_POOL_FLAG = 128;
27 | /** The value of the Long Running Operation flag, 100000000. */
28 | public static final int LONG_RUNNING_OP_FLAG = 256;
29 | /** The value of the Batch Request flag, 1000000000. */
30 | public static final int BATCH_REQUEST_FLAG = 512;
31 | /** The value of the Page Iterator flag, 10000000000. */
32 | public static final int PAGE_ITERATOR_FLAG = 1024;
33 | /** The value of the File Upload flag, 100000000000. */
34 | public static final int FILE_UPLOAD_FLAG = 2048;
35 | /** The value of the UrlReplacement flag, 1000000000000. */
36 | public static final int URL_REPLACEMENT_FLAG = 4096;
37 | }
38 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/testModels/TestChatMessage.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.testModels;
2 |
3 | import com.microsoft.kiota.serialization.AdditionalDataHolder;
4 | import com.microsoft.kiota.serialization.Parsable;
5 | import com.microsoft.kiota.serialization.ParseNode;
6 | import com.microsoft.kiota.serialization.SerializationWriter;
7 | import jakarta.annotation.Nonnull;
8 |
9 | import java.util.ArrayList;
10 | import java.util.HashMap;
11 | import java.util.Objects;
12 | import java.util.function.Consumer;
13 |
14 | public class TestChatMessage implements Parsable, AdditionalDataHolder {
15 |
16 | private HashMap additionalData;
17 | private String etag;
18 |
19 | public TestChatMessage() {
20 | }
21 |
22 | public String getETag() {
23 | return etag;
24 | }
25 |
26 | public void setEtag(String etag) {
27 | this.etag = etag;
28 | }
29 |
30 | @Nonnull
31 | public HashMap getAdditionalData() {
32 | return additionalData;
33 | }
34 |
35 | public void setAdditionalData(HashMap additionalData) {
36 | this.additionalData = additionalData;
37 | }
38 |
39 | public HashMap> getFieldDeserializers() {
40 | HashMap> fieldDeserializers = new HashMap<>();
41 | fieldDeserializers.put("etag", (n) -> { setEtag(n.getStringValue()); });
42 | return fieldDeserializers;
43 | }
44 |
45 | public void serialize(SerializationWriter writer) {
46 | Objects.requireNonNull(writer);
47 | writer.writeStringValue("etag", getETag());
48 | writer.writeAdditionalData(getAdditionalData());
49 | }
50 |
51 | public static TestChatMessage createFromDiscriminatorValue(ParseNode parseNode) {
52 | if (parseNode == null) {
53 | throw new IllegalArgumentException("The parseNode cannot be null.");
54 | }
55 | return new TestChatMessage();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/testModels/TestEventsDeltaResponse.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.testModels;
2 |
3 | import com.microsoft.kiota.serialization.AdditionalDataHolder;
4 | import com.microsoft.kiota.serialization.Parsable;
5 | import com.microsoft.kiota.serialization.ParseNode;
6 | import com.microsoft.kiota.serialization.SerializationWriter;
7 |
8 | import java.util.*;
9 | import java.util.function.Consumer;
10 |
11 | public class TestEventsDeltaResponse extends BaseCollectionPaginationCountResponse {
12 | private String odataDeltaLink;
13 | public List value;
14 |
15 | public TestEventsDeltaResponse() {
16 | super();
17 | }
18 |
19 | public String getOdataDeltaLink() {
20 | return odataDeltaLink;
21 | }
22 |
23 | public void setOdataDeltaLink(String odataDeltaLink) {
24 | this.odataDeltaLink = odataDeltaLink;
25 | }
26 |
27 | public List getValue() {
28 | return value;
29 | }
30 |
31 | public void setValue(List value) {
32 | this.value = value;
33 | }
34 |
35 | public Map> getFieldDeserializers() {
36 | final HashMap> deserializerMap = new HashMap>(super.getFieldDeserializers());
37 | deserializerMap.put("value", (n) -> { this.setValue(n.getCollectionOfObjectValues(TestEventItem::createFromDiscriminatorValue)); });
38 | return deserializerMap;
39 | }
40 |
41 | public void serialize(SerializationWriter writer) {
42 | Objects.requireNonNull(writer);
43 | super.serialize(writer);
44 | writer.writeCollectionOfObjectValues("value", getValue());
45 | }
46 |
47 | public static TestEventsDeltaResponse createFromDiscriminatorValue(ParseNode parseNode) {
48 | if (parseNode == null) {
49 | throw new IllegalArgumentException("parseNode");
50 | }
51 | return new TestEventsDeltaResponse();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/models/IUploadSession.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.models;
2 |
3 | import com.microsoft.kiota.serialization.AdditionalDataHolder;
4 | import com.microsoft.kiota.serialization.Parsable;
5 |
6 | import jakarta.annotation.Nonnull;
7 | import jakarta.annotation.Nullable;
8 | import java.time.OffsetDateTime;
9 | import java.util.List;
10 |
11 | /**
12 | * Interface defining and UploadSession
13 | */
14 | public interface IUploadSession extends Parsable, AdditionalDataHolder {
15 | /**
16 | * Gets the Upload Url.
17 | * The URL endpoint that accepts PUT requests for byte ranges of the file.
18 | * @return the upload Url
19 | */
20 | @Nonnull
21 | String getUploadUrl();
22 | /**
23 | * Sets the Upload Url
24 | * @param url the upload Url for the session
25 | */
26 | void setUploadUrl(@Nonnull final String url);
27 | /**
28 | * Gets the Next Expected Ranges.
29 | * A collection of byte ranges that the server is missing for the file. These ranges are zero indexed and of the format 'start-end' (e.g. '0-26' to indicate the first 27 bytes of the file). When uploading files as Outlook attachments, instead of a collection of ranges, this property always indicates a single value '{start}', the location in the file where the next upload should begin.
30 | * @return the Next Expected Ranges.
31 | */
32 | @Nullable
33 | List getNextExpectedRanges();
34 | /**
35 | * Sets the ranges that are yet to be uploaded.
36 | * @param nextExpectedRanges the byte ranges yet to be uploaded.
37 | */
38 | void setNextExpectedRanges(@Nonnull final List nextExpectedRanges);
39 | /**
40 | * Expiration date of the upload session
41 | * @return the expiration date.
42 | */
43 | @Nullable
44 | OffsetDateTime getExpirationDateTime();
45 | /**
46 | * Set the expiration date of the UploadSession
47 | * @param dateTime the expiration date of the UploadSession.
48 | */
49 | void setExpirationDateTime(@Nonnull final OffsetDateTime dateTime);
50 | }
51 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/testModels/TestDrive.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.testModels;
2 |
3 | import com.microsoft.kiota.serialization.AdditionalDataHolder;
4 | import com.microsoft.kiota.serialization.Parsable;
5 | import com.microsoft.kiota.serialization.ParseNode;
6 | import com.microsoft.kiota.serialization.SerializationWriter;
7 |
8 | import jakarta.annotation.Nonnull;
9 | import java.util.HashMap;
10 | import java.util.Map;
11 | import java.util.function.Consumer;
12 |
13 | public class TestDrive implements Parsable, AdditionalDataHolder {
14 | public String id;
15 | public String odataType;
16 | public String name;
17 | public HashMap additionalData;
18 |
19 | public TestDrive() {
20 | this.odataType = "microsoft.graph.drive";
21 | this.additionalData = new HashMap<>();
22 | }
23 |
24 | @Override
25 | public HashMap> getFieldDeserializers() {
26 | HashMap> props = new HashMap<>();
27 | props.put("@odata.type", (n) -> this.odataType = n.getStringValue());
28 | props.put("id", (n) -> this.id = n.getStringValue());
29 | props.put("name", (n) -> this.name = n.getStringValue());
30 | return props;
31 | }
32 |
33 | @Override
34 | public void serialize(SerializationWriter writer) {
35 | if (writer == null) {
36 | throw new IllegalArgumentException("The writer parameter cannot be null.");
37 | }
38 | writer.writeStringValue("@odata.type", odataType);
39 | writer.writeStringValue("id", id);
40 | writer.writeStringValue("name", name);
41 | writer.writeAdditionalData(additionalData);
42 | }
43 |
44 | @Nonnull
45 | @Override
46 | public Map getAdditionalData() {
47 | return this.additionalData;
48 | }
49 |
50 | public static TestDrive createFromDiscriminatorValue(ParseNode parseNode) {
51 | if (parseNode == null) {
52 | throw new IllegalArgumentException("parseNode cannot be null");
53 | }
54 | return new TestDrive();
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/testModels/TestDriveItem.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.testModels;
2 |
3 | import com.microsoft.kiota.serialization.AdditionalDataHolder;
4 | import com.microsoft.kiota.serialization.Parsable;
5 | import com.microsoft.kiota.serialization.ParseNode;
6 | import com.microsoft.kiota.serialization.SerializationWriter;
7 |
8 | import jakarta.annotation.Nonnull;
9 | import java.util.HashMap;
10 | import java.util.Map;
11 | import java.util.Objects;
12 | import java.util.function.Consumer;
13 |
14 | public class TestDriveItem implements Parsable, AdditionalDataHolder {
15 |
16 | public String id;
17 | public String oDataType = "#microsoft.graph.driveItem";
18 | public String name;
19 | public long size;
20 | public HashMap additionalData = new HashMap<>();
21 |
22 | public TestDriveItem() {}
23 |
24 | @Nonnull
25 | @Override
26 | public Map getAdditionalData() {
27 | return this.additionalData;
28 | }
29 |
30 | @Nonnull
31 | @Override
32 | public Map> getFieldDeserializers() {
33 | final HashMap> deserializerMap = new HashMap>();
34 | deserializerMap.put("id", (n)-> this.id = n.getStringValue());
35 | deserializerMap.put("@odata.type", (n)-> this.oDataType = n.getStringValue());
36 | deserializerMap.put("name", (n)-> this.name = n.getStringValue());
37 | deserializerMap.put("size", (n)-> this.size = n.getLongValue());
38 | return deserializerMap;
39 | }
40 |
41 | @Override
42 | public void serialize(@Nonnull SerializationWriter writer) {
43 | Objects.requireNonNull(writer);
44 | writer.writeStringValue("id", id);
45 | writer.writeStringValue("@odata.type", oDataType);
46 | writer.writeStringValue("name", name);
47 | writer.writeLongValue("size", size);
48 | }
49 |
50 | public static TestDriveItem createFromDiscriminatorValue(ParseNode parseNode) {
51 | Objects.requireNonNull(parseNode);
52 | return new TestDriveItem();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/testModels/TestNoteBook.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.testModels;
2 |
3 | import com.microsoft.kiota.serialization.AdditionalDataHolder;
4 | import com.microsoft.kiota.serialization.Parsable;
5 | import com.microsoft.kiota.serialization.ParseNode;
6 | import com.microsoft.kiota.serialization.SerializationWriter;
7 |
8 | import jakarta.annotation.Nonnull;
9 | import java.util.HashMap;
10 | import java.util.Map;
11 | import java.util.function.Consumer;
12 |
13 | public class TestNoteBook implements Parsable, AdditionalDataHolder {
14 | public String id;
15 | public String odataType;
16 | public String displayName;
17 | public HashMap additionalData;
18 |
19 | public TestNoteBook() {
20 | this.odataType = "microsoft.graph.notebook";
21 | this.additionalData = new HashMap<>();
22 | }
23 |
24 | @Override
25 | public HashMap> getFieldDeserializers() {
26 | HashMap> props = new HashMap<>();
27 | props.put("@odata.type", (n) -> odataType = n.getStringValue());
28 | props.put("id", (n) -> id = n.getStringValue());
29 | props.put("displayName", (n) -> displayName = n.getStringValue());
30 | return props;
31 | }
32 |
33 | @Override
34 | public void serialize(SerializationWriter writer) {
35 | if (writer == null) {
36 | throw new IllegalArgumentException("The writer parameter cannot be null.");
37 | }
38 | writer.writeStringValue("@odata.type", odataType);
39 | writer.writeStringValue("id", id);
40 | writer.writeStringValue("displayName", displayName);
41 | writer.writeAdditionalData(additionalData);
42 | }
43 |
44 | public static TestNoteBook createFromDiscriminatorValue(ParseNode parseNode) {
45 | if (parseNode == null) {
46 | throw new IllegalArgumentException("The parseNode parameter cannot be null.");
47 | }
48 | return new TestNoteBook();
49 | }
50 | @Nonnull
51 | @Override
52 | public Map getAdditionalData() {
53 | return this.additionalData;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/scripts/validatePackageContents.ps1:
--------------------------------------------------------------------------------
1 | # Checks that expected files are present & have contents after the publish process to the local cache
2 | param(
3 | [Parameter(Mandatory=$true)][string] $ArtifactId,
4 | [Parameter(Mandatory=$true)][string] $Version,
5 | [Parameter()][string] $GroupId = "com.microsoft.graph",
6 | [Parameter()][string] $MavenLocalCachePath = "~" + [System.IO.Path]::DirectorySeparatorChar + ".m2" + [System.IO.Path]::DirectorySeparatorChar + "repository",
7 | [Parameter()][bool] $ValidateMavenMetadata = $true
8 | )
9 |
10 | $groupIdPath = $GroupId -replace "\.", [System.IO.Path]::DirectorySeparatorChar
11 | $packagePath = Join-Path -Path $groupIdPath -ChildPath $ArtifactId
12 | $packageFullPath = Join-Path -Path $MavenLocalCachePath -ChildPath $packagePath -AdditionalChildPath $Version
13 |
14 | Write-Output "---------------------------------------------------"
15 | Write-Output "Validating package contents at $packageFullPath"
16 |
17 | if(-not (Test-Path -Path $packageFullPath)) {
18 | Write-Output "Package not found in local cache."
19 | exit 1
20 | }
21 |
22 | Write-Output "Package exists in local cache."
23 |
24 | $expectedFiles = @(
25 | "-javadoc.jar",
26 | "-javadoc.jar.asc",
27 | "-sources.jar",
28 | "-sources.jar.asc",
29 | ".module",
30 | ".module.asc",
31 | ".pom",
32 | ".pom.asc",
33 | ".jar",
34 | ".jar.asc"
35 | )
36 |
37 | foreach($file in $expectedFiles) {
38 | $file = $ArtifactId + "-" + $Version + $file
39 | $filePath = Join-Path -Path $packageFullPath -ChildPath $file
40 | if(-not (Test-Path -Path $filePath)) {
41 | Write-Output "Expected file $file not found in package."
42 | exit 1
43 | }
44 | $fileSize = (Get-Item -Path $filePath).length
45 | if($fileSize -eq 0) {
46 | Write-Output "File $file is empty."
47 | exit 1
48 | }
49 | }
50 |
51 | $mavenMetadataFiles = Get-ChildItem -Path $packageFullPath -Filter "maven-metadata*.xml"
52 | if($mavenMetadataFiles.Count -eq 0 -and $ValidateMavenMetadata -eq $true) {
53 | Write-Output "No maven-metadata*.xml files found in package."
54 | exit 1
55 | }
56 |
57 | Write-Output "Package $ArtifactId is valid."
58 | Write-Output "---------------------------------------------------"
59 | exit 0
60 |
61 |
62 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/testModels/TestEmailAddress.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.testModels;
2 |
3 | import com.microsoft.kiota.serialization.AdditionalDataHolder;
4 | import com.microsoft.kiota.serialization.Parsable;
5 | import com.microsoft.kiota.serialization.ParseNode;
6 | import com.microsoft.kiota.serialization.SerializationWriter;
7 |
8 | import jakarta.annotation.Nonnull;
9 | import java.util.HashMap;
10 | import java.util.Map;
11 | import java.util.function.Consumer;
12 |
13 | public class TestEmailAddress implements Parsable, AdditionalDataHolder {
14 | public String name;
15 | public String address;
16 | public HashMap additionalData;
17 | public String odataType;
18 |
19 | public TestEmailAddress() {
20 | this.odataType = "microsoft.graph.emailAddress";
21 | this.additionalData = new HashMap<>();
22 | }
23 |
24 | @Override
25 | public HashMap> getFieldDeserializers() {
26 | HashMap> props = new HashMap<>();
27 | props.put("@odata.type", (n) -> this.odataType = n.getStringValue());
28 | props.put("name", (n) -> this.name = n.getStringValue());
29 | props.put("address", (n) -> this.address = n.getStringValue());
30 | return props;
31 | }
32 |
33 | @Override
34 | public void serialize(SerializationWriter writer) {
35 | if (writer == null) {
36 | throw new IllegalArgumentException("The writer parameter cannot be null.");
37 | }
38 | writer.writeStringValue("name", name);
39 | writer.writeStringValue("address", address);
40 | writer.writeStringValue("@odata.type", odataType);
41 | writer.writeAdditionalData(additionalData);
42 | }
43 |
44 | public static TestEmailAddress createFromDiscriminatorValue(ParseNode parseNode) {
45 | if (parseNode == null) {
46 | throw new IllegalArgumentException("The parseNode parameter cannot be null.");
47 | }
48 | return new TestEmailAddress();
49 | }
50 |
51 | @Nonnull
52 | @Override
53 | public Map getAdditionalData() {
54 | return this.additionalData;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/testModels/TestRecipient.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.testModels;
2 |
3 | import com.microsoft.kiota.serialization.AdditionalDataHolder;
4 | import com.microsoft.kiota.serialization.Parsable;
5 | import com.microsoft.kiota.serialization.ParseNode;
6 | import com.microsoft.kiota.serialization.SerializationWriter;
7 |
8 | import jakarta.annotation.Nonnull;
9 | import java.util.HashMap;
10 | import java.util.Map;
11 | import java.util.function.Consumer;
12 |
13 | public class TestRecipient implements Parsable, AdditionalDataHolder {
14 | public TestEmailAddress emailAddress;
15 | public HashMap additionalData;
16 | public String ODataType;
17 |
18 | public TestRecipient() {
19 | this.ODataType = "microsoft.graph.recipient";
20 | }
21 |
22 | @Override
23 | public HashMap> getFieldDeserializers() {
24 | HashMap> props = new HashMap<>();
25 | props.put("@odata.type", (n) -> this.ODataType = n.getStringValue());
26 | props.put("emailAddress", (n) -> this.emailAddress = n.getObjectValue(TestEmailAddress::createFromDiscriminatorValue));
27 | return props;
28 | }
29 |
30 | @Override
31 | public void serialize(@Nonnull SerializationWriter writer) {
32 | writer.writeStringValue("@odata.type", ODataType);
33 | writer.writeObjectValue("emailAddress", emailAddress);
34 | writer.writeAdditionalData(additionalData);
35 | }
36 |
37 | public static TestRecipient createFromParseNode(ParseNode parseNode) {
38 | if (parseNode == null) {
39 | throw new IllegalArgumentException("The parseNode parameter cannot be null.");
40 | }
41 | ParseNode mappingValueNode = parseNode.getChildNode("@odata.type");
42 | assert mappingValueNode != null;
43 | String mappingValue = mappingValueNode.getStringValue();
44 | if (mappingValue == null) {
45 | return new TestRecipient();
46 | }
47 | if (mappingValue.equals("microsoft.graph.attendee")) {
48 | return new TestAttendee();
49 | }
50 | return new TestRecipient();
51 | }
52 |
53 | @Nonnull
54 | @Override
55 | public Map getAdditionalData() {
56 | return this.additionalData;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 | 4.0.0
8 |
9 | com.microsoft.graph
10 | microsoft-graph-core
11 |
12 | 3.6.5
13 |
14 | pom
15 |
16 |
17 | 1.8
18 | 1.8
19 |
20 |
21 |
22 |
23 | com.google.code.gson
24 | gson
25 | 2.13.2
26 |
27 |
28 | com.squareup.okhttp3
29 | okhttp
30 | 4.12.0
31 |
32 |
33 | com.azure
34 | azure-core
35 | 1.56.1
36 |
37 |
38 | org.junit.jupiter
39 | junit-jupiter-api
40 | 5.13.4
41 | test
42 |
43 |
44 | org.junit.jupiter
45 | junit-jupiter-params
46 | 5.13.4
47 | test
48 |
49 |
50 | org.mockito
51 | mockito-inline
52 | 5.2.0
53 | test
54 |
55 |
56 | com.github.spotbugs
57 | spotbugs-annotations
58 | 4.9.4
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/testModels/TestDateTimeTimeZone.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.testModels;
2 |
3 | import com.microsoft.kiota.serialization.AdditionalDataHolder;
4 | import com.microsoft.kiota.serialization.Parsable;
5 | import com.microsoft.kiota.serialization.ParseNode;
6 | import com.microsoft.kiota.serialization.SerializationWriter;
7 |
8 | import java.util.HashMap;
9 | import java.util.function.Consumer;
10 |
11 | public class TestDateTimeTimeZone implements Parsable, AdditionalDataHolder {
12 | private String dateTime;
13 | private String timeZone;
14 | private HashMap additionalData = new HashMap<>();
15 | private String oDataType;
16 |
17 | public TestDateTimeTimeZone() {
18 | this.oDataType = "microsoft.graph.dateTimeTimeZone";
19 | }
20 |
21 | public String getDateTime() {
22 | return dateTime;
23 | }
24 |
25 | public void setDateTime(String dateTime) {
26 | this.dateTime = dateTime;
27 | }
28 |
29 | public String getTimeZone() {
30 | return timeZone;
31 | }
32 |
33 | public void setTimeZone(String timeZone) {
34 | this.timeZone = timeZone;
35 | }
36 |
37 | public HashMap getAdditionalData() {
38 | return additionalData;
39 | }
40 |
41 | public void setAdditionalData(HashMap additionalData) {
42 | this.additionalData = additionalData;
43 | }
44 |
45 | public String getODataType() {
46 | return oDataType;
47 | }
48 |
49 | public void setODataType(String oDataType) {
50 | this.oDataType = oDataType;
51 | }
52 |
53 | public HashMap> getFieldDeserializers() {
54 | HashMap> fieldDeserializers = new HashMap<>();
55 | fieldDeserializers.put("dateTime", (n) -> setDateTime(n.getStringValue()));
56 | fieldDeserializers.put("timeZone", (n) -> setTimeZone(n.getStringValue()));
57 | fieldDeserializers.put("@odata.type", (n) -> setODataType(n.getStringValue()));
58 | return fieldDeserializers;
59 | }
60 |
61 | public void serialize(SerializationWriter writer) {
62 | writer.writeStringValue("dateTime", dateTime);
63 | writer.writeStringValue("timeZone", timeZone);
64 | writer.writeStringValue("@odata.type", oDataType);
65 | writer.writeAdditionalData(additionalData);
66 | }
67 |
68 | public static TestDateTimeTimeZone createFromDiscriminatorValue(ParseNode parseNode) {
69 | return new TestDateTimeTimeZone();
70 | }
71 | }
72 |
73 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/tasks/PageIteratorBuilder.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.tasks;
2 |
3 | import com.microsoft.graph.core.requests.IBaseClient;
4 | import com.microsoft.kiota.RequestAdapter;
5 | import com.microsoft.kiota.RequestInformation;
6 | import com.microsoft.kiota.serialization.AdditionalDataHolder;
7 | import com.microsoft.kiota.serialization.Parsable;
8 | import com.microsoft.kiota.serialization.ParsableFactory;
9 |
10 | import jakarta.annotation.Nonnull;
11 | import java.lang.reflect.InvocationTargetException;
12 | import java.util.function.UnaryOperator;
13 |
14 | interface PageIteratorBuilder {
15 | /**
16 | * Sets the client for the PageIteratorBuilder.
17 | * @param client the client to set.
18 | */
19 | public PageIteratorBuilder client(@Nonnull IBaseClient client);
20 | /**
21 | * Sets the request adapter for the PageIteratorBuilder.
22 | * @param requestAdapter the request adapter to set.
23 | */
24 | public PageIteratorBuilder requestAdapter(@Nonnull RequestAdapter requestAdapter);
25 | /**
26 | * Sets the page to be iterated over.
27 | * @param collectionPage the page to be iterated over.
28 | */
29 | public PageIteratorBuilder collectionPage(@Nonnull TCollectionPage collectionPage) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException;
30 | /**
31 | * Sets factory to use for creating a collection page.
32 | * @param collectionPageFactory the factory to use for creating a collection page.
33 | */
34 | public PageIteratorBuilder collectionPageFactory(@Nonnull ParsableFactory collectionPageFactory);
35 | /**
36 | * Sets the function to configure each subsequent request.
37 | * @param requestConfigurator function to configure each subsequent request.
38 | */
39 | public PageIteratorBuilder requestConfigurator(@Nonnull UnaryOperator requestConfigurator);
40 | /**
41 | * Build the PageIterator.
42 | * Should fail if request adapter is not set.
43 | * Should fail if current collection page is not set.
44 | * Should fail if collection page factory is not set.
45 | * Should fail if process page item callback is not set.
46 | * @return the built PageIterator.
47 | */
48 | PageIterator build() throws InvocationTargetException, IllegalAccessException, NoSuchMethodException;
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/testModels/TestItemBody.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.testModels;
2 |
3 | import com.microsoft.kiota.serialization.AdditionalDataHolder;
4 | import com.microsoft.kiota.serialization.Parsable;
5 | import com.microsoft.kiota.serialization.ParseNode;
6 | import com.microsoft.kiota.serialization.SerializationWriter;
7 |
8 | import java.util.HashMap;
9 | import java.util.function.Consumer;
10 |
11 | public class TestItemBody implements Parsable, AdditionalDataHolder {
12 |
13 | private TestBodyType contentType;
14 | private String content;
15 | private HashMap additionalData = new HashMap<>();
16 | private String oDataType;
17 |
18 | public TestItemBody() {
19 | this.oDataType = "microsoft.graph.itemBody";
20 | }
21 |
22 | public TestBodyType getContentType() {
23 | return contentType;
24 | }
25 |
26 | public void setContentType(TestBodyType contentType) {
27 | this.contentType = contentType;
28 | }
29 |
30 | public String getContent() {
31 | return content;
32 | }
33 |
34 | public void setContent(String content) {
35 | this.content = content;
36 | }
37 |
38 | public HashMap getAdditionalData() {
39 | return additionalData;
40 | }
41 |
42 | public void setAdditionalData(HashMap additionalData) {
43 | this.additionalData = additionalData;
44 | }
45 |
46 | public String getODataType() {
47 | return oDataType;
48 | }
49 |
50 | public void setODataType(String oDataType) {
51 | this.oDataType = oDataType;
52 | }
53 |
54 | public HashMap> getFieldDeserializers() {
55 | return new HashMap>() {{
56 | put("@odata.type", (n) -> { setODataType(n.getStringValue()); });
57 | put("contentType", (n) -> { setContentType(n.getEnumValue(TestBodyType::forValue)); });
58 | put("content", (n) -> { setContent(n.getStringValue()); });
59 | }};
60 | }
61 |
62 | public void serialize(SerializationWriter writer) {
63 | if (writer == null) {
64 | throw new IllegalArgumentException("writer cannot be null");
65 | }
66 | writer.writeStringValue("@odata.type", oDataType);
67 | writer.writeEnumValue("contentType", contentType);
68 | writer.writeStringValue("content", content);
69 | writer.writeAdditionalData(additionalData);
70 | }
71 |
72 | public static TestItemBody createFromDiscriminatorValue(ParseNode parseNode) {
73 | if (parseNode == null) {
74 | throw new IllegalArgumentException("parseNode cannot be null");
75 | }
76 | return new TestItemBody();
77 | }
78 | }
79 |
80 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Security
4 |
5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
6 |
7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
8 |
9 | ## Reporting Security Issues
10 |
11 | **Please do not report security vulnerabilities through public GitHub issues.**
12 |
13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
14 |
15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
16 |
17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
18 |
19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
20 |
21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
22 | * Full paths of source file(s) related to the manifestation of the issue
23 | * The location of the affected source code (tag/branch/commit or direct URL)
24 | * Any special configuration required to reproduce the issue
25 | * Step-by-step instructions to reproduce the issue
26 | * Proof-of-concept or exploit code (if possible)
27 | * Impact of the issue, including how an attacker might exploit the issue
28 |
29 | This information will help us triage your report more quickly.
30 |
31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
32 |
33 | ## Preferred Languages
34 |
35 | We prefer all communications to be in English.
36 |
37 | ## Policy
38 |
39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/BaseClient.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core;
2 |
3 | import com.microsoft.graph.core.requests.BaseGraphRequestAdapter;
4 | import com.microsoft.graph.core.requests.BatchRequestBuilder;
5 | import com.microsoft.graph.core.requests.IBaseClient;
6 | import com.microsoft.kiota.RequestAdapter;
7 | import com.microsoft.kiota.authentication.AuthenticationProvider;
8 |
9 | import jakarta.annotation.Nonnull;
10 |
11 | /**
12 | * Default client implementation.
13 | */
14 | public class BaseClient implements IBaseClient {
15 |
16 | private RequestAdapter requestAdapter;
17 | private BatchRequestBuilder batchRequestBuilder;
18 |
19 | /**
20 | * Constructor requiring only a RequestAdapter.
21 | *
22 | * @param requestAdapter the specified RequestAdapter used to complete requests.
23 | */
24 | public BaseClient(@Nonnull RequestAdapter requestAdapter) {
25 | setRequestAdapter(requestAdapter);
26 | }
27 | /**
28 | * Constructor requiring only an AuthenticationProvider.
29 | *
30 | * @param authenticationProvider the specified AuthenticationProvider for use in requests.
31 | */
32 | @SuppressWarnings("LambdaLast")
33 | public BaseClient(@Nonnull AuthenticationProvider authenticationProvider) {
34 | this(new BaseGraphRequestAdapter(authenticationProvider));
35 | }
36 | /**
37 | * Constructor requiring an AuthenticationProvider and Base URL.
38 | *
39 | * @param authenticationProvider the specified AuthenticationProvider for use in requests.
40 | * @param baseUrl the specified base URL for use in requests.
41 | */
42 | @SuppressWarnings("LambdaLast")
43 | public BaseClient(@Nonnull AuthenticationProvider authenticationProvider, @Nonnull String baseUrl) {
44 | this(new BaseGraphRequestAdapter(authenticationProvider, baseUrl));
45 | }
46 |
47 | /**
48 | * Method to set the RequestAdapter property
49 | * @param requestAdapter specifies the desired RequestAdapter
50 | */
51 | @Override
52 | public void setRequestAdapter(@Nonnull final RequestAdapter requestAdapter) {
53 | this.requestAdapter = requestAdapter;
54 | }
55 |
56 | /**
57 | * Returns the current RequestAdapter for sending requests
58 | * @return the RequestAdapter currently in use
59 | */
60 | @Nonnull
61 | @Override
62 | public RequestAdapter getRequestAdapter() {
63 | return this.requestAdapter;
64 | }
65 |
66 | /**
67 | * Gets the BatchRequestBuilder
68 | * @return the BatchRequestBuilder instance
69 | */
70 | @Override
71 | @Nonnull
72 | public BatchRequestBuilder getBatchRequestBuilder() {
73 | if(this.batchRequestBuilder == null) {
74 | this.batchRequestBuilder = new BatchRequestBuilder(getRequestAdapter());
75 | }
76 | return this.batchRequestBuilder;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/authentication/AzureIdentityAuthenticationProvider.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.authentication;
2 |
3 | import jakarta.annotation.Nonnull;
4 | import jakarta.annotation.Nullable;
5 |
6 | import com.azure.core.credential.TokenCredential;
7 | import com.microsoft.kiota.authentication.BaseBearerTokenAuthenticationProvider;
8 | import com.microsoft.kiota.authentication.ObservabilityOptions;
9 | /** Implementation of Authentication provider for Azure Identity with Microsoft Graph defaults */
10 | public class AzureIdentityAuthenticationProvider extends BaseBearerTokenAuthenticationProvider {
11 | /**
12 | * Creates a new instance of AzureIdentityAuthenticationProvider.
13 | * @param tokenCredential The Azure.Identity.TokenCredential implementation to use.
14 | * @param allowedHosts The list of allowed hosts for which to request access tokens.
15 | * @param scopes The scopes to request access tokens for.
16 | */
17 | @SuppressWarnings("LambdaLast")
18 | public AzureIdentityAuthenticationProvider(@Nonnull final TokenCredential tokenCredential, @Nonnull final String[] allowedHosts, @Nonnull final String... scopes) {
19 | this(tokenCredential, allowedHosts, null, scopes);
20 | }
21 | /**
22 | * Creates a new instance of AzureIdentityAuthenticationProvider.
23 | * @param tokenCredential The Azure.Identity.TokenCredential implementation to use.
24 | * @param allowedHosts The list of allowed hosts for which to request access tokens.
25 | * @param observabilityOptions The observability options to use.
26 | * @param scopes The scopes to request access tokens for.
27 | */
28 | @SuppressWarnings("LambdaLast")
29 | public AzureIdentityAuthenticationProvider(@Nonnull final TokenCredential tokenCredential, @Nonnull final String[] allowedHosts, @Nullable final ObservabilityOptions observabilityOptions, @Nonnull final String... scopes) {
30 | this(tokenCredential, allowedHosts, observabilityOptions, true, scopes);
31 | }
32 |
33 | /**
34 | * Creates a new instance of AzureIdentityAuthenticationProvider.
35 | * @param tokenCredential The Azure.Identity.TokenCredential implementation to use.
36 | * @param allowedHosts The list of allowed hosts for which to request access tokens.
37 | * @param observabilityOptions The observability options to use.
38 | * @param isCaeEnabled Whether to enable Continuous Access Evaluation, defaults to true.
39 | * @param scopes The scopes to request access tokens for.
40 | */
41 | @SuppressWarnings("LambdaLast")
42 | public AzureIdentityAuthenticationProvider(@Nonnull final TokenCredential tokenCredential, @Nonnull final String[] allowedHosts, @Nullable final ObservabilityOptions observabilityOptions, final boolean isCaeEnabled, @Nonnull final String... scopes) {
43 | super(new AzureIdentityAccessTokenProvider(tokenCredential, allowedHosts, observabilityOptions, isCaeEnabled, scopes));
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/authentication/AzureIdentityAccessTokenProvider.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.authentication;
2 |
3 | import java.util.HashSet;
4 |
5 | import jakarta.annotation.Nonnull;
6 | import jakarta.annotation.Nullable;
7 |
8 | import com.azure.core.credential.TokenCredential;
9 | import com.microsoft.kiota.authentication.ObservabilityOptions;
10 |
11 | /** AzureIdentityAccessTokenProvider wrapper from Kiota library with Microsoft Graph defaults. */
12 | public class AzureIdentityAccessTokenProvider extends com.microsoft.kiota.authentication.AzureIdentityAccessTokenProvider {
13 | /**
14 | * Creates a new instance of AzureIdentityAccessTokenProvider.
15 | * @param tokenCredential The Azure.Identity.TokenCredential implementation to use.
16 | */
17 | public AzureIdentityAccessTokenProvider(@Nonnull TokenCredential tokenCredential) {
18 | this(tokenCredential, new String[] {}, null);
19 | }
20 | /**
21 | * Creates a new instance of AzureIdentityAccessTokenProvider.
22 | * @param tokenCredential The Azure.Identity.TokenCredential implementation to use.
23 | * @param allowedHosts The list of allowed hosts for which to request access tokens.
24 | * @param scopes The scopes to request access tokens for.
25 | * @param observabilityOptions The observability options to use.
26 | */
27 | @SuppressWarnings("LambdaLast")
28 | public AzureIdentityAccessTokenProvider(@Nonnull final TokenCredential tokenCredential, @Nonnull final String[] allowedHosts,
29 | @Nullable final ObservabilityOptions observabilityOptions, @Nonnull final String... scopes) {
30 | this(tokenCredential, allowedHosts, observabilityOptions, true, scopes);
31 | }
32 |
33 | /**
34 | * Creates a new instance of AzureIdentityAccessTokenProvider.
35 | * @param tokenCredential The Azure.Identity.TokenCredential implementation to use.
36 | * @param allowedHosts The list of allowed hosts for which to request access tokens.
37 | * @param scopes The scopes to request access tokens for.
38 | * @param observabilityOptions The observability options to use.
39 | * @param isCaeEnabled Whether to enable Continuous Access Evaluation, defaults to true.
40 | */
41 | @SuppressWarnings("LambdaLast")
42 | public AzureIdentityAccessTokenProvider(@Nonnull final TokenCredential tokenCredential, @Nonnull final String[] allowedHosts,
43 | @Nullable final ObservabilityOptions observabilityOptions, final boolean isCaeEnabled, @Nonnull final String... scopes) {
44 | super(tokenCredential, allowedHosts, observabilityOptions, isCaeEnabled, scopes);
45 | if (allowedHosts == null || allowedHosts.length == 0) {
46 | final HashSet allowedHostsSet = new HashSet();
47 | allowedHostsSet.add("graph.microsoft.com");
48 | allowedHostsSet.add("graph.microsoft.us");
49 | allowedHostsSet.add("dod-graph.microsoft.us");
50 | allowedHostsSet.add("graph.microsoft.de");
51 | allowedHostsSet.add("microsoftgraph.chinacloudapi.cn");
52 | allowedHostsSet.add("canary.graph.microsoft.com");
53 | this.getAllowedHostsValidator().setAllowedHosts(allowedHostsSet);
54 | }
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=
74 |
75 |
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
95 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=
74 |
75 |
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
95 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/requests/upload/UploadSessionRequestBuilder.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.requests.upload;
2 |
3 | import com.microsoft.graph.core.models.IUploadSession;
4 | import com.microsoft.graph.core.models.UploadResult;
5 | import com.microsoft.kiota.*;
6 | import com.microsoft.kiota.serialization.Parsable;
7 | import com.microsoft.kiota.serialization.ParsableFactory;
8 | import okhttp3.Response;
9 |
10 | import jakarta.annotation.Nonnull;
11 | import java.io.InputStream;
12 | import java.util.Objects;
13 |
14 | /**
15 | * UploadSessionRequestBuilder class to get and delete an UploadSession.
16 | * @param The type of object being uploaded.
17 | */
18 | public class UploadSessionRequestBuilder {
19 |
20 | private final UploadResponseHandler responseHandler;
21 | private final RequestAdapter requestAdapter;
22 | private final String urlTemplate;
23 | private final ParsableFactory factory;
24 | /**
25 | * Create a new UploadSessionRequest.
26 | * @param sessionUrl The uploadSession url to use in the request.
27 | * @param requestAdapter The RequestAdapted to execute the request.
28 | * @param factory The ParsableFactory defining the instantiation of the object being uploaded.
29 | */
30 | public UploadSessionRequestBuilder(@Nonnull String sessionUrl,
31 | @Nonnull final RequestAdapter requestAdapter,
32 | @Nonnull final ParsableFactory factory) {
33 | this.responseHandler = new UploadResponseHandler();
34 | this.requestAdapter = Objects.requireNonNull(requestAdapter);
35 | if(Compatibility.isBlank(sessionUrl))
36 | {
37 | throw new IllegalArgumentException("sessionUrl cannot be null or empty");
38 | }
39 | this.urlTemplate = sessionUrl;
40 | this.factory = Objects.requireNonNull(factory);
41 | }
42 | /**
43 | * Gets the specified UploadSession.
44 | * @return the IUploadSession
45 | */
46 | @Nonnull
47 | public IUploadSession get() {
48 | RequestInformation requestInformation = toGetRequestInformation();
49 | NativeResponseHandler nativeResponseHandler = new NativeResponseHandler();
50 | requestInformation.setResponseHandler(nativeResponseHandler);
51 | requestAdapter.sendPrimitive(requestInformation, null, InputStream.class);
52 | UploadResult result = responseHandler.handleResponse((Response) nativeResponseHandler.getValue(), factory);
53 | return result.uploadSession;
54 | }
55 | private RequestInformation toGetRequestInformation() {
56 | RequestInformation requestInformation = new RequestInformation();
57 | requestInformation.httpMethod = HttpMethod.GET;
58 | requestInformation.urlTemplate = this.urlTemplate;
59 | return requestInformation;
60 | }
61 | /**
62 | * Deletes the specified UploadSession.
63 | */
64 | public void delete() {
65 | RequestInformation requestInfo = this.toDeleteRequestInformation();
66 | this.requestAdapter.sendPrimitive(requestInfo, null, Void.class);
67 | }
68 | private RequestInformation toDeleteRequestInformation() {
69 | RequestInformation requestInformation = new RequestInformation();
70 | requestInformation.httpMethod = HttpMethod.DELETE;
71 | requestInformation.urlTemplate = this.urlTemplate;
72 | return requestInformation;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [main, support/2.x.x]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [main, support/2.x.x]
20 | schedule:
21 | - cron: '0 1 * * 4'
22 | workflow_dispatch:
23 |
24 | jobs:
25 | analyze:
26 | name: Analyze
27 | runs-on: 'ubuntu-latest'
28 | timeout-minutes: 10
29 | permissions:
30 | actions: read
31 | contents: read
32 | security-events: write
33 |
34 | strategy:
35 | fail-fast: false
36 | matrix:
37 | language: [ 'java' ]
38 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ]
39 | # Use only 'java' to analyze code written in Java, Kotlin or both
40 | # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
41 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
42 |
43 | steps:
44 | - name: Checkout repository
45 | uses: actions/checkout@v5
46 |
47 | - name: Set up JDK
48 | uses: actions/setup-java@v5
49 | with:
50 | java-version: 21
51 | distribution: 'temurin'
52 | cache: gradle
53 |
54 | # Initializes the CodeQL tools for scanning.
55 | - name: Initialize CodeQL
56 | uses: github/codeql-action/init@v4
57 | with:
58 | languages: ${{ matrix.language }}
59 | # If you wish to specify custom queries, you can do so here or in a config file.
60 | # By default, queries listed here will override any specified in a config file.
61 | # Prefix the list here with "+" to use these queries and those in the config file.
62 |
63 | # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
64 | # queries: security-extended,security-and-quality
65 |
66 |
67 | # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
68 | # If this step fails, then you should remove it and run the build manually (see below)
69 | # - name: Autobuild
70 | # uses: github/codeql-action/autobuild@v2
71 |
72 | # ℹ️ Command-line programs to run using the OS shell.
73 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
74 |
75 | # If the Autobuild fails above, remove it and uncomment the following three lines.
76 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
77 |
78 | - name: Grant execute permission for gradlew
79 | run: chmod +x gradlew
80 | - name: Build with Gradle
81 | run: ./gradlew build
82 |
83 | - name: Perform CodeQL Analysis
84 | uses: github/codeql-action/analyze@v4
85 | with:
86 | category: "/language:${{matrix.language}}"
87 |
--------------------------------------------------------------------------------
/.github/workflows/project-auto-add.yml:
--------------------------------------------------------------------------------
1 | # This workflow is used to add new issues to GitHub GraphSDKs Project
2 |
3 | name: Add Issue or PR to project
4 | on:
5 | issues:
6 | types:
7 | - opened
8 | pull_request:
9 | types:
10 | - opened
11 | branches:
12 | - "main"
13 |
14 | jobs:
15 | track_issue:
16 | if: github.actor != 'dependabot[bot]' && github.event.pull_request.head.repo.fork == false
17 | runs-on: ubuntu-latest
18 | steps:
19 | - name: Generate token
20 | id: generate_token
21 | uses: actions/create-github-app-token@v2
22 | with:
23 | app-id: ${{ secrets.GRAPHBOT_APP_ID }}
24 | private-key: ${{ secrets.GRAPHBOT_APP_PEM }}
25 |
26 | - name: Get project data
27 | env:
28 | GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
29 | ORGANIZATION: microsoftgraph
30 | PROJECT_NUMBER: 55
31 | run: |
32 | gh api graphql -f query='
33 | query($org: String!, $number: Int!) {
34 | organization(login: $org){
35 | projectV2(number: $number) {
36 | id
37 | fields(first:20) {
38 | nodes {
39 | ... on ProjectV2SingleSelectField {
40 | id
41 | name
42 | options {
43 | id
44 | name
45 | }
46 | }
47 | }
48 | }
49 | }
50 | }
51 | }' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json
52 |
53 | echo 'PROJECT_ID='$(jq '.data.organization.projectV2.id' project_data.json) >> $GITHUB_ENV
54 | echo 'LANGUAGE_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Language") | .id' project_data.json) >> $GITHUB_ENV
55 | echo 'LANGUAGE_OPTION_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Language") | .options[] | select(.name=="Java") |.id' project_data.json) >> $GITHUB_ENV
56 |
57 | - name: Add Issue or PR to project
58 | env:
59 | GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
60 | ISSUE_ID: ${{ github.event_name == 'issues' && github.event.issue.node_id || github.event.pull_request.node_id }}
61 | run: |
62 | item_id="$( gh api graphql -f query='
63 | mutation($project:ID!, $issue:ID!) {
64 | addProjectV2ItemById(input: {projectId: $project, contentId: $issue}) {
65 | item {
66 | id
67 | }
68 | }
69 | }' -f project=$PROJECT_ID -f issue=$ISSUE_ID --jq '.data.addProjectV2ItemById.item.id')"
70 |
71 | echo 'ITEM_ID='$item_id >> $GITHUB_ENV
72 |
73 | - name: Set Language
74 | env:
75 | GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
76 | run: |
77 | gh api graphql -f query='
78 | mutation (
79 | $project: ID!
80 | $item: ID!
81 | $language_field: ID!
82 | $language_value: String!
83 | ) {
84 | set_status: updateProjectV2ItemFieldValue(input: {
85 | projectId: $project
86 | itemId: $item
87 | fieldId: $language_field
88 | value: {singleSelectOptionId: $language_value}
89 | }) {
90 | projectV2Item {
91 | id
92 | }
93 | }
94 | }' -f project=$PROJECT_ID -f item=$ITEM_ID -f language_field=$LANGUAGE_FIELD_ID -f language_value=${{ env.LANGUAGE_OPTION_ID }} --silent
95 |
--------------------------------------------------------------------------------
/.github/policies/resourceManagement.yml:
--------------------------------------------------------------------------------
1 | id:
2 | name: GitOps.PullRequestIssueManagement
3 | description: GitOps.PullRequestIssueManagement primitive
4 | owner:
5 | resource: repository
6 | disabled: false
7 | where:
8 | configuration:
9 | resourceManagementConfiguration:
10 | scheduledSearches:
11 | - description:
12 | frequencies:
13 | - hourly:
14 | hour: 6
15 | filters:
16 | - isIssue
17 | - isOpen
18 | - hasLabel:
19 | label: 'Needs: author feedback'
20 | - hasLabel:
21 | label: no-recent-activity
22 | - noActivitySince:
23 | days: 3
24 | - isNotLabeledWith:
25 | label: service bug
26 | actions:
27 | - closeIssue
28 | - description:
29 | frequencies:
30 | - hourly:
31 | hour: 6
32 | filters:
33 | - isIssue
34 | - isOpen
35 | - hasLabel:
36 | label: 'Needs: author feedback'
37 | - noActivitySince:
38 | days: 4
39 | - isNotLabeledWith:
40 | label: no-recent-activity
41 | actions:
42 | - addLabel:
43 | label: no-recent-activity
44 | - addReply:
45 | reply: This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for **4 days**. It will be closed if no further activity occurs **within 3 days of this comment**.
46 | - description:
47 | frequencies:
48 | - hourly:
49 | hour: 6
50 | filters:
51 | - isIssue
52 | - isOpen
53 | - hasLabel:
54 | label: duplicate
55 | - noActivitySince:
56 | days: 1
57 | actions:
58 | - addReply:
59 | reply: This issue has been marked as duplicate and has not had any activity for **1 day**. It will be closed for housekeeping purposes.
60 | - closeIssue
61 | eventResponderTasks:
62 | - if:
63 | - payloadType: Issues
64 | - isAction:
65 | action: Closed
66 | - hasLabel:
67 | label: 'status:waiting-for-author-feedback'
68 | then:
69 | - removeLabel:
70 | label: 'status:waiting-for-author-feedback'
71 | description:
72 | - if:
73 | - payloadType: Issue_Comment
74 | - isAction:
75 | action: Created
76 | - isActivitySender:
77 | issueAuthor: True
78 | - hasLabel:
79 | label: 'Needs: author feedback'
80 | then:
81 | - addLabel:
82 | label: needs attention
83 | - removeLabel:
84 | label: 'Needs: author feedback'
85 | description:
86 | - if:
87 | - payloadType: Issues
88 | - not:
89 | isAction:
90 | action: Closed
91 | - hasLabel:
92 | label: no-recent-activity
93 | then:
94 | - removeLabel:
95 | label: no-recent-activity
96 | description:
97 | - if:
98 | - payloadType: Issues
99 | - labelAdded:
100 | label: service bug
101 | then: []
102 | description:
103 | - if:
104 | - payloadType: Issue_Comment
105 | - activitySenderHasAssociation:
106 | association: Contributor
107 | - bodyContains:
108 | pattern: '?'
109 | isRegex: False
110 | - bodyContains:
111 | pattern: '@'
112 | isRegex: False
113 | then:
114 | - addLabel:
115 | label: 'Needs: author feedback'
116 | description:
117 | - if:
118 | - payloadType: Issues
119 | - or:
120 | - isAssignedToSomeone
121 | - isAction:
122 | action: Closed
123 | then:
124 | - removeLabel:
125 | label: ToTriage
126 | description:
127 | onFailure:
128 | onSuccess:
129 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/01-sdk-bug.yml:
--------------------------------------------------------------------------------
1 | name: SDK Bug Report
2 | description: File SDK bug report
3 | labels: ["type:bug", "status:waiting-for-triage"]
4 | body:
5 | - type: markdown
6 | attributes:
7 | value: |
8 | **Thank you for taking the time to fill out this bug report!**
9 | 💥Before submitting a new request, please search existing issues to see if an issue already exists.
10 | - type: textarea
11 | id: description
12 | attributes:
13 | label: Describe the bug
14 | description: |
15 | Provide a description of the actual behavior observed. If applicable please include any error messages, exception stacktraces or a screenshot.
16 | placeholder: I am trying to do [...] but [...]
17 | validations:
18 | required: true
19 | - type: textarea
20 | id: expected-behavior
21 | attributes:
22 | label: Expected behavior
23 | description: |
24 | A clear and concise description of what you expected to happen.
25 | placeholder: Expected behavior
26 | validations:
27 | required: true
28 | - type: textarea
29 | id: repro-steps
30 | attributes:
31 | label: How to reproduce
32 | description: |
33 | Please include minimal steps to reproduce the problem if possible. E.g.: the smallest possible code snippet; or steps to run project in link above. If possible include text as text rather than screenshots (so it shows up in searches).
34 | If there's a link to a public repo where the sample code exists, include it too.
35 | placeholder: Minimal Reproduction steps
36 | validations:
37 | required: true
38 | - type: input
39 | attributes:
40 | label: SDK Version
41 | placeholder: e.g. 5.32.1
42 | description: Version of the SDK with the bug described above.
43 | validations:
44 | required: false
45 | - type: input
46 | id: regression
47 | attributes:
48 | label: Latest version known to work for scenario above?
49 | description: |
50 | Did this work in a previous build or release of the SDK or API client? If you can try a previous release or build to find out, that can help us narrow down the problem. If you don't know, that's OK.
51 | placeholder: version-number
52 | validations:
53 | required: false
54 | - type: textarea
55 | id: known-workarounds
56 | attributes:
57 | label: Known Workarounds
58 | description: |
59 | Please provide a description of any known workarounds.
60 | placeholder: Known Workarounds
61 | validations:
62 | required: false
63 | - type: textarea
64 | id: logs
65 | attributes:
66 | label: Debug output
67 | description: Please copy and paste the debug output below.
68 | value: |
69 | Click to expand log
70 | ```
71 |
72 |
73 |
74 | ```
75 |
76 | validations:
77 | required: false
78 | - type: textarea
79 | id: configuration
80 | attributes:
81 | label: Configuration
82 | description: |
83 | Please provide more information on your SDK configuration:
84 | * What OS and version, and what distro if applicable (Windows 10, Windows 11, MacOS Catalina, Ubuntu 22.04)?
85 | * What is the architecture (x64, x86, ARM, ARM64)?
86 | * Do you know whether it is specific to that configuration?
87 | placeholder: |
88 | - OS:
89 | - architecture:
90 | validations:
91 | required: false
92 | - type: textarea
93 | id: other-info
94 | attributes:
95 | label: Other information
96 | description: |
97 | If you have an idea where the problem might lie, let us know that here. Please include any pointers to code, relevant changes, or related issues you know of.
98 | placeholder: Other information
99 | validations:
100 | required: false
101 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/requests/BatchRequestBuilderTest.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.requests;
2 |
3 | import com.microsoft.graph.core.BaseClient;
4 | import com.microsoft.graph.core.CoreConstants;
5 | import com.microsoft.graph.core.content.BatchRequestContent;
6 | import com.microsoft.graph.core.models.BatchRequestStep;
7 | import com.microsoft.kiota.HttpMethod;
8 | import com.microsoft.kiota.RequestInformation;
9 | import com.microsoft.kiota.authentication.AnonymousAuthenticationProvider;
10 | import okhttp3.MediaType;
11 | import okhttp3.Request;
12 | import okhttp3.RequestBody;
13 | import org.junit.jupiter.api.Test;
14 |
15 | import java.io.IOException;
16 | import java.io.InputStream;
17 | import java.net.URI;
18 | import java.nio.charset.StandardCharsets;
19 | import java.util.ArrayList;
20 | import java.util.Arrays;
21 | import java.util.List;
22 | import java.io.ByteArrayInputStream;
23 |
24 | import static org.junit.jupiter.api.Assertions.assertEquals;
25 | import static org.junit.jupiter.api.Assertions.assertNotNull;
26 |
27 | class BatchRequestBuilderTest {
28 |
29 | @Test
30 | void BatchRequestBuilder_DefaultBuilderTest() throws IOException {
31 | BaseClient client = new BaseClient(new AnonymousAuthenticationProvider(), "https://localhost");
32 | BatchRequestBuilder batchRequestBuilder = new BatchRequestBuilder(client.getRequestAdapter());
33 |
34 | Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/me/").build();
35 | RequestBody requestBody = RequestBody.create("{}", MediaType.get(CoreConstants.MimeTypeNames.APPLICATION_JSON));
36 | Request request2 = new Request.Builder().url("https://graph.microsoft.com/v1.0/me/onenote/notebooks").post(requestBody).build();
37 | BatchRequestStep batchRequestStep = new BatchRequestStep("1", request);
38 | BatchRequestStep batchRequestStep2 = new BatchRequestStep("2", request2, Arrays.asList("1"));
39 |
40 | BatchRequestContent batchRequestContent = new BatchRequestContent(client,Arrays.asList(batchRequestStep, batchRequestStep2));
41 | RequestInformation requestInformation = batchRequestBuilder.toPostRequestInformation(batchRequestContent);
42 |
43 | assertEquals("{+baseurl}/$batch", requestInformation.urlTemplate);
44 | assertEquals(client.getRequestAdapter(), batchRequestBuilder.getRequestAdapter());
45 |
46 | }
47 | @Test
48 | void BatchContentDoesNotDeadlockOnLargeContent() throws IOException {
49 | final BaseClient client = new BaseClient(new AnonymousAuthenticationProvider(), "https://localhost");
50 | final BatchRequestContent batchRequestContent = new BatchRequestContent(client);
51 | final List streamsToClose = new ArrayList<>();
52 | for (int i = 0; i < 20; i++) {
53 | final RequestInformation requestInformation = new RequestInformation();
54 | requestInformation.httpMethod = HttpMethod.POST;
55 | requestInformation.setUri(URI.create("https://graph.microsoft.com/v1.0/me/"));
56 | final String payload = "{\"displayName\": \"Test\", \"lastName\": \"User\", \"mailNickname\": \"testuser\", \"userPrincipalName\": \"testUser\", \"passwordProfile\": {\"forceChangePasswordNextSignIn\": true, \"password\": \"password\"}, \"accountEnabled\": true}";
57 | final InputStream content = new ByteArrayInputStream(payload.getBytes(StandardCharsets.UTF_8));
58 | streamsToClose.add(content);
59 | requestInformation.setStreamContent(content, CoreConstants.MimeTypeNames.APPLICATION_JSON);
60 | batchRequestContent.addBatchRequestStep(requestInformation);
61 | }
62 | BatchRequestBuilder batchRequestBuilder = new BatchRequestBuilder(client.getRequestAdapter());
63 | RequestInformation requestInformation = batchRequestBuilder.toPostRequestInformation(batchRequestContent);
64 | assertNotNull(requestInformation);
65 | for (final InputStream inputStream : streamsToClose) {
66 | inputStream.close();
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/models/TokenValidableTests.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.models;
2 |
3 | import com.microsoft.graph.core.testModels.TestChangeNotification;
4 | import com.microsoft.graph.core.testModels.TestChangeNotificationCollection;
5 | import com.microsoft.graph.core.testModels.TestChangeNotificationEncryptedContent;
6 | import org.junit.jupiter.api.Test;
7 |
8 | import java.util.ArrayList;
9 | import java.util.List;
10 | import java.util.UUID;
11 |
12 | import static org.junit.jupiter.api.Assertions.*;
13 |
14 | public class TokenValidableTests {
15 | @Test
16 | void TestTokenValidWithNoValidationTokens() {
17 | var testChangeNotification = new TestChangeNotificationCollection ();
18 | var tenantIds = new ArrayList();
19 | var appIds = new ArrayList();
20 | var result = TokenValidable.areTokensValid(testChangeNotification,tenantIds,appIds);
21 | assertTrue(result);
22 | }
23 |
24 | @Test
25 | void TestTokenValidWithNoEncryptedData() {
26 | var testChangeNotificationCollection = new TestChangeNotificationCollection ();
27 | var testTokens = new ArrayList();
28 | testTokens.add("testToken");
29 | testChangeNotificationCollection.setValidationTokens(testTokens);
30 | var testNotifications = new ArrayList();
31 | var testChangeNotification = new TestChangeNotification();
32 | testNotifications.add(testChangeNotification);
33 | testChangeNotificationCollection.setValue(testNotifications);
34 | var tenantIds = new ArrayList();
35 | var appIds = new ArrayList();
36 | var result = TokenValidable.areTokensValid(testChangeNotificationCollection,tenantIds,appIds);
37 | assertTrue(result); // no encrypted content
38 | }
39 | @Test
40 | void TestTokenValidWithEncryptedDataAndNoParameters() {
41 | var testChangeNotificationCollection = new TestChangeNotificationCollection ();
42 | var testTokens = new ArrayList();
43 | testTokens.add("testToken");
44 | testChangeNotificationCollection.setValidationTokens(testTokens);
45 | var testNotifications = new ArrayList();
46 | var testChangeNotification = new TestChangeNotification();
47 | var testEncryptedContent = new TestChangeNotificationEncryptedContent();
48 | testChangeNotification.setEncryptedContent(testEncryptedContent);
49 | testNotifications.add(testChangeNotification);
50 | testChangeNotificationCollection.setValue(testNotifications);
51 | var tenantIds = new ArrayList();
52 | var appIds = new ArrayList();
53 | assertThrows(IllegalArgumentException.class,() -> TokenValidable.areTokensValid(testChangeNotificationCollection,tenantIds,appIds));
54 | }
55 |
56 | @Test
57 | void TestTokenValidWithEncryptedData() {
58 | var testChangeNotificationCollection = new TestChangeNotificationCollection ();
59 | var testTokens = new ArrayList();
60 | testTokens.add("testToken");
61 | testChangeNotificationCollection.setValidationTokens(testTokens);
62 | var testNotifications = new ArrayList();
63 | var testChangeNotification = new TestChangeNotification();
64 | var testEncryptedContent = new TestChangeNotificationEncryptedContent();
65 | testChangeNotification.setEncryptedContent(testEncryptedContent);
66 | testNotifications.add(testChangeNotification);
67 | testChangeNotificationCollection.setValue(testNotifications);
68 | var tenantIds = new ArrayList();
69 | tenantIds.add(UUID.randomUUID());
70 | var appIds = new ArrayList();
71 | appIds.add(UUID.randomUUID());
72 | var exception = assertThrows(IllegalArgumentException.class,() -> TokenValidable.areTokensValid(testChangeNotificationCollection,tenantIds,appIds));
73 | assertEquals("Invalid token",exception.getMessage()); // issuer for the token is invalid
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to the Microsoft Graph Core SDK for Java
2 |
3 | The Microsoft Graph Core SDK for Java is available for all manner of contribution. There are a couple of different recommended paths to get contributions into the released version of this SDK.
4 |
5 | __NOTE__ A signed a contribution license agreement is required for all contributions, and is checked automatically on new pull requests. Please read and sign the agreement https://cla.microsoft.com/ before starting any work for this repository.
6 |
7 | ## File issues
8 |
9 | The best way to get started with a contribution is to start a dialog with the owners of this repository. Sometimes features will be under development or out of scope for this SDK and it's best to check before starting work on contribution.
10 |
11 | ## Submit pull requests for trivial changes
12 |
13 | If you are making a change that does not affect the interface components and does not affect other downstream callers, feel free to make a pull request against the __main__ branch. The main branch will be updated frequently.
14 |
15 | Revisions of this nature will result in a 0.0.X change of the version number.
16 |
17 | ## Submit pull requests for features
18 |
19 | If major functionality is being added, or there will need to be gestation time for a change, it should be submitted against the __feature__ branch.
20 |
21 | Revisions of this nature will result in a 0.X.X change of the version number.
22 |
23 | ## Commit message format
24 |
25 | To support our automated release process, pull requests are required to follow the [Conventional Commit](https://www.conventionalcommits.org/en/v1.0.0/)
26 | format.
27 |
28 | Each commit message consists of a **header**, an optional **body** and an optional **footer**. The header is the first line of the commit and
29 | MUST have a **type** (see below for a list of types) and a **description**. An optional **scope** can be added to the header to give extra context.
30 |
31 | ```
32 | [optional scope]:
33 |
34 |
35 |
36 |
37 | ```
38 |
39 | The recommended commit types used are:
40 |
41 | - **feat** for feature updates (increments the _minor_ version)
42 | - **fix** for bug fixes (increments the _patch_ version)
43 | - **perf** for performance related changes e.g. optimizing an algorithm
44 | - **refactor** for code refactoring changes
45 | - **test** for test suite updates e.g. adding a test or fixing a test
46 | - **style** for changes that don't affect the meaning of code. e.g. formatting changes
47 | - **docs** for documentation updates e.g. ReadMe update or code documentation updates
48 | - **build** for build system changes (gradle updates, external dependency updates)
49 | - **ci** for CI configuration file changes e.g. updating a pipeline
50 | - **chore** for miscallaneous non-sdk changesin the repo e.g. removing an unused file
51 |
52 | Adding a footer with the prefix **BREAKING CHANGE:** will cause an increment of the _major_ version.
53 |
54 | ## Add yourself as a contributor
55 |
56 | This project follows the [all contributors](https://github.com/kentcdodds/all-contributors) specification. When making a contribution, please add yourself to the table of contributors:
57 |
58 | 1. In section 5. of the [README.md](https://github.com/microsoftgraph/msgraph-sdk-java-core/blob/main/readme.md), after the last "|", copy and paste a new blank contributor element
59 | ```html
60 | [
61 | Your Name](your website or github page)
62 | [emoji](link "alt-text") |
63 | ```
64 |
65 | You can get your GitHub UID by inspecting your GitHub avatar image.
66 |
67 | 2. For each contribution type (see [emoji key](https://github.com/kentcdodds/all-contributors#emoji-key) for a list of contribution types), add an emoji and a relevant link and alt-text.
68 |
69 | For example, if you write a blogpost on how to use the SDK, you would include:
70 |
71 | ```html
72 | [??]("https://myblog.com/using-the-java-sdk" "Blog Post")
73 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/models/BatchRequestStep.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.models;
2 |
3 | import com.microsoft.graph.core.CoreConstants;
4 | import com.microsoft.graph.core.ErrorConstants;
5 | import com.microsoft.kiota.Compatibility;
6 | import com.microsoft.kiota.http.middleware.UrlReplaceHandler;
7 | import okhttp3.Request;
8 |
9 | import jakarta.annotation.Nonnull;
10 | import java.util.*;
11 |
12 | /**
13 | * Represents a single request in a batch request
14 | */
15 | public class BatchRequestStep {
16 |
17 | private final String requestId;
18 | private final Request request;
19 | private List dependsOn;
20 | /**
21 | * Creates a new BatchRequestStep
22 | * @param requestId The id of the request
23 | * @param request The request
24 | */
25 | public BatchRequestStep(@Nonnull String requestId, @Nonnull Request request) {
26 | Objects.requireNonNull(request, ErrorConstants.Messages.NULL_PARAMETER + "request");
27 | if(Compatibility.isBlank(requestId)) {
28 | throw new IllegalArgumentException("requestId cannot be null or empty.");
29 | }
30 | this.requestId = requestId;
31 | this.request = UrlReplaceHandler.replaceRequestUrl(request, CoreConstants.ReplacementConstants.getDefaultReplacementPairs());
32 | }
33 | /**
34 | * Creates a new BatchRequestStep
35 | * @param requestId The id of the request
36 | * @param request The request
37 | * @param dependsOn The ids of the requests that this request depends on
38 | */
39 | public BatchRequestStep(@Nonnull String requestId, @Nonnull Request request, @Nonnull List dependsOn) {
40 | this(requestId, request);
41 | this.dependsOn = new ArrayList<>(dependsOn);
42 | }
43 | /**
44 | * Gets the request
45 | * @return The request
46 | */
47 | @Nonnull
48 | public Request getRequest() {
49 | return this.request;
50 | }
51 | /**
52 | * Gets the id of the request
53 | * @return The id of the request
54 | */
55 | @Nonnull
56 | public String getRequestId() {
57 | return this.requestId;
58 | }
59 | /**
60 | * Gets the ids of the requests that this request depends on
61 | * @return The ids of the requests that this request depends on
62 | */
63 | @Nonnull
64 | public List getDependsOn() {
65 | if(dependsOn == null) {
66 | return new ArrayList<>();
67 | }
68 | return new ArrayList<>(dependsOn);
69 | }
70 | /**
71 | * Sets the ids of the requests that this request depends on
72 | * @param dependsOn The ids of the requests that this request depends on
73 | */
74 | public void setDependsOn(@Nonnull List dependsOn) {
75 | this.dependsOn = new ArrayList<>(dependsOn);
76 | }
77 | /**
78 | * Adds a request id to the dependsOn list.
79 | * @param id The id of the request to add to the dependsOn list.
80 | */
81 | public void addDependsOnId(@Nonnull String id) {
82 | if(Compatibility.isBlank(id)) {
83 | throw new IllegalArgumentException("id cannot be null or empty");
84 | }
85 | if(dependsOn == null) {
86 | dependsOn = new ArrayList<>();
87 | }
88 | dependsOn.add(id);
89 | }
90 | /**
91 | * Removes a request id from the dependsOn list.
92 | *
93 | * @param id The id of the request to remove.
94 | * @return true if the request id is no longer present in the dependsOn collection, false if dependsOn is null.
95 | */
96 | public boolean removeDependsOnId(@Nonnull String id) {
97 | Objects.requireNonNull(id);
98 | if(dependsOn != null) {
99 | if(!dependsOn.contains(id) || id.isEmpty()) {
100 | throw new IllegalArgumentException("id is not present in the dependsOn collection or is empty");
101 | }
102 | dependsOn.removeAll(Collections.singleton(id));
103 | return true;
104 | }
105 | return false;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/requests/upload/UploadSliceRequestTest.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.requests.upload;
2 |
3 | import com.microsoft.graph.core.CoreConstants;
4 | import com.microsoft.graph.core.models.UploadResult;
5 | import com.microsoft.graph.core.models.UploadSession;
6 | import com.microsoft.graph.core.testModels.TestDriveItem;
7 | import com.microsoft.kiota.authentication.AnonymousAuthenticationProvider;
8 | import com.microsoft.kiota.http.OkHttpRequestAdapter;
9 | import com.microsoft.kiota.serialization.JsonParseNodeFactory;
10 | import com.microsoft.kiota.serialization.ParsableFactory;
11 | import com.microsoft.kiota.serialization.ParseNodeFactoryRegistry;
12 | import okhttp3.*;
13 | import org.junit.jupiter.api.Test;
14 | import org.mockito.stubbing.Answer;
15 |
16 | import java.io.ByteArrayInputStream;
17 | import java.io.IOException;
18 | import java.net.HttpURLConnection;
19 | import java.time.OffsetDateTime;
20 |
21 | import static com.microsoft.kiota.serialization.ParseNodeFactoryRegistry.defaultInstance;
22 | import static org.junit.jupiter.api.Assertions.*;
23 | import static org.mockito.Mockito.*;
24 |
25 | class UploadSliceRequestTest {
26 | ParseNodeFactoryRegistry registry = defaultInstance;
27 |
28 | @Test
29 | void putReturnsExpectedUploadSession() throws IOException {
30 | registry.contentTypeAssociatedFactories.put(CoreConstants.MimeTypeNames.APPLICATION_JSON, new JsonParseNodeFactory());
31 | ParsableFactory factory = TestDriveItem::createFromDiscriminatorValue;
32 | ResponseBody body = ResponseBody.create(
33 | "{\n" +
34 | " \"expirationDateTime\": \"2015-01-29T09:21:55.523Z\",\n" +
35 | " \"nextExpectedRanges\": [\n" +
36 | " \"12345-55232\",\n" +
37 | " \"77829-99375\"\n" +
38 | " ]" +
39 | "}", MediaType.parse(CoreConstants.MimeTypeNames.APPLICATION_JSON));
40 | Response response = new Response.Builder()
41 | .request(new Request.Builder().post(mock(RequestBody.class)).url("https://a.b.c/").build())
42 | .protocol(Protocol.HTTP_1_1)
43 | .message("Accepted")
44 | .body(body)
45 | .code(HttpURLConnection.HTTP_ACCEPTED)
46 | .build();
47 |
48 | OkHttpClient mockClient = getMockClient(response);
49 | final OkHttpRequestAdapter adapter =
50 | new OkHttpRequestAdapter(new AnonymousAuthenticationProvider(), null, null,mockClient);
51 |
52 | byte[] mockData = new byte[500];
53 | ByteArrayInputStream stream = new ByteArrayInputStream(mockData);
54 |
55 | UploadSliceRequestBuilder sliceRequestBuilder = new UploadSliceRequestBuilder<>(
56 | "https://a.b.c/", adapter, 0, 200 , 1000, factory);
57 |
58 | UploadResult result = sliceRequestBuilder.put(stream);
59 | UploadSession session = (UploadSession) result.uploadSession;
60 |
61 | assertFalse(result.isUploadSuccessful());
62 | assertNotNull(session);
63 | assertTrue(session.getUploadUrl().isEmpty());
64 | assertEquals(OffsetDateTime.parse("2015-01-29T09:21:55.523Z"), session.getExpirationDateTime());
65 | assertEquals("12345-55232", session.getNextExpectedRanges().get(0));
66 | assertEquals("77829-99375", session.getNextExpectedRanges().get(1));
67 | assertEquals(2, session.getNextExpectedRanges().size());
68 | }
69 |
70 | public static OkHttpClient getMockClient(final Response response) throws IOException {
71 | final OkHttpClient mockClient = mock(OkHttpClient.class);
72 | final Call remoteCall = mock(Call.class);
73 | final Dispatcher dispatcher = new Dispatcher();
74 | when(remoteCall.execute()).thenReturn(response);
75 | doAnswer((Answer) invocation -> {
76 | Callback callback = invocation.getArgument(0);
77 | callback.onResponse(null, response);
78 | return null;
79 | }).when(remoteCall).enqueue(any(Callback.class));
80 | when(mockClient.dispatcher()).thenReturn(dispatcher);
81 | when(mockClient.newCall(any())).thenReturn(remoteCall);
82 | return mockClient;
83 | }
84 |
85 | }
86 |
--------------------------------------------------------------------------------
/spotBugsExcludeFilter.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/testModels/BaseCollectionPaginationCountResponse.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.testModels;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import java.util.Objects;
6 |
7 | import com.microsoft.kiota.serialization.AdditionalDataHolder;
8 | import com.microsoft.kiota.serialization.Parsable;
9 | import com.microsoft.kiota.serialization.ParseNode;
10 | import com.microsoft.kiota.serialization.SerializationWriter;
11 |
12 | public class BaseCollectionPaginationCountResponse implements AdditionalDataHolder, Parsable {
13 | public Map additionalData;
14 | private String odataNextLink;
15 | private Long odataCount;
16 | /**
17 | * Instantiates a new BaseCollectionPaginationCountResponse and sets the default values.
18 | */
19 | public BaseCollectionPaginationCountResponse() {
20 | this.setAdditionalData(new HashMap<>());
21 | }
22 | /**
23 | * Creates a new instance of the appropriate class based on discriminator value
24 | * @param parseNode The parse node to use to read the discriminator value and create the object
25 | * @return a BaseCollectionPaginationCountResponse
26 | */
27 | @jakarta.annotation.Nonnull
28 | public static BaseCollectionPaginationCountResponse createFromDiscriminatorValue(@jakarta.annotation.Nonnull final ParseNode parseNode) {
29 | Objects.requireNonNull(parseNode);
30 | return new BaseCollectionPaginationCountResponse();
31 | }
32 | /**
33 | * Gets the AdditionalData property value. Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
34 | * @return a Map
35 | */
36 | @jakarta.annotation.Nonnull
37 | public Map getAdditionalData() {
38 | return this.additionalData;
39 | }
40 | /**
41 | * The deserialization information for the current model
42 | * @return a Map>
43 | */
44 | @jakarta.annotation.Nonnull
45 | public Map> getFieldDeserializers() {
46 | final HashMap> deserializerMap = new HashMap>(2);
47 | deserializerMap.put("@odata.count", (n) -> { this.setOdataCount(n.getLongValue()); });
48 | deserializerMap.put("@odata.nextLink", (n) -> { this.setOdataNextLink(n.getStringValue()); });
49 | return deserializerMap;
50 | }
51 | /**
52 | * Gets the @odata.count property value. The OdataCount property
53 | * @return a Long
54 | */
55 | @jakarta.annotation.Nullable
56 | public Long getOdataCount() {
57 | return this.odataCount;
58 | }
59 | /**
60 | * Gets the @odata.nextLink property value. The OdataNextLink property
61 | * @return a String
62 | */
63 | @jakarta.annotation.Nullable
64 | public String getOdataNextLink() {
65 | return this.odataNextLink;
66 | }
67 | /**
68 | * Serializes information the current object
69 | * @param writer Serialization writer to use to serialize this model
70 | */
71 | public void serialize(@jakarta.annotation.Nonnull final SerializationWriter writer) {
72 | Objects.requireNonNull(writer);
73 | writer.writeLongValue("@odata.count", this.getOdataCount());
74 | writer.writeStringValue("@odata.nextLink", this.getOdataNextLink());
75 | writer.writeAdditionalData(this.getAdditionalData());
76 | }
77 | /**
78 | * Sets the AdditionalData property value. Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
79 | * @param value Value to set for the AdditionalData property.
80 | */
81 | public void setAdditionalData(@jakarta.annotation.Nullable final Map value) {
82 | this.additionalData = value;
83 | }
84 | /**
85 | * Sets the @odata.count property value. The OdataCount property
86 | * @param value Value to set for the @odata.count property.
87 | */
88 | public void setOdataCount(@jakarta.annotation.Nullable final Long value) {
89 | this.odataCount = value;
90 | }
91 | /**
92 | * Sets the @odata.nextLink property value. The OdataNextLink property
93 | * @param value Value to set for the @odata.nextLink property.
94 | */
95 | public void setOdataNextLink(@jakarta.annotation.Nullable final String value) {
96 | this.odataNextLink = value;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/testModels/TestEvent.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.testModels;
2 |
3 | import com.microsoft.kiota.serialization.AdditionalDataHolder;
4 | import com.microsoft.kiota.serialization.Parsable;
5 | import com.microsoft.kiota.serialization.ParseNode;
6 | import com.microsoft.kiota.serialization.SerializationWriter;
7 |
8 | import jakarta.annotation.Nonnull;
9 | import java.util.ArrayList;
10 | import java.util.HashMap;
11 | import java.util.Objects;
12 | import java.util.function.Consumer;
13 |
14 | public class TestEvent implements Parsable, AdditionalDataHolder {
15 | private String id;
16 | private String oDataType;
17 | private HashMap additionalData;
18 | private String subject;
19 | private TestItemBody body;
20 | private TestDateTimeTimeZone end;
21 | private TestDateTimeTimeZone start;
22 | private ArrayList attendees;
23 |
24 | public TestEvent() {
25 | this.oDataType = "microsoft.graph.event";
26 | }
27 |
28 | public String getId() {
29 | return id;
30 | }
31 |
32 | public void setId(String id) {
33 | this.id = id;
34 | }
35 |
36 | public String getODataType() {
37 | return oDataType;
38 | }
39 |
40 | public void setODataType(String oDataType) {
41 | this.oDataType = oDataType;
42 | }
43 |
44 | @Nonnull
45 | public HashMap getAdditionalData() {
46 | return additionalData;
47 | }
48 |
49 | public void setAdditionalData(HashMap additionalData) {
50 | this.additionalData = additionalData;
51 | }
52 |
53 | public String getSubject() {
54 | return subject;
55 | }
56 |
57 | public void setSubject(String subject) {
58 | this.subject = subject;
59 | }
60 |
61 | public TestItemBody getBody() {
62 | return body;
63 | }
64 |
65 | public void setBody(TestItemBody body) {
66 | this.body = body;
67 | }
68 |
69 | public TestDateTimeTimeZone getEnd() {
70 | return end;
71 | }
72 |
73 | public void setEnd(TestDateTimeTimeZone end) {
74 | this.end = end;
75 | }
76 |
77 | public TestDateTimeTimeZone getStart() {
78 | return start;
79 | }
80 |
81 | public void setStart(TestDateTimeTimeZone start) {
82 | this.start = start;
83 | }
84 |
85 | public ArrayList getAttendees() {
86 | return attendees;
87 | }
88 |
89 | public void setAttendees(ArrayList attendees) {
90 | this.attendees = attendees;
91 | }
92 |
93 | public HashMap> getFieldDeserializers() {
94 | HashMap> fieldDeserializers = new HashMap<>();
95 | fieldDeserializers.put("@odata.type", (n) -> { setODataType(n.getStringValue()); });
96 | fieldDeserializers.put("id", (n) -> { setId(n.getStringValue()); });
97 | fieldDeserializers.put("subject", (n) -> { setSubject(n.getStringValue()); });
98 | fieldDeserializers.put("body", (n) -> { setBody(n.getObjectValue(TestItemBody::createFromDiscriminatorValue)); });
99 | fieldDeserializers.put("end", (n) -> { setEnd(n.getObjectValue(TestDateTimeTimeZone::createFromDiscriminatorValue)); });
100 | fieldDeserializers.put("start", (n) -> { setStart(n.getObjectValue(TestDateTimeTimeZone::createFromDiscriminatorValue)); });
101 | fieldDeserializers.put("attendees", (n) -> { setAttendees((ArrayList) n.getCollectionOfObjectValues(TestAttendee::createFromDiscriminatorValue)); });
102 | return fieldDeserializers;
103 | }
104 |
105 | public void serialize(SerializationWriter writer) {
106 | Objects.requireNonNull(writer);
107 | writer.writeStringValue("@odata.type", getODataType());
108 | writer.writeStringValue("id", getId());
109 | writer.writeStringValue("subject", getSubject());
110 | writer.writeObjectValue("body", getBody());
111 | writer.writeObjectValue("end", getEnd());
112 | writer.writeObjectValue("start", getStart());
113 | writer.writeCollectionOfObjectValues("attendees", getAttendees());
114 | writer.writeAdditionalData(getAdditionalData());
115 | }
116 |
117 | public static TestEvent createFromDiscriminatorValue(ParseNode parseNode) {
118 | if (parseNode == null) {
119 | throw new IllegalArgumentException("The parseNode cannot be null.");
120 | }
121 | return new TestEvent();
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/testModels/TestUser.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.testModels;
2 |
3 | import com.microsoft.kiota.serialization.AdditionalDataHolder;
4 | import com.microsoft.kiota.serialization.Parsable;
5 | import com.microsoft.kiota.serialization.ParseNode;
6 | import com.microsoft.kiota.serialization.SerializationWriter;
7 |
8 | import java.util.ArrayList;
9 | import java.util.HashMap;
10 | import java.util.List;
11 | import java.util.function.Consumer;
12 |
13 | public class TestUser implements Parsable, AdditionalDataHolder {
14 | private String id;
15 | private String oDataType;
16 | private HashMap additionalData;
17 | private String givenName;
18 | private String displayName;
19 | private String state;
20 | private String surname;
21 | private List eventDeltas;
22 |
23 | public TestUser() {
24 | this.oDataType = "microsoft.graph.user";
25 | }
26 |
27 | public String getId() {
28 | return id;
29 | }
30 |
31 | public void setId(String id) {
32 | this.id = id;
33 | }
34 |
35 | public String getODataType() {
36 | return oDataType;
37 | }
38 |
39 | public void setODataType(String oDataType) {
40 | this.oDataType = oDataType;
41 | }
42 |
43 | public HashMap getAdditionalData() {
44 | return additionalData;
45 | }
46 |
47 | public void setAdditionalData(HashMap additionalData) {
48 | this.additionalData = additionalData;
49 | }
50 |
51 | public String getGivenName() {
52 | return givenName;
53 | }
54 |
55 | public void setGivenName(String givenName) {
56 | this.givenName = givenName;
57 | }
58 |
59 | public String getDisplayName() {
60 | return displayName;
61 | }
62 |
63 | public void setDisplayName(String displayName) {
64 | this.displayName = displayName;
65 | }
66 |
67 | public String getState() {
68 | return state;
69 | }
70 |
71 | public void setState(String state) {
72 | this.state = state;
73 | }
74 |
75 | public String getSurname() {
76 | return surname;
77 | }
78 |
79 | public void setSurname(String surname) {
80 | this.surname = surname;
81 | }
82 |
83 | public List getEventDeltas() {
84 | return eventDeltas;
85 | }
86 |
87 | public void setEventDeltas(List eventDeltas) {
88 | this.eventDeltas = eventDeltas;
89 | }
90 |
91 | public HashMap> getFieldDeserializers() {
92 | final HashMap> deserializerMap = new HashMap>();
93 | deserializerMap.put("id", (n) -> { setId(n.getStringValue()); });
94 | deserializerMap.put("@odata.type", (n) -> { setODataType(n.getStringValue()); });
95 | deserializerMap.put("givenName", (n) -> { setGivenName(n.getStringValue()); });
96 | deserializerMap.put("displayName", (n) -> { setDisplayName(n.getStringValue()); });
97 | deserializerMap.put("state", (n) -> { setState(n.getStringValue()); });
98 | deserializerMap.put("surname", (n) -> { setSurname(n.getStringValue()); });
99 | deserializerMap.put("eventDeltas", (n) -> {
100 | ArrayList eventList = new ArrayList<>();
101 | for (TestEvent item : n.getCollectionOfObjectValues(TestEvent::createFromDiscriminatorValue)) {
102 | eventList.add(item);
103 | }
104 | setEventDeltas(eventList);
105 | });
106 | return deserializerMap;
107 | }
108 |
109 | public void serialize(SerializationWriter writer) {
110 | if (writer == null) {
111 | throw new IllegalArgumentException("writer cannot be null");
112 | }
113 | writer.writeStringValue("id", id);
114 | writer.writeStringValue("@odata.type", oDataType);
115 | writer.writeStringValue("givenName", givenName);
116 | writer.writeStringValue("displayName", displayName);
117 | writer.writeStringValue("state", state);
118 | writer.writeStringValue("surname", surname);
119 | writer.writeCollectionOfObjectValues("eventDeltas", eventDeltas);
120 | writer.writeAdditionalData(additionalData);
121 | }
122 |
123 | public static TestUser createFromDiscriminatorValue(ParseNode parseNode) {
124 | if (parseNode == null) {
125 | throw new IllegalArgumentException("parseNode cannot be null");
126 | }
127 | return new TestUser();
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/.github/policies/msgraph-sdk-java-core-branch-protection.yml:
--------------------------------------------------------------------------------
1 | # Copyright (c) Microsoft Corporation.
2 | # Licensed under the MIT License.
3 |
4 | name: msgraph-sdk-java-core-branch-protection
5 | description: Branch protection policy for the msgraph-sdk-java-core repository
6 | resource: repository
7 | configuration:
8 | branchProtectionRules:
9 |
10 | - branchNamePattern: main
11 | # This branch pattern applies to the following branches as of 20/05/2024 10:31:16:
12 | # main
13 |
14 | # Specifies whether this branch can be deleted. boolean
15 | allowsDeletions: false
16 | # Specifies whether forced pushes are allowed on this branch. boolean
17 | allowsForcePushes: false
18 | # Specifies whether new commits pushed to the matching branches dismiss pull request review approvals. boolean
19 | dismissStaleReviews: true
20 | # Specifies whether admins can overwrite branch protection. boolean
21 | isAdminEnforced: false
22 | # Indicates whether "Require a pull request before merging" is enabled. boolean
23 | requiresPullRequestBeforeMerging: true
24 | # Specifies the number of pull request reviews before merging. int (0-6). Should be null/empty if PRs are not required
25 | requiredApprovingReviewsCount: 1
26 | # Require review from Code Owners. Requires requiredApprovingReviewsCount. boolean
27 | requireCodeOwnersReview: true
28 | # Are commits required to be signed. boolean. TODO: all contributors must have commit signing on local machines.
29 | requiresCommitSignatures: false
30 | # Are conversations required to be resolved before merging? boolean
31 | requiresConversationResolution: true
32 | # Are merge commits prohibited from being pushed to this branch. boolean
33 | requiresLinearHistory: false
34 | # Required status checks to pass before merging. Values can be any string, but if the value does not correspond to any existing status check, the status check will be stuck on pending for status since nothing exists to push an actual status
35 | requiredStatusChecks:
36 | - license/cla
37 | - Build
38 | - lint-api-level
39 | - Analyze (java)
40 | - build
41 | # Require branches to be up to date before merging. Requires requiredStatusChecks. boolean
42 | requiresStrictStatusChecks: true
43 | # Indicates whether there are restrictions on who can push. boolean. Should be set with whoCanPush.
44 | restrictsPushes: false
45 | # Restrict who can dismiss pull request reviews. boolean
46 | restrictsReviewDismissals: false
47 |
48 | - branchNamePattern: support/2.x.x
49 | # This branch pattern applies to the following branches as of 2/14/2024 12:24
50 | # support/2.x.x
51 |
52 | # Specifies whether this branch can be deleted. boolean
53 | allowsDeletions: false
54 | # Specifies whether forced pushes are allowed on this branch. boolean
55 | allowsForcePushes: false
56 | # Specifies whether new commits pushed to the matching branches dismiss pull request review approvals. boolean
57 | dismissStaleReviews: true
58 | # Specifies whether admins can overwrite branch protection. boolean
59 | isAdminEnforced: false
60 | # Indicates whether "Require a pull request before merging" is enabled. boolean
61 | requiresPullRequestBeforeMerging: true
62 | # Specifies the number of pull request reviews before merging. int (0-6). Should be null/empty if PRs are not required
63 | requiredApprovingReviewsCount: 1
64 | # Require review from Code Owners. Requires requiredApprovingReviewsCount. boolean
65 | requireCodeOwnersReview: true
66 | # Are commits required to be signed. boolean. TODO: all contributors must have commit signing on local machines.
67 | requiresCommitSignatures: false
68 | # Are conversations required to be resolved before merging? boolean
69 | requiresConversationResolution: true
70 | # Are merge commits prohibited from being pushed to this branch. boolean
71 | requiresLinearHistory: false
72 | # Required status checks to pass before merging. Values can be any string, but if the value does not correspond to any existing status check, the status check will be stuck on pending for status since nothing exists to push an actual status
73 | requiredStatusChecks:
74 | - license/cla
75 | - Build
76 | - lint-api-level
77 | - Analyze (java)
78 | - build
79 | # Require branches to be up to date before merging. Requires requiredStatusChecks. boolean
80 | requiresStrictStatusChecks: true
81 | # Indicates whether there are restrictions on who can push. boolean. Should be set with whoCanPush.
82 | restrictsPushes: false
83 | # Restrict who can dismiss pull request reviews. boolean
84 | restrictsReviewDismissals: false
85 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/requests/options/GraphClientOption.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.requests.options;
2 |
3 | import java.util.UUID;
4 |
5 | import com.microsoft.graph.core.requests.FeatureTracker;
6 | import com.microsoft.kiota.Compatibility;
7 | import jakarta.annotation.Nonnull;
8 | import jakarta.annotation.Nullable;
9 |
10 | import com.microsoft.graph.core.CoreConstants;
11 | import com.microsoft.kiota.RequestOption;
12 |
13 | /**
14 | * Options to be passed to the telemetry middleware.
15 | */
16 | public class GraphClientOption implements RequestOption {
17 |
18 | private String clientRequestId;
19 | private String clientLibraryVersion;
20 | private String coreLibraryVersion;
21 | private String graphServiceTargetVersion;
22 | /**
23 | * Default constructor
24 | */
25 | public GraphClientOption() {
26 | //Default constructor
27 | }
28 |
29 | /**
30 | * Feature Tracker instance
31 | */
32 | public final FeatureTracker featureTracker = new FeatureTracker();
33 | /**
34 | * Sets the client request id
35 | * @param clientRequestId the client request id to set, preferably the string representation of a GUID
36 | */
37 | public void setClientRequestId(@Nonnull final String clientRequestId) {
38 | if(Compatibility.isBlank(clientRequestId)) {
39 | throw new IllegalArgumentException("clientRequestId cannot be null or empty");
40 | }
41 | this.clientRequestId = clientRequestId;
42 | }
43 | /**
44 | * Gets the client request id
45 | * @return the client request id
46 | */
47 | @Nonnull
48 | public String getClientRequestId() {
49 | if(clientRequestId == null) {
50 | clientRequestId = UUID.randomUUID().toString();
51 | }
52 | return clientRequestId;
53 | }
54 | /**
55 | * Sets a string representation of the client library
56 | * @param clientLibraryVersion client library version specified by user.
57 | */
58 | public void setClientLibraryVersion(@Nonnull final String clientLibraryVersion) {
59 | if(Compatibility.isBlank(clientLibraryVersion))
60 | {
61 | throw new IllegalArgumentException("clientLibraryVersion cannot be null or empty");
62 | }
63 | this.clientLibraryVersion = clientLibraryVersion;
64 | }
65 | /**
66 | * Get the client library version as a string
67 | * If null return null;
68 | * @return client library version.
69 | */
70 | @Nullable
71 | public String getClientLibraryVersion() {
72 | return this.clientLibraryVersion == null ? null : this.clientLibraryVersion;
73 | }
74 | /**
75 | * Set the core library version as a String, in this format 'x.x.x'
76 | * @param coreLibraryVersion core library version specified by user.
77 | */
78 | public void setCoreLibraryVersion(@Nonnull final String coreLibraryVersion) {
79 | if(Compatibility.isBlank(coreLibraryVersion))
80 | {
81 | throw new IllegalArgumentException("coreLibraryVersion cannot be null or empty");
82 | }
83 | this.coreLibraryVersion = coreLibraryVersion;
84 | }
85 | /**
86 | * Get the core library version as a String, in this format 'x.x.x'
87 | * If null return the value in CoreConstants.
88 | * @return core library version.
89 | */
90 | @Nonnull
91 | public String getCoreLibraryVersion() {
92 | return this.coreLibraryVersion == null ? CoreConstants.Headers.VERSION : this.coreLibraryVersion;
93 | }
94 | /**
95 | * Set the target version of the api endpoint we are targeting (v1 or beta)
96 | * @param graphServiceVersion the version of the Api endpoint we are targeting
97 | */
98 | public void setGraphServiceTargetVersion(@Nonnull final String graphServiceVersion) {
99 | if(Compatibility.isBlank(graphServiceVersion))
100 | {
101 | throw new IllegalArgumentException("graphServiceVersion cannot be null or empty");
102 | }
103 | this.graphServiceTargetVersion = graphServiceVersion;
104 | }
105 | /**
106 | * Get the target version of the api endpoint we are targeting (v1 or beta)
107 | * return 'v1' if not specified.
108 | * @return the version of the Api endpoint we are targeting.
109 | */
110 | @Nonnull
111 | public String getGraphServiceTargetVersion() {
112 | return this.graphServiceTargetVersion == null ? "v1.0" : this.graphServiceTargetVersion;
113 | }
114 |
115 | @Override
116 | @Nonnull
117 | public Class getType() {
118 | return (Class) GraphClientOption.class;
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/requests/BatchRequestBuilder.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.requests;
2 |
3 | import com.microsoft.graph.core.CoreConstants;
4 | import com.microsoft.graph.core.content.BatchRequestContent;
5 | import com.microsoft.graph.core.content.BatchRequestContentCollection;
6 | import com.microsoft.graph.core.content.BatchResponseContent;
7 | import com.microsoft.graph.core.content.BatchResponseContentCollection;
8 | import com.microsoft.graph.core.ErrorConstants;
9 | import com.microsoft.kiota.HttpMethod;
10 | import com.microsoft.kiota.NativeResponseHandler;
11 | import com.microsoft.kiota.RequestAdapter;
12 | import com.microsoft.kiota.RequestInformation;
13 | import com.microsoft.kiota.serialization.Parsable;
14 | import com.microsoft.kiota.serialization.ParsableFactory;
15 | import okhttp3.Response;
16 |
17 | import jakarta.annotation.Nonnull;
18 | import jakarta.annotation.Nullable;
19 |
20 | import java.io.IOException;
21 | import java.io.InputStream;
22 | import java.util.HashMap;
23 | import java.util.List;
24 | import java.util.Map;
25 | import java.util.Objects;
26 |
27 | /**
28 | * A request builder for creating batch requests.
29 | */
30 | public class BatchRequestBuilder {
31 | private final RequestAdapter requestAdapter;
32 | /**
33 | * Instantiates a new BatchRequestBuilder.
34 | * @param requestAdapter the adapter to use to build requests.
35 | */
36 | public BatchRequestBuilder(@Nonnull RequestAdapter requestAdapter) {
37 | this.requestAdapter = Objects.requireNonNull(requestAdapter, ErrorConstants.Messages.NULL_PARAMETER + "requestAdapter");
38 | }
39 | /**
40 | * Posts a batch request.
41 | * @param requestContent the batch request content.
42 | * @param errorMappings the error mappings to use when parsing the response.
43 | * @return the batch response content.
44 | * @throws IOException if there was an error writing the request content.
45 | */
46 | @Nonnull
47 | public BatchResponseContent post(@Nonnull BatchRequestContent requestContent, @Nullable Map> errorMappings) throws IOException {
48 | Objects.requireNonNull(requestContent, ErrorConstants.Messages.NULL_PARAMETER + "requestContent");
49 | RequestInformation requestInfo = toPostRequestInformation(requestContent);
50 | NativeResponseHandler nativeResponseHandler = new NativeResponseHandler();
51 | requestInfo.setResponseHandler(nativeResponseHandler);
52 | requestAdapter.sendPrimitive(requestInfo, errorMappings == null ? null : new HashMap<>(errorMappings) ,InputStream.class);
53 | return new BatchResponseContent((Response) nativeResponseHandler.getValue(), errorMappings);
54 | }
55 | /**
56 | * Posts a BatchRequestContentCollection.
57 | * @param batchRequestContentCollection the BatchRequestContentCollection to post.
58 | * @param errorMappings the error mappings to use when parsing the response.
59 | * @return the BatchResponseContentCollection.
60 | * @throws IOException if there was an error writing the request content.
61 | */
62 | @Nonnull
63 | public BatchResponseContentCollection post(@Nonnull BatchRequestContentCollection batchRequestContentCollection, @Nullable Map> errorMappings) throws IOException {
64 | BatchResponseContentCollection collection = new BatchResponseContentCollection();
65 | List requests = batchRequestContentCollection.getBatchRequestsForExecution();
66 | for (BatchRequestContent request : requests) {
67 | BatchResponseContent responseContent = post(request, errorMappings);
68 | collection.addBatchResponse(request.getBatchRequestSteps().keySet(), responseContent);
69 | }
70 | return collection;
71 | }
72 | /**
73 | * Creates the request information for a batch request.
74 | * @param requestContent the batch request content.
75 | * @return the request information.
76 | * @throws IOException if there was an error writing the request content.
77 | */
78 | @Nonnull
79 | public RequestInformation toPostRequestInformation(@Nonnull BatchRequestContent requestContent) throws IOException {
80 | Objects.requireNonNull(requestContent, ErrorConstants.Messages.NULL_PARAMETER + "requestContent");
81 | RequestInformation requestInfo = new RequestInformation();
82 | requestInfo.httpMethod = HttpMethod.POST;
83 | requestInfo.urlTemplate = "{+baseurl}/$batch";
84 | requestInfo.content = requestContent.getBatchRequestContent();
85 | requestInfo.headers.add("Content-Type", CoreConstants.MimeTypeNames.APPLICATION_JSON);
86 | return requestInfo;
87 | }
88 | /**
89 | * Gets the request adapter.
90 | * @return the request adapter.
91 | */
92 | @Nonnull
93 | public RequestAdapter getRequestAdapter() {
94 | return requestAdapter;
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/testModels/TestResourceData.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.testModels;
2 |
3 | import com.microsoft.kiota.serialization.AdditionalDataHolder;
4 | import com.microsoft.kiota.serialization.Parsable;
5 | import com.microsoft.kiota.serialization.ParseNode;
6 | import com.microsoft.kiota.serialization.SerializationWriter;
7 | import com.microsoft.kiota.store.BackedModel;
8 | import com.microsoft.kiota.store.BackingStore;
9 | import com.microsoft.kiota.store.BackingStoreFactorySingleton;
10 | import java.util.HashMap;
11 | import java.util.Map;
12 | import java.util.Objects;
13 |
14 | public class TestResourceData implements AdditionalDataHolder, BackedModel, Parsable {
15 | /**
16 | * Stores model information.
17 | */
18 | @jakarta.annotation.Nonnull
19 | protected BackingStore backingStore;
20 | /**
21 | * Instantiates a new {@link TestResourceData} and sets the default values.
22 | */
23 | public TestResourceData() {
24 | this.backingStore = BackingStoreFactorySingleton.instance.createBackingStore();
25 | this.setAdditionalData(new HashMap<>());
26 | }
27 | /**
28 | * Creates a new instance of the appropriate class based on discriminator value
29 | * @param parseNode The parse node to use to read the discriminator value and create the object
30 | * @return a {@link TestResourceData}
31 | */
32 | @jakarta.annotation.Nonnull
33 | public static TestResourceData createFromDiscriminatorValue(@jakarta.annotation.Nonnull final ParseNode parseNode) {
34 | Objects.requireNonNull(parseNode);
35 | return new TestResourceData();
36 | }
37 | /**
38 | * Gets the AdditionalData property value. Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
39 | * @return a {@link Map}
40 | */
41 | @jakarta.annotation.Nonnull
42 | public Map getAdditionalData() {
43 | Map value = this.backingStore.get("additionalData");
44 | if(value == null) {
45 | value = new HashMap<>();
46 | this.setAdditionalData(value);
47 | }
48 | return value;
49 | }
50 | /**
51 | * Gets the backingStore property value. Stores model information.
52 | * @return a {@link BackingStore}
53 | */
54 | @jakarta.annotation.Nonnull
55 | public BackingStore getBackingStore() {
56 | return this.backingStore;
57 | }
58 | /**
59 | * The deserialization information for the current model
60 | * @return a {@link Map>}
61 | */
62 | @jakarta.annotation.Nonnull
63 | public Map> getFieldDeserializers() {
64 | final HashMap> deserializerMap = new HashMap>(1);
65 | deserializerMap.put("@odata.type", (n) -> { this.setOdataType(n.getStringValue()); });
66 | return deserializerMap;
67 | }
68 | /**
69 | * Gets the @odata.type property value. The OdataType property
70 | * @return a {@link String}
71 | */
72 | @jakarta.annotation.Nullable
73 | public String getOdataType() {
74 | return this.backingStore.get("odataType");
75 | }
76 | /**
77 | * Serializes information the current object
78 | * @param writer Serialization writer to use to serialize this model
79 | */
80 | public void serialize(@jakarta.annotation.Nonnull final SerializationWriter writer) {
81 | Objects.requireNonNull(writer);
82 | writer.writeStringValue("@odata.type", this.getOdataType());
83 | writer.writeAdditionalData(this.getAdditionalData());
84 | }
85 | /**
86 | * Sets the AdditionalData property value. Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
87 | * @param value Value to set for the AdditionalData property.
88 | */
89 | public void setAdditionalData(@jakarta.annotation.Nullable final Map value) {
90 | this.backingStore.set("additionalData", value);
91 | }
92 | /**
93 | * Sets the backingStore property value. Stores model information.
94 | * @param value Value to set for the backingStore property.
95 | */
96 | public void setBackingStore(@jakarta.annotation.Nonnull final BackingStore value) {
97 | Objects.requireNonNull(value);
98 | this.backingStore = value;
99 | }
100 | /**
101 | * Sets the @odata.type property value. The OdataType property
102 | * @param value Value to set for the @odata.type property.
103 | */
104 | public void setOdataType(@jakarta.annotation.Nullable final String value) {
105 | this.backingStore.set("odataType", value);
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/requests/upload/UploadSliceRequestBuilder.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.requests.upload;
2 |
3 | import com.microsoft.graph.core.models.UploadResult;
4 | import com.microsoft.kiota.*;
5 | import com.microsoft.kiota.serialization.Parsable;
6 | import com.microsoft.kiota.serialization.ParsableFactory;
7 | import okhttp3.Response;
8 |
9 | import jakarta.annotation.Nonnull;
10 | import java.io.InputStream;
11 | import java.util.Locale;
12 | import java.util.Objects;
13 |
14 | /**
15 | * Request for uploading a slice of a large file.
16 | * @param The type of the object being uploaded.
17 | */
18 | public class UploadSliceRequestBuilder {
19 |
20 | private final UploadResponseHandler responseHandler;
21 | private final RequestAdapter requestAdapter;
22 | private final String urlTemplate;
23 | private final long rangeBegin;
24 | private final long rangeEnd;
25 | private final long totalSessionLength;
26 | private final long rangeLength;
27 | private final ParsableFactory factory;
28 |
29 | /**
30 | * Request for uploading one slice of a session.
31 | * @param sessionUrl URL to upload the slice.
32 | * @param requestAdapter Request adapted used for uploading the slice.
33 | * @param rangeBegin Beginning of the range for this slice.
34 | * @param rangeEnd End of the range for this slice.
35 | * @param totalSessionLength Total session length. This MUST be consistent.
36 | * @param factory The ParsableFactory defining the instantiation of the object being uploaded.
37 | */
38 | public UploadSliceRequestBuilder(@Nonnull String sessionUrl,
39 | @Nonnull final RequestAdapter requestAdapter,
40 | long rangeBegin,
41 | long rangeEnd,
42 | long totalSessionLength,
43 | @Nonnull ParsableFactory factory) {
44 | if(Compatibility.isBlank(sessionUrl))
45 | {
46 | throw new IllegalArgumentException("sessionUrl cannot be null or empty");
47 | }
48 | this.urlTemplate = sessionUrl;
49 | this.requestAdapter = Objects.requireNonNull(requestAdapter);
50 | this.factory = factory;
51 | this.rangeBegin = rangeBegin;
52 | this.rangeEnd = rangeEnd;
53 | this.rangeLength = (rangeEnd-rangeBegin+1);
54 | this.totalSessionLength = totalSessionLength;
55 | this.responseHandler = new UploadResponseHandler();
56 | }
57 | /**
58 | * Uploads the slice using PUT.
59 | * @param stream The stream of data to be uploaded.
60 | * @return The model containing the Upload information retrieved from the response.
61 | */
62 | @Nonnull
63 | public UploadResult put(@Nonnull InputStream stream) {
64 | Objects.requireNonNull(stream);
65 | RequestInformation requestInformation = this.toPutRequestInformation(stream);
66 | NativeResponseHandler nativeResponseHandler = new NativeResponseHandler();
67 | requestInformation.setResponseHandler(nativeResponseHandler);
68 | requestAdapter.sendPrimitive(requestInformation,null, InputStream.class);
69 | return responseHandler.handleResponse((Response) nativeResponseHandler.getValue(), factory);
70 | }
71 | private RequestInformation toPutRequestInformation(InputStream stream) {
72 | Objects.requireNonNull(stream);
73 | RequestInformation requestInfo = new RequestInformation();
74 | requestInfo.httpMethod = HttpMethod.PUT;
75 | requestInfo.urlTemplate = this.urlTemplate;
76 | requestInfo.setStreamContent(stream,"application/octet-stream");
77 | requestInfo.headers.add("Content-Range", String.format(Locale.US, "bytes %d-%d/%d", this.rangeBegin, this.rangeEnd, this.totalSessionLength));
78 | requestInfo.headers.add("Content-Length", ""+this.rangeLength);
79 | return requestInfo;
80 | }
81 | /**
82 | * Get the range of bytes for this slice.
83 | * @return the range of bytes in this slice.
84 | */
85 | public long getRangeLength() {
86 | return rangeLength;
87 | }
88 | /**
89 | * Get the starting byte position for this upload slice.
90 | * @return The byte position where this upload slice begins.
91 | */
92 | public long getRangeBegin() {
93 | return rangeBegin;
94 | }
95 | /**
96 | * Get the ending byte position for this upload slice.
97 | * @return the position where this upload slice ends.
98 | */
99 | public long getRangeEnd() {
100 | return rangeEnd;
101 | }
102 | /**
103 | * Get the total number of bytes being uploaded in the session.
104 | * @return The total number of bytes in this upload session.
105 | */
106 | public long getTotalSessionLength() {
107 | return totalSessionLength;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/requests/middleware/GraphTelemetryHandler.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.requests.middleware;
2 |
3 | import java.io.IOException;
4 | import java.lang.reflect.Field;
5 | import java.util.Objects;
6 |
7 | import com.microsoft.graph.core.requests.options.GraphClientOption;
8 | import jakarta.annotation.Nonnull;
9 |
10 | import com.microsoft.graph.core.CoreConstants;
11 |
12 | import okhttp3.Interceptor;
13 | import okhttp3.Request;
14 | import okhttp3.Response;
15 |
16 | /**
17 | * Middleware responsible for adding telemetry information on SDK usage
18 | * Note: the telemetry only collects anonymous information on SDK version and usage. No personal information is collected.
19 | */
20 | public class GraphTelemetryHandler implements Interceptor{
21 |
22 | private GraphClientOption mGraphClientOption;
23 |
24 | /**
25 | * Instantiate a GraphTelemetryHandler with default GraphClientOption.
26 | */
27 | public GraphTelemetryHandler(){
28 | this(new GraphClientOption());
29 | }
30 | /**
31 | * Instantiate a GraphTelemetryHandler with specified GraphClientOption
32 | * @param graphClientOption the specified GraphClientOption for the GraphTelemetryHandler.
33 | */
34 | public GraphTelemetryHandler(@Nonnull final GraphClientOption graphClientOption){
35 | this.mGraphClientOption = Objects.requireNonNull(graphClientOption);
36 | }
37 |
38 | @Override
39 | @Nonnull
40 | public Response intercept(@Nonnull final Chain chain) throws IOException {
41 | final Request request = chain.request();
42 | final Request.Builder telemetryAddedBuilder = request.newBuilder();
43 |
44 | final String clientLibraryUsed = "graph-java" + (mGraphClientOption.getGraphServiceTargetVersion().equals("v1.0") ? "" : "-"+mGraphClientOption.getGraphServiceTargetVersion()); //graph-java | graph-java-beta
45 | final String sdkVersion = (mGraphClientOption.getClientLibraryVersion() == null ? "" : "/"+ mGraphClientOption.getClientLibraryVersion()); //SDK version value
46 |
47 | final String coreVersionHeader = CoreConstants.Headers.GRAPH_VERSION_PREFIX + "/" + mGraphClientOption.getCoreLibraryVersion(); //"graph-java-core/3.0.0"
48 |
49 | final String featureUsage = "(featureUsage=" + mGraphClientOption.featureTracker.getSerializedFeatureUsage(); // (featureUsage=
50 |
51 | final String jreVersion = System.getProperty("java.version");
52 | final String jreVersionHeader = (CoreConstants.Headers.DEFAULT_VERSION_VALUE.equals(jreVersion) ? "" : ("; runtimeEnvironment=JRE/"+jreVersion)); //runtimeEnvironment=JRE/
53 |
54 | final String androidVersion = getAndroidAPILevel(); // android/
55 | final String androidVersionHeader = (CoreConstants.Headers.DEFAULT_VERSION_VALUE.equals(androidVersion) ? "" : ("; " + CoreConstants.Headers.ANDROID_VERSION_PREFIX + "/" + androidVersion));
56 |
57 | final String sdkTelemetry = clientLibraryUsed + sdkVersion + ", " + coreVersionHeader + " " + featureUsage + jreVersionHeader + androidVersionHeader+")";
58 |
59 | telemetryAddedBuilder.addHeader(CoreConstants.Headers.SDK_VERSION_HEADER_NAME, sdkTelemetry);
60 | if(request.header(CoreConstants.Headers.CLIENT_REQUEST_ID) == null) {
61 | telemetryAddedBuilder.addHeader(CoreConstants.Headers.CLIENT_REQUEST_ID, mGraphClientOption.getClientRequestId());
62 | }
63 |
64 | return chain.proceed(telemetryAddedBuilder.build());
65 | }
66 |
67 | private String androidAPILevel;
68 | private String getAndroidAPILevel() {
69 | if(androidAPILevel == null) {
70 | androidAPILevel = getAndroidAPILevelInternal();
71 | }
72 | return androidAPILevel;
73 | }
74 |
75 | private String getAndroidAPILevelInternal() {
76 | try {
77 | final Class> buildClass = Class.forName("android.os.Build");
78 | final Class>[] subclasses = buildClass.getDeclaredClasses();
79 | Class> versionClass = null;
80 | for(final Class> subclass : subclasses) {
81 | if(subclass.getName().endsWith("VERSION")) {
82 | versionClass = subclass;
83 | break;
84 | }
85 | }
86 | if(versionClass == null)
87 | return CoreConstants.Headers.DEFAULT_VERSION_VALUE;
88 | else {
89 | final Field sdkVersionField = versionClass.getField("SDK_INT");
90 | final Object value = sdkVersionField.get(null);
91 | final String valueStr = String.valueOf(value);
92 | return valueStr == null || valueStr.equals("") ? CoreConstants.Headers.DEFAULT_VERSION_VALUE : valueStr;
93 | }
94 | } catch (IllegalAccessException | ClassNotFoundException | NoSuchFieldException ex) {
95 | // we're not on android and return "0" to align with java version which returns "0" when running on android
96 | return CoreConstants.Headers.DEFAULT_VERSION_VALUE;
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/content/BatchResponseContentCollection.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.content;
2 |
3 | import com.microsoft.kiota.ResponseHandler;
4 | import com.microsoft.kiota.serialization.Parsable;
5 | import com.microsoft.kiota.serialization.ParsableFactory;
6 | import okhttp3.Response;
7 |
8 | import jakarta.annotation.Nonnull;
9 | import jakarta.annotation.Nullable;
10 | import java.io.InputStream;
11 | import java.util.*;
12 |
13 | /**
14 | * A collection of BatchResponseContent objects.
15 | */
16 | public class BatchResponseContentCollection {
17 |
18 | private List batchResponses;
19 |
20 | /**
21 | * Instantiates a new Batch response content collection.
22 | */
23 | public BatchResponseContentCollection() {
24 | batchResponses = new ArrayList<>();
25 | }
26 | /**
27 | * Add BatchResponseContent object to the collection.
28 | * @param keys the keys of the requests that were batched together.
29 | * @param content the BatchResponseContent object to add to the collection.
30 | */
31 | public void addBatchResponse(@Nonnull Collection keys, @Nonnull BatchResponseContent content) {
32 | batchResponses.add(new KeyedBatchResponseContent(new HashSet<>(keys), content));
33 | }
34 | /**
35 | * Gets the BatchResponseContent object containing the response for the request with the given id.
36 | * @param requestId the id of the request to get the response for.
37 | * @return the BatchResponseContent object containing the response for the request with the given id, null if no response was found.
38 | */
39 | private BatchResponseContent getBatchResponseContaining(@Nonnull String requestId) {
40 | Objects.requireNonNull(requestId);
41 | for(KeyedBatchResponseContent keyedResponse : batchResponses) {
42 | if(keyedResponse.keys.contains(requestId)) {
43 | return keyedResponse.response;
44 | }
45 | }
46 | return null;
47 | }
48 | /**
49 | * Gets the response for the request with the given id.
50 | * @param requestId the id of the request to get the response for.
51 | * @return the response for the request with the given id, null if no response was found.
52 | */
53 | @Nullable
54 | public Response getResponseById(@Nonnull String requestId) {
55 | Objects.requireNonNull(requestId);
56 | BatchResponseContent response = getBatchResponseContaining(requestId);
57 | return response == null ? null : response.getResponseById(requestId);
58 | }
59 | /**
60 | * Gets the response for the request with the given id.
61 | * @param requestId the id of the request to get the response for.
62 | * @param handler the handler to use when deserializing the response.
63 | * @return the response for the request with the given id, null if no response was found.
64 | * @param the type of the response.
65 | */
66 | @Nullable
67 | public T getResponseById(@Nonnull String requestId, @Nonnull ResponseHandler handler) {
68 | Objects.requireNonNull(requestId);
69 | BatchResponseContent response = getBatchResponseContaining(requestId);
70 | return response == null ? null : response.getResponseById(requestId, handler);
71 | }
72 | /**
73 | * Gets the response for the request with the given id.
74 | * @param requestId the id of the request to get the response for.
75 | * @param factory the factory to use when deserializing the response.
76 | * @return the response for the request with the given id, null if no response was found.
77 | * @param the type of the response.
78 | */
79 | @Nullable
80 | public T getResponseById(@Nonnull String requestId, @Nonnull ParsableFactory factory) {
81 | Objects.requireNonNull(requestId);
82 | BatchResponseContent response = getBatchResponseContaining(requestId);
83 | return response == null ? null : response.getResponseById(requestId, factory);
84 | }
85 | /**
86 | * Gets the response for the request with the given id as a stream.
87 | * @param requestId the id of the request to get the response for.
88 | * @return the response for the request with the given id, null if no response was found.
89 | */
90 | @Nullable
91 | public InputStream getResponseStreamById(@Nonnull String requestId) {
92 | BatchResponseContent response = getBatchResponseContaining(requestId);
93 | return response == null ? null : response.getResponseStreamById(requestId);
94 | }
95 | /**
96 | * Gets the response codes for all the requests in the batch.
97 | * @return the response codes for all the requests in the batch.
98 | */
99 | @Nonnull
100 | public Map getResponsesStatusCodes() {
101 | HashMap statusCodes = new HashMap<>();
102 | for(KeyedBatchResponseContent keyedResponse : batchResponses) {
103 | Map responseStatusCodes = keyedResponse.response.getResponsesStatusCode();
104 | statusCodes.putAll(responseStatusCodes);
105 | }
106 | return statusCodes;
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/requests/upload/UploadResponseHandler.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.requests.upload;
2 |
3 | import com.microsoft.graph.core.ErrorConstants;
4 | import com.microsoft.graph.core.models.UploadResult;
5 | import com.microsoft.graph.core.models.UploadSession;
6 | import com.microsoft.kiota.ApiException;
7 | import com.microsoft.kiota.ApiExceptionBuilder;
8 | import com.microsoft.kiota.http.HeadersCompatibility;
9 | import com.microsoft.kiota.serialization.*;
10 | import okhttp3.Response;
11 | import okhttp3.ResponseBody;
12 |
13 | import jakarta.annotation.Nonnull;
14 | import jakarta.annotation.Nullable;
15 |
16 | import java.io.IOException;
17 | import java.io.InputStream;
18 | import java.net.HttpURLConnection;
19 | import java.net.URI;
20 | import java.net.URISyntaxException;
21 | import java.util.List;
22 | import java.util.Objects;
23 |
24 | /**
25 | * The request handler for upload requests.
26 | */
27 | public class UploadResponseHandler {
28 |
29 | private final ParseNodeFactory parseNodeFactory;
30 | /**
31 | * UploadResponseHandler constructor.
32 | */
33 | public UploadResponseHandler() {
34 | this(null);
35 | }
36 | /**
37 | * UploadResponseHandler constructor.
38 | * @param parseNodeFactory The ParseNodeFactory to use for response parsing.
39 | */
40 | public UploadResponseHandler(@Nullable ParseNodeFactory parseNodeFactory) {
41 | this.parseNodeFactory = (parseNodeFactory == null) ? ParseNodeFactoryRegistry.defaultInstance : parseNodeFactory;
42 | }
43 | /**
44 | * Process the raw HTTP response from an upload request.
45 | * @param response The HTTP response returned from the upload request.
46 | * @param factory The ParsableFactory defining the instantiation of the object being uploaded.
47 | * @param The type of the object being uploaded.
48 | * @return An UploadResult model containing the information from the server resulting from the upload request.
49 | */
50 | @Nonnull
51 | public UploadResult handleResponse(@Nonnull final Response response, @Nonnull final ParsableFactory factory) {
52 | Objects.requireNonNull(response);
53 | Objects.requireNonNull(factory);
54 | try (final ResponseBody body = response.body()) {
55 | UploadResult uploadResult = new UploadResult<>();
56 | String contentLengthHeader = response.headers().get("content-length");
57 | // rely on content-type OR content-length headers to determine if response body is empty.
58 | // Response body() may be non-null despite being empty in raw response https://square.github.io/okhttp/3.x/okhttp/okhttp3/Response.html#body--
59 | // content-length header is not always present in Graph responses. Content-type is more reliable
60 | if (Objects.isNull(body)
61 | || Objects.isNull(body.contentType())
62 | || (!Objects.isNull(contentLengthHeader) && Integer.parseInt(contentLengthHeader) == 0)
63 | ) {
64 | if (response.code() == HttpURLConnection.HTTP_CREATED) {
65 | final String location = response.headers().get("location");
66 | if(!Objects.isNull(location) && !location.isEmpty()) {
67 | uploadResult.location = new URI(location);
68 | return uploadResult;
69 | }
70 | }
71 | throw new ApiException(ErrorConstants.Messages.NO_RESPONSE_FOR_UPLOAD);
72 | }
73 | try(final InputStream in = body.byteStream()){
74 | if(!response.isSuccessful()) {
75 | throw new ApiExceptionBuilder()
76 | .withMessage(ErrorConstants.Codes.GENERAL_EXCEPTION)
77 | .withResponseStatusCode(response.code())
78 | .withResponseHeaders(HeadersCompatibility.getResponseHeaders(response.headers()))
79 | .build();
80 | }
81 | boolean canBeParsed = (!Objects.isNull(contentLengthHeader) && Integer.parseInt(contentLengthHeader) > 0) || !Objects.isNull(body.contentType());
82 | String contentType = canBeParsed ? body.contentType().toString().split(";")[0] : null; //contentType.toString() returns in format ;, we only want the mediaType.
83 | if (canBeParsed) {
84 | final ParseNode parseNode = parseNodeFactory.getParseNode(contentType, in);
85 | if (response.code() == HttpURLConnection.HTTP_CREATED) {
86 | uploadResult.itemResponse = parseNode.getObjectValue(factory);
87 | } else {
88 | final UploadSession uploadSession = parseNode.getObjectValue(UploadSession::createFromDiscriminatorValue);
89 | final List nextExpectedRanges = uploadSession.getNextExpectedRanges();
90 | if (!(nextExpectedRanges == null || nextExpectedRanges.isEmpty())) {
91 | uploadResult.uploadSession = uploadSession;
92 | } else {
93 | uploadResult.itemResponse = parseNode.getObjectValue(factory);
94 | }
95 | }
96 | }
97 | return uploadResult;
98 | }
99 | }
100 | catch(IOException | URISyntaxException ex) {
101 | throw new RuntimeException(ex);
102 | }
103 | }
104 |
105 | }
106 |
107 |
108 |
--------------------------------------------------------------------------------
/src/main/java/com/microsoft/graph/core/requests/ResponseBodyHandler.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.requests;
2 |
3 | import com.microsoft.graph.core.ErrorConstants;
4 | import com.microsoft.kiota.ApiException;
5 | import com.microsoft.kiota.ApiExceptionBuilder;
6 | import com.microsoft.kiota.http.HeadersCompatibility;
7 | import com.microsoft.kiota.serialization.*;
8 |
9 | import okhttp3.Response;
10 | import okhttp3.ResponseBody;
11 |
12 | import jakarta.annotation.Nonnull;
13 | import jakarta.annotation.Nullable;
14 | import java.io.*;
15 | import java.util.HashMap;
16 |
17 | /**
18 | * A response handler for deserializing responses to a ModelType. Particularly for Batch requests.
19 | * @param the ModelType of the response body.
20 | */
21 | public class ResponseBodyHandler implements com.microsoft.kiota.ResponseHandler {
22 | private final ParseNodeFactory parseNodeFactory;
23 | private final ParsableFactory factory;
24 | /**
25 | * Instantiates a new response handler.
26 | * @param parseNodeFactory the parse node factory to use when deserializing the response.
27 | * @param factory the factory to use when deserializing the response to a ModelType.
28 | */
29 | public ResponseBodyHandler(@Nullable ParseNodeFactory parseNodeFactory, @Nonnull ParsableFactory factory) {
30 | this.parseNodeFactory = (parseNodeFactory == null) ? ParseNodeFactoryRegistry.defaultInstance : parseNodeFactory;
31 | this.factory = factory;
32 | }
33 | /**
34 | * Instantiates a new response handler.
35 | * @param factory the factory to use when deserializing the response to a ModelType.
36 | */
37 | public ResponseBodyHandler(@Nonnull ParsableFactory factory) {
38 | this(null, factory);
39 | }
40 | /**
41 | * Handles the response and returns the deserialized response body as a ModelType.
42 | * @param response The native response object.
43 | * @param errorMappings the error mappings for the response to use when deserializing failed responses bodies. Where an error code like 401 applies specifically to that status code, a class code like 4XX applies to all status codes within the range if an the specific error code is not present.
44 | * @return the deserialized response.
45 | * @param The type of the native response object.
46 | * @param The type of the response model object.
47 | */
48 | @Nullable
49 | @Override
50 | public ModelType handleResponse(@Nonnull NativeResponseType response, @Nullable HashMap> errorMappings) {
51 | if(response instanceof Response && ((Response) response).body()!=null) {
52 | Response nativeResponse = (Response) response;
53 | ResponseBody body = nativeResponse.body();
54 | try(final InputStream in = body.byteStream()) {
55 | ParseNode parseNode = this.parseNodeFactory.getParseNode(body.contentType().type() + "/" + body.contentType().subtype(), in);
56 | body.close();
57 | if(nativeResponse.isSuccessful()) {
58 | final ModelType result = (ModelType) parseNode.getObjectValue(this.factory); //We can be sure this is the correct type since return of this method is based on the type of the factory.
59 | return result;
60 | } else {
61 | handleFailedResponse(nativeResponse, errorMappings, parseNode);
62 | }
63 | }
64 | catch(IOException ex) {
65 | throw new RuntimeException(ex);
66 | }
67 | } else {
68 | throw new IllegalArgumentException("The provided response type is not supported by this response handler.");
69 | }
70 | return null;
71 | }
72 |
73 | private void handleFailedResponse(Response nativeResponse, HashMap> errorMappings, ParseNode parseNode) {
74 | int statusCode = nativeResponse.code();
75 | String statusCodeString = String.valueOf(statusCode);
76 | if (errorMappings == null ||
77 | !errorMappings.containsKey(statusCodeString) &&
78 | !(statusCode >= 400 && statusCode <= 499 && errorMappings.containsKey("4XX")) &&
79 | !(statusCode >= 500 && statusCode <= 599 && errorMappings.containsKey("5XX"))) {
80 | throw new ApiExceptionBuilder()
81 | .withMessage(ErrorConstants.Codes.GENERAL_EXCEPTION)
82 | .withResponseStatusCode(statusCode)
83 | .withResponseHeaders(HeadersCompatibility.getResponseHeaders(nativeResponse.headers()))
84 | .build();
85 | } else {
86 | String statusCodePattern = statusCodeString;
87 | if (!errorMappings.containsKey(statusCodePattern)) {
88 | if (statusCode >= 400 && statusCode <= 499 && errorMappings.containsKey("4XX")) {
89 | statusCodePattern = "4XX";
90 | } else if (statusCode >= 500 && statusCode <= 599 && errorMappings.containsKey("5XX")) {
91 | statusCodePattern = "5XX";
92 | }
93 | }
94 | Parsable result = parseNode.getObjectValue(errorMappings.get(statusCodePattern));
95 | if (!(result instanceof Exception)) {
96 | throw new ApiException("The server returned an unexpected status code and the error registered for this code failed to deserialize: " + statusCodeString);
97 | }
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/test/java/com/microsoft/graph/core/requests/middleware/GraphTelemetryHandlerTest.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.core.requests.middleware;
2 |
3 | import com.microsoft.graph.core.CoreConstants;
4 | import com.microsoft.graph.core.requests.GraphClientFactory;
5 | import com.microsoft.graph.core.requests.options.GraphClientOption;
6 | import com.microsoft.kiota.http.middleware.RedirectHandler;
7 | import com.microsoft.kiota.http.middleware.RetryHandler;
8 |
9 | import okhttp3.Interceptor;
10 | import okhttp3.OkHttpClient;
11 | import okhttp3.Request;
12 | import okhttp3.Response;
13 |
14 | import org.junit.jupiter.api.Test;
15 |
16 | import static org.junit.jupiter.api.Assertions.assertNotNull;
17 | import static org.junit.jupiter.api.Assertions.assertTrue;
18 |
19 | import java.io.IOException;
20 |
21 | class GraphTelemetryHandlerTest {
22 |
23 | private static final String defaultSDKVersion = "graph-java";
24 |
25 | @Test
26 | void telemetryHandlerDefaultTests() throws IOException {
27 | final String expectedCore = CoreConstants.Headers.GRAPH_VERSION_PREFIX + "/" + CoreConstants.Headers.VERSION;
28 |
29 | final OkHttpClient client = GraphClientFactory.create().build();
30 | final Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/users/").build();
31 | final Response response = client.newCall(request).execute();
32 |
33 | assertNotNull(response);
34 | assertNotNull(response.request());
35 | assertNotNull(response.request().header(CoreConstants.Headers.SDK_VERSION_HEADER_NAME));
36 | assertTrue(response.request().header(CoreConstants.Headers.SDK_VERSION_HEADER_NAME).contains(expectedCore));
37 | assertTrue(!response.request().header(CoreConstants.Headers.SDK_VERSION_HEADER_NAME).contains(
38 | CoreConstants.Headers.ANDROID_VERSION_PREFIX)); // Android version is not going to be present on unit tests running on java platform
39 | assertTrue(
40 | response.request().header(CoreConstants.Headers.SDK_VERSION_HEADER_NAME).contains(defaultSDKVersion));
41 | }
42 |
43 | @Test
44 | void arrayInterceptorsTest() throws IOException {
45 | final String expectedCore = CoreConstants.Headers.GRAPH_VERSION_PREFIX + "/" + CoreConstants.Headers.VERSION;
46 |
47 | final Interceptor[] interceptors = {new GraphTelemetryHandler(), new RetryHandler(),
48 | new RedirectHandler()};
49 | final OkHttpClient client = GraphClientFactory.create(interceptors).build();
50 | final Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/users/").build();
51 | final Response response = client.newCall(request).execute();
52 |
53 | assertNotNull(response);
54 | assertNotNull(response.request());
55 | assertNotNull(response.request().header(CoreConstants.Headers.SDK_VERSION_HEADER_NAME));
56 | assertTrue(response.request().header(CoreConstants.Headers.SDK_VERSION_HEADER_NAME).contains(expectedCore));
57 | assertTrue(
58 | response.request().header(CoreConstants.Headers.SDK_VERSION_HEADER_NAME).contains(defaultSDKVersion));
59 | }
60 |
61 | @Test
62 | void arrayInterceptorEmptyTest() throws IOException {
63 | final String expectedCore = CoreConstants.Headers.GRAPH_VERSION_PREFIX + "/" + CoreConstants.Headers.VERSION;
64 |
65 | final Interceptor[] interceptors = new Interceptor[]{};
66 | final OkHttpClient client = GraphClientFactory.create(interceptors).build();
67 | final Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/users/").build();
68 | final Response response = client.newCall(request).execute();
69 |
70 | assertNotNull(response);
71 | assertNotNull(response.request());
72 | assertNotNull(response.request().header(CoreConstants.Headers.SDK_VERSION_HEADER_NAME));
73 | assertTrue(response.request().header(CoreConstants.Headers.SDK_VERSION_HEADER_NAME).contains(expectedCore));
74 | assertTrue(
75 | response.request().header(CoreConstants.Headers.SDK_VERSION_HEADER_NAME).contains(defaultSDKVersion));
76 | }
77 |
78 | @Test
79 | void testClientOptions() throws IOException {
80 | String requestId = "1234567890";
81 | String coreLibVer = "3.1.1";
82 | String clientLibVer = "6.1.1";
83 | String serviceLibVer = "beta";
84 |
85 | final GraphClientOption graphClientOption = new GraphClientOption();
86 | graphClientOption.setClientRequestId(requestId);
87 | graphClientOption.setCoreLibraryVersion(coreLibVer);
88 | graphClientOption.setClientLibraryVersion(clientLibVer);
89 | graphClientOption.setGraphServiceTargetVersion(serviceLibVer);
90 |
91 | final String expectedCoreVer =
92 | CoreConstants.Headers.GRAPH_VERSION_PREFIX + "/" + coreLibVer;
93 | final String expectedClientEndpoint =
94 | CoreConstants.Headers.JAVA_VERSION_PREFIX + "-" + serviceLibVer + "/" + clientLibVer;
95 |
96 | final OkHttpClient client = GraphClientFactory.create(graphClientOption).build();
97 | final Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/users/").build();
98 | final Response response = client.newCall(request).execute();
99 |
100 | assertNotNull(response);
101 | assertNotNull(response.request());
102 | assertNotNull(response.request().header(CoreConstants.Headers.SDK_VERSION_HEADER_NAME));
103 | assertTrue(response.request().header(CoreConstants.Headers.SDK_VERSION_HEADER_NAME).contains(expectedCoreVer));
104 | assertTrue(
105 | response.request().header(CoreConstants.Headers.SDK_VERSION_HEADER_NAME).contains(expectedClientEndpoint));
106 | assertTrue(response.request().header(CoreConstants.Headers.CLIENT_REQUEST_ID).contains(requestId));
107 | }
108 | }
109 |
110 |
111 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Microsoft Graph Core SDK for Java
2 |
3 | [](https://search.maven.org/artifact/com.microsoft.graph/microsoft-graph-core) [](https://sonarcloud.io/dashboard?id=microsoftgraph_msgraph-sdk-java-core) [](https://sonarcloud.io/dashboard?id=microsoftgraph_msgraph-sdk-java-core)
4 |
5 | Get started with the Microsoft Graph Core SDK for Java by integrating the [Microsoft Graph API](https://developer.microsoft.com/en-us/graph/get-started/java) into your Java and Android application! You can also have a look at the [Javadoc](https://docs.microsoft.com/en-us/java/api/com.microsoft.graph.httpcore?view=graph-core-java)
6 |
7 | ## Samples and usage guide
8 |
9 | - [Middleware usage](https://github.com/microsoftgraph/msgraph-sdk-design/)
10 | - [Batching](https://docs.microsoft.com/en-us/graph/sdks/batch-requests?tabs=java)
11 |
12 | ## 1. Installation
13 |
14 | ### 1.1 Install via Gradle
15 |
16 | Add the repository and a compile dependency for `microsoft-graph-core` to your project's `build.gradle`:
17 |
18 | ```groovy
19 | repositories {
20 | mavenCentral()
21 | }
22 |
23 | dependencies {
24 | // Include the sdk as a dependency
25 | // x-release-please-start-version
26 | implementation 'com.microsoft.graph:microsoft-graph-core:3.6.5'
27 | // x-release-please-end
28 | // This dependency is only needed if you are using the TokenCredentialAuthProvider
29 | implementation 'com.azure:azure-identity:1.11.0'
30 | }
31 | ```
32 |
33 | ### 1.2 Install via Maven
34 |
35 | Add the dependency in `dependencies` in pom.xml
36 |
37 | ```xml
38 |
39 |
40 | com.microsoft.graph
41 | microsoft-graph-core
42 |
43 | 3.6.5
44 |
45 |
46 | com.azure
47 | azure-identity
48 | 1.11.0
49 |
50 | ```
51 |
52 | ### 1.3 Enable ProGuard (Android)
53 |
54 | The nature of the Graph API is such that the SDK needs quite a large set of classes to describe its functionality. You need to ensure that [ProGuard](https://developer.android.com/studio/build/shrink-code.html) is enabled on your project. Otherwise, you will incur long build times for functionality that is not necessarily relevant to your particular application. If you are still hitting the 64K method limit, you can also enable [multidexing](https://developer.android.com/studio/build/multidex.html).
55 |
56 | ## 2. Getting started
57 |
58 | ### 2.1 Register your application
59 |
60 | Register your application by following the steps at [Register your app with the Microsoft Identity Platform](https://docs.microsoft.com/graph/auth-register-app-v2).
61 |
62 | ### 2.2 Create an AuthenticationProvider object
63 |
64 | [Initialize an `AuthenticationProvider`](https://learn.microsoft.com/en-us/graph/sdks/choose-authentication-providers?view=graph-rest-1.0&tabs=java) based on your preferred authentication flow
65 |
66 | ### 2.3 Get a OkHttpClient object
67 |
68 | You must get an **OkHttpClient** object to make requests against the service.
69 |
70 | Using the `GraphClientFactory`, you can initialize an `OkHttpClient` pre-configured for use with Microsoft Graph
71 |
72 | ```java
73 | OkHttpClient client = GraphClientFactory.create(authenticationProvider).build();
74 | ```
75 |
76 | ## 3. Make requests against the service
77 |
78 | After you have an authenticated `OkHttpClient`, you can begin making calls against the service. The requests against the service look like our [REST API](https://developer.microsoft.com/en-us/graph/docs/concepts/overview).
79 |
80 | ### 3.1 Get the user's details
81 |
82 | To retrieve the user's details
83 |
84 | ```java
85 | Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/me/").build();
86 |
87 | client.newCall(request).enqueue(new Callback() {
88 | @Override
89 | public void onResponse(Call call, Response response) throws IOException {
90 | String responseBody = response.body().string();
91 | // Your processing with the response body
92 | }
93 |
94 | @Override
95 | public void onFailure(Call call, IOException e) {
96 | e.printStackTrace();
97 | }
98 | });
99 | ```
100 |
101 | ### 3.2 Get the user's drive
102 |
103 | To retrieve the user's drive:
104 |
105 | ```java
106 | Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/me/drive").build();
107 |
108 | client.newCall(request).enqueue(new Callback() {
109 | @Override
110 | public void onResponse(Call call, Response response) throws IOException {
111 | String responseBody = response.body().string();
112 | // Your processing with the response body
113 | }
114 |
115 | @Override
116 | public void onFailure(Call call, IOException e) {
117 | e.printStackTrace();
118 | }
119 | });
120 | ```
121 |
122 | ## 4. Issues
123 |
124 | For known issues, see [issues](https://github.com/MicrosoftGraph/msgraph-sdk-java-core/issues).
125 |
126 | ## 5. Contributions
127 |
128 | The Microsoft Graph SDK is open for contribution. To contribute to this project, see the [Contributing](https://github.com/microsoftgraph/msgraph-sdk-java-core/blob/main/CONTRIBUTING.md) guide.
129 |
130 | ## 6. Supported Java versions
131 |
132 | The Microsoft Graph SDK for Java library is supported at runtime for Java 8 and [Android API revision 26](http://source.android.com/source/build-numbers.html) or greater.
133 |
134 | ## 7. License
135 |
136 | Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the [MIT license](LICENSE).
137 |
138 | ## 8. Third-party notices
139 |
140 | [Third-party notices](THIRD%20PARTY%20NOTICES)
141 |
--------------------------------------------------------------------------------