diff --git a/.github/workflows/api-level-lint.yml b/.github/workflows/api-level-lint.yml new file mode 100644 index 000000000..b576a559c --- /dev/null +++ b/.github/workflows/api-level-lint.yml @@ -0,0 +1,37 @@ +name: "Checks the SDK only using APIs from the targeted API level" + +on: + push: + branches: + - dev + - master + pull_request: + branches: + - dev + - master + - feature/v2 + +jobs: + lint-api-level: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-java@v1 + with: + java-version: 15 + - name: Setup Android SDK + uses: android-actions/setup-android@v2 + - name: Add execution right to the script + run: chmod +x gradlew + working-directory: ./android + - name: Build SDK with Android project configuration + id: lint + run: ./gradlew --no-daemon build + working-directory: ./android + - name: Upload linting results + if: failure() && steps.lint.outcome == 'failure' + uses: actions/upload-artifact@v2 + with: + name: lint-report + path: ./android/build/reports + diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 000000000..f06dfad69 --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,2 @@ +.gradle +build \ No newline at end of file diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml new file mode 100644 index 000000000..da53f5433 --- /dev/null +++ b/android/AndroidManifest.xml @@ -0,0 +1,24 @@ + + + + + + + + + + \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 000000000..0156e989f --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,71 @@ +buildscript { + repositories { + google() + gradlePluginPortal() + maven { + url "https://plugins.gradle.org/m2/" + } + } + + dependencies { + classpath "com.gradle:gradle-enterprise-gradle-plugin:3.5" + classpath "com.android.tools.build:gradle:4.0.1" + classpath "com.github.ben-manes:gradle-versions-plugin:0.36.0" + classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5" + } +} + +repositories { + google() + gradlePluginPortal() +} + +apply plugin: "com.android.library" +apply plugin: "com.github.ben-manes.versions" + +android { + compileSdkVersion 30 + + defaultConfig { + versionCode 1 + versionName "1.0" + minSdkVersion 21 + targetSdkVersion 30 + } + + buildTypes { + release { + minifyEnabled false + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + lintOptions { + textOutput "stdout" + checkAllWarnings true + warningsAsErrors true + disable "UnusedResources" // Unused will be removed on release + disable "IconExpectedSize" // Using the material icons provided from Google + disable "GoogleAppIndexingApiWarning" // We might want to index our app later + disable "InvalidPackage" // Butterknife, Okio and Realm + disable "ResourceType" // Annotation binding + disable "GradleDependency" + disable "NewerVersionAvailable" + } + sourceSets { + main { + java.srcDirs = ['../src/main/java'] + res.srcDirs = ['../src/main/java'] + manifest.srcFile 'AndroidManifest.xml' + } + androidTest { + setRoot '../src/test' + } + } +} + +apply from: "../gradle/dependencies.gradle" diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 000000000..221229e60 --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,44 @@ +# Project-wide Gradle settings. + +# IDE users: +# Settings specified in this file will override any Gradle settings +# configured through the IDE. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# Default value: -Xmx10248m -XX:MaxPermSize=256m +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true + +# The size of the library demands a large amount of RAM to build. Increase as necessary if you get GC errors +## linux requires 10G, OSX requires 11G +org.gradle.jvmargs=-XX:MaxPermSize=512m -Xmx2g +org.gradle.parallel=true +org.gradle.caching=true + +mavenGroupId = com.microsoft.graph +mavenArtifactId = microsoft-graph-core +mavenMajorVersion = 2 +mavenMinorVersion = 3 +mavenPatchVersion = 1 +mavenArtifactSuffix = +nightliesUrl = http://dl.bintray.com/MicrosoftGraph/Maven + +#These values are used to run functional tests +#If you wish to run the functional tests, edit the gradle.properties +#file in your user directory instead of adding them here. +#ex: C:\Users\username\.gradle\gradle.properties +ClientId="CLIENT_ID" +Username="USERNAME" +Password="PASSWORD" + +#enable mavenCentralPublishingEnabled to publish to maven central +mavenCentralSnapshotArtifactSuffix = -SNAPSHOT +mavenCentralPublishingEnabled=false diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..e708b1c02 Binary files /dev/null and b/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..be52383ef --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/android/gradlew b/android/gradlew new file mode 100644 index 000000000..4f906e0c8 --- /dev/null +++ b/android/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/android/gradlew.bat b/android/gradlew.bat new file mode 100644 index 000000000..107acd32c --- /dev/null +++ b/android/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 000000000..ab8f7824a --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,10 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user manual at https://docs.gradle.org/6.6/userguide/multi_project_builds.html + */ + +rootProject.name = 'msgraph-sdk-java-core' diff --git a/build.gradle b/build.gradle index 83db05839..ba39414df 100644 --- a/build.gradle +++ b/build.gradle @@ -28,14 +28,7 @@ repositories { mavenCentral() } -dependencies { - // Use JUnit test framework - testImplementation 'junit:junit:4.13' - - api 'com.squareup.okhttp3:okhttp:4.9.0' - - implementation 'com.google.code.gson:gson:2.8.6' -} +apply from: "gradle/dependencies.gradle" def pomConfig = { licenses { diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle new file mode 100644 index 000000000..a278b65a9 --- /dev/null +++ b/gradle/dependencies.gradle @@ -0,0 +1,10 @@ +dependencies { + // Use JUnit test framework + testImplementation 'junit:junit:4.13' + + api 'com.squareup.okhttp3:okhttp:4.9.0' + + api 'com.google.code.findbugs:jsr305:3.0.2' // can be replaced by guava if we need guava + + implementation 'com.google.code.gson:gson:2.8.6' +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 6c9a22477..be52383ef 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/readme.md b/readme.md index 5dacfe52a..97b5c600e 100644 --- a/readme.md +++ b/readme.md @@ -120,7 +120,7 @@ The Microsoft Graph SDK is open for contribution. To contribute to this project, ## 6. Supported Java versions -The Microsoft Graph SDK for Java library is supported at runtime for Java 8+ and [Android API revision 15](http://source.android.com/source/build-numbers.html) and greater through [desugaring](https://developer.android.com/studio/write/java8-support.html#library-desugaring). +The Microsoft Graph SDK for Java library is supported at runtime for Java 8+ and [Android API revision 21](http://source.android.com/source/build-numbers.html) and greater. ## 7. License diff --git a/src/main/java/com/microsoft/graph/content/MSBatchRequestContent.java b/src/main/java/com/microsoft/graph/content/MSBatchRequestContent.java index 64eed6c23..6d0c6034a 100644 --- a/src/main/java/com/microsoft/graph/content/MSBatchRequestContent.java +++ b/src/main/java/com/microsoft/graph/content/MSBatchRequestContent.java @@ -7,6 +7,9 @@ import java.util.Map; import java.util.concurrent.ThreadLocalRandom; +import javax.annotation.Nullable; +import javax.annotation.Nonnull; + import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -30,7 +33,7 @@ public class MSBatchRequestContent { * * @param batchRequestStepsArray List of batch steps for batching */ - public MSBatchRequestContent(final List batchRequestStepsArray) { + public MSBatchRequestContent(@Nonnull final List batchRequestStepsArray) { if (batchRequestStepsArray.size() > MAX_NUMBER_OF_REQUESTS) throw new IllegalArgumentException("Number of batch request steps cannot exceed " + MAX_NUMBER_OF_REQUESTS); @@ -52,7 +55,7 @@ public MSBatchRequestContent() { * @return true or false based on addition or no addition of batch request step * given */ - public boolean addBatchRequestStep(final MSBatchRequestStep batchRequestStep) { + public boolean addBatchRequestStep(@Nonnull final MSBatchRequestStep batchRequestStep) { if (batchRequestStepsHashMap.containsKey(batchRequestStep.getRequestId()) || batchRequestStepsHashMap.size() >= MAX_NUMBER_OF_REQUESTS) return false; @@ -66,7 +69,8 @@ public boolean addBatchRequestStep(final MSBatchRequestStep batchRequestStep) { * @param arrayOfDependsOnIds ids of steps this step depends on * @return the step id */ - public String addBatchRequestStep(final Request request, final String... arrayOfDependsOnIds) { + @Nonnull + public String addBatchRequestStep(@Nonnull final Request request, @Nullable final String... arrayOfDependsOnIds) { String requestId; do { requestId = Integer.toString(ThreadLocalRandom.current().nextInt(1, Integer.MAX_VALUE)); @@ -83,7 +87,7 @@ public String addBatchRequestStep(final Request request, final String... arrayOf * @return true or false based on removal or no removal of batch request step * with given id */ - public boolean removeBatchRequestStepWithId(final String requestId) { + public boolean removeBatchRequestStepWithId(@Nonnull final String requestId) { boolean removed = false; if (batchRequestStepsHashMap.containsKey(requestId)) { batchRequestStepsHashMap.remove(requestId); @@ -101,6 +105,7 @@ public boolean removeBatchRequestStepWithId(final String requestId) { /* * @return Batch request content's json as String */ + @Nonnull public String getBatchRequestContent() { final JsonObject batchRequestContentMap = new JsonObject(); final JsonArray batchContentArray = new JsonArray(); diff --git a/src/main/java/com/microsoft/graph/content/MSBatchRequestStep.java b/src/main/java/com/microsoft/graph/content/MSBatchRequestStep.java index ac13bb0ab..509701db2 100644 --- a/src/main/java/com/microsoft/graph/content/MSBatchRequestStep.java +++ b/src/main/java/com/microsoft/graph/content/MSBatchRequestStep.java @@ -2,6 +2,9 @@ import java.util.List; +import javax.annotation.Nullable; +import javax.annotation.Nonnull; + import okhttp3.Request; public class MSBatchRequestStep { @@ -9,7 +12,7 @@ public class MSBatchRequestStep { private Request request; private List arrayOfDependsOnIds; - public MSBatchRequestStep(String requestId, Request request, List arrayOfDependsOnIds) { + public MSBatchRequestStep(@Nonnull final String requestId, @Nonnull final Request request, @Nullable final List arrayOfDependsOnIds) { if(requestId == null) throw new IllegalArgumentException("Request Id cannot be null."); if(requestId.length() == 0) @@ -22,14 +25,17 @@ public MSBatchRequestStep(String requestId, Request request, List arrayO this.arrayOfDependsOnIds = arrayOfDependsOnIds; } + @Nonnull public String getRequestId() { return requestId; } + @Nonnull public Request getRequest() { return request; } + @Nullable public List getArrayOfDependsOnIds(){ return arrayOfDependsOnIds; } diff --git a/src/main/java/com/microsoft/graph/content/MSBatchResponseContent.java b/src/main/java/com/microsoft/graph/content/MSBatchResponseContent.java index ca40384e9..58c1011e7 100644 --- a/src/main/java/com/microsoft/graph/content/MSBatchResponseContent.java +++ b/src/main/java/com/microsoft/graph/content/MSBatchResponseContent.java @@ -5,6 +5,9 @@ import java.util.Iterator; import java.util.Map; +import javax.annotation.Nullable; +import javax.annotation.Nonnull; + import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -28,7 +31,7 @@ public class MSBatchResponseContent { /* * @param batchResponse OkHttp batch response on execution of batch requests */ - public MSBatchResponseContent(final Response batchResponse) { + public MSBatchResponseContent(@Nullable final Response batchResponse) { this.batchResponse = batchResponse; update(batchResponse); } @@ -40,7 +43,8 @@ public MSBatchResponseContent(final Response batchResponse) { * * @return OkHttp Response corresponding to requestId */ - public Response getResponseById(final String requestId) { + @Nullable + public Response getResponseById(@Nonnull final String requestId) { if (batchResponseArray == null) return null; @@ -106,6 +110,7 @@ public Response getResponseById(final String requestId) { * * @return responses in Map of id and response */ + @Nonnull public Map getResponses() { if (batchResponseArray == null) return null; @@ -121,12 +126,13 @@ public Map getResponses() { * * @return iterator for responses */ + @Nullable public Iterator> getResponsesIterator() { final Map responsesMap = getResponses(); return responsesMap != null ? responsesMap.entrySet().iterator() : null; } - public void update(final Response batchResponse) { + public void update(@Nonnull final Response batchResponse) { if (batchResponse == null) throw new IllegalArgumentException("Batch Response cannot be null"); @@ -166,6 +172,7 @@ public void update(final Response batchResponse) { /* * @return nextLink of batch response */ + @Nullable public String nextLink() { return nextLink; } diff --git a/src/main/java/com/microsoft/graph/httpcore/AuthenticationHandler.java b/src/main/java/com/microsoft/graph/httpcore/AuthenticationHandler.java index b48b8b337..f5230ac94 100644 --- a/src/main/java/com/microsoft/graph/httpcore/AuthenticationHandler.java +++ b/src/main/java/com/microsoft/graph/httpcore/AuthenticationHandler.java @@ -2,6 +2,9 @@ import java.io.IOException; +import javax.annotation.Nullable; +import javax.annotation.Nonnull; + import com.microsoft.graph.httpcore.middlewareoption.MiddlewareType; import com.microsoft.graph.httpcore.middlewareoption.TelemetryOptions; @@ -15,12 +18,13 @@ public class AuthenticationHandler implements Interceptor { private ICoreAuthenticationProvider authProvider; - public AuthenticationHandler(ICoreAuthenticationProvider authProvider) { + public AuthenticationHandler(@Nonnull final ICoreAuthenticationProvider authProvider) { this.authProvider = authProvider; } @Override - public Response intercept(Chain chain) throws IOException { + @Nullable + public Response intercept(@Nonnull final Chain chain) throws IOException { Request originalRequest = chain.request(); if(originalRequest.tag(TelemetryOptions.class) == null) diff --git a/src/main/java/com/microsoft/graph/httpcore/ChaosHttpHandler.java b/src/main/java/com/microsoft/graph/httpcore/ChaosHttpHandler.java index 69601d187..d056abb77 100644 --- a/src/main/java/com/microsoft/graph/httpcore/ChaosHttpHandler.java +++ b/src/main/java/com/microsoft/graph/httpcore/ChaosHttpHandler.java @@ -3,6 +3,9 @@ import java.io.IOException; import java.util.concurrent.ThreadLocalRandom; +import javax.annotation.Nullable; +import javax.annotation.Nonnull; + import com.microsoft.graph.httpcore.middlewareoption.MiddlewareType; import com.microsoft.graph.httpcore.middlewareoption.TelemetryOptions; @@ -38,7 +41,8 @@ public class ChaosHttpHandler implements Interceptor { public static final int MSClientErrorCodeTooManyRequests = 429; @Override - public Response intercept(Chain chain) throws IOException { + @Nullable + public Response intercept(@Nonnull final Chain chain) throws IOException { Request request = chain.request(); if(request.tag(TelemetryOptions.class) == null) diff --git a/src/main/java/com/microsoft/graph/httpcore/HttpClients.java b/src/main/java/com/microsoft/graph/httpcore/HttpClients.java index e6bea9a00..d1e92aa47 100644 --- a/src/main/java/com/microsoft/graph/httpcore/HttpClients.java +++ b/src/main/java/com/microsoft/graph/httpcore/HttpClients.java @@ -2,6 +2,9 @@ import java.util.Arrays; +import javax.annotation.Nullable; +import javax.annotation.Nonnull; + import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Protocol; @@ -18,6 +21,7 @@ private HttpClients() { * * @return OkHttpClient.Builder() custom builder for developer to add its own interceptors to it */ + @Nonnull public static Builder custom() { return new OkHttpClient.Builder() .addInterceptor(new TelemetryHandler()) @@ -32,7 +36,8 @@ public static Builder custom() { * @param auth Use IAuthenticationProvider instance provided while constructing http client * @return OkHttpClient build with authentication provider given, default redirect and default retry handlers */ - public static OkHttpClient createDefault(ICoreAuthenticationProvider auth) { + @Nonnull + public static OkHttpClient createDefault(@Nonnull final ICoreAuthenticationProvider auth) { return custom() .addInterceptor(new AuthenticationHandler(auth)) .addInterceptor(new RetryHandler()) @@ -46,7 +51,8 @@ public static OkHttpClient createDefault(ICoreAuthenticationProvider auth) { * @param interceptors Use interceptors provided while constructing http client * @return OkHttpClient build with interceptors provided */ - public static OkHttpClient createFromInterceptors(Interceptor[] interceptors) { + @Nonnull + public static OkHttpClient createFromInterceptors(@Nullable final Interceptor[] interceptors) { OkHttpClient.Builder builder = custom(); if(interceptors != null) for(Interceptor interceptor : interceptors) { diff --git a/src/main/java/com/microsoft/graph/httpcore/ICoreAuthenticationProvider.java b/src/main/java/com/microsoft/graph/httpcore/ICoreAuthenticationProvider.java index 1ca39a432..be9afbe0e 100644 --- a/src/main/java/com/microsoft/graph/httpcore/ICoreAuthenticationProvider.java +++ b/src/main/java/com/microsoft/graph/httpcore/ICoreAuthenticationProvider.java @@ -2,6 +2,8 @@ import okhttp3.Request; +import javax.annotation.Nonnull; + public interface ICoreAuthenticationProvider { /** * Authenticates the request @@ -9,5 +11,6 @@ public interface ICoreAuthenticationProvider { * @param request the request to authenticate * @return Request with Authorization header added to it */ - Request authenticateRequest(Request request); + @Nonnull + Request authenticateRequest(@Nonnull final Request request); } diff --git a/src/main/java/com/microsoft/graph/httpcore/RedirectHandler.java b/src/main/java/com/microsoft/graph/httpcore/RedirectHandler.java index b04d774c7..b3d88ee7d 100644 --- a/src/main/java/com/microsoft/graph/httpcore/RedirectHandler.java +++ b/src/main/java/com/microsoft/graph/httpcore/RedirectHandler.java @@ -9,6 +9,9 @@ import java.io.IOException; import java.net.ProtocolException; +import javax.annotation.Nullable; +import javax.annotation.Nonnull; + import com.microsoft.graph.httpcore.middlewareoption.MiddlewareType; import com.microsoft.graph.httpcore.middlewareoption.RedirectOptions; import com.microsoft.graph.httpcore.middlewareoption.TelemetryOptions; @@ -34,7 +37,7 @@ public RedirectHandler() { /* * @param redirectOptions pass instance of redirect options to be used */ - public RedirectHandler(RedirectOptions redirectOptions) { + public RedirectHandler(@Nullable final RedirectOptions redirectOptions) { this.mRedirectOptions = redirectOptions; if(redirectOptions == null) { this.mRedirectOptions = new RedirectOptions(); @@ -105,7 +108,8 @@ Request getRedirect( // Intercept request and response made to network @Override - public Response intercept(Chain chain) throws IOException { + @Nullable + public Response intercept(@Nonnull final Chain chain) throws IOException { Request request = chain.request(); if(request.tag(TelemetryOptions.class) == null) diff --git a/src/main/java/com/microsoft/graph/httpcore/RetryHandler.java b/src/main/java/com/microsoft/graph/httpcore/RetryHandler.java index 9478060e6..8d156183e 100644 --- a/src/main/java/com/microsoft/graph/httpcore/RetryHandler.java +++ b/src/main/java/com/microsoft/graph/httpcore/RetryHandler.java @@ -2,6 +2,9 @@ import java.io.IOException; +import javax.annotation.Nullable; +import javax.annotation.Nonnull; + import com.microsoft.graph.httpcore.middlewareoption.IShouldRetry; import com.microsoft.graph.httpcore.middlewareoption.MiddlewareType; import com.microsoft.graph.httpcore.middlewareoption.RetryOptions; @@ -36,7 +39,7 @@ public class RetryHandler implements Interceptor{ /* * @retryOption Create Retry handler using retry option */ - public RetryHandler(RetryOptions retryOption) { + public RetryHandler(@Nullable final RetryOptions retryOption) { this.mRetryOption = retryOption; if(this.mRetryOption == null) { this.mRetryOption = new RetryOptions(); @@ -130,7 +133,8 @@ boolean isBuffered(Response response, Request request) { } @Override - public Response intercept(Chain chain) throws IOException { + @Nullable + public Response intercept(@Nonnull final Chain chain) throws IOException { Request request = chain.request(); if(request.tag(TelemetryOptions.class) == null) diff --git a/src/main/java/com/microsoft/graph/httpcore/TelemetryHandler.java b/src/main/java/com/microsoft/graph/httpcore/TelemetryHandler.java index 51d3569c5..e10675ce1 100644 --- a/src/main/java/com/microsoft/graph/httpcore/TelemetryHandler.java +++ b/src/main/java/com/microsoft/graph/httpcore/TelemetryHandler.java @@ -2,6 +2,9 @@ import java.io.IOException; +import javax.annotation.Nullable; +import javax.annotation.Nonnull; + import com.microsoft.graph.httpcore.middlewareoption.TelemetryOptions; import okhttp3.Interceptor; @@ -17,7 +20,8 @@ public class TelemetryHandler implements Interceptor{ public static final String CLIENT_REQUEST_ID = "client-request-id"; @Override - public Response intercept(Chain chain) throws IOException { + @Nullable + public Response intercept(@Nonnull final Chain chain) throws IOException { Request request = chain.request(); Request.Builder telemetryAddedBuilder = request.newBuilder(); @@ -25,7 +29,7 @@ public Response intercept(Chain chain) throws IOException { if(telemetryOptions == null) telemetryOptions = new TelemetryOptions(); - String featureUsage = "(featureUsage=" + telemetryOptions.getFeatureUsage() + ")"; + String featureUsage = "(featureUsage=" + telemetryOptions.getSerializedFeatureUsage() + ")"; String javaVersion = System.getProperty("java.version"); String sdkversion_value = GRAPH_VERSION_PREFIX + "/" + VERSION + " " + featureUsage + " " + JAVA_VERSION_PREFIX + "/" + javaVersion; telemetryAddedBuilder.addHeader(SDK_VERSION, sdkversion_value); diff --git a/src/main/java/com/microsoft/graph/httpcore/middlewareoption/IShouldRedirect.java b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/IShouldRedirect.java index 8ca9cd545..dab75623b 100644 --- a/src/main/java/com/microsoft/graph/httpcore/middlewareoption/IShouldRedirect.java +++ b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/IShouldRedirect.java @@ -1,7 +1,9 @@ package com.microsoft.graph.httpcore.middlewareoption; +import javax.annotation.Nonnull; + import okhttp3.Response; public interface IShouldRedirect { - boolean shouldRedirect(final Response response); + boolean shouldRedirect(@Nonnull final Response response); } diff --git a/src/main/java/com/microsoft/graph/httpcore/middlewareoption/IShouldRetry.java b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/IShouldRetry.java index 249a5ba3e..90ab05284 100644 --- a/src/main/java/com/microsoft/graph/httpcore/middlewareoption/IShouldRetry.java +++ b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/IShouldRetry.java @@ -3,6 +3,8 @@ import okhttp3.Request; import okhttp3.Response; +import javax.annotation.Nonnull; + public interface IShouldRetry { - boolean shouldRetry(long delay, int executionCount, Request request,Response response); + boolean shouldRetry(long delay, int executionCount, @Nonnull final Request request, @Nonnull final Response response); } diff --git a/src/main/java/com/microsoft/graph/httpcore/middlewareoption/RedirectOptions.java b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/RedirectOptions.java index f4ef54900..0444db9f3 100644 --- a/src/main/java/com/microsoft/graph/httpcore/middlewareoption/RedirectOptions.java +++ b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/RedirectOptions.java @@ -2,6 +2,9 @@ import okhttp3.Response; +import javax.annotation.Nullable; +import javax.annotation.Nonnull; + public class RedirectOptions implements IMiddlewareControl{ private int maxRedirects; public static final int DEFAULT_MAX_REDIRECTS = 5; @@ -26,7 +29,7 @@ public RedirectOptions() { * @param maxRedirects Max redirects to occur * @param shouldRedirect Should redirect callback called before every redirect */ - public RedirectOptions(int maxRedirects, IShouldRedirect shouldRedirect) { + public RedirectOptions(int maxRedirects, @Nullable final IShouldRedirect shouldRedirect) { if(maxRedirects < 0) throw new IllegalArgumentException("Max redirects cannot be negative"); if(maxRedirects > MAX_REDIRECTS) @@ -46,6 +49,7 @@ public int maxRedirects() { /* * @return should redirect */ + @Nonnull public IShouldRedirect shouldRedirect() { return this.shouldRedirect; } diff --git a/src/main/java/com/microsoft/graph/httpcore/middlewareoption/RetryOptions.java b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/RetryOptions.java index 9010122f5..69ad5db26 100644 --- a/src/main/java/com/microsoft/graph/httpcore/middlewareoption/RetryOptions.java +++ b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/RetryOptions.java @@ -3,6 +3,9 @@ import okhttp3.Request; import okhttp3.Response; +import javax.annotation.Nullable; +import javax.annotation.Nonnull; + public class RetryOptions implements IMiddlewareControl { private IShouldRetry mShouldretry; public static final IShouldRetry DEFAULT_SHOULD_RETRY = new IShouldRetry() { @@ -35,7 +38,8 @@ public RetryOptions(){ * @param maxRetries Number of max retires for a request * @param delay Delay in seconds between retries */ - public RetryOptions(IShouldRetry shouldRetry, int maxRetries, long delay) { + @SuppressWarnings("LambdaLast") + public RetryOptions(@Nullable final IShouldRetry shouldRetry, int maxRetries, long delay) { if(delay > MAX_DELAY) throw new IllegalArgumentException("Delay cannot exceed " + MAX_DELAY); if(delay < 0) @@ -53,6 +57,7 @@ public RetryOptions(IShouldRetry shouldRetry, int maxRetries, long delay) { /* * @return should retry callback */ + @Nonnull public IShouldRetry shouldRetry() { return mShouldretry; } diff --git a/src/main/java/com/microsoft/graph/httpcore/middlewareoption/TelemetryOptions.java b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/TelemetryOptions.java index 60def57d8..415fe509c 100644 --- a/src/main/java/com/microsoft/graph/httpcore/middlewareoption/TelemetryOptions.java +++ b/src/main/java/com/microsoft/graph/httpcore/middlewareoption/TelemetryOptions.java @@ -2,6 +2,8 @@ import java.util.UUID; +import javax.annotation.Nonnull; + public class TelemetryOptions { public static final int NONE_FLAG = 0; @@ -18,14 +20,20 @@ public void setFeatureUsage(int flag) { featureUsage = featureUsage | flag; } - public String getFeatureUsage() { + public int getFeatureUsage() { + return featureUsage; + } + + @Nonnull + public String getSerializedFeatureUsage() { return Integer.toHexString(featureUsage); } - public void setClientRequestId(String clientRequestId) { + public void setClientRequestId(@Nonnull final String clientRequestId) { this.clientRequestId = clientRequestId; } + @Nonnull public String getClientRequestId() { if(clientRequestId == null) { clientRequestId = UUID.randomUUID().toString(); diff --git a/src/test/java/com/microsoft/graph/httpcore/TelemetryOptionsTest.java b/src/test/java/com/microsoft/graph/httpcore/TelemetryOptionsTest.java index dece2ef55..9ba6eedb9 100644 --- a/src/test/java/com/microsoft/graph/httpcore/TelemetryOptionsTest.java +++ b/src/test/java/com/microsoft/graph/httpcore/TelemetryOptionsTest.java @@ -21,16 +21,16 @@ public void setFeatureUsageTest() { TelemetryOptions telemetryOptions = new TelemetryOptions(); telemetryOptions.setFeatureUsage(TelemetryOptions.AUTH_HANDLER_ENABLED_FLAG); telemetryOptions.setFeatureUsage(TelemetryOptions.REDIRECT_HANDLER_ENABLED_FLAG); - assertTrue(telemetryOptions.getFeatureUsage().compareTo("5")==0); + assertTrue(telemetryOptions.getSerializedFeatureUsage().compareTo("5")==0); } @Test - public void getFeatureUsageTest() { + public void getSerializedFeatureUsageTest() { TelemetryOptions telemetryOptions = new TelemetryOptions(); telemetryOptions.setFeatureUsage(TelemetryOptions.AUTH_HANDLER_ENABLED_FLAG); telemetryOptions.setFeatureUsage(TelemetryOptions.REDIRECT_HANDLER_ENABLED_FLAG); telemetryOptions.setFeatureUsage(TelemetryOptions.RETRY_HANDLER_ENABLED_FLAG); - assertTrue(telemetryOptions.getFeatureUsage().compareTo("7")==0); + assertTrue(telemetryOptions.getSerializedFeatureUsage().compareTo("7")==0); } @Test