diff --git a/.azure-pipelines/buildAndPackage.yml b/.azure-pipelines/buildAndPackage.yml index 417ca04dd..6eaed042f 100644 --- a/.azure-pipelines/buildAndPackage.yml +++ b/.azure-pipelines/buildAndPackage.yml @@ -85,7 +85,7 @@ steps: settings.gradle gradle.properties **/gradle/wrapper/* - Scripts/getLatestVersion.ps1 + Scripts/** TargetFolder: '$(Build.ArtifactStagingDirectory)/' - task: PublishBuildArtifacts@1 diff --git a/.azure-pipelines/prValidate.yml b/.azure-pipelines/prValidate.yml index 64bbf4c0b..cf2bd540d 100644 --- a/.azure-pipelines/prValidate.yml +++ b/.azure-pipelines/prValidate.yml @@ -43,13 +43,6 @@ steps: inputs: debugMode: false -- task: PowerShell@2 - condition: and(failed(), eq(variables['Build.SourceBranchName'], 'dev')) - inputs: - filePath: '$(System.DefaultWorkingDirectory)\Scripts\validateMavenVersion.ps1' - pwsh: true - arguments: '-packageName "$(PACKAGE_NAME)" -propertiesPath "$(PROPERTIES_PATH)"' - - task: Gradle@2 inputs: gradleWrapperFile: 'gradlew' diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..3bf6f4f2b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,5 @@ +[*.java] +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true \ No newline at end of file diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..10a1e9e17 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @baywet @ddyett @MichaelMainer @nikithauc @zengin \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 767270516..75c8395a5 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,7 +5,7 @@ updates: schedule: interval: daily open-pull-requests-limit: 10 -- package-ecosystem: maven +- package-ecosystem: github-actions directory: "/" schedule: interval: daily diff --git a/.gitignore b/.gitignore index f121de793..e34a1d606 100644 --- a/.gitignore +++ b/.gitignore @@ -31,5 +31,4 @@ hs_err_pid* # Maven /target/ -/pom.xml local.properties \ No newline at end of file diff --git a/Scripts/incrementMinorVersion.ps1 b/Scripts/incrementMinorVersion.ps1 new file mode 100644 index 000000000..3d5758f1e --- /dev/null +++ b/Scripts/incrementMinorVersion.ps1 @@ -0,0 +1,59 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +<# +.Synopsis + Increment the minor version string in the gradle.properties if the major, + minor, or patch version hasn't been manually updated. +.Description + Assumptions: + Targets Gradle.properties + This script assumes it is run from the repo root. + Minor version is typically auto-incremented. + +#> + +function Update-ReadmeVersion([string]$readmeFilePath, [version]$version) { + $readmeFileContent = Get-Content -Path $readmeFilePath -Raw + $readmeFileContent = $readmeFileContent -replace "\d{1,}\.\d{1,}\.\d{1,}", $version.ToString() + Set-Content -Path $readmeFilePath $readmeFileContent +} + +function Update-TelemetryVersion([string]$telemetryFilePath, [version]$version) { + $telemetryFileContent = Get-Content -Path $telemetryFilePath -Raw + $telemetryFileContent = $telemetryFileContent -replace "\d{1,}\.\d{1,}\.\d{1,}", $version.ToString() + Set-Content -Path $telemetryFilePath $telemetryFileContent +} + +function Update-PackageVersion([string]$propertiesFilePath, [version]$version) { + $propertiesFileContent = Get-Content -Path $propertiesFilePath -Raw + $propertiesFileContent = $propertiesFileContent -replace "mavenMajorVersion\s+=\s+\d{1,}", "mavenMajorVersion = $($version.Major)" + $propertiesFileContent = $propertiesFileContent -replace "mavenMinorVersion\s+=\s+\d{1,}", "mavenMinorVersion = $($version.Minor)" + $propertiesFileContent = $propertiesFileContent -replace "mavenPatchVersion\s+=\s+\d{1,}", "mavenPatchVersion = $($version.Build)" + Set-Content -Path $propertiesFilePath $propertiesFileContent +} +function Get-CurrentTelemetryVersion([string]$telemetryFilePath) { + $telemetryFileContent = Get-Content -Path $telemetryFilePath -Raw + if($telemetryFileContent -match "(\d{1,}\.\d{1,}\.\d{1,})") { + return [version]::Parse($Matches[1]) + } else { + Write-Error "Invalid version number format" + return $null; + } +} + +function Update-MinorVersionNumber([version]$currentVersion) { + return [version]::new($currentVersion.Major, $currentVersion.Minor + 1, 0); +} + +function Update-MinorVersion() { + $readmeFilePath = Join-Path -Path $PWD.ToString() -ChildPath "../readme.md" + $propertiesFilePath = Join-Path -Path $PWD.ToString() -ChildPath "../gradle.properties" + $telemetryFilePath = Join-Path -Path $PWD.ToString() -ChildPath "../src/main/java/com/microsoft/graph/httpcore/TelemetryHandler.java" + $currentVersion = Get-CurrentTelemetryVersion -telemetryFilePath $telemetryFilePath + $nextVersion = Update-MinorVersionNumber -currentVersion $currentVersion + Update-ReadmeVersion -version $nextVersion -readmeFilePath $readmeFilePath + Update-TelemetryVersion -version $nextVersion -telemetryFilePath $telemetryFilePath + Update-PackageVersion -version $nextVersion -propertiesFilePath $propertiesFilePath +} +Update-MinorVersion \ No newline at end of file diff --git a/Scripts/validateMavenVersion.ps1 b/Scripts/validateMavenVersion.ps1 deleted file mode 100644 index da1742bd2..000000000 --- a/Scripts/validateMavenVersion.ps1 +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. - -<# -.Synopsis - Ensure the maven version is updated in the case that the pull request is - to the main/master branch of the repo. -.Description - Retrieves the local, Maven, and Bintray versions of the Java-Core build. - Checks that the Maven and Bintray versions are aligned, trigger warning if not. - Checks that the current local version is greater than those currently deployed. -.Parameter propertiesPath -#> - - -Param( - [string]$propertiesPath -) - -#Find the local version from the Gradle.Properties file -if($propertiesPath -eq "" -or $null -eq $propertiesPath) { - $propertiesPath = Join-Path -Path $PSScriptRoot -ChildPath "../gradle.properties" -} -$file = get-item $propertiesPath -$findLocalVersions = $file | Select-String -Pattern "mavenMajorVersion" -Context 0,2 -$findLocalVersions = $findLocalVersions -split "`r`n" -$packageName = ($file | Select-String -Pattern "mavenArtifactId").Line.Split("=")[1].Trim() - -$localMajor = $findLocalVersions[0].Substring($findLocalVersions[0].Length-1) -$localMinor = $findLocalVersions[1].Substring($findLocalVersions[1].Length-1) -$localPatch = $findLocalVersions[2].Substring($findLocalVersions[2].Length-1) -$localVersion = [version]"$localMajor.$localMinor.$localPatch" - -#Set Web Client and retrieve Maven and Bintray versions from their respective repos. -$web_client = New-Object System.Net.WebClient - -$mavenAPIurl = "https://search.maven.org/solrsearch/select?q=$packageName&rows=20&wt=json" -$jsonResult = $web_client.DownloadString($mavenAPIurl) | ConvertFrom-Json -$mavenVersion = [version]$jsonResult.response.docs.latestVersion - -$bintrayAPIurl = "https://api.bintray.com/search/packages?name=$packageName" -$jsonResult = $web_client.DownloadString($bintrayAPIurl) | ConvertFrom-Json -$bintrayVersion = [version]$jsonResult.latest_version - -#If the api calls return empty then this library cannot be compared to the online versions -#may proceed with the pull request -if(($mavenVersion -eq $null) -and ($bintrayVersion -eq $null)) -{ - Write-Information "This package does not exist yet in the online repository, therefore there are no versions to compare." - return -} - -#Inform host of current Maven and Bintray versions -Write-Host 'The current version in the Maven central repository is:' $mavenVersion -Write-Host 'The current version in the Bintray central repository is:' $bintrayVersion - -#Warn in case Maven and Bintray versions are not the same. -if($mavenVersion -ne $bintrayVersion){ - Write-Warning "The current Maven and Bintray versions are not the same" -} -#Success if Local version has been updated, Error otherwise. -if($localVersion -gt $bintrayVersion -and $localVersion -gt $mavenVersion){ - Write-Host "The current pull request is of a greater version" -} -else{ - Write-Error "The current local version is not updated. Please update the local version in the Gradle.Properties file." -} diff --git a/build.gradle b/build.gradle index 5cfd7cbd4..9991b2fa3 100644 --- a/build.gradle +++ b/build.gradle @@ -20,6 +20,14 @@ java { modularity.inferModulePath = true } +sourceSets { + main { + java { + exclude 'pom.xml' + } + } +} + // In this section you declare where to find the dependencies of your project repositories { // Use jcenter for resolving your dependencies. @@ -30,7 +38,7 @@ repositories { dependencies { // Use JUnit test framework - testImplementation 'junit:junit:4.13' + testImplementation 'junit:junit:4.13.1' api 'com.squareup.okhttp3:okhttp:3.12.1' diff --git a/gradle.properties b/gradle.properties index 74406c825..17a8f7ac8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -25,7 +25,7 @@ mavenGroupId = com.microsoft.graph mavenArtifactId = microsoft-graph-core mavenMajorVersion = 1 mavenMinorVersion = 0 -mavenPatchVersion = 5 +mavenPatchVersion = 6 mavenArtifactSuffix = nightliesUrl = http://dl.bintray.com/MicrosoftGraph/Maven diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..dc77c1858 --- /dev/null +++ b/pom.xml @@ -0,0 +1,26 @@ + + + 4.0.0 + + com.microsoft.graph + microsoft-graph-core + 1.0.6 + pom + + + + com.google.code.gson + gson + 2.8.6 + + + com.squareup.okhttp3 + gson + 3.12.1 + + + \ No newline at end of file diff --git a/readme.md b/readme.md index 53619c747..b280482d9 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ # Microsoft Graph Core SDK for Java -Get started with the Microsoft Graph Core SDK for Java by integrating the [Microsoft Graph API](https://graph.microsoft.io/en-us/getting-started) into your Java and Android application! +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) ## Samples and usage guide @@ -20,7 +20,7 @@ repositories { dependencies { // Include the sdk as a dependency - implementation 'com.microsoft.graph:microsoft-graph-core:1.0.5' + implementation 'com.microsoft.graph:microsoft-graph-core:1.0.6' } ``` @@ -32,7 +32,7 @@ Add the dependency in `dependencies` in pom.xml com.microsoft.graph microsoft-graph-core - 1.0.5 + 1.0.6 ``` diff --git a/src/main/java/com/microsoft/graph/content/MSBatchRequestContent.java b/src/main/java/com/microsoft/graph/content/MSBatchRequestContent.java index 64eed6c23..4b9fc0a9e 100644 --- a/src/main/java/com/microsoft/graph/content/MSBatchRequestContent.java +++ b/src/main/java/com/microsoft/graph/content/MSBatchRequestContent.java @@ -6,6 +6,8 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ThreadLocalRandom; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import com.google.gson.JsonArray; import com.google.gson.JsonElement; @@ -27,7 +29,7 @@ public class MSBatchRequestContent { /* * Creates Batch request content using list provided - * + * * @param batchRequestStepsArray List of batch steps for batching */ public MSBatchRequestContent(final List batchRequestStepsArray) { @@ -48,7 +50,7 @@ public MSBatchRequestContent() { /* * @param batchRequestStep Batch request step adding to batch content - * + * * @return true or false based on addition or no addition of batch request step * given */ @@ -79,7 +81,7 @@ public String addBatchRequestStep(final Request request, final String... arrayOf /* * @param requestId Id of Batch request step to be removed - * + * * @return true or false based on removal or no removal of batch request step * with given id */ @@ -113,13 +115,14 @@ public String getBatchRequestContent() { return content; } + private static final Pattern protocolAndHostReplacementPattern = Pattern.compile("(?i)^http[s]?:\\/\\/graph\\.microsoft\\.com\\/(?>v1\\.0|beta)\\/?"); // (?i) case insensitive private JsonObject getBatchRequestObjectFromRequestStep(final MSBatchRequestStep batchRequestStep) { final JsonObject contentmap = new JsonObject(); contentmap.add("id", new JsonPrimitive(batchRequestStep.getRequestId())); - final String url = batchRequestStep.getRequest().url().toString() - .replaceAll("https://graph.microsoft.com/v1.0/", "").replaceAll("http://graph.microsoft.com/v1.0/", "") - .replaceAll("https://graph.microsoft.com/beta/", "").replaceAll("http://graph.microsoft.com/beta/", ""); + final Matcher protocolAndHostReplacementMatcher = protocolAndHostReplacementPattern.matcher(batchRequestStep.getRequest().url().toString()); + + final String url = protocolAndHostReplacementMatcher.replaceAll(""); contentmap.add("url", new JsonPrimitive(url)); contentmap.add("method", new JsonPrimitive(batchRequestStep.getRequest().method().toString())); @@ -178,5 +181,5 @@ private JsonObject requestBodyToJSONObject(final Request request) throws IOExcep else return requestBodyElement.getAsJsonObject(); } - + } diff --git a/src/main/java/com/microsoft/graph/httpcore/TelemetryHandler.java b/src/main/java/com/microsoft/graph/httpcore/TelemetryHandler.java index 51d3569c5..b5da60c3f 100644 --- a/src/main/java/com/microsoft/graph/httpcore/TelemetryHandler.java +++ b/src/main/java/com/microsoft/graph/httpcore/TelemetryHandler.java @@ -1,6 +1,7 @@ package com.microsoft.graph.httpcore; import java.io.IOException; +import java.lang.reflect.Field; import com.microsoft.graph.httpcore.middlewareoption.TelemetryOptions; @@ -10,31 +11,60 @@ public class TelemetryHandler implements Interceptor{ - public static final String SDK_VERSION = "SdkVersion"; - public static final String VERSION = "v1.0.5"; - public static final String GRAPH_VERSION_PREFIX = "graph-java-core"; - public static final String JAVA_VERSION_PREFIX = "java"; - public static final String CLIENT_REQUEST_ID = "client-request-id"; + public static final String SDK_VERSION = "SdkVersion"; + public static final String VERSION = "v1.0.6"; + public static final String GRAPH_VERSION_PREFIX = "graph-java-core"; + public static final String JAVA_VERSION_PREFIX = "java"; + public static final String ANDROID_VERSION_PREFIX = "android"; + public static final String CLIENT_REQUEST_ID = "client-request-id"; - @Override - public Response intercept(Chain chain) throws IOException { - Request request = chain.request(); - Request.Builder telemetryAddedBuilder = request.newBuilder(); + @Override + public Response intercept(Chain chain) throws IOException { + final Request request = chain.request(); + final Request.Builder telemetryAddedBuilder = request.newBuilder(); - TelemetryOptions telemetryOptions = request.tag(TelemetryOptions.class); - if(telemetryOptions == null) - telemetryOptions = new TelemetryOptions(); + TelemetryOptions telemetryOptions = request.tag(TelemetryOptions.class); + if(telemetryOptions == null) + telemetryOptions = new TelemetryOptions(); - String featureUsage = "(featureUsage=" + telemetryOptions.getFeatureUsage() + ")"; - String javaVersion = System.getProperty("java.version"); - String sdkversion_value = GRAPH_VERSION_PREFIX + "/" + VERSION + " " + featureUsage + " " + JAVA_VERSION_PREFIX + "/" + javaVersion; - telemetryAddedBuilder.addHeader(SDK_VERSION, sdkversion_value); + final String featureUsage = "(featureUsage=" + telemetryOptions.getFeatureUsage() + ")"; + final String javaVersion = System.getProperty("java.version"); + final String androidVersion = getAndroidAPILevel(); + final String sdkversion_value = GRAPH_VERSION_PREFIX + "/" + VERSION + " " + featureUsage + " " + JAVA_VERSION_PREFIX + "/" + javaVersion + " " + ANDROID_VERSION_PREFIX + "/" + androidVersion; + telemetryAddedBuilder.addHeader(SDK_VERSION, sdkversion_value); - if(request.header(CLIENT_REQUEST_ID) == null) { - telemetryAddedBuilder.addHeader(CLIENT_REQUEST_ID, telemetryOptions.getClientRequestId()); - } + if(request.header(CLIENT_REQUEST_ID) == null) { + telemetryAddedBuilder.addHeader(CLIENT_REQUEST_ID, telemetryOptions.getClientRequestId()); + } - return chain.proceed(telemetryAddedBuilder.build()); - } + return chain.proceed(telemetryAddedBuilder.build()); + } + private String androidAPILevel; + private String getAndroidAPILevel() { + if(androidAPILevel == null) { + androidAPILevel = getAndroidAPILevelInternal(); + } + return androidAPILevel; + } + private String getAndroidAPILevelInternal() { + try { + final Class buildClass = Class.forName("android.os.Build"); + final Class[] subclasses = buildClass.getDeclaredClasses(); + Class versionClass = null; + for(final Class subclass : subclasses) { + if(subclass.getName().endsWith("VERSION")) { + versionClass = subclass; + break; + } + } + final Field sdkVersionField = versionClass.getField("SDK_INT"); + final Object value = sdkVersionField.get(null); + final String valueStr = String.valueOf(value); + return valueStr == null || valueStr == "" ? "0" : valueStr; + } catch (IllegalAccessException | ClassNotFoundException | NoSuchFieldException ex) { + // we're not on android and return "0" to align with java version which returns "0" when running on android + return "0"; + } + } } diff --git a/src/test/java/com/microsoft/graph/httpcore/TelemetryHandlerTest.java b/src/test/java/com/microsoft/graph/httpcore/TelemetryHandlerTest.java index deab260a4..8fcffc3df 100644 --- a/src/test/java/com/microsoft/graph/httpcore/TelemetryHandlerTest.java +++ b/src/test/java/com/microsoft/graph/httpcore/TelemetryHandlerTest.java @@ -5,7 +5,6 @@ import java.io.IOException; -import org.junit.Ignore; import org.junit.Test; import okhttp3.Interceptor; @@ -13,60 +12,61 @@ import okhttp3.Request; import okhttp3.Response; -@Ignore public class TelemetryHandlerTest { - @Test - public void telemetryInitTest() { - TelemetryHandler telemetryHandler = new TelemetryHandler(); - assertNotNull(telemetryHandler); - } - - @Test - public void interceptTest() throws IOException { - String expectedHeader = TelemetryHandler.SDK_VERSION + TelemetryHandler.GRAPH_VERSION_PREFIX +"/" - +TelemetryHandler.VERSION; - OkHttpClient client = HttpClients.createDefault(new ICoreAuthenticationProvider() { - @Override - public Request authenticateRequest(Request request) { - return request; - } - }); - Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/users/").build(); - Response response = client.newCall(request).execute(); - assertNotNull(response); - assertTrue(response.request().header("SdkVersion").contains(expectedHeader)); - } - - @Test - public void arrayInterceptorsTest() throws IOException { - - AuthenticationHandler authenticationHandler = new AuthenticationHandler(new ICoreAuthenticationProvider() { - - @Override - public Request authenticateRequest(Request request) { - return request; - } - }); - Interceptor[] interceptors = {new RetryHandler(), new RedirectHandler(), authenticationHandler}; - OkHttpClient client = HttpClients.createFromInterceptors(interceptors); - String expectedHeader = TelemetryHandler.SDK_VERSION + TelemetryHandler.GRAPH_VERSION_PREFIX +"/" - +TelemetryHandler.VERSION; - Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/users/").build(); - Response response = client.newCall(request).execute(); - assertNotNull(response); - assertTrue(response.request().header("SdkVersion").contains(expectedHeader)); - } - - @Test - public void arrayInterceptorEmptyTest() throws IOException { - Interceptor[] interceptors = null; - OkHttpClient client = HttpClients.createFromInterceptors(interceptors); - String expectedHeader = TelemetryHandler.SDK_VERSION + TelemetryHandler.GRAPH_VERSION_PREFIX +"/" - +TelemetryHandler.VERSION; - Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/users/").build(); - Response response = client.newCall(request).execute(); - assertNotNull(response); - assertTrue(response.request().header("SdkVersion").contains(expectedHeader)); - } - + @Test + public void telemetryInitTest() { + final TelemetryHandler telemetryHandler = new TelemetryHandler(); + assertNotNull(telemetryHandler); + } + + @Test + public void interceptTest() throws IOException { + final String expectedHeader = TelemetryHandler.GRAPH_VERSION_PREFIX +"/" + +TelemetryHandler.VERSION; + final OkHttpClient client = HttpClients.createDefault(new ICoreAuthenticationProvider() { + @Override + public Request authenticateRequest(Request request) { + return request; + } + }); + final Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/users/").build(); + final Response response = client.newCall(request).execute(); + assertNotNull(response); + assertTrue(response.request().header(TelemetryHandler.SDK_VERSION).contains(expectedHeader)); + assertTrue(response.request().header(TelemetryHandler.SDK_VERSION).contains(TelemetryHandler.ANDROID_VERSION_PREFIX)); + assertTrue(response.request().header(TelemetryHandler.SDK_VERSION).contains(TelemetryHandler.JAVA_VERSION_PREFIX)); + } + + @Test + public void arrayInterceptorsTest() throws IOException { + + final AuthenticationHandler authenticationHandler = new AuthenticationHandler(new ICoreAuthenticationProvider() { + + @Override + public Request authenticateRequest(Request request) { + return request; + } + }); + final Interceptor[] interceptors = {new RetryHandler(), new RedirectHandler(), authenticationHandler}; + final OkHttpClient client = HttpClients.createFromInterceptors(interceptors); + final String expectedHeader = TelemetryHandler.GRAPH_VERSION_PREFIX +"/" + +TelemetryHandler.VERSION; + final Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/users/").build(); + final Response response = client.newCall(request).execute(); + assertNotNull(response); + assertTrue(response.request().header(TelemetryHandler.SDK_VERSION).contains(expectedHeader)); + } + + @Test + public void arrayInterceptorEmptyTest() throws IOException { + final Interceptor[] interceptors = null; + final OkHttpClient client = HttpClients.createFromInterceptors(interceptors); + final String expectedHeader = TelemetryHandler.GRAPH_VERSION_PREFIX +"/" + +TelemetryHandler.VERSION; + final Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/users/").build(); + final Response response = client.newCall(request).execute(); + assertNotNull(response); + assertTrue(response.request().header(TelemetryHandler.SDK_VERSION).contains(expectedHeader)); + } + }