From 23b94249499a929b606fe445a4d552da5cda04c2 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Tue, 1 Mar 2016 11:19:40 -0800 Subject: [PATCH 01/42] Fix flattening and bump up to 1.0.0-beta1 --- azure-android-client-authentication/build.gradle | 7 ++++--- azure-client-authentication/build.gradle | 5 +++-- azure-client-runtime/build.gradle | 5 +++-- client-runtime/build.gradle | 3 ++- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/azure-android-client-authentication/build.gradle b/azure-android-client-authentication/build.gradle index bb0b8f88caa0..9354d2edb123 100644 --- a/azure-android-client-authentication/build.gradle +++ b/azure-android-client-authentication/build.gradle @@ -8,7 +8,7 @@ buildscript { apply plugin: 'com.android.library' apply plugin: 'maven' -version = '1.0.0-SNAPSHOT' +version = '1.0.0-beta1' android { compileSdkVersion 23 @@ -18,7 +18,7 @@ android { minSdkVersion 15 targetSdkVersion 23 versionCode 1 - versionName "0.0.1-SNAPSHOT" + versionName "1.0.0-beta1" } buildTypes { @@ -42,7 +42,7 @@ dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.microsoft.aad:adal:1.1.11' - compile 'com.microsoft.rest:client-runtime:1.0.0-SNAPSHOT' + compile 'com.microsoft.rest:client-runtime:1.0.0-beta1' testCompile 'junit:junit:4.12' testCompile 'junit:junit-dep:4.11' deployerJars "org.apache.maven.wagon:wagon-ftp:2.10" @@ -55,6 +55,7 @@ uploadArchives { snapshotRepository(url: "ftp://waws-prod-bay-005.ftp.azurewebsites.windows.net/site/wwwroot/") { authentication(userName: username, password: password) } + repository(url: "file://$buildDir/repository") pom.setArtifactId "azure-android-client-authentication" pom.project { name 'Microsoft Azure AutoRest Authentication Library for Java' diff --git a/azure-client-authentication/build.gradle b/azure-client-authentication/build.gradle index eec78c76db0c..15729482f5ef 100644 --- a/azure-client-authentication/build.gradle +++ b/azure-client-authentication/build.gradle @@ -10,7 +10,7 @@ buildscript { apply plugin: 'java' apply plugin: 'checkstyle' -version = '1.0.0-SNAPSHOT' +version = '1.0.0-beta1' checkstyle { configFile = new File("$rootDir/Tools/checkstyle/checkstyle.xml") @@ -20,7 +20,7 @@ checkstyle { dependencies { compile 'com.microsoft.azure:adal4j:1.1.2' - compile 'com.microsoft.rest:client-runtime:1.0.0-SNAPSHOT' + compile 'com.microsoft.rest:client-runtime:1.0.0-beta1' testCompile 'junit:junit:4.12' testCompile 'junit:junit-dep:4.11' deployerJars "org.apache.maven.wagon:wagon-ftp:2.10" @@ -33,6 +33,7 @@ uploadArchives { snapshotRepository(url: "ftp://waws-prod-bay-005.ftp.azurewebsites.windows.net/site/wwwroot/") { authentication(userName: username, password: password) } + repository(url: "file://$buildDir/repository") pom.setArtifactId "azure-client-authentication" pom.project { name 'Microsoft Azure AutoRest Authentication Library for Java' diff --git a/azure-client-runtime/build.gradle b/azure-client-runtime/build.gradle index 069bdd82a7fc..d4781b7a197f 100644 --- a/azure-client-runtime/build.gradle +++ b/azure-client-runtime/build.gradle @@ -10,7 +10,7 @@ buildscript { apply plugin: 'java' apply plugin: 'checkstyle' -version = '1.0.0-SNAPSHOT' +version = '1.0.0-beta1' checkstyle { toolVersion = "6.9" @@ -20,7 +20,7 @@ checkstyle { } dependencies { - compile 'com.microsoft.rest:client-runtime:1.0.0-SNAPSHOT' + compile 'com.microsoft.rest:client-runtime:1.0.0-beta1' testCompile 'junit:junit:4.12' testCompile 'junit:junit-dep:4.11' deployerJars "org.apache.maven.wagon:wagon-ftp:2.10" @@ -33,6 +33,7 @@ uploadArchives { snapshotRepository(url: "ftp://waws-prod-bay-005.ftp.azurewebsites.windows.net/site/wwwroot/") { authentication(userName: username, password: password) } + repository(url: "file://$buildDir/repository") pom.setArtifactId "azure-client-runtime" pom.project { name 'Microsoft Azure AutoRest Runtime for Java' diff --git a/client-runtime/build.gradle b/client-runtime/build.gradle index f5b95fb92b21..3b40508b0914 100644 --- a/client-runtime/build.gradle +++ b/client-runtime/build.gradle @@ -12,7 +12,7 @@ apply plugin: 'com.github.johnrengelman.shadow' apply plugin: 'checkstyle' group = 'com.microsoft.rest' -version = '1.0.0-SNAPSHOT' +version = '1.0.0-beta1' checkstyle { toolVersion = "6.9" @@ -43,6 +43,7 @@ uploadArchives { snapshotRepository(url: "ftp://waws-prod-bay-005.ftp.azurewebsites.windows.net/site/wwwroot/") { authentication(userName: username, password: password) } + repository(url: "file://$buildDir/repository") pom.project { name 'Microsoft AutoRest Runtime for Java' description 'This is the client runtime for AutoRest generated Java clients.' From 54f180a3dc0fe4076e7a2c2bf995b2f76b036377 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Thu, 3 Mar 2016 15:19:56 -0800 Subject: [PATCH 02/42] Add gradle task to generate git revision --- azure-android-client-authentication/build.gradle | 15 +++++++++++++-- azure-client-authentication/build.gradle | 13 ++++++++++++- azure-client-runtime/build.gradle | 13 ++++++++++++- client-runtime/build.gradle | 13 ++++++++++++- 4 files changed, 49 insertions(+), 5 deletions(-) diff --git a/azure-android-client-authentication/build.gradle b/azure-android-client-authentication/build.gradle index bb0b8f88caa0..2d491a9d6867 100644 --- a/azure-android-client-authentication/build.gradle +++ b/azure-android-client-authentication/build.gradle @@ -85,6 +85,16 @@ uploadArchives { } } +task versionInfo(type:Exec){ + commandLine 'git rev-parse HEAD'.split() + ext.versionfile = new File("${projectDir}/.gitrevision") + standardOutput = new ByteArrayOutputStream() + + doLast { + versionfile.text = standardOutput.toString() + } +} + task sourcesJar(type: Jar) { from android.sourceSets.main.java.srcDirs classifier = 'sources' @@ -96,12 +106,13 @@ task javadoc(type: Javadoc) { options.encoding = 'UTF-8' } -task javadocJar(type: Jar, dependsOn: javadoc) { +task javadocJar(type: Jar, dependsOn: [javadoc, versionInfo]) { classifier = 'javadoc' from javadoc.destinationDir } artifacts { - archives javadocJar archives sourcesJar + archives javadocJar + archives file: file("${projectDir}/.gitrevision") } \ No newline at end of file diff --git a/azure-client-authentication/build.gradle b/azure-client-authentication/build.gradle index eec78c76db0c..7bbe92d96dc2 100644 --- a/azure-client-authentication/build.gradle +++ b/azure-client-authentication/build.gradle @@ -69,6 +69,16 @@ test { } } +task versionInfo(type:Exec){ + commandLine 'git rev-parse HEAD'.split() + ext.versionfile = new File("${projectDir}/.gitrevision") + standardOutput = new ByteArrayOutputStream() + + doLast { + versionfile.text = standardOutput.toString() + } +} + javadoc { options.encoding = 'UTF-8' } @@ -78,7 +88,7 @@ task sourcesJar(type: Jar, dependsOn:classes) { from sourceSets.main.allSource } -task javadocJar(type: Jar, dependsOn: javadoc) { +task javadocJar(type: Jar, dependsOn: [javadoc, versionInfo]) { classifier = 'javadoc' from javadoc.destinationDir } @@ -86,6 +96,7 @@ task javadocJar(type: Jar, dependsOn: javadoc) { artifacts { archives sourcesJar archives javadocJar + archives file: file("${projectDir}/.gitrevision") } test { diff --git a/azure-client-runtime/build.gradle b/azure-client-runtime/build.gradle index 069bdd82a7fc..4a4b146d9b47 100644 --- a/azure-client-runtime/build.gradle +++ b/azure-client-runtime/build.gradle @@ -69,6 +69,16 @@ test { } } +task versionInfo(type:Exec){ + commandLine 'git rev-parse HEAD'.split() + ext.versionfile = new File("${projectDir}/.gitrevision") + standardOutput = new ByteArrayOutputStream() + + doLast { + versionfile.text = standardOutput.toString() + } +} + javadoc { options.encoding = 'UTF-8' } @@ -78,7 +88,7 @@ task sourcesJar(type: Jar, dependsOn:classes) { from sourceSets.main.allSource } -task javadocJar(type: Jar, dependsOn: javadoc) { +task javadocJar(type: Jar, dependsOn: [javadoc, versionInfo]) { classifier = 'javadoc' from javadoc.destinationDir } @@ -86,6 +96,7 @@ task javadocJar(type: Jar, dependsOn: javadoc) { artifacts { archives sourcesJar archives javadocJar + archives file: file("${projectDir}/.gitrevision") } test { diff --git a/client-runtime/build.gradle b/client-runtime/build.gradle index f5b95fb92b21..6e4b77b891f2 100644 --- a/client-runtime/build.gradle +++ b/client-runtime/build.gradle @@ -78,6 +78,16 @@ test { } } +task versionInfo(type:Exec){ + commandLine 'git rev-parse HEAD'.split() + ext.versionfile = new File("${projectDir}/.gitrevision") + standardOutput = new ByteArrayOutputStream() + + doLast { + versionfile.text = standardOutput.toString() + } +} + javadoc { options.encoding = 'UTF-8' } @@ -87,7 +97,7 @@ task sourcesJar(type: Jar, dependsOn:classes) { from sourceSets.main.allSource } -task javadocJar(type: Jar, dependsOn: javadoc) { +task javadocJar(type: Jar, dependsOn: [javadoc, versionInfo]) { classifier = 'javadoc' from javadoc.destinationDir } @@ -95,6 +105,7 @@ task javadocJar(type: Jar, dependsOn: javadoc) { artifacts { archives sourcesJar archives javadocJar + archives file: file("${projectDir}/.gitrevision") } test { From c1ce2de5c17d2407b46debdf6bd0ca847fddcd3c Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Thu, 3 Mar 2016 15:30:52 -0800 Subject: [PATCH 03/42] Add more info to revision file --- azure-android-client-authentication/build.gradle | 2 +- azure-client-authentication/build.gradle | 2 +- azure-client-runtime/build.gradle | 2 +- client-runtime/build.gradle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/azure-android-client-authentication/build.gradle b/azure-android-client-authentication/build.gradle index 2d491a9d6867..beed64d3e133 100644 --- a/azure-android-client-authentication/build.gradle +++ b/azure-android-client-authentication/build.gradle @@ -91,7 +91,7 @@ task versionInfo(type:Exec){ standardOutput = new ByteArrayOutputStream() doLast { - versionfile.text = standardOutput.toString() + versionfile.text = "Azure/autorest#" + standardOutput.toString() } } diff --git a/azure-client-authentication/build.gradle b/azure-client-authentication/build.gradle index 7bbe92d96dc2..eb10dc273666 100644 --- a/azure-client-authentication/build.gradle +++ b/azure-client-authentication/build.gradle @@ -75,7 +75,7 @@ task versionInfo(type:Exec){ standardOutput = new ByteArrayOutputStream() doLast { - versionfile.text = standardOutput.toString() + versionfile.text = "Azure/autorest#" + standardOutput.toString() } } diff --git a/azure-client-runtime/build.gradle b/azure-client-runtime/build.gradle index 4a4b146d9b47..dcdaddcea285 100644 --- a/azure-client-runtime/build.gradle +++ b/azure-client-runtime/build.gradle @@ -75,7 +75,7 @@ task versionInfo(type:Exec){ standardOutput = new ByteArrayOutputStream() doLast { - versionfile.text = standardOutput.toString() + versionfile.text = "Azure/autorest#" + standardOutput.toString() } } diff --git a/client-runtime/build.gradle b/client-runtime/build.gradle index 6e4b77b891f2..8877d3117848 100644 --- a/client-runtime/build.gradle +++ b/client-runtime/build.gradle @@ -84,7 +84,7 @@ task versionInfo(type:Exec){ standardOutput = new ByteArrayOutputStream() doLast { - versionfile.text = standardOutput.toString() + versionfile.text = "Azure/autorest#" + standardOutput.toString() } } From d44df631e03f3488c48f0cea7a20787791a6e599 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Thu, 3 Mar 2016 18:17:41 -0800 Subject: [PATCH 04/42] Fix credentials test --- .../azure/credentials/UserTokenCredentialsTests.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/azure-client-authentication/src/test/java/com/microsoft/azure/credentials/UserTokenCredentialsTests.java b/azure-client-authentication/src/test/java/com/microsoft/azure/credentials/UserTokenCredentialsTests.java index 25b117460b8f..afce04b56ecd 100644 --- a/azure-client-authentication/src/test/java/com/microsoft/azure/credentials/UserTokenCredentialsTests.java +++ b/azure-client-authentication/src/test/java/com/microsoft/azure/credentials/UserTokenCredentialsTests.java @@ -30,7 +30,7 @@ public class UserTokenCredentialsTests { public void testAcquireToken() throws Exception { credentials.refreshToken(); Assert.assertEquals("token1", credentials.getToken()); - Thread.sleep(1000); + Thread.sleep(1500); Assert.assertEquals("token2", credentials.getToken()); } @@ -62,7 +62,7 @@ private void acquireAccessToken() throws IOException { null, "token1", "refresh", - 0, + 1, null, null, false); @@ -73,7 +73,7 @@ private void acquireAccessTokenFromRefreshToken() throws IOException { null, "token2", "refresh", - 0, + 1, null, null, false); From aa043b79156df29ca6bad331ad5b21376198fc7d Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Tue, 8 Mar 2016 16:02:56 -0800 Subject: [PATCH 05/42] Fix recursive validation --- .../src/main/java/com/microsoft/rest/Validator.java | 2 +- .../src/test/java/com/microsoft/rest/ValidatorTests.java | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/client-runtime/src/main/java/com/microsoft/rest/Validator.java b/client-runtime/src/main/java/com/microsoft/rest/Validator.java index 248e7b490329..1d04bcdf3f2b 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/Validator.java +++ b/client-runtime/src/main/java/com/microsoft/rest/Validator.java @@ -90,7 +90,7 @@ else if (TypeToken.of(Map.class).isAssignableFrom(propertyType)) { Validator.validate(entry.getValue()); } } - else if (parameter.getClass().getDeclaringClass() != propertyType) { + else if (parameter.getClass() != propertyType) { Validator.validate(property); } } catch (IllegalArgumentException ex) { diff --git a/client-runtime/src/test/java/com/microsoft/rest/ValidatorTests.java b/client-runtime/src/test/java/com/microsoft/rest/ValidatorTests.java index 026920c796f5..5120c33df0ce 100644 --- a/client-runtime/src/test/java/com/microsoft/rest/ValidatorTests.java +++ b/client-runtime/src/test/java/com/microsoft/rest/ValidatorTests.java @@ -8,6 +8,8 @@ package com.microsoft.rest; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.node.TextNode; + import org.junit.Assert; import org.joda.time.LocalDate; import org.junit.Test; @@ -130,6 +132,12 @@ public void validateObject() throws Exception { Validator.validate(product); } + @Test + public void validateRecursive() throws Exception { + TextNode textNode = new TextNode("\"\""); + Validator.validate(textNode); + } + public final class IntWrapper { @JsonProperty(required = true) // CHECKSTYLE IGNORE VisibilityModifier FOR NEXT 2 LINES From d75ac2c9a80827c258af17255ebb5325c0ae441a Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Tue, 8 Mar 2016 16:12:17 -0800 Subject: [PATCH 06/42] parameter.getClass() -> parameterType --- client-runtime/src/main/java/com/microsoft/rest/Validator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client-runtime/src/main/java/com/microsoft/rest/Validator.java b/client-runtime/src/main/java/com/microsoft/rest/Validator.java index 1d04bcdf3f2b..51c24722404a 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/Validator.java +++ b/client-runtime/src/main/java/com/microsoft/rest/Validator.java @@ -90,7 +90,7 @@ else if (TypeToken.of(Map.class).isAssignableFrom(propertyType)) { Validator.validate(entry.getValue()); } } - else if (parameter.getClass() != propertyType) { + else if (parameterType != propertyType) { Validator.validate(property); } } catch (IllegalArgumentException ex) { From 97b717469128891bcd320f033629720a47a91f09 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Thu, 10 Mar 2016 18:06:48 -0800 Subject: [PATCH 07/42] Unify resources in runtime --- .../com/microsoft/azure/BaseResource.java | 14 --- .../java/com/microsoft/azure/Resource.java | 109 ++++++++++++++++++ .../java/com/microsoft/azure/SubResource.java | 36 ++++++ 3 files changed, 145 insertions(+), 14 deletions(-) delete mode 100644 azure-client-runtime/src/main/java/com/microsoft/azure/BaseResource.java create mode 100644 azure-client-runtime/src/main/java/com/microsoft/azure/Resource.java create mode 100644 azure-client-runtime/src/main/java/com/microsoft/azure/SubResource.java diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/BaseResource.java b/azure-client-runtime/src/main/java/com/microsoft/azure/BaseResource.java deleted file mode 100644 index 16ef8f472a26..000000000000 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/BaseResource.java +++ /dev/null @@ -1,14 +0,0 @@ -/** - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - * - */ - -package com.microsoft.azure; - -/** - * Defines Azure resource. - */ -public abstract class BaseResource { -} diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/Resource.java b/azure-client-runtime/src/main/java/com/microsoft/azure/Resource.java new file mode 100644 index 000000000000..732035538ef6 --- /dev/null +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/Resource.java @@ -0,0 +1,109 @@ +/** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + */ + +package com.microsoft.azure; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Map; + +/** + * The Resource model. + */ +public class Resource { + /** + * Resource Id. + */ + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + private String id; + + /** + * Resource name. + */ + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + private String name; + + /** + * Resource type. + */ + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + private String type; + + /** + * Resource location. + */ + @JsonProperty(required = true) + private String location; + + /** + * Resource tags. + */ + private Map tags; + + /** + * Get the id value. + * + * @return the id value + */ + public String getId() { + return this.id; + } + + /** + * Get the name value. + * + * @return the name value + */ + public String getName() { + return this.name; + } + + /** + * Get the type value. + * + * @return the type value + */ + public String getType() { + return this.type; + } + + /** + * Get the location value. + * + * @return the location value + */ + public String getLocation() { + return this.location; + } + + /** + * Set the location value. + * + * @param location the location value to set + */ + public void setLocation(String location) { + this.location = location; + } + + /** + * Get the tags value. + * + * @return the tags value + */ + public Map getTags() { + return this.tags; + } + + /** + * Set the tags value. + * + * @param tags the tags value to set + */ + public void setTags(Map tags) { + this.tags = tags; + } +} \ No newline at end of file diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/SubResource.java b/azure-client-runtime/src/main/java/com/microsoft/azure/SubResource.java new file mode 100644 index 000000000000..36ca18ae3665 --- /dev/null +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/SubResource.java @@ -0,0 +1,36 @@ +/** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + */ + +package com.microsoft.azure; + +/** + * The SubResource model. + */ +public class SubResource { + /** + * Resource Id. + */ + private String id; + + /** + * Get the id value. + * + * @return the id value + */ + public String getId() { + return this.id; + } + + /** + * Set the id value. + * + * @param id the id value to set + */ + public void setId(String id) { + this.id = id; + } +} \ No newline at end of file From 5e04616987eb1b2adc56f1aacac98abfacc434ff Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Thu, 10 Mar 2016 18:21:46 -0800 Subject: [PATCH 08/42] Use 1.0.0-SNAPSHOT for new dev phase --- azure-android-client-authentication/build.gradle | 4 ++-- azure-client-authentication/build.gradle | 2 +- azure-client-runtime/build.gradle | 3 +-- client-runtime/build.gradle | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/azure-android-client-authentication/build.gradle b/azure-android-client-authentication/build.gradle index 87cfd02a4c8e..0884db281a5a 100644 --- a/azure-android-client-authentication/build.gradle +++ b/azure-android-client-authentication/build.gradle @@ -8,7 +8,7 @@ buildscript { apply plugin: 'com.android.library' apply plugin: 'maven' -version = '1.0.0-beta1' +version = '1.0.0-SNAPSHOT' android { compileSdkVersion 23 @@ -18,7 +18,7 @@ android { minSdkVersion 15 targetSdkVersion 23 versionCode 1 - versionName "1.0.0-beta1" + versionName "1.0.0-SNAPSHOT" } buildTypes { diff --git a/azure-client-authentication/build.gradle b/azure-client-authentication/build.gradle index 3e6dd5900c54..a04020e1fd37 100644 --- a/azure-client-authentication/build.gradle +++ b/azure-client-authentication/build.gradle @@ -10,7 +10,7 @@ buildscript { apply plugin: 'java' apply plugin: 'checkstyle' -version = '1.0.0-beta1' +version = '1.0.0-SNAPSHOT' checkstyle { configFile = new File("$rootDir/Tools/checkstyle/checkstyle.xml") diff --git a/azure-client-runtime/build.gradle b/azure-client-runtime/build.gradle index 91192c1fd282..3d90bc184cff 100644 --- a/azure-client-runtime/build.gradle +++ b/azure-client-runtime/build.gradle @@ -10,7 +10,7 @@ buildscript { apply plugin: 'java' apply plugin: 'checkstyle' -version = '1.0.0-beta1' +version = '1.0.0-SNAPSHOT' checkstyle { toolVersion = "6.9" @@ -33,7 +33,6 @@ uploadArchives { snapshotRepository(url: "ftp://waws-prod-bay-005.ftp.azurewebsites.windows.net/site/wwwroot/") { authentication(userName: username, password: password) } - repository(url: "file://$buildDir/repository") pom.setArtifactId "azure-client-runtime" pom.project { name 'Microsoft Azure AutoRest Runtime for Java' diff --git a/client-runtime/build.gradle b/client-runtime/build.gradle index da9b41c14092..a707bf6df58e 100644 --- a/client-runtime/build.gradle +++ b/client-runtime/build.gradle @@ -12,7 +12,7 @@ apply plugin: 'com.github.johnrengelman.shadow' apply plugin: 'checkstyle' group = 'com.microsoft.rest' -version = '1.0.0-beta1' +version = '1.0.0-SNAPSHOT' checkstyle { toolVersion = "6.9" From b1e56191929913c88228ad3ea1d226295f93e56a Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Wed, 16 Mar 2016 12:11:57 -0700 Subject: [PATCH 09/42] A working solution for lazy initiliazed paging --- .../java/com/microsoft/azure/PagedList.java | 245 ++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java new file mode 100644 index 000000000000..72dba3664b8d --- /dev/null +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java @@ -0,0 +1,245 @@ +/** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + */ + +package com.microsoft.azure; + +import java.io.IOException; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.NoSuchElementException; + +import javax.xml.bind.DataBindingException; +import javax.xml.ws.WebServiceException; + +/** + * Defines a page interface in Azure responses. + * + * @param the element type. + */ +public abstract class PagedList implements List { + private List items; + private int pageCount; + private String nextPageLink; + + public PagedList(Page page) { + items = page.getItems(); + nextPageLink = page.getNextPageLink(); + pageCount = 1; + } + + public abstract Page loadPage(String nextPageLink) throws CloudException, IOException; + + public void loadAll() { + while (nextPageLink != null) { + try { + Page nextPage = loadPage(nextPageLink); + nextPageLink = nextPage.getNextPageLink(); + addAll(nextPage.getItems()); + } catch (CloudException e) { + throw new WebServiceException(e.toString(), e); + } catch (IOException e) { + throw new DataBindingException(e.getMessage(), e); + } + } + } + + private class Itr implements Iterator { + Iterator itemsItr; + + public Itr() { + itemsItr = items.iterator(); + } + + @Override + public boolean hasNext() { + return itemsItr.hasNext() || nextPageLink != null; + } + + @Override + public E next() { + if (!itemsItr.hasNext()) { + if (nextPageLink == null) { + throw new NoSuchElementException(); + } else { + try { + loadPage(nextPageLink); + itemsItr = items.iterator(); + } catch (CloudException e) { + throw new WebServiceException(e.toString(), e); + } catch (IOException e) { + throw new DataBindingException(e.getMessage(), e); + } + } + } + return itemsItr.next(); + } + + @Override + public void remove() { + itemsItr.remove(); + } + } + + private class ListItr extends Itr implements ListIterator { + ListIterator itemsListItr; + + public ListItr(int index) { + itemsListItr = items.listIterator(index); + } + + @Override + public boolean hasPrevious() { + return itemsListItr.hasPrevious(); + } + + @Override + public E previous() { + return itemsListItr.previous(); + } + + @Override + public int nextIndex() { + return itemsListItr.nextIndex(); + } + + @Override + public int previousIndex() { + return itemsListItr.previousIndex(); + } + + @Override + public void set(E e) { + itemsListItr.set(e); + } + + @Override + public void add(E e) { + itemsListItr.add(e); + } + } + + @Override + public int size() { + loadAll(); + return items.size(); + } + + @Override + public boolean isEmpty() { + return items.isEmpty() && nextPageLink == null; + } + + @Override + public boolean contains(Object o) { + loadAll(); + return items.contains(o); + } + + @Override + public Iterator iterator() { + return new Itr(); + } + + @Override + public Object[] toArray() { + loadAll(); + return items.toArray(); + } + + @Override + public T[] toArray(T[] a) { + loadAll(); + return items.toArray(a); + } + + @Override + public boolean add(E e) { + return items.add(e); + } + + @Override + public boolean remove(Object o) { + return items.remove(o); + } + + @Override + public boolean containsAll(Collection c) { + return items.containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + return items.addAll(c); + } + + @Override + public boolean addAll(int index, Collection c) { + return items.addAll(index, c); + } + + @Override + public boolean removeAll(Collection c) { + return items.removeAll(c); + } + + @Override + public boolean retainAll(Collection c) { + return items.retainAll(c); + } + + @Override + public void clear() { + items.clear(); + } + + @Override + public E get(int index) { + return items.get(index); + } + + @Override + public E set(int index, E element) { + return items.set(index, element); + } + + @Override + public void add(int index, E element) { + items.add(index, element); + } + + @Override + public E remove(int index) { + return items.remove(index); + } + + @Override + public int indexOf(Object o) { + return items.indexOf(o); + } + + @Override + public int lastIndexOf(Object o) { + return items.lastIndexOf(o); + } + + @Override + public ListIterator listIterator() { + return new ListItr(0); + } + + @Override + public ListIterator listIterator(int index) { + return new ListItr(index); + } + + @Override + public List subList(int fromIndex, int toIndex) { + return items.subList(fromIndex, toIndex); + } +} From 6fc1dd986715f8f1df8ed6e8b60582598f81dfeb Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Wed, 16 Mar 2016 15:08:35 -0700 Subject: [PATCH 10/42] Add Javadoc and cleanup --- .../java/com/microsoft/azure/PagedList.java | 49 ++++++++++++++++--- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java index 72dba3664b8d..a300ff6a3e2a 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java @@ -18,23 +18,40 @@ import javax.xml.ws.WebServiceException; /** - * Defines a page interface in Azure responses. + * Defines a list response from a paging operation. The pages are + * lazy initialized when an instance of this class is iterated. * * @param the element type. */ public abstract class PagedList implements List { + /** The actual items in the list. */ private List items; - private int pageCount; + /** Stores the link to get the next page of items. */ private String nextPageLink; + /** + * Creates an instance of PagedList from a {@link Page} response. + * + * @param page the {@link Page} object. + */ public PagedList(Page page) { items = page.getItems(); nextPageLink = page.getNextPageLink(); - pageCount = 1; } + /** + * Override this method to load the next page of items from a next page link. + * + * @param nextPageLink the link to get the next page of items. + * @return the {@link Page} object storing a page of items and a link to the next page. + * @throws CloudException thrown if an error is raised from Azure. + * @throws IOException thrown if there's any failure in deserialization. + */ public abstract Page loadPage(String nextPageLink) throws CloudException, IOException; + /** + * Keep loading the next page from the next page link until all items are loaded. + */ public void loadAll() { while (nextPageLink != null) { try { @@ -49,9 +66,16 @@ public void loadAll() { } } + /** + * The implementation of {@link Iterator} for PagedList. + */ private class Itr implements Iterator { - Iterator itemsItr; + /** The iterator for the actual list of items. */ + private Iterator itemsItr; + /** + * Creates an instance of the iterator. + */ public Itr() { itemsItr = items.iterator(); } @@ -68,7 +92,9 @@ public E next() { throw new NoSuchElementException(); } else { try { - loadPage(nextPageLink); + Page nextPage = loadPage(nextPageLink); + nextPageLink = nextPage.getNextPageLink(); + addAll(nextPage.getItems()); itemsItr = items.iterator(); } catch (CloudException e) { throw new WebServiceException(e.toString(), e); @@ -86,9 +112,18 @@ public void remove() { } } + /** + * The implementation of {@link ListIterator} for PagedList. + */ private class ListItr extends Itr implements ListIterator { - ListIterator itemsListItr; - + /** The list iterator for the actual list of items. */ + private ListIterator itemsListItr; + + /** + * Creates an instance of the ListIterator. + * + * @param index the position in the list to start. + */ public ListItr(int index) { itemsListItr = items.listIterator(index); } From 31794efeaf56a1fa357eb8b45c44ff3bb340b3bd Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Wed, 16 Mar 2016 15:33:44 -0700 Subject: [PATCH 11/42] Add lazy behavior in get() --- .../src/main/java/com/microsoft/azure/PagedList.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java index a300ff6a3e2a..cdd38a5ca3a1 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java @@ -235,6 +235,17 @@ public void clear() { @Override public E get(int index) { + while (index >= items.size() && nextPageLink != null) { + try { + Page nextPage = loadPage(nextPageLink); + nextPageLink = nextPage.getNextPageLink(); + addAll(nextPage.getItems()); + } catch (CloudException e) { + throw new WebServiceException(e.toString(), e); + } catch (IOException e) { + throw new DataBindingException(e.getMessage(), e); + } + } return items.get(index); } From f4307d2b61aaa6ac2ab956b0f119acbe9ba59c5a Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Thu, 17 Mar 2016 11:30:29 -0700 Subject: [PATCH 12/42] Fix iterator and add tests for PagedList --- .../java/com/microsoft/azure/PagedList.java | 46 ++++------ .../com/microsoft/azure/PagedListTests.java | 91 +++++++++++++++++++ 2 files changed, 107 insertions(+), 30 deletions(-) create mode 100644 azure-client-runtime/src/test/java/com/microsoft/azure/PagedListTests.java diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java index cdd38a5ca3a1..a2b9b67933aa 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java @@ -67,35 +67,38 @@ public void loadAll() { } /** - * The implementation of {@link Iterator} for PagedList. + * The implementation of {@link ListIterator} for PagedList. */ - private class Itr implements Iterator { - /** The iterator for the actual list of items. */ - private Iterator itemsItr; + private class ListItr implements ListIterator { + /** The list iterator for the actual list of items. */ + private ListIterator itemsListItr; /** - * Creates an instance of the iterator. + * Creates an instance of the ListIterator. + * + * @param index the position in the list to start. */ - public Itr() { - itemsItr = items.iterator(); + public ListItr(int index) { + itemsListItr = items.listIterator(index); } @Override public boolean hasNext() { - return itemsItr.hasNext() || nextPageLink != null; + return itemsListItr.hasNext() || nextPageLink != null; } @Override public E next() { - if (!itemsItr.hasNext()) { + if (!itemsListItr.hasNext()) { if (nextPageLink == null) { throw new NoSuchElementException(); } else { try { Page nextPage = loadPage(nextPageLink); nextPageLink = nextPage.getNextPageLink(); + int size = items.size(); addAll(nextPage.getItems()); - itemsItr = items.iterator(); + itemsListItr = items.listIterator(size); } catch (CloudException e) { throw new WebServiceException(e.toString(), e); } catch (IOException e) { @@ -103,29 +106,12 @@ public E next() { } } } - return itemsItr.next(); + return itemsListItr.next(); } @Override public void remove() { - itemsItr.remove(); - } - } - - /** - * The implementation of {@link ListIterator} for PagedList. - */ - private class ListItr extends Itr implements ListIterator { - /** The list iterator for the actual list of items. */ - private ListIterator itemsListItr; - - /** - * Creates an instance of the ListIterator. - * - * @param index the position in the list to start. - */ - public ListItr(int index) { - itemsListItr = items.listIterator(index); + itemsListItr.remove(); } @Override @@ -178,7 +164,7 @@ public boolean contains(Object o) { @Override public Iterator iterator() { - return new Itr(); + return new ListItr(0); } @Override diff --git a/azure-client-runtime/src/test/java/com/microsoft/azure/PagedListTests.java b/azure-client-runtime/src/test/java/com/microsoft/azure/PagedListTests.java new file mode 100644 index 000000000000..6ddc0c61ea4a --- /dev/null +++ b/azure-client-runtime/src/test/java/com/microsoft/azure/PagedListTests.java @@ -0,0 +1,91 @@ +/** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + */ + +package com.microsoft.azure; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class PagedListTests { + private PagedList list; + + @Before + public void setupList() { + list = new PagedList(new TestPage(0, 20)) { + @Override + public Page loadPage(String nextPageLink) throws CloudException, IOException { + int pageNum = Integer.parseInt(nextPageLink); + return new TestPage(pageNum, 20); + } + }; + } + + @Test + public void sizeTest() { + Assert.assertEquals(20, list.size()); + } + + @Test + public void getTest() { + Assert.assertEquals(15, (int) list.get(15)); + } + + @Test + public void iterateTest() { + int j = 0; + for (int i : list) { + Assert.assertEquals(i, j++); + } + } + + @Test + public void removeTest() { + Integer i = list.get(10); + list.remove(10); + Assert.assertEquals(19, list.size()); + Assert.assertEquals(19, (int) list.get(18)); + } + + @Test + public void addTest() { + Integer i = list.get(10); + list.add(100); + Assert.assertEquals(21, list.size()); + Assert.assertEquals(100, (int) list.get(11)); + Assert.assertEquals(19, (int) list.get(20)); + } + + public static class TestPage implements Page { + private int page; + private int max; + + public TestPage(int page, int max) { + this.page = page; + this.max = max; + } + + @Override + public String getNextPageLink() { + if (page + 1 == max) { + return null; + } + return Integer.toString(page + 1); + } + + @Override + public List getItems() { + List items = new ArrayList<>(); + items.add(page); + return items; + } + } +} From 689ff03d80f8bbe03bb27e85baf2dabf18ac4695 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Fri, 18 Mar 2016 17:35:46 -0700 Subject: [PATCH 13/42] Add more laziness to PagedList --- .../java/com/microsoft/azure/PagedList.java | 96 ++++++++++++------- .../com/microsoft/azure/PagedListTests.java | 38 +++++++- 2 files changed, 96 insertions(+), 38 deletions(-) diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java index a2b9b67933aa..5f1676ff2b68 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java @@ -47,22 +47,31 @@ public PagedList(Page page) { * @throws CloudException thrown if an error is raised from Azure. * @throws IOException thrown if there's any failure in deserialization. */ - public abstract Page loadPage(String nextPageLink) throws CloudException, IOException; + public abstract Page nextPage(String nextPageLink) throws CloudException, IOException; + + public boolean hasNextPage() { + return this.nextPageLink != null; + } + + public void loadNextPage() { + try { + Page nextPage = nextPage(this.nextPageLink); + this.nextPageLink = nextPage.getNextPageLink(); + this.items.addAll(nextPage.getItems()); + } catch (CloudException e) { + throw new WebServiceException(e.toString(), e); + } catch (IOException e) { + throw new DataBindingException(e.getMessage(), e); + } + + } /** * Keep loading the next page from the next page link until all items are loaded. */ public void loadAll() { - while (nextPageLink != null) { - try { - Page nextPage = loadPage(nextPageLink); - nextPageLink = nextPage.getNextPageLink(); - addAll(nextPage.getItems()); - } catch (CloudException e) { - throw new WebServiceException(e.toString(), e); - } catch (IOException e) { - throw new DataBindingException(e.getMessage(), e); - } + while (hasNextPage()) { + loadNextPage(); } } @@ -90,20 +99,12 @@ public boolean hasNext() { @Override public E next() { if (!itemsListItr.hasNext()) { - if (nextPageLink == null) { + if (!hasNextPage()) { throw new NoSuchElementException(); } else { - try { - Page nextPage = loadPage(nextPageLink); - nextPageLink = nextPage.getNextPageLink(); - int size = items.size(); - addAll(nextPage.getItems()); - itemsListItr = items.listIterator(size); - } catch (CloudException e) { - throw new WebServiceException(e.toString(), e); - } catch (IOException e) { - throw new DataBindingException(e.getMessage(), e); - } + int size = items.size(); + loadNextPage(); + itemsListItr = items.listIterator(size); } } return itemsListItr.next(); @@ -158,8 +159,7 @@ public boolean isEmpty() { @Override public boolean contains(Object o) { - loadAll(); - return items.contains(o); + return indexOf(o) >= 0; } @Override @@ -191,7 +191,12 @@ public boolean remove(Object o) { @Override public boolean containsAll(Collection c) { - return items.containsAll(c); + for (Object e : c) { + if (!contains(e)) { + return false; + } + } + return true; } @Override @@ -221,16 +226,8 @@ public void clear() { @Override public E get(int index) { - while (index >= items.size() && nextPageLink != null) { - try { - Page nextPage = loadPage(nextPageLink); - nextPageLink = nextPage.getNextPageLink(); - addAll(nextPage.getItems()); - } catch (CloudException e) { - throw new WebServiceException(e.toString(), e); - } catch (IOException e) { - throw new DataBindingException(e.getMessage(), e); - } + while (index >= items.size() && hasNextPage()) { + loadNextPage(); } return items.get(index); } @@ -252,11 +249,28 @@ public E remove(int index) { @Override public int indexOf(Object o) { - return items.indexOf(o); + int index = 0; + if (o == null) { + for (E item : this) { + if (item == null) { + return index; + } + ++index; + } + } else { + for (E item : this) { + if (item == o) { + return index; + } + ++index; + } + } + return -1; } @Override public int lastIndexOf(Object o) { + loadAll(); return items.lastIndexOf(o); } @@ -267,11 +281,19 @@ public ListIterator listIterator() { @Override public ListIterator listIterator(int index) { + while (index >= items.size() && hasNextPage()) { + loadNextPage(); + } return new ListItr(index); } @Override public List subList(int fromIndex, int toIndex) { + while ((fromIndex >= items.size() + || toIndex >= items.size()) + && hasNextPage()) { + loadNextPage(); + } return items.subList(fromIndex, toIndex); } } diff --git a/azure-client-runtime/src/test/java/com/microsoft/azure/PagedListTests.java b/azure-client-runtime/src/test/java/com/microsoft/azure/PagedListTests.java index 6ddc0c61ea4a..b82c8d062878 100644 --- a/azure-client-runtime/src/test/java/com/microsoft/azure/PagedListTests.java +++ b/azure-client-runtime/src/test/java/com/microsoft/azure/PagedListTests.java @@ -13,6 +13,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; public class PagedListTests { @@ -22,7 +23,7 @@ public class PagedListTests { public void setupList() { list = new PagedList(new TestPage(0, 20)) { @Override - public Page loadPage(String nextPageLink) throws CloudException, IOException { + public Page nextPage(String nextPageLink) throws CloudException, IOException { int pageNum = Integer.parseInt(nextPageLink); return new TestPage(pageNum, 20); } @@ -64,6 +65,41 @@ public void addTest() { Assert.assertEquals(19, (int) list.get(20)); } + @Test + public void containsTest() { + Assert.assertTrue(list.contains(0)); + Assert.assertTrue(list.contains(3)); + Assert.assertTrue(list.contains(19)); + Assert.assertFalse(list.contains(20)); + } + + @Test + public void containsAllTest() { + List subList = new ArrayList<>(); + subList.addAll(Arrays.asList(0, 3, 19)); + Assert.assertTrue(list.containsAll(subList)); + subList.add(20); + Assert.assertFalse(list.containsAll(subList)); + } + + @Test + public void subListTest() { + List subList = list.subList(5, 15); + Assert.assertEquals(10, subList.size()); + Assert.assertTrue(list.containsAll(subList)); + Assert.assertEquals(7, (int) subList.get(2)); + } + + @Test + public void testIndexOf() { + Assert.assertEquals(15, list.indexOf(15)); + } + + @Test + public void testLastIndexOf() { + Assert.assertEquals(15, list.lastIndexOf(15)); + } + public static class TestPage implements Page { private int page; private int max; From d1d64d73ea7e5a0214f71141b2816066edc4cf0d Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Fri, 18 Mar 2016 17:43:00 -0700 Subject: [PATCH 14/42] Add missing javadoc --- .../src/main/java/com/microsoft/azure/PagedList.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java index 5f1676ff2b68..8c42851d4e85 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java @@ -49,10 +49,19 @@ public PagedList(Page page) { */ public abstract Page nextPage(String nextPageLink) throws CloudException, IOException; + /** + * If there are more pages available. + * + * @return true if there are more pages to load. False otherwise. + */ public boolean hasNextPage() { return this.nextPageLink != null; } + /** + * Loads a page from next page link. + * The exceptions are wrapped into Java Runtime exceptions. + */ public void loadNextPage() { try { Page nextPage = nextPage(this.nextPageLink); From 6ac47d9b87b7fb99749c2f9ed01d2b381d804c57 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Fri, 18 Mar 2016 13:23:09 -0700 Subject: [PATCH 15/42] Manually change byte[] to File --- client-runtime/build.gradle | 3 ++- .../main/java/com/microsoft/rest/ServiceResponseBuilder.java | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/client-runtime/build.gradle b/client-runtime/build.gradle index a707bf6df58e..d7986885d788 100644 --- a/client-runtime/build.gradle +++ b/client-runtime/build.gradle @@ -24,7 +24,8 @@ checkstyle { dependencies { compile 'com.google.guava:guava:18.0' compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4' - compile 'com.squareup.okhttp3:okhttp:3.1.2' + compile 'com.squareup.okhttp3:okhttp:3.2.0' + compile 'com.squareup.okio:okio:1.7.0-SNAPSHOT' compile 'com.squareup.okhttp3:logging-interceptor:3.1.1' compile 'com.squareup.okhttp3:okhttp-urlconnection:3.1.1' compile 'com.squareup.retrofit2:converter-jackson:2.0.0-beta4' diff --git a/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java b/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java index 96ed7cd0b413..a7b428382aa6 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java +++ b/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java @@ -270,7 +270,9 @@ protected Object buildBody(int statusCode, ResponseBody responseBody) throws IOE } // Return raw response if InputStream is the target type else if (type == InputStream.class) { - return responseBody.byteStream(); + InputStream stream = responseBody.byteStream(); + responseBody.close(); + return stream; } // Deserialize else { From 4bbb4a516fa9f53868cfd19bb76841ff93beb1fa Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Fri, 18 Mar 2016 14:11:38 -0700 Subject: [PATCH 16/42] add close() to response bodies --- .../main/java/com/microsoft/azure/AzureClient.java | 14 ++++++++++++++ .../java/com/microsoft/azure/PollingState.java | 3 +++ .../com/microsoft/rest/ServiceResponseBuilder.java | 4 ++++ .../com/microsoft/rest/retry/RetryHandler.java | 1 + 4 files changed, 22 insertions(+) diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java b/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java index 2ab41868f4e5..eea314cb5fda 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java @@ -99,6 +99,7 @@ public ServiceResponse getPutOrPatchResult(Response respons exception.setResponse(response); if (responseBody != null) { exception.setBody((CloudError) mapperAdapter.deserialize(responseBody.string(), CloudError.class)); + responseBody.close(); } throw exception; } @@ -108,6 +109,7 @@ public ServiceResponse getPutOrPatchResult(Response respons // Check provisioning state while (!AzureAsyncOperation.getTerminalStatuses().contains(pollingState.getStatus())) { + System.err.println(pollingState.getStatus()); Thread.sleep(pollingState.getDelayInMilliseconds()); if (pollingState.getAzureAsyncOperationHeaderLink() != null @@ -186,6 +188,7 @@ public AsyncPollingTask getPutOrPatchResultAsync(Response r try { if (responseBody != null) { exception.setBody((CloudError) mapperAdapter.deserialize(responseBody.string(), CloudError.class)); + responseBody.close(); } } catch (Exception e) { /* ignore serialization errors on top of service errors */ } callback.failure(exception); @@ -272,6 +275,7 @@ public ServiceResponse getPostOrDeleteResult(Response respo exception.setResponse(response); if (responseBody != null) { exception.setBody((CloudError) mapperAdapter.deserialize(responseBody.string(), CloudError.class)); + responseBody.close(); } throw exception; } @@ -281,6 +285,7 @@ public ServiceResponse getPostOrDeleteResult(Response respo // Check provisioning state while (!AzureAsyncOperation.getTerminalStatuses().contains(pollingState.getStatus())) { Thread.sleep(pollingState.getDelayInMilliseconds()); + System.err.println(pollingState.getStatus()); if (pollingState.getAzureAsyncOperationHeaderLink() != null && !pollingState.getAzureAsyncOperationHeaderLink().isEmpty()) { @@ -358,6 +363,7 @@ public AsyncPollingTask getPostOrDeleteResultAsync(Response try { if (responseBody != null) { exception.setBody((CloudError) mapperAdapter.deserialize(responseBody.string(), CloudError.class)); + responseBody.close(); } } catch (Exception e) { /* ignore serialization errors on top of service errors */ } callback.failure(exception); @@ -581,6 +587,7 @@ private void updateStateFromAzureAsyncOperationHeader(PollingState pollin AzureAsyncOperation body = null; if (response.body() != null) { body = mapperAdapter.deserialize(response.body().string(), AzureAsyncOperation.class); + response.body().close(); } if (body == null || body.getStatus() == null) { @@ -588,6 +595,7 @@ private void updateStateFromAzureAsyncOperationHeader(PollingState pollin exception.setResponse(response); if (response.errorBody() != null) { exception.setBody((CloudError) mapperAdapter.deserialize(response.errorBody().string(), CloudError.class)); + response.errorBody().close(); } throw exception; } @@ -619,12 +627,14 @@ public void success(ServiceResponse result) { AzureAsyncOperation body = null; if (result.getBody() != null) { body = mapperAdapter.deserialize(result.getBody().string(), AzureAsyncOperation.class); + result.getBody().close(); } if (body == null || body.getStatus() == null) { CloudException exception = new CloudException("no body"); exception.setResponse(result.getResponse()); if (result.getResponse().errorBody() != null) { exception.setBody((CloudError) mapperAdapter.deserialize(result.getResponse().errorBody().string(), CloudError.class)); + result.getResponse().errorBody().close(); } failure(exception); } else { @@ -664,8 +674,10 @@ private Response poll(String url) throws CloudException, IOExcepti exception.setResponse(response); if (response.body() != null) { exception.setBody((CloudError) mapperAdapter.deserialize(response.body().string(), CloudError.class)); + response.body().close(); } else if (response.errorBody() != null) { exception.setBody((CloudError) mapperAdapter.deserialize(response.errorBody().string(), CloudError.class)); + response.errorBody().close(); } throw exception; } @@ -704,8 +716,10 @@ public void onResponse(Call call, Response response) exception.setResponse(response); if (response.body() != null) { exception.setBody((CloudError) mapperAdapter.deserialize(response.body().string(), CloudError.class)); + response.body().close(); } else if (response.errorBody() != null) { exception.setBody((CloudError) mapperAdapter.deserialize(response.errorBody().string(), CloudError.class)); + response.errorBody().close(); } callback.failure(exception); return; diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/PollingState.java b/azure-client-runtime/src/main/java/com/microsoft/azure/PollingState.java index aadbdb1c8d1c..50255ba60089 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/PollingState.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/PollingState.java @@ -60,6 +60,7 @@ public PollingState(Response response, Integer retryTimeout, Type PollingResource resource = null; if (response.body() != null) { responseContent = response.body().string(); + response.body().close(); } if (responseContent != null && !responseContent.isEmpty()) { this.resource = mapperAdapter.deserialize(responseContent, resourceType); @@ -95,6 +96,7 @@ public void updateFromResponseOnPutPatch(Response response) throws String responseContent = null; if (response.body() != null) { responseContent = response.body().string(); + response.body().close(); } if (responseContent == null || responseContent.isEmpty()) { @@ -130,6 +132,7 @@ public void updateFromResponseOnDeletePost(Response response) thro String responseContent = null; if (response.body() != null) { responseContent = response.body().string(); + response.body().close(); } this.setResource(mapperAdapter.deserialize(responseContent, resourceType)); setStatus(AzureAsyncOperation.SUCCESS_STATUS); diff --git a/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java b/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java index a7b428382aa6..6a9e302c8391 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java +++ b/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java @@ -181,6 +181,7 @@ public ServiceResponse buildEmpty(Response response) throws E, IOExcept try { E exception = (E) exceptionType.getConstructor(String.class).newInstance("Invalid status code " + statusCode); exceptionType.getMethod("setResponse", response.getClass()).invoke(exception, response); + response.errorBody().close(); throw exception; } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { throw new IOException("Invalid status code " + statusCode + ", but an instance of " + exceptionType.getCanonicalName() @@ -213,6 +214,7 @@ public ServiceResponseWithHeaders buildWithHeaders(Respons THeader headers = mapperAdapter.deserialize( mapperAdapter.serialize(response.headers()), headerType); + response.errorBody().close(); return new ServiceResponseWithHeaders<>(bodyResponse.getBody(), headers, bodyResponse.getResponse()); } @@ -238,6 +240,7 @@ public ServiceResponseWithHeaders buildEmptyWithHeaders(Re THeader headers = mapperAdapter.deserialize( mapperAdapter.serialize(response.headers()), headerType); + response.errorBody().close(); return new ServiceResponseWithHeaders<>(headers, bodyResponse.getHeadResponse()); } @@ -277,6 +280,7 @@ else if (type == InputStream.class) { // Deserialize else { String responseContent = responseBody.string(); + responseBody.close(); if (responseContent.length() <= 0) { return null; } diff --git a/client-runtime/src/main/java/com/microsoft/rest/retry/RetryHandler.java b/client-runtime/src/main/java/com/microsoft/rest/retry/RetryHandler.java index e78704248c93..e56c061de6a0 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/retry/RetryHandler.java +++ b/client-runtime/src/main/java/com/microsoft/rest/retry/RetryHandler.java @@ -67,6 +67,7 @@ public Response intercept(Chain chain) throws IOException { // try the request Response response = chain.proceed(request); + response.body().close(); int tryCount = 0; while (retryStrategy.shouldRetry(tryCount, response)) { From 9946a019ed13f7224d26aceb7455e15dd7528505 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Fri, 18 Mar 2016 16:08:24 -0700 Subject: [PATCH 17/42] Fix close() in retry handler --- .../src/main/java/com/microsoft/rest/retry/RetryHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client-runtime/src/main/java/com/microsoft/rest/retry/RetryHandler.java b/client-runtime/src/main/java/com/microsoft/rest/retry/RetryHandler.java index e56c061de6a0..649a769af99f 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/retry/RetryHandler.java +++ b/client-runtime/src/main/java/com/microsoft/rest/retry/RetryHandler.java @@ -67,11 +67,11 @@ public Response intercept(Chain chain) throws IOException { // try the request Response response = chain.proceed(request); - response.body().close(); int tryCount = 0; while (retryStrategy.shouldRetry(tryCount, response)) { tryCount++; + response.body().close(); // retry the request response = chain.proceed(request); } From 639f69ec456829d6e2148b5e7493a4ab130d714c Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Sat, 19 Mar 2016 22:00:43 -0700 Subject: [PATCH 18/42] Change file upload type to java.io.File --- client-runtime/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client-runtime/build.gradle b/client-runtime/build.gradle index d7986885d788..47cbaf08c639 100644 --- a/client-runtime/build.gradle +++ b/client-runtime/build.gradle @@ -25,7 +25,7 @@ dependencies { compile 'com.google.guava:guava:18.0' compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4' compile 'com.squareup.okhttp3:okhttp:3.2.0' - compile 'com.squareup.okio:okio:1.7.0-SNAPSHOT' + compile ('com.squareup.okio:okio:1.7.0-SNAPSHOT') { changing = true } compile 'com.squareup.okhttp3:logging-interceptor:3.1.1' compile 'com.squareup.okhttp3:okhttp-urlconnection:3.1.1' compile 'com.squareup.retrofit2:converter-jackson:2.0.0-beta4' From 4d078448058143dcf7fa0543a61c40ba5f080e9f Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Sat, 19 Mar 2016 22:03:57 -0700 Subject: [PATCH 19/42] Remove system.err --- .../src/main/java/com/microsoft/azure/AzureClient.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java b/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java index eea314cb5fda..77c8c6c0e48c 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java @@ -109,7 +109,6 @@ public ServiceResponse getPutOrPatchResult(Response respons // Check provisioning state while (!AzureAsyncOperation.getTerminalStatuses().contains(pollingState.getStatus())) { - System.err.println(pollingState.getStatus()); Thread.sleep(pollingState.getDelayInMilliseconds()); if (pollingState.getAzureAsyncOperationHeaderLink() != null @@ -285,7 +284,6 @@ public ServiceResponse getPostOrDeleteResult(Response respo // Check provisioning state while (!AzureAsyncOperation.getTerminalStatuses().contains(pollingState.getStatus())) { Thread.sleep(pollingState.getDelayInMilliseconds()); - System.err.println(pollingState.getStatus()); if (pollingState.getAzureAsyncOperationHeaderLink() != null && !pollingState.getAzureAsyncOperationHeaderLink().isEmpty()) { From 26c3d3ac49ace3acabfa34ac51e1c182bf426b02 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Sat, 19 Mar 2016 22:40:15 -0700 Subject: [PATCH 20/42] Fix NPE --- .../main/java/com/microsoft/rest/ServiceResponseBuilder.java | 2 -- .../src/main/java/com/microsoft/rest/retry/RetryHandler.java | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java b/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java index 6a9e302c8391..2915ae5e44b8 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java +++ b/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java @@ -214,7 +214,6 @@ public ServiceResponseWithHeaders buildWithHeaders(Respons THeader headers = mapperAdapter.deserialize( mapperAdapter.serialize(response.headers()), headerType); - response.errorBody().close(); return new ServiceResponseWithHeaders<>(bodyResponse.getBody(), headers, bodyResponse.getResponse()); } @@ -240,7 +239,6 @@ public ServiceResponseWithHeaders buildEmptyWithHeaders(Re THeader headers = mapperAdapter.deserialize( mapperAdapter.serialize(response.headers()), headerType); - response.errorBody().close(); return new ServiceResponseWithHeaders<>(headers, bodyResponse.getHeadResponse()); } diff --git a/client-runtime/src/main/java/com/microsoft/rest/retry/RetryHandler.java b/client-runtime/src/main/java/com/microsoft/rest/retry/RetryHandler.java index 649a769af99f..586673e513bd 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/retry/RetryHandler.java +++ b/client-runtime/src/main/java/com/microsoft/rest/retry/RetryHandler.java @@ -71,7 +71,9 @@ public Response intercept(Chain chain) throws IOException { int tryCount = 0; while (retryStrategy.shouldRetry(tryCount, response)) { tryCount++; - response.body().close(); + if (response.body() != null) { + response.body().close(); + } // retry the request response = chain.proceed(request); } From 589df22dd4e3105d8d02bd0684f365784904ba49 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Mon, 21 Mar 2016 18:18:33 -0700 Subject: [PATCH 21/42] Add download streaming support --- client-runtime/build.gradle | 1 + .../src/main/java/com/microsoft/rest/ServiceResponseBuilder.java | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/client-runtime/build.gradle b/client-runtime/build.gradle index 47cbaf08c639..b1bea55897fb 100644 --- a/client-runtime/build.gradle +++ b/client-runtime/build.gradle @@ -32,6 +32,7 @@ dependencies { compile 'com.fasterxml.jackson.core:jackson-databind:2.7.1' compile 'com.fasterxml.jackson.datatype:jackson-datatype-joda:2.7.1' compile 'org.apache.commons:commons-lang3:3.4' + compile 'commons-io:commons-io:2.4' testCompile 'junit:junit:4.12' testCompile 'junit:junit-dep:4.11' deployerJars "org.apache.maven.wagon:wagon-ftp:2.10" diff --git a/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java b/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java index 2915ae5e44b8..e94a166cd176 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java +++ b/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java @@ -272,7 +272,6 @@ protected Object buildBody(int statusCode, ResponseBody responseBody) throws IOE // Return raw response if InputStream is the target type else if (type == InputStream.class) { InputStream stream = responseBody.byteStream(); - responseBody.close(); return stream; } // Deserialize From a718459696152aa07480469bde117c9c93ef9fdd Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Mon, 21 Mar 2016 18:20:26 -0700 Subject: [PATCH 22/42] commons-io was for debugging --- client-runtime/build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/client-runtime/build.gradle b/client-runtime/build.gradle index b1bea55897fb..47cbaf08c639 100644 --- a/client-runtime/build.gradle +++ b/client-runtime/build.gradle @@ -32,7 +32,6 @@ dependencies { compile 'com.fasterxml.jackson.core:jackson-databind:2.7.1' compile 'com.fasterxml.jackson.datatype:jackson-datatype-joda:2.7.1' compile 'org.apache.commons:commons-lang3:3.4' - compile 'commons-io:commons-io:2.4' testCompile 'junit:junit:4.12' testCompile 'junit:junit-dep:4.11' deployerJars "org.apache.maven.wagon:wagon-ftp:2.10" From d9c5f885471633dec9962301bcc0e945085a34e7 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Mon, 21 Mar 2016 10:57:00 -0700 Subject: [PATCH 23/42] #742: Hide DateTimeRfc1123 --- .../src/main/java/com/microsoft/rest/DateTimeRfc1123.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client-runtime/src/main/java/com/microsoft/rest/DateTimeRfc1123.java b/client-runtime/src/main/java/com/microsoft/rest/DateTimeRfc1123.java index 4e61173fd711..d4e8078cb717 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/DateTimeRfc1123.java +++ b/client-runtime/src/main/java/com/microsoft/rest/DateTimeRfc1123.java @@ -48,6 +48,9 @@ public DateTimeRfc1123(String formattedString) { * @return The underlying DateTime. */ public DateTime getDateTime() { + if (this.dateTime == null) { + return null; + } return this.dateTime; } From 84c75d9b3d83cbc9df258050fd0f38b67ff0d724 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Mon, 21 Mar 2016 17:17:15 -0700 Subject: [PATCH 24/42] #742 Hide RFC1123 on parameters --- .../com/microsoft/rest/serializer/JacksonMapperAdapter.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client-runtime/src/main/java/com/microsoft/rest/serializer/JacksonMapperAdapter.java b/client-runtime/src/main/java/com/microsoft/rest/serializer/JacksonMapperAdapter.java index 97abf853630b..ae2af3c5f6ac 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/serializer/JacksonMapperAdapter.java +++ b/client-runtime/src/main/java/com/microsoft/rest/serializer/JacksonMapperAdapter.java @@ -7,6 +7,7 @@ package com.microsoft.rest.serializer; +import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; @@ -58,6 +59,10 @@ protected void initializeObjectMapper(ObjectMapper mapper) { .registerModule(DateTimeSerializer.getModule()) .registerModule(DateTimeRfc1123Serializer.getModule()) .registerModule(HeadersSerializer.getModule()); + mapper.setVisibility(mapper.getSerializationConfig().getDefaultVisibilityChecker() + .withFieldVisibility(JsonAutoDetect.Visibility.ANY) + .withSetterVisibility(JsonAutoDetect.Visibility.NONE) + .withGetterVisibility(JsonAutoDetect.Visibility.NONE)); } /** From 7fbb811d8521295c8f03c755fda15e87a83a5505 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Tue, 22 Mar 2016 14:38:16 -0700 Subject: [PATCH 25/42] Fix stream type in input mappings --- .../src/main/java/com/microsoft/azure/PagedList.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java index 8c42851d4e85..e13926390c42 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java @@ -7,6 +7,8 @@ package com.microsoft.azure; +import com.microsoft.rest.AutoRestException; + import java.io.IOException; import java.util.Collection; import java.util.Iterator; @@ -44,10 +46,10 @@ public PagedList(Page page) { * * @param nextPageLink the link to get the next page of items. * @return the {@link Page} object storing a page of items and a link to the next page. - * @throws CloudException thrown if an error is raised from Azure. + * @throws AutoRestException thrown if an error is raised from Azure. * @throws IOException thrown if there's any failure in deserialization. */ - public abstract Page nextPage(String nextPageLink) throws CloudException, IOException; + public abstract Page nextPage(String nextPageLink) throws AutoRestException, IOException; /** * If there are more pages available. @@ -67,7 +69,7 @@ public void loadNextPage() { Page nextPage = nextPage(this.nextPageLink); this.nextPageLink = nextPage.getNextPageLink(); this.items.addAll(nextPage.getItems()); - } catch (CloudException e) { + } catch (AutoRestException e) { throw new WebServiceException(e.toString(), e); } catch (IOException e) { throw new DataBindingException(e.getMessage(), e); From 045fb77efaa21df12045f9ae950d20ce477c1903 Mon Sep 17 00:00:00 2001 From: "Dmitry.Tretyakov" Date: Mon, 28 Mar 2016 17:36:40 +0300 Subject: [PATCH 26/42] Fix status code validation in java client --- .../src/main/java/com/microsoft/azure/AzureClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java b/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java index 77c8c6c0e48c..2f3569fc51c5 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java @@ -355,7 +355,7 @@ public AsyncPollingTask getPostOrDeleteResultAsync(Response } else { responseBody = response.errorBody(); } - if (statusCode != 200 && statusCode != 201 && statusCode != 202) { + if (statusCode != 200 && statusCode != 202 && statusCode != 204) { CloudException exception = new CloudException(statusCode + " is not a valid polling status code"); exception.setResponse(response); try { From 49a0c035afd8879d61bf915cc67cdcd5464e5788 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Tue, 29 Mar 2016 14:37:01 -0700 Subject: [PATCH 27/42] Fix head response with headers --- .../main/java/com/microsoft/rest/ServiceResponseBuilder.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java b/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java index e94a166cd176..1fae7e4e9fe5 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java +++ b/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java @@ -239,7 +239,9 @@ public ServiceResponseWithHeaders buildEmptyWithHeaders(Re THeader headers = mapperAdapter.deserialize( mapperAdapter.serialize(response.headers()), headerType); - return new ServiceResponseWithHeaders<>(headers, bodyResponse.getHeadResponse()); + ServiceResponseWithHeaders serviceResponse = new ServiceResponseWithHeaders<>(headers, bodyResponse.getHeadResponse()); + serviceResponse.setBody(bodyResponse.getBody()); + return serviceResponse; } /** From 711df8324f56803eb0b229d47f6c36660e871fdb Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Thu, 31 Mar 2016 11:41:53 -0700 Subject: [PATCH 28/42] Azure/azure-sdk-for-java#622: Shutdown ADAL auth executors --- .../azure/credentials/ApplicationTokenCredentials.java | 6 +++++- .../microsoft/azure/credentials/UserTokenCredentials.java | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/azure-client-authentication/src/main/java/com/microsoft/azure/credentials/ApplicationTokenCredentials.java b/azure-client-authentication/src/main/java/com/microsoft/azure/credentials/ApplicationTokenCredentials.java index a50faee9cf16..3e995fb06a08 100644 --- a/azure-client-authentication/src/main/java/com/microsoft/azure/credentials/ApplicationTokenCredentials.java +++ b/azure-client-authentication/src/main/java/com/microsoft/azure/credentials/ApplicationTokenCredentials.java @@ -13,6 +13,7 @@ import com.microsoft.rest.credentials.TokenCredentials; import java.io.IOException; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** @@ -103,7 +104,8 @@ public void refreshToken() throws IOException { private void acquireAccessToken() throws IOException { String authorityUrl = this.getEnvironment().getAuthenticationEndpoint() + this.getDomain(); - AuthenticationContext context = new AuthenticationContext(authorityUrl, this.getEnvironment().isValidateAuthority(), Executors.newSingleThreadExecutor()); + ExecutorService executor = Executors.newSingleThreadExecutor(); + AuthenticationContext context = new AuthenticationContext(authorityUrl, this.getEnvironment().isValidateAuthority(), executor); try { authenticationResult = context.acquireToken( this.getEnvironment().getTokenAudience(), @@ -111,6 +113,8 @@ private void acquireAccessToken() throws IOException { null).get(); } catch (Exception e) { throw new IOException(e.getMessage(), e); + } finally { + executor.shutdown(); } } } diff --git a/azure-client-authentication/src/main/java/com/microsoft/azure/credentials/UserTokenCredentials.java b/azure-client-authentication/src/main/java/com/microsoft/azure/credentials/UserTokenCredentials.java index 995f32fabc4a..af02c07507b7 100644 --- a/azure-client-authentication/src/main/java/com/microsoft/azure/credentials/UserTokenCredentials.java +++ b/azure-client-authentication/src/main/java/com/microsoft/azure/credentials/UserTokenCredentials.java @@ -13,6 +13,7 @@ import java.io.IOException; import java.util.Date; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** @@ -146,7 +147,8 @@ private void acquireAccessToken() throws IOException { private void acquireAccessTokenFromRefreshToken() throws IOException { String authorityUrl = this.getEnvironment().getAuthenticationEndpoint() + this.getDomain(); - AuthenticationContext context = new AuthenticationContext(authorityUrl, this.getEnvironment().isValidateAuthority(), Executors.newSingleThreadExecutor()); + ExecutorService executor = Executors.newSingleThreadExecutor(); + AuthenticationContext context = new AuthenticationContext(authorityUrl, this.getEnvironment().isValidateAuthority(), executor); try { authenticationResult = context.acquireTokenByRefreshToken( authenticationResult.getRefreshToken(), @@ -154,6 +156,8 @@ private void acquireAccessTokenFromRefreshToken() throws IOException { null, null).get(); } catch (Exception e) { throw new IOException(e.getMessage(), e); + } finally { + executor.shutdown(); } } } From a6feaf0af271d9cf4fb213d22cdc4db8129f5d41 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Fri, 15 Apr 2016 09:45:37 -0700 Subject: [PATCH 29/42] Okio 1.7.0 --- client-runtime/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client-runtime/build.gradle b/client-runtime/build.gradle index 47cbaf08c639..b734d33608ea 100644 --- a/client-runtime/build.gradle +++ b/client-runtime/build.gradle @@ -25,7 +25,7 @@ dependencies { compile 'com.google.guava:guava:18.0' compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4' compile 'com.squareup.okhttp3:okhttp:3.2.0' - compile ('com.squareup.okio:okio:1.7.0-SNAPSHOT') { changing = true } + compile 'com.squareup.okio:okio:1.7.0' compile 'com.squareup.okhttp3:logging-interceptor:3.1.1' compile 'com.squareup.okhttp3:okhttp-urlconnection:3.1.1' compile 'com.squareup.retrofit2:converter-jackson:2.0.0-beta4' From fc7d9a9575c2f3bdfacc6cd4d3e5a080a238d8e4 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Fri, 1 Apr 2016 11:55:37 -0700 Subject: [PATCH 30/42] Rename AutoRestException to RestException --- azure-android-client-authentication/build.gradle | 2 +- azure-client-authentication/build.gradle | 2 +- azure-client-runtime/build.gradle | 2 +- .../microsoft/azure/AzureServiceResponseBuilder.java | 4 ++-- .../main/java/com/microsoft/azure/CloudException.java | 4 ++-- .../src/main/java/com/microsoft/azure/PagedList.java | 8 ++++---- .../{AutoRestException.java => RestException.java} | 10 +++++----- .../main/java/com/microsoft/rest/ServiceException.java | 2 +- .../com/microsoft/rest/ServiceResponseBuilder.java | 6 +++--- 9 files changed, 20 insertions(+), 20 deletions(-) rename client-runtime/src/main/java/com/microsoft/rest/{AutoRestException.java => RestException.java} (79%) diff --git a/azure-android-client-authentication/build.gradle b/azure-android-client-authentication/build.gradle index 0884db281a5a..1f082a664464 100644 --- a/azure-android-client-authentication/build.gradle +++ b/azure-android-client-authentication/build.gradle @@ -42,7 +42,7 @@ dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.microsoft.aad:adal:1.1.11' - compile 'com.microsoft.rest:client-runtime:1.0.0-beta1' + compile 'com.microsoft.rest:client-runtime:1.0.0-SNAPSHOT' testCompile 'junit:junit:4.12' testCompile 'junit:junit-dep:4.11' deployerJars "org.apache.maven.wagon:wagon-ftp:2.10" diff --git a/azure-client-authentication/build.gradle b/azure-client-authentication/build.gradle index a04020e1fd37..5235b4c23a4d 100644 --- a/azure-client-authentication/build.gradle +++ b/azure-client-authentication/build.gradle @@ -20,7 +20,7 @@ checkstyle { dependencies { compile 'com.microsoft.azure:adal4j:1.1.2' - compile 'com.microsoft.rest:client-runtime:1.0.0-beta1' + compile 'com.microsoft.rest:client-runtime:1.0.0-SNAPSHOT' testCompile 'junit:junit:4.12' testCompile 'junit:junit-dep:4.11' deployerJars "org.apache.maven.wagon:wagon-ftp:2.10" diff --git a/azure-client-runtime/build.gradle b/azure-client-runtime/build.gradle index 3d90bc184cff..dcdaddcea285 100644 --- a/azure-client-runtime/build.gradle +++ b/azure-client-runtime/build.gradle @@ -20,7 +20,7 @@ checkstyle { } dependencies { - compile 'com.microsoft.rest:client-runtime:1.0.0-beta1' + compile 'com.microsoft.rest:client-runtime:1.0.0-SNAPSHOT' testCompile 'junit:junit:4.12' testCompile 'junit:junit-dep:4.11' deployerJars "org.apache.maven.wagon:wagon-ftp:2.10" diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/AzureServiceResponseBuilder.java b/azure-client-runtime/src/main/java/com/microsoft/azure/AzureServiceResponseBuilder.java index f553fd575cc0..7ad369ecc568 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/AzureServiceResponseBuilder.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/AzureServiceResponseBuilder.java @@ -8,7 +8,7 @@ package com.microsoft.azure; import com.google.common.reflect.TypeToken; -import com.microsoft.rest.AutoRestException; +import com.microsoft.rest.RestException; import com.microsoft.rest.ServiceResponse; import com.microsoft.rest.ServiceResponseBuilder; import com.microsoft.rest.serializer.JacksonMapperAdapter; @@ -27,7 +27,7 @@ * @param the return type from caller. * @param the exception to throw in case of error. */ -public class AzureServiceResponseBuilder extends ServiceResponseBuilder { +public class AzureServiceResponseBuilder extends ServiceResponseBuilder { /** * Create a ServiceResponseBuilder instance. * diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/CloudException.java b/azure-client-runtime/src/main/java/com/microsoft/azure/CloudException.java index 00969b08e656..2e0a9db74783 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/CloudException.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/CloudException.java @@ -7,13 +7,13 @@ package com.microsoft.azure; -import com.microsoft.rest.AutoRestException; +import com.microsoft.rest.RestException; import retrofit2.Response; /** * Exception thrown for an invalid response with custom error information. */ -public class CloudException extends AutoRestException { +public class CloudException extends RestException { /** * Information about the associated HTTP response. */ diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java index e13926390c42..81aabf55f556 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java @@ -7,7 +7,7 @@ package com.microsoft.azure; -import com.microsoft.rest.AutoRestException; +import com.microsoft.rest.RestException; import java.io.IOException; import java.util.Collection; @@ -46,10 +46,10 @@ public PagedList(Page page) { * * @param nextPageLink the link to get the next page of items. * @return the {@link Page} object storing a page of items and a link to the next page. - * @throws AutoRestException thrown if an error is raised from Azure. + * @throws RestException thrown if an error is raised from Azure. * @throws IOException thrown if there's any failure in deserialization. */ - public abstract Page nextPage(String nextPageLink) throws AutoRestException, IOException; + public abstract Page nextPage(String nextPageLink) throws RestException, IOException; /** * If there are more pages available. @@ -69,7 +69,7 @@ public void loadNextPage() { Page nextPage = nextPage(this.nextPageLink); this.nextPageLink = nextPage.getNextPageLink(); this.items.addAll(nextPage.getItems()); - } catch (AutoRestException e) { + } catch (RestException e) { throw new WebServiceException(e.toString(), e); } catch (IOException e) { throw new DataBindingException(e.getMessage(), e); diff --git a/client-runtime/src/main/java/com/microsoft/rest/AutoRestException.java b/client-runtime/src/main/java/com/microsoft/rest/RestException.java similarity index 79% rename from client-runtime/src/main/java/com/microsoft/rest/AutoRestException.java rename to client-runtime/src/main/java/com/microsoft/rest/RestException.java index 72db4288ab3a..cf5dff556aea 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/AutoRestException.java +++ b/client-runtime/src/main/java/com/microsoft/rest/RestException.java @@ -10,18 +10,18 @@ /** * Exception thrown for an invalid response with custom error information. */ -public abstract class AutoRestException extends Exception { +public abstract class RestException extends Exception { /** * Initializes a new instance of the AutoRestException class. */ - public AutoRestException() { } + public RestException() { } /** * Initializes a new instance of the AutoRestException class. * * @param message The exception message. */ - public AutoRestException(String message) { + public RestException(String message) { super(message); } @@ -30,7 +30,7 @@ public AutoRestException(String message) { * * @param cause exception that caused this exception to occur */ - public AutoRestException(Throwable cause) { + public RestException(Throwable cause) { super(cause); } @@ -40,7 +40,7 @@ public AutoRestException(Throwable cause) { * @param message the exception message * @param cause exception that caused this exception to occur */ - public AutoRestException(String message, Throwable cause) { + public RestException(String message, Throwable cause) { super(message, cause); } } diff --git a/client-runtime/src/main/java/com/microsoft/rest/ServiceException.java b/client-runtime/src/main/java/com/microsoft/rest/ServiceException.java index bf187c9d043a..c041ae3bda3a 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/ServiceException.java +++ b/client-runtime/src/main/java/com/microsoft/rest/ServiceException.java @@ -12,7 +12,7 @@ /** * Exception thrown for an invalid response with custom error information. */ -public class ServiceException extends AutoRestException { +public class ServiceException extends RestException { /** * Information about the associated HTTP response. */ diff --git a/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java b/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java index 1fae7e4e9fe5..b6e057a0e607 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java +++ b/client-runtime/src/main/java/com/microsoft/rest/ServiceResponseBuilder.java @@ -27,7 +27,7 @@ * @param The return type the caller expects from the REST response. * @param the exception to throw in case of error. */ -public class ServiceResponseBuilder { +public class ServiceResponseBuilder { /** * A mapping of HTTP status codes and their corresponding return types. */ @@ -36,7 +36,7 @@ public class ServiceResponseBuilder { /** * The exception type to thrown in case of error. */ - protected Class exceptionType; + protected Class exceptionType; /** * The mapperAdapter used for deserializing the response. @@ -83,7 +83,7 @@ public ServiceResponseBuilder register(int statusCode, final Type type) { * @param type the type to deserialize. * @return the same builder instance. */ - public ServiceResponseBuilder registerError(final Class type) { + public ServiceResponseBuilder registerError(final Class type) { this.exceptionType = type; try { Field f = type.getDeclaredField("body"); From cea6f72139c100dd99191e35b03494336841c4b6 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Tue, 5 Apr 2016 17:05:04 -0700 Subject: [PATCH 31/42] Remove get prefix on model property getters --- .../src/main/java/com/microsoft/azure/Resource.java | 8 ++++---- .../src/main/java/com/microsoft/azure/SubResource.java | 2 +- .../microsoft/rest/serializer/JacksonMapperAdapter.java | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/Resource.java b/azure-client-runtime/src/main/java/com/microsoft/azure/Resource.java index 732035538ef6..f108f9edbc93 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/Resource.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/Resource.java @@ -49,7 +49,7 @@ public class Resource { * * @return the id value */ - public String getId() { + public String id() { return this.id; } @@ -58,7 +58,7 @@ public String getId() { * * @return the name value */ - public String getName() { + public String name() { return this.name; } @@ -67,7 +67,7 @@ public String getName() { * * @return the type value */ - public String getType() { + public String type() { return this.type; } @@ -76,7 +76,7 @@ public String getType() { * * @return the location value */ - public String getLocation() { + public String location() { return this.location; } diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/SubResource.java b/azure-client-runtime/src/main/java/com/microsoft/azure/SubResource.java index 36ca18ae3665..4f89c0afb8be 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/SubResource.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/SubResource.java @@ -21,7 +21,7 @@ public class SubResource { * * @return the id value */ - public String getId() { + public String id() { return this.id; } diff --git a/client-runtime/src/main/java/com/microsoft/rest/serializer/JacksonMapperAdapter.java b/client-runtime/src/main/java/com/microsoft/rest/serializer/JacksonMapperAdapter.java index ae2af3c5f6ac..a59247207502 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/serializer/JacksonMapperAdapter.java +++ b/client-runtime/src/main/java/com/microsoft/rest/serializer/JacksonMapperAdapter.java @@ -62,7 +62,8 @@ protected void initializeObjectMapper(ObjectMapper mapper) { mapper.setVisibility(mapper.getSerializationConfig().getDefaultVisibilityChecker() .withFieldVisibility(JsonAutoDetect.Visibility.ANY) .withSetterVisibility(JsonAutoDetect.Visibility.NONE) - .withGetterVisibility(JsonAutoDetect.Visibility.NONE)); + .withGetterVisibility(JsonAutoDetect.Visibility.NONE) + .withIsGetterVisibility(JsonAutoDetect.Visibility.NONE)); } /** From 4ff082d3046b5bbb3185f4fb121ce7935555389b Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Fri, 8 Apr 2016 10:50:59 -0700 Subject: [PATCH 32/42] Extend functionality for paged lists --- azure-client-runtime/build.gradle | 2 +- .../java/com/microsoft/azure/PagedList.java | 28 ++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/azure-client-runtime/build.gradle b/azure-client-runtime/build.gradle index dcdaddcea285..52894c8727a6 100644 --- a/azure-client-runtime/build.gradle +++ b/azure-client-runtime/build.gradle @@ -30,7 +30,7 @@ uploadArchives { repositories { mavenDeployer { configuration = configurations.deployerJars - snapshotRepository(url: "ftp://waws-prod-bay-005.ftp.azurewebsites.windows.net/site/wwwroot/") { + snapshotRepository(url: "file://\\\\aaptfile01\\ADXSDK\\Java\\internal-snapshots") { authentication(userName: username, password: password) } pom.setArtifactId "azure-client-runtime" diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java index 81aabf55f556..c2441cfd6cc2 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java @@ -10,6 +10,7 @@ import com.microsoft.rest.RestException; import java.io.IOException; +import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; @@ -30,6 +31,12 @@ public abstract class PagedList implements List { private List items; /** Stores the link to get the next page of items. */ private String nextPageLink; + /** Stores the latest page fetched. */ + private Page currentPage; + + public PagedList() { + items = new ArrayList<>(); + } /** * Creates an instance of PagedList from a {@link Page} response. @@ -39,6 +46,7 @@ public abstract class PagedList implements List { public PagedList(Page page) { items = page.getItems(); nextPageLink = page.getNextPageLink(); + currentPage = page; } /** @@ -69,12 +77,12 @@ public void loadNextPage() { Page nextPage = nextPage(this.nextPageLink); this.nextPageLink = nextPage.getNextPageLink(); this.items.addAll(nextPage.getItems()); + this.currentPage = nextPage; } catch (RestException e) { throw new WebServiceException(e.toString(), e); } catch (IOException e) { throw new DataBindingException(e.getMessage(), e); } - } /** @@ -86,6 +94,24 @@ public void loadAll() { } } + /** + * Gets the latest page fetched. + * + * @return the latest page. + */ + public Page currentPage() { + return currentPage; + } + + /** + * Gets the next page's link. + * + * @return the next page link. + */ + public String nextPageLink() { + return nextPageLink; + } + /** * The implementation of {@link ListIterator} for PagedList. */ From ea61512e0fb825bce4a3b6899f1bffb6d3cb0adf Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Fri, 15 Apr 2016 09:42:53 -0700 Subject: [PATCH 33/42] Fix paged list to use hasNextPage() for hasNext() --- .../src/main/java/com/microsoft/azure/PagedList.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java index c2441cfd6cc2..d9e83b890c52 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java @@ -130,7 +130,7 @@ public ListItr(int index) { @Override public boolean hasNext() { - return itemsListItr.hasNext() || nextPageLink != null; + return itemsListItr.hasNext() || hasNextPage(); } @Override @@ -191,7 +191,7 @@ public int size() { @Override public boolean isEmpty() { - return items.isEmpty() && nextPageLink == null; + return items.isEmpty() && !hasNextPage(); } @Override From b7dc8782c2a5b3d1d013bc6b0dd64cc128c9c746 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Fri, 15 Apr 2016 15:45:58 -0700 Subject: [PATCH 34/42] Use String for OData --- .../src/main/java/com/microsoft/azure/PagedList.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java index d9e83b890c52..f13aca518532 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/PagedList.java @@ -34,6 +34,9 @@ public abstract class PagedList implements List { /** Stores the latest page fetched. */ private Page currentPage; + /** + * Creates an instance of Pagedlist. + */ public PagedList() { items = new ArrayList<>(); } From dfba322607236949d74e31b90d4274584c953eb4 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Mon, 25 Apr 2016 16:54:47 -0700 Subject: [PATCH 35/42] Move .build() from collection calls to initialize() --- .../com/microsoft/rest/ServiceClient.java | 21 ++++++------ .../com/microsoft/rest/CredentialsTests.java | 33 +++++++++++-------- .../com/microsoft/rest/RetryHandlerTests.java | 20 +++++++---- .../microsoft/rest/ServiceClientTests.java | 13 +++++--- .../com/microsoft/rest/UserAgentTests.java | 33 +++++++++++-------- 5 files changed, 73 insertions(+), 47 deletions(-) diff --git a/client-runtime/src/main/java/com/microsoft/rest/ServiceClient.java b/client-runtime/src/main/java/com/microsoft/rest/ServiceClient.java index a0655bc3ab79..5c7a8cd89b28 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/ServiceClient.java +++ b/client-runtime/src/main/java/com/microsoft/rest/ServiceClient.java @@ -35,6 +35,16 @@ public abstract class ServiceClient { */ protected Retrofit.Builder retrofitBuilder; + /** + * The OkHttp client. + */ + protected OkHttpClient httpClient; + + /** + * The rest adapter. + */ + protected Retrofit retrofit; + /** * The adapter for {@link com.fasterxml.jackson.databind.ObjectMapper} for serialization * and deserialization operations. @@ -74,17 +84,6 @@ public List getClientInterceptors() { return this.clientBuilder.interceptors(); } - /** - * Sets the logging level for OkHttp client. - * - * @param logLevel the logging level enum - */ - public void setLogLevel(Level logLevel) { - HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); - loggingInterceptor.setLevel(logLevel); - this.getClientInterceptors().add(loggingInterceptor); - } - /** * Gets the adapter for {@link com.fasterxml.jackson.databind.ObjectMapper} for serialization * and deserialization operations.. diff --git a/client-runtime/src/test/java/com/microsoft/rest/CredentialsTests.java b/client-runtime/src/test/java/com/microsoft/rest/CredentialsTests.java index 296c7c910095..d6bfbf3e148e 100644 --- a/client-runtime/src/test/java/com/microsoft/rest/CredentialsTests.java +++ b/client-runtime/src/test/java/com/microsoft/rest/CredentialsTests.java @@ -10,8 +10,11 @@ import com.microsoft.rest.credentials.BasicAuthenticationCredentials; import com.microsoft.rest.credentials.TokenCredentials; import okhttp3.Interceptor; +import okhttp3.OkHttpClient; import okhttp3.Protocol; import okhttp3.Response; +import retrofit2.Retrofit; + import org.junit.Assert; import org.junit.Test; @@ -20,29 +23,30 @@ public class CredentialsTests { @Test public void basicCredentialsTest() throws Exception { - ServiceClient serviceClient = new ServiceClient() { }; - BasicAuthenticationCredentials credentials = new BasicAuthenticationCredentials("user", "pass"); - credentials.applyCredentialsFilter(serviceClient.clientBuilder); - serviceClient.getClientInterceptors().add(new Interceptor() { + OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); + Retrofit.Builder retrofitBuilder = new Retrofit.Builder(); + clientBuilder.addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { String header = chain.request().header("Authorization"); Assert.assertEquals("Basic dXNlcjpwYXNz", header); - return new Response.Builder() - .request(chain.request()) - .code(200) - .protocol(Protocol.HTTP_1_1) - .build(); + return new Response.Builder() + .request(chain.request()) + .code(200) + .protocol(Protocol.HTTP_1_1) + .build(); } }); + ServiceClient serviceClient = new ServiceClient(clientBuilder, retrofitBuilder) { }; + BasicAuthenticationCredentials credentials = new BasicAuthenticationCredentials("user", "pass"); + credentials.applyCredentialsFilter(serviceClient.clientBuilder); } @Test public void tokenCredentialsTest() throws Exception { - ServiceClient serviceClient = new ServiceClient() { }; - TokenCredentials credentials = new TokenCredentials(null, "this_is_a_token"); - credentials.applyCredentialsFilter(serviceClient.clientBuilder); - serviceClient.getClientInterceptors().add(new Interceptor() { + OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); + Retrofit.Builder retrofitBuilder = new Retrofit.Builder(); + clientBuilder.addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { String header = chain.request().header("Authorization"); @@ -54,5 +58,8 @@ public Response intercept(Chain chain) throws IOException { .build(); } }); + ServiceClient serviceClient = new ServiceClient(clientBuilder, retrofitBuilder) { }; + TokenCredentials credentials = new TokenCredentials(null, "this_is_a_token"); + credentials.applyCredentialsFilter(serviceClient.clientBuilder); } } diff --git a/client-runtime/src/test/java/com/microsoft/rest/RetryHandlerTests.java b/client-runtime/src/test/java/com/microsoft/rest/RetryHandlerTests.java index 4291450c27d1..b0ddd36a1860 100644 --- a/client-runtime/src/test/java/com/microsoft/rest/RetryHandlerTests.java +++ b/client-runtime/src/test/java/com/microsoft/rest/RetryHandlerTests.java @@ -10,9 +10,12 @@ import com.microsoft.rest.retry.RetryHandler; import okhttp3.Interceptor; +import okhttp3.OkHttpClient; import okhttp3.Protocol; import okhttp3.Request; import okhttp3.Response; +import retrofit2.Retrofit; + import org.junit.Assert; import org.junit.Test; @@ -21,9 +24,10 @@ public class RetryHandlerTests { @Test public void exponentialRetryEndOn501() throws Exception { - ServiceClient serviceClient = new ServiceClient() { }; - serviceClient.getClientInterceptors().add(new RetryHandler()); - serviceClient.getClientInterceptors().add(new Interceptor() { + OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); + Retrofit.Builder retrofitBuilder = new Retrofit.Builder(); + clientBuilder.addInterceptor(new RetryHandler()); + clientBuilder.addInterceptor(new Interceptor() { // Send 408, 500, 502, all retried, with a 501 ending private int[] codes = new int[]{408, 500, 502, 501}; private int count = 0; @@ -37,6 +41,7 @@ public Response intercept(Chain chain) throws IOException { .build(); } }); + ServiceClient serviceClient = new ServiceClient(clientBuilder, retrofitBuilder) { }; Response response = serviceClient.clientBuilder.build().newCall( new Request.Builder().url("http://localhost").get().build()).execute(); Assert.assertEquals(501, response.code()); @@ -44,11 +49,13 @@ public Response intercept(Chain chain) throws IOException { @Test public void exponentialRetryMax() throws Exception { - ServiceClient serviceClient = new ServiceClient() { }; - serviceClient.getClientInterceptors().add(new RetryHandler()); - serviceClient.getClientInterceptors().add(new Interceptor() { + OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); + Retrofit.Builder retrofitBuilder = new Retrofit.Builder(); + clientBuilder.addInterceptor(new RetryHandler()); + clientBuilder.addInterceptor(new Interceptor() { // Send 500 until max retry is hit private int count = 0; + @Override public Response intercept(Chain chain) throws IOException { Assert.assertTrue(count++ < 5); @@ -59,6 +66,7 @@ public Response intercept(Chain chain) throws IOException { .build(); } }); + ServiceClient serviceClient = new ServiceClient(clientBuilder, retrofitBuilder) { }; Response response = serviceClient.clientBuilder.build().newCall( new Request.Builder().url("http://localhost").get().build()).execute(); Assert.assertEquals(500, response.code()); diff --git a/client-runtime/src/test/java/com/microsoft/rest/ServiceClientTests.java b/client-runtime/src/test/java/com/microsoft/rest/ServiceClientTests.java index f30127974005..ee116d1bfa52 100644 --- a/client-runtime/src/test/java/com/microsoft/rest/ServiceClientTests.java +++ b/client-runtime/src/test/java/com/microsoft/rest/ServiceClientTests.java @@ -8,7 +8,10 @@ package com.microsoft.rest; import okhttp3.Interceptor; +import okhttp3.OkHttpClient; import okhttp3.Response; +import retrofit2.Retrofit; + import org.junit.Assert; import org.junit.Test; @@ -17,10 +20,11 @@ public class ServiceClientTests { @Test public void filterTests() throws Exception { - ServiceClient serviceClient = new ServiceClient() { }; - serviceClient.getClientInterceptors().add(0, new FirstFilter()); - serviceClient.getClientInterceptors().add(1, new SecondFilter()); - serviceClient.getClientInterceptors().add(new Interceptor() { + OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); + Retrofit.Builder retrofitBuilder = new Retrofit.Builder(); + clientBuilder.interceptors().add(0, new FirstFilter()); + clientBuilder.interceptors().add(1, new SecondFilter()); + clientBuilder.interceptors().add(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Assert.assertEquals("1", chain.request().header("filter1")); @@ -28,6 +32,7 @@ public Response intercept(Chain chain) throws IOException { return chain.proceed(chain.request()); } }); + ServiceClient serviceClient = new ServiceClient(clientBuilder, retrofitBuilder) { }; } public class FirstFilter implements Interceptor { diff --git a/client-runtime/src/test/java/com/microsoft/rest/UserAgentTests.java b/client-runtime/src/test/java/com/microsoft/rest/UserAgentTests.java index ce06a25b8869..a87c951dfc36 100644 --- a/client-runtime/src/test/java/com/microsoft/rest/UserAgentTests.java +++ b/client-runtime/src/test/java/com/microsoft/rest/UserAgentTests.java @@ -8,8 +8,11 @@ package com.microsoft.rest; import okhttp3.Interceptor; +import okhttp3.OkHttpClient; import okhttp3.Protocol; import okhttp3.Response; +import retrofit2.Retrofit; + import org.junit.Assert; import org.junit.Test; @@ -18,36 +21,40 @@ public class UserAgentTests { @Test public void defaultUserAgentTests() throws Exception { - ServiceClient serviceClient = new ServiceClient() { }; - serviceClient.getClientInterceptors().add(new Interceptor() { + OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); + Retrofit.Builder retrofitBuilder = new Retrofit.Builder(); + clientBuilder.addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { String header = chain.request().header("User-Agent"); Assert.assertEquals("AutoRest-Java", header); return new Response.Builder() - .request(chain.request()) - .code(200) - .protocol(Protocol.HTTP_1_1) - .build(); + .request(chain.request()) + .code(200) + .protocol(Protocol.HTTP_1_1) + .build(); } }); + ServiceClient serviceClient = new ServiceClient(clientBuilder, retrofitBuilder) { }; } @Test public void customUserAgentTests() throws Exception { - ServiceClient serviceClient = new ServiceClient() { }; - serviceClient.getClientInterceptors().add(new UserAgentInterceptor("Awesome")); - serviceClient.getClientInterceptors().add(new Interceptor() { + OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); + Retrofit.Builder retrofitBuilder = new Retrofit.Builder(); + clientBuilder.addInterceptor(new UserAgentInterceptor("Awesome")); + clientBuilder.addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { String header = chain.request().header("User-Agent"); Assert.assertEquals("Awesome", header); return new Response.Builder() - .request(chain.request()) - .code(200) - .protocol(Protocol.HTTP_1_1) - .build(); + .request(chain.request()) + .code(200) + .protocol(Protocol.HTTP_1_1) + .build(); } }); + ServiceClient serviceClient = new ServiceClient(clientBuilder, retrofitBuilder) { }; } } From b6c78d51b070f589c1c43d11058fad941f52c085 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Tue, 26 Apr 2016 16:49:03 -0700 Subject: [PATCH 36/42] Add RestClient --- .../java/com/microsoft/azure/AzureClient.java | 88 +++------- .../microsoft/azure/AzureServiceClient.java | 39 +---- .../microsoft/rest/BaseUrlInterceptor.java | 45 ++++++ .../rest/CustomHeadersInterceptor.java | 135 ++++++++++++++++ .../java/com/microsoft/rest/RestClient.java | 153 ++++++++++++++++++ .../com/microsoft/rest/ServiceClient.java | 90 ++--------- .../com/microsoft/rest/CredentialsTests.java | 54 ++++--- .../com/microsoft/rest/RetryHandlerTests.java | 10 +- .../microsoft/rest/ServiceClientTests.java | 23 ++- .../com/microsoft/rest/UserAgentTests.java | 6 +- 10 files changed, 435 insertions(+), 208 deletions(-) create mode 100644 client-runtime/src/main/java/com/microsoft/rest/BaseUrlInterceptor.java create mode 100644 client-runtime/src/main/java/com/microsoft/rest/CustomHeadersInterceptor.java create mode 100644 client-runtime/src/main/java/com/microsoft/rest/RestClient.java diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java b/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java index 2f3569fc51c5..36237bf80689 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java @@ -7,6 +7,7 @@ package com.microsoft.azure; +import com.microsoft.rest.RestClient; import com.microsoft.rest.ServiceCall; import com.microsoft.rest.ServiceCallback; import com.microsoft.rest.ServiceException; @@ -14,7 +15,6 @@ import com.microsoft.rest.ServiceResponseCallback; import com.microsoft.rest.ServiceResponseWithHeaders; import com.microsoft.rest.credentials.ServiceClientCredentials; -import com.microsoft.rest.serializer.JacksonMapperAdapter; import java.io.IOException; import java.lang.reflect.Type; @@ -24,11 +24,9 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import okhttp3.OkHttpClient; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Response; -import retrofit2.Retrofit; import retrofit2.http.GET; import retrofit2.http.Url; @@ -42,32 +40,18 @@ public class AzureClient extends AzureServiceClient { * used if null. */ private Integer longRunningOperationRetryTimeout; - /** - * The credentials to use for authentication for long running operations. - */ - private ServiceClientCredentials credentials; /** * The executor for asynchronous requests. */ private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); - /** - * Initializes an instance of this class. - */ - public AzureClient() { - super(); - } - /** * Initializes an instance of this class with customized client metadata. * - * @param clientBuilder customized http client. - * @param retrofitBuilder customized retrofit builder - * @param mapperAdapter the adapter for the Jackson object mapper + * @param restClient the REST client to connect to Azure */ - public AzureClient(OkHttpClient.Builder clientBuilder, Retrofit.Builder retrofitBuilder, JacksonMapperAdapter mapperAdapter) { - super(clientBuilder, retrofitBuilder); - this.mapperAdapter = mapperAdapter; + public AzureClient(RestClient restClient) { + super(restClient); } /** @@ -98,13 +82,13 @@ public ServiceResponse getPutOrPatchResult(Response respons CloudException exception = new CloudException(statusCode + " is not a valid polling status code"); exception.setResponse(response); if (responseBody != null) { - exception.setBody((CloudError) mapperAdapter.deserialize(responseBody.string(), CloudError.class)); + exception.setBody((CloudError) restClient().mapperAdapter().deserialize(responseBody.string(), CloudError.class)); responseBody.close(); } throw exception; } - PollingState pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, mapperAdapter); + PollingState pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, restClient().mapperAdapter()); String url = response.raw().request().url().toString(); // Check provisioning state @@ -151,7 +135,7 @@ public ServiceResponseWithHeaders getPutOrPatchResultWi ServiceResponse bodyResponse = getPutOrPatchResult(response, resourceType); return new ServiceResponseWithHeaders<>( bodyResponse.getBody(), - mapperAdapter.deserialize(mapperAdapter.serialize(bodyResponse.getResponse().headers()), headerType), + restClient().mapperAdapter().deserialize(restClient().mapperAdapter().serialize(bodyResponse.getResponse().headers()), headerType), bodyResponse.getResponse() ); } @@ -186,7 +170,7 @@ public AsyncPollingTask getPutOrPatchResultAsync(Response r exception.setResponse(response); try { if (responseBody != null) { - exception.setBody((CloudError) mapperAdapter.deserialize(responseBody.string(), CloudError.class)); + exception.setBody((CloudError) restClient().mapperAdapter().deserialize(responseBody.string(), CloudError.class)); responseBody.close(); } } catch (Exception e) { /* ignore serialization errors on top of service errors */ } @@ -196,7 +180,7 @@ public AsyncPollingTask getPutOrPatchResultAsync(Response r PollingState pollingState; try { - pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, mapperAdapter); + pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, restClient().mapperAdapter()); } catch (IOException e) { callback.failure(e); return null; @@ -235,7 +219,7 @@ public void success(ServiceResponse result) { try { callback.success(new ServiceResponseWithHeaders<>( result.getBody(), - mapperAdapter.deserialize(mapperAdapter.serialize(result.getResponse().headers()), headerType), + restClient().mapperAdapter().deserialize(restClient().mapperAdapter().serialize(result.getResponse().headers()), headerType), result.getResponse() )); } catch (IOException e) { @@ -273,13 +257,13 @@ public ServiceResponse getPostOrDeleteResult(Response respo CloudException exception = new CloudException(statusCode + " is not a valid polling status code"); exception.setResponse(response); if (responseBody != null) { - exception.setBody((CloudError) mapperAdapter.deserialize(responseBody.string(), CloudError.class)); + exception.setBody((CloudError) restClient().mapperAdapter().deserialize(responseBody.string(), CloudError.class)); responseBody.close(); } throw exception; } - PollingState pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, mapperAdapter); + PollingState pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, restClient().mapperAdapter()); // Check provisioning state while (!AzureAsyncOperation.getTerminalStatuses().contains(pollingState.getStatus())) { @@ -325,7 +309,7 @@ public ServiceResponseWithHeaders getPostOrDeleteResult ServiceResponse bodyResponse = getPostOrDeleteResult(response, resourceType); return new ServiceResponseWithHeaders<>( bodyResponse.getBody(), - mapperAdapter.deserialize(mapperAdapter.serialize(bodyResponse.getResponse().headers()), headerType), + restClient().mapperAdapter().deserialize(restClient().mapperAdapter().serialize(bodyResponse.getResponse().headers()), headerType), bodyResponse.getResponse() ); } @@ -360,7 +344,7 @@ public AsyncPollingTask getPostOrDeleteResultAsync(Response exception.setResponse(response); try { if (responseBody != null) { - exception.setBody((CloudError) mapperAdapter.deserialize(responseBody.string(), CloudError.class)); + exception.setBody((CloudError) restClient().mapperAdapter().deserialize(responseBody.string(), CloudError.class)); responseBody.close(); } } catch (Exception e) { /* ignore serialization errors on top of service errors */ } @@ -370,7 +354,7 @@ public AsyncPollingTask getPostOrDeleteResultAsync(Response PollingState pollingState; try { - pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, mapperAdapter); + pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, restClient().mapperAdapter()); } catch (IOException e) { callback.failure(e); return null; @@ -408,7 +392,7 @@ public void success(ServiceResponse result) { try { callback.success(new ServiceResponseWithHeaders<>( result.getBody(), - mapperAdapter.deserialize(mapperAdapter.serialize(result.getResponse().headers()), headerType), + restClient().mapperAdapter().deserialize(restClient().mapperAdapter().serialize(result.getResponse().headers()), headerType), result.getResponse() )); } catch (IOException e) { @@ -584,7 +568,7 @@ private void updateStateFromAzureAsyncOperationHeader(PollingState pollin AzureAsyncOperation body = null; if (response.body() != null) { - body = mapperAdapter.deserialize(response.body().string(), AzureAsyncOperation.class); + body = restClient().mapperAdapter().deserialize(response.body().string(), AzureAsyncOperation.class); response.body().close(); } @@ -592,7 +576,7 @@ private void updateStateFromAzureAsyncOperationHeader(PollingState pollin CloudException exception = new CloudException("no body"); exception.setResponse(response); if (response.errorBody() != null) { - exception.setBody((CloudError) mapperAdapter.deserialize(response.errorBody().string(), CloudError.class)); + exception.setBody((CloudError) restClient().mapperAdapter().deserialize(response.errorBody().string(), CloudError.class)); response.errorBody().close(); } throw exception; @@ -624,14 +608,14 @@ public void success(ServiceResponse result) { try { AzureAsyncOperation body = null; if (result.getBody() != null) { - body = mapperAdapter.deserialize(result.getBody().string(), AzureAsyncOperation.class); + body = restClient().mapperAdapter().deserialize(result.getBody().string(), AzureAsyncOperation.class); result.getBody().close(); } if (body == null || body.getStatus() == null) { CloudException exception = new CloudException("no body"); exception.setResponse(result.getResponse()); if (result.getResponse().errorBody() != null) { - exception.setBody((CloudError) mapperAdapter.deserialize(result.getResponse().errorBody().string(), CloudError.class)); + exception.setBody((CloudError) restClient().mapperAdapter().deserialize(result.getResponse().errorBody().string(), CloudError.class)); result.getResponse().errorBody().close(); } failure(exception); @@ -663,18 +647,17 @@ private Response poll(String url) throws CloudException, IOExcepti if (port == -1) { port = endpoint.getDefaultPort(); } - AsyncService service = this.retrofitBuilder - .baseUrl(endpoint.getProtocol() + "://" + endpoint.getHost() + ":" + port).build().create(AsyncService.class); + AsyncService service = restClient().retrofit().create(AsyncService.class); Response response = service.get(endpoint.getFile()).execute(); int statusCode = response.code(); if (statusCode != 200 && statusCode != 201 && statusCode != 202 && statusCode != 204) { CloudException exception = new CloudException(statusCode + " is not a valid polling status code"); exception.setResponse(response); if (response.body() != null) { - exception.setBody((CloudError) mapperAdapter.deserialize(response.body().string(), CloudError.class)); + exception.setBody((CloudError) restClient().mapperAdapter().deserialize(response.body().string(), CloudError.class)); response.body().close(); } else if (response.errorBody() != null) { - exception.setBody((CloudError) mapperAdapter.deserialize(response.errorBody().string(), CloudError.class)); + exception.setBody((CloudError) restClient().mapperAdapter().deserialize(response.errorBody().string(), CloudError.class)); response.errorBody().close(); } throw exception; @@ -701,8 +684,7 @@ private Call pollAsync(String url, final ServiceCallback call = service.get(endpoint.getFile()); call.enqueue(new ServiceResponseCallback(callback) { @Override @@ -713,10 +695,10 @@ public void onResponse(Call call, Response response) CloudException exception = new CloudException(statusCode + " is not a valid polling status code"); exception.setResponse(response); if (response.body() != null) { - exception.setBody((CloudError) mapperAdapter.deserialize(response.body().string(), CloudError.class)); + exception.setBody((CloudError) restClient().mapperAdapter().deserialize(response.body().string(), CloudError.class)); response.body().close(); } else if (response.errorBody() != null) { - exception.setBody((CloudError) mapperAdapter.deserialize(response.errorBody().string(), CloudError.class)); + exception.setBody((CloudError) restClient().mapperAdapter().deserialize(response.errorBody().string(), CloudError.class)); response.errorBody().close(); } callback.failure(exception); @@ -749,24 +731,6 @@ public void setLongRunningOperationRetryTimeout(Integer longRunningOperationRetr this.longRunningOperationRetryTimeout = longRunningOperationRetryTimeout; } - /** - * Gets the credentials used for authentication. - * - * @return the credentials. - */ - public ServiceClientCredentials getCredentials() { - return credentials; - } - - /** - * Sets the credentials used for authentication. - * - * @param credentials the credentials. - */ - public void setCredentials(ServiceClientCredentials credentials) { - this.credentials = credentials; - } - /** * The Retrofit service used for polling. */ diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/AzureServiceClient.java b/azure-client-runtime/src/main/java/com/microsoft/azure/AzureServiceClient.java index 5feea13fa74d..666cdc982dbb 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/AzureServiceClient.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/AzureServiceClient.java @@ -8,9 +8,11 @@ package com.microsoft.azure; import com.microsoft.azure.serializer.AzureJacksonMapperAdapter; +import com.microsoft.rest.RestClient; import com.microsoft.rest.ServiceClient; import com.microsoft.rest.UserAgentInterceptor; import com.microsoft.rest.retry.RetryHandler; +import com.microsoft.rest.serializer.JacksonMapperAdapter; import java.net.CookieManager; import java.net.CookiePolicy; @@ -23,42 +25,17 @@ * ServiceClient is the abstraction for accessing REST operations and their payload data types. */ public abstract class AzureServiceClient extends ServiceClient { - /** - * Initializes a new instance of the ServiceClient class. - */ - protected AzureServiceClient() { - super(); + protected AzureServiceClient(String baseUrl) { + this(new RestClient.Builder(baseUrl) + .withMapperAdapter(new AzureJacksonMapperAdapter()).build()); } /** * Initializes a new instance of the ServiceClient class. * - * @param clientBuilder the builder to build up an OkHttp client - * @param retrofitBuilder the builder to build up a rest adapter - */ - protected AzureServiceClient(OkHttpClient.Builder clientBuilder, Retrofit.Builder retrofitBuilder) { - super(clientBuilder, retrofitBuilder); - } - - /** - * This method initializes the builders for Http client and Retrofit with common - * behaviors for all service clients. + * @param restClient the REST client */ - @Override - protected void initialize() { - // Add retry handler - CookieManager cookieManager = new CookieManager(); - cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL); - - // Set up OkHttp client - this.clientBuilder = clientBuilder - .cookieJar(new JavaNetCookieJar(cookieManager)) - .addInterceptor(new RetryHandler()) - .addInterceptor(new UserAgentInterceptor()); - // Set up rest adapter - this.mapperAdapter = new AzureJacksonMapperAdapter(); - this.retrofitBuilder = retrofitBuilder - .client(clientBuilder.build()) - .addConverterFactory(mapperAdapter.getConverterFactory()); + protected AzureServiceClient(RestClient restClient) { + super(restClient); } } diff --git a/client-runtime/src/main/java/com/microsoft/rest/BaseUrlInterceptor.java b/client-runtime/src/main/java/com/microsoft/rest/BaseUrlInterceptor.java new file mode 100644 index 000000000000..e715cfe08538 --- /dev/null +++ b/client-runtime/src/main/java/com/microsoft/rest/BaseUrlInterceptor.java @@ -0,0 +1,45 @@ +/** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + */ + +package com.microsoft.rest; + +import java.io.IOException; + +import okhttp3.HttpUrl; +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.internal.Version; +import retrofit2.BaseUrl; + +/** + * User agent interceptor for putting a 'User-Agent' header in the request. + */ +public class BaseUrlInterceptor implements Interceptor { + private String baseUrl; + + public BaseUrlInterceptor() { + } + + public void setBaseUrl(String baseUrl) { + this.baseUrl = baseUrl; + } + + @Override + public Response intercept(Chain chain) throws IOException { + Request request = chain.request(); + if (baseUrl != null) { + HttpUrl newUrl = request.url().newBuilder() + .host(baseUrl) + .build(); + request = request.newBuilder() + .url(newUrl) + .build(); + } + return chain.proceed(request); + } +} diff --git a/client-runtime/src/main/java/com/microsoft/rest/CustomHeadersInterceptor.java b/client-runtime/src/main/java/com/microsoft/rest/CustomHeadersInterceptor.java new file mode 100644 index 000000000000..b49da885c2cd --- /dev/null +++ b/client-runtime/src/main/java/com/microsoft/rest/CustomHeadersInterceptor.java @@ -0,0 +1,135 @@ +/** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + */ + +package com.microsoft.rest; + +import okhttp3.Headers; +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * An instance of this class enables adding custom headers in client requests + * when added to the {@link okhttp3.OkHttpClient} interceptors. + */ +public class CustomHeadersInterceptor implements Interceptor { + /** + * A mapping of custom headers. + */ + private Map> headers; + + /** + * Initialize an instance of {@link CustomHeadersInterceptor} class. + */ + public CustomHeadersInterceptor() { + headers = new HashMap>(); + } + + /** + * Initialize an instance of {@link CustomHeadersInterceptor} class. + * + * @param key the key for the header + * @param value the value of the header + */ + public CustomHeadersInterceptor(String key, String value) { + this(); + addHeader(key, value); + } + + /** + * Add a single header key-value pair. If one with the name already exists, + * it gets replaced. + * + * @param name the name of the header. + * @param value the value of the header. + * @return the interceptor instance itself. + */ + public CustomHeadersInterceptor replaceHeader(String name, String value) { + this.headers.put(name, Collections.singletonList(value)); + return this; + } + + /** + * Add a single header key-value pair. If one with the name already exists, + * both stay in the header map. + * + * @param name the name of the header. + * @param value the value of the header. + * @return the interceptor instance itself. + */ + public CustomHeadersInterceptor addHeader(String name, String value) { + if (this.headers.containsKey(name)) { + this.headers.get(name).add(value); + } else { + this.headers.put(name, Collections.singletonList(value)); + } + return this; + } + + /** + * Add all headers in a {@link Headers} object. + * + * @param headers an OkHttp {@link Headers} object. + * @return the interceptor instance itself. + */ + public CustomHeadersInterceptor addHeaders(Headers headers) { + this.headers.putAll(headers.toMultimap()); + return this; + } + + /** + * Add all headers in a header map. + * + * @param headers a map of headers. + * @return the interceptor instance itself. + */ + public CustomHeadersInterceptor addHeaderMap(Map headers) { + for (Map.Entry header : headers.entrySet()) { + this.headers.put(header.getKey(), Collections.singletonList(header.getValue())); + } + return this; + } + + /** + * Add all headers in a header multimap. + * + * @param headers a multimap of headers. + * @return the interceptor instance itself. + */ + public CustomHeadersInterceptor addHeaderMultimap(Map> headers) { + this.headers.putAll(headers); + return this; + } + + /** + * Remove a header. + * + * @param name the name of the header to remove. + * @return the interceptor instance itself. + */ + public CustomHeadersInterceptor removeHeader(String name) { + this.headers.remove(name); + return this; + } + + @Override + public Response intercept(Chain chain) throws IOException { + Request.Builder builder = chain.request().newBuilder(); + for (Map.Entry> header : headers.entrySet()) { + for (String value : header.getValue()) { + builder = builder.header(header.getKey(), value); + } + } + return chain.proceed(builder.build()); + } +} diff --git a/client-runtime/src/main/java/com/microsoft/rest/RestClient.java b/client-runtime/src/main/java/com/microsoft/rest/RestClient.java new file mode 100644 index 000000000000..4342a513e2e0 --- /dev/null +++ b/client-runtime/src/main/java/com/microsoft/rest/RestClient.java @@ -0,0 +1,153 @@ +/** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + */ + +package com.microsoft.rest; + +import com.microsoft.rest.credentials.ServiceClientCredentials; +import com.microsoft.rest.retry.RetryHandler; +import com.microsoft.rest.serializer.JacksonMapperAdapter; + +import java.net.CookieManager; +import java.net.CookiePolicy; + +import okhttp3.Interceptor; +import okhttp3.JavaNetCookieJar; +import okhttp3.OkHttpClient; +import retrofit2.Retrofit; + +/** + * An instance of this class stores the client information for making REST calls. + */ +public class RestClient { + private OkHttpClient httpClient; + private Retrofit retrofit; + private ServiceClientCredentials credentials; + private CustomHeadersInterceptor customHeadersInterceptor; + private BaseUrlInterceptor baseUrlInterceptor; + private JacksonMapperAdapter mapperAdapter; + + private RestClient(OkHttpClient httpClient, + Retrofit retrofit, + ServiceClientCredentials credentials, + CustomHeadersInterceptor customHeadersInterceptor, + BaseUrlInterceptor baseUrlInterceptor, + JacksonMapperAdapter mapperAdapter) { + this.httpClient = httpClient; + this.retrofit = retrofit; + this.credentials = credentials; + this.customHeadersInterceptor = customHeadersInterceptor; + this.baseUrlInterceptor = baseUrlInterceptor; + this.mapperAdapter = mapperAdapter; + } + + public CustomHeadersInterceptor headers() { + return customHeadersInterceptor; + } + + public JacksonMapperAdapter mapperAdapter() { + return mapperAdapter; + } + + public OkHttpClient httpClient() { + return httpClient; + } + + public Retrofit retrofit() { + return retrofit; + } + + public String baseUrl() { + return retrofit.baseUrl().url().toString(); + } + + public void baseUrl(String baseUrl) { + baseUrlInterceptor.setBaseUrl(baseUrl); + } + + public ServiceClientCredentials credentials() { + return this.credentials; + } + + public static class Builder { + private OkHttpClient.Builder httpClientBuilder; + private Retrofit.Builder retrofitBuilder; + private ServiceClientCredentials credentials; + private CustomHeadersInterceptor customHeadersInterceptor; + private BaseUrlInterceptor baseUrlInterceptor; + private JacksonMapperAdapter mapperAdapter; + + public Builder(String baseUrl) { + this(baseUrl, new OkHttpClient.Builder(), new Retrofit.Builder()); + } + + public Builder(String baseUrl, OkHttpClient.Builder httpClientBuilder, Retrofit.Builder retrofitBuilder) { + if (baseUrl == null) { + throw new IllegalArgumentException("baseUrl == null"); + } + if (httpClientBuilder == null) { + throw new IllegalArgumentException("httpClientBuilder == null"); + } + if (retrofitBuilder == null) { + throw new IllegalArgumentException("retrofitBuilder == null"); + } + CookieManager cookieManager = new CookieManager(); + cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL); + customHeadersInterceptor = new CustomHeadersInterceptor(); + baseUrlInterceptor = new BaseUrlInterceptor(); + // Set up OkHttp client + this.httpClientBuilder = httpClientBuilder + .cookieJar(new JavaNetCookieJar(cookieManager)) + .addInterceptor(new RetryHandler()) + .addInterceptor(new UserAgentInterceptor()) + .addInterceptor(customHeadersInterceptor) + .addInterceptor(baseUrlInterceptor); + // Set up rest adapter + this.retrofitBuilder = retrofitBuilder.baseUrl(baseUrl); + } + + public Builder withBaseUrl(String baseUrl) { + this.retrofitBuilder.baseUrl(baseUrl); + return this; + } + + public Builder withUserAgent(String userAgent) { + this.httpClientBuilder.addInterceptor(new UserAgentInterceptor(userAgent)); + return this; + } + + public Builder withMapperAdapter(JacksonMapperAdapter mapperAdapter) { + if (mapperAdapter != null) { + this.mapperAdapter = mapperAdapter; + this.retrofitBuilder = retrofitBuilder.addConverterFactory(mapperAdapter.getConverterFactory()); + } + return this; + } + + public Builder withCredentials(ServiceClientCredentials credentials) { + this.credentials = credentials; + if (credentials != null) { + credentials.applyCredentialsFilter(httpClientBuilder); + } + return this; + } + + public Builder withInterceptor(Interceptor interceptor) { + this.httpClientBuilder.addInterceptor(interceptor); + return this; + } + + public RestClient build() { + OkHttpClient httpClient = httpClientBuilder.build(); + return new RestClient(httpClient, + retrofitBuilder.client(httpClient).build(), + credentials, + customHeadersInterceptor, + baseUrlInterceptor, + mapperAdapter); + } + } +} diff --git a/client-runtime/src/main/java/com/microsoft/rest/ServiceClient.java b/client-runtime/src/main/java/com/microsoft/rest/ServiceClient.java index 5c7a8cd89b28..ef2f8cae9cfe 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/ServiceClient.java +++ b/client-runtime/src/main/java/com/microsoft/rest/ServiceClient.java @@ -7,20 +7,8 @@ package com.microsoft.rest; -import com.microsoft.rest.retry.RetryHandler; import com.microsoft.rest.serializer.JacksonMapperAdapter; -import java.net.CookieManager; -import java.net.CookiePolicy; -import java.util.List; - -import okhttp3.Interceptor; -import okhttp3.JavaNetCookieJar; -import okhttp3.OkHttpClient; -import okhttp3.logging.HttpLoggingInterceptor; -import okhttp3.logging.HttpLoggingInterceptor.Level; -import retrofit2.Retrofit; - /** * ServiceClient is the abstraction for accessing REST operations and their payload data types. */ @@ -28,89 +16,33 @@ public abstract class ServiceClient { /** * The builder for building the OkHttp client. */ - protected OkHttpClient.Builder clientBuilder; - - /** - * The builder for building Retrofit services. - */ - protected Retrofit.Builder retrofitBuilder; - - /** - * The OkHttp client. - */ - protected OkHttpClient httpClient; - - /** - * The rest adapter. - */ - protected Retrofit retrofit; - - /** - * The adapter for {@link com.fasterxml.jackson.databind.ObjectMapper} for serialization - * and deserialization operations. - */ - protected JacksonMapperAdapter mapperAdapter; + private RestClient restClient; /** * Initializes a new instance of the ServiceClient class. */ - protected ServiceClient() { - this(new OkHttpClient.Builder(), new Retrofit.Builder()); + protected ServiceClient(String baseUrl) { + this(new RestClient.Builder(baseUrl) + .withMapperAdapter(new JacksonMapperAdapter()).build()); } /** * Initializes a new instance of the ServiceClient class. * - * @param clientBuilder the builder to build up an OkHttp client - * @param retrofitBuilder the builder to build up a rest adapter + * @param restClient the builder to build up an REST client */ - protected ServiceClient(OkHttpClient.Builder clientBuilder, Retrofit.Builder retrofitBuilder) { - if (clientBuilder == null) { - throw new IllegalArgumentException("clientBuilder == null"); - } - if (retrofitBuilder == null) { - throw new IllegalArgumentException("retrofitBuilder == null"); + protected ServiceClient(RestClient restClient) { + if (restClient == null) { + throw new IllegalArgumentException("restClient == null"); } - - this.clientBuilder = clientBuilder; - this.retrofitBuilder = retrofitBuilder; + this.restClient = restClient; } /** * Get the list of interceptors the OkHttp client will execute. * @return the list of interceptors */ - public List getClientInterceptors() { - return this.clientBuilder.interceptors(); - } - - /** - * Gets the adapter for {@link com.fasterxml.jackson.databind.ObjectMapper} for serialization - * and deserialization operations.. - * - * @return the adapter. - */ - public JacksonMapperAdapter getMapperAdapter() { - return this.mapperAdapter; - } - - /** - * This method initializes the builders for Http client and Retrofit with common - * behaviors for all service clients. - */ - protected void initialize() { - // Add retry handler - CookieManager cookieManager = new CookieManager(); - cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL); - - // Set up OkHttp client - this.clientBuilder = clientBuilder - .cookieJar(new JavaNetCookieJar(cookieManager)) - .addInterceptor(new RetryHandler()) - .addInterceptor(new UserAgentInterceptor()); - // Set up rest adapter - this.mapperAdapter = new JacksonMapperAdapter(); - this.retrofitBuilder = retrofitBuilder - .addConverterFactory(mapperAdapter.getConverterFactory()); + public RestClient restClient() { + return this.restClient; } } diff --git a/client-runtime/src/test/java/com/microsoft/rest/CredentialsTests.java b/client-runtime/src/test/java/com/microsoft/rest/CredentialsTests.java index d6bfbf3e148e..19b7a8ca2a4f 100644 --- a/client-runtime/src/test/java/com/microsoft/rest/CredentialsTests.java +++ b/client-runtime/src/test/java/com/microsoft/rest/CredentialsTests.java @@ -9,23 +9,28 @@ import com.microsoft.rest.credentials.BasicAuthenticationCredentials; import com.microsoft.rest.credentials.TokenCredentials; -import okhttp3.Interceptor; -import okhttp3.OkHttpClient; -import okhttp3.Protocol; -import okhttp3.Response; -import retrofit2.Retrofit; import org.junit.Assert; import org.junit.Test; import java.io.IOException; +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; +import retrofit2.Retrofit; + public class CredentialsTests { @Test public void basicCredentialsTest() throws Exception { OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); Retrofit.Builder retrofitBuilder = new Retrofit.Builder(); - clientBuilder.addInterceptor(new Interceptor() { + BasicAuthenticationCredentials credentials = new BasicAuthenticationCredentials("user", "pass"); + RestClient.Builder restBuilder = new RestClient.Builder("http://localhost", clientBuilder, retrofitBuilder) + .withCredentials(credentials) + .withInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { String header = chain.request().header("Authorization"); @@ -37,29 +42,32 @@ public Response intercept(Chain chain) throws IOException { .build(); } }); - ServiceClient serviceClient = new ServiceClient(clientBuilder, retrofitBuilder) { }; - BasicAuthenticationCredentials credentials = new BasicAuthenticationCredentials("user", "pass"); - credentials.applyCredentialsFilter(serviceClient.clientBuilder); + ServiceClient serviceClient = new ServiceClient(restBuilder.build()) { }; + Response response = serviceClient.restClient().httpClient().newCall(new Request.Builder().url("http://localhost").build()).execute(); + Assert.assertEquals(200, response.code()); } @Test public void tokenCredentialsTest() throws Exception { OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); Retrofit.Builder retrofitBuilder = new Retrofit.Builder(); - clientBuilder.addInterceptor(new Interceptor() { - @Override - public Response intercept(Chain chain) throws IOException { - String header = chain.request().header("Authorization"); - Assert.assertEquals("Bearer this_is_a_token", header); - return new Response.Builder() - .request(chain.request()) - .code(200) - .protocol(Protocol.HTTP_1_1) - .build(); - } - }); - ServiceClient serviceClient = new ServiceClient(clientBuilder, retrofitBuilder) { }; TokenCredentials credentials = new TokenCredentials(null, "this_is_a_token"); - credentials.applyCredentialsFilter(serviceClient.clientBuilder); + RestClient.Builder restBuilder = new RestClient.Builder("http://localhost", clientBuilder, retrofitBuilder) + .withCredentials(credentials) + .withInterceptor(new Interceptor() { + @Override + public Response intercept(Chain chain) throws IOException { + String header = chain.request().header("Authorization"); + Assert.assertEquals("Bearer this_is_a_token", header); + return new Response.Builder() + .request(chain.request()) + .code(200) + .protocol(Protocol.HTTP_1_1) + .build(); + } + }); + ServiceClient serviceClient = new ServiceClient(restBuilder.build()) { }; + Response response = serviceClient.restClient().httpClient().newCall(new Request.Builder().url("http://localhost").build()).execute(); + Assert.assertEquals(200, response.code()); } } diff --git a/client-runtime/src/test/java/com/microsoft/rest/RetryHandlerTests.java b/client-runtime/src/test/java/com/microsoft/rest/RetryHandlerTests.java index b0ddd36a1860..050e7374aba1 100644 --- a/client-runtime/src/test/java/com/microsoft/rest/RetryHandlerTests.java +++ b/client-runtime/src/test/java/com/microsoft/rest/RetryHandlerTests.java @@ -41,8 +41,9 @@ public Response intercept(Chain chain) throws IOException { .build(); } }); - ServiceClient serviceClient = new ServiceClient(clientBuilder, retrofitBuilder) { }; - Response response = serviceClient.clientBuilder.build().newCall( + RestClient.Builder restBuilder = new RestClient.Builder("http://localhost", clientBuilder, retrofitBuilder); + ServiceClient serviceClient = new ServiceClient(restBuilder.build()) { }; + Response response = serviceClient.restClient().httpClient().newCall( new Request.Builder().url("http://localhost").get().build()).execute(); Assert.assertEquals(501, response.code()); } @@ -66,8 +67,9 @@ public Response intercept(Chain chain) throws IOException { .build(); } }); - ServiceClient serviceClient = new ServiceClient(clientBuilder, retrofitBuilder) { }; - Response response = serviceClient.clientBuilder.build().newCall( + RestClient.Builder restBuilder = new RestClient.Builder("http://localhost", clientBuilder, retrofitBuilder); + ServiceClient serviceClient = new ServiceClient(restBuilder.build()) { }; + Response response = serviceClient.restClient().httpClient().newCall( new Request.Builder().url("http://localhost").get().build()).execute(); Assert.assertEquals(500, response.code()); } diff --git a/client-runtime/src/test/java/com/microsoft/rest/ServiceClientTests.java b/client-runtime/src/test/java/com/microsoft/rest/ServiceClientTests.java index ee116d1bfa52..5497d607549d 100644 --- a/client-runtime/src/test/java/com/microsoft/rest/ServiceClientTests.java +++ b/client-runtime/src/test/java/com/microsoft/rest/ServiceClientTests.java @@ -7,16 +7,18 @@ package com.microsoft.rest; -import okhttp3.Interceptor; -import okhttp3.OkHttpClient; -import okhttp3.Response; -import retrofit2.Retrofit; - import org.junit.Assert; import org.junit.Test; import java.io.IOException; +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; +import retrofit2.Retrofit; + public class ServiceClientTests { @Test public void filterTests() throws Exception { @@ -29,10 +31,17 @@ public void filterTests() throws Exception { public Response intercept(Chain chain) throws IOException { Assert.assertEquals("1", chain.request().header("filter1")); Assert.assertEquals("2", chain.request().header("filter2")); - return chain.proceed(chain.request()); + return new Response.Builder() + .request(chain.request()) + .code(200) + .protocol(Protocol.HTTP_1_1) + .build(); } }); - ServiceClient serviceClient = new ServiceClient(clientBuilder, retrofitBuilder) { }; + RestClient.Builder restBuilder = new RestClient.Builder("http://localhost", clientBuilder, retrofitBuilder); + ServiceClient serviceClient = new ServiceClient(restBuilder.build()) { }; + Response response = serviceClient.restClient().httpClient().newCall(new Request.Builder().url("http://localhost").build()).execute(); + Assert.assertEquals(200, response.code()); } public class FirstFilter implements Interceptor { diff --git a/client-runtime/src/test/java/com/microsoft/rest/UserAgentTests.java b/client-runtime/src/test/java/com/microsoft/rest/UserAgentTests.java index a87c951dfc36..e6b938f93368 100644 --- a/client-runtime/src/test/java/com/microsoft/rest/UserAgentTests.java +++ b/client-runtime/src/test/java/com/microsoft/rest/UserAgentTests.java @@ -35,7 +35,8 @@ public Response intercept(Chain chain) throws IOException { .build(); } }); - ServiceClient serviceClient = new ServiceClient(clientBuilder, retrofitBuilder) { }; + RestClient.Builder restBuilder = new RestClient.Builder("http://localhost", clientBuilder, retrofitBuilder); + ServiceClient serviceClient = new ServiceClient(restBuilder.build()) { }; } @Test @@ -55,6 +56,7 @@ public Response intercept(Chain chain) throws IOException { .build(); } }); - ServiceClient serviceClient = new ServiceClient(clientBuilder, retrofitBuilder) { }; + RestClient.Builder restBuilder = new RestClient.Builder("http://localhost", clientBuilder, retrofitBuilder); + ServiceClient serviceClient = new ServiceClient(restBuilder.build()) { }; } } From 9a27d689cd45f07f413269ecbbf2d57c3630191a Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Wed, 27 Apr 2016 14:14:00 -0700 Subject: [PATCH 37/42] Support base URL replace using Interceptor (Retrofit 2.0) --- .../java/com/microsoft/azure/AzureClient.java | 1 - .../microsoft/azure/AzureServiceClient.java | 10 -- ...rlInterceptor.java => BaseUrlHandler.java} | 29 +++- .../rest/CustomHeadersInterceptor.java | 11 +- .../java/com/microsoft/rest/RestClient.java | 142 ++++++++++++++++-- 5 files changed, 159 insertions(+), 34 deletions(-) rename client-runtime/src/main/java/com/microsoft/rest/{BaseUrlInterceptor.java => BaseUrlHandler.java} (50%) diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java b/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java index 36237bf80689..d8389869810f 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java @@ -14,7 +14,6 @@ import com.microsoft.rest.ServiceResponse; import com.microsoft.rest.ServiceResponseCallback; import com.microsoft.rest.ServiceResponseWithHeaders; -import com.microsoft.rest.credentials.ServiceClientCredentials; import java.io.IOException; import java.lang.reflect.Type; diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/AzureServiceClient.java b/azure-client-runtime/src/main/java/com/microsoft/azure/AzureServiceClient.java index 666cdc982dbb..94142029cfc6 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/AzureServiceClient.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/AzureServiceClient.java @@ -10,16 +10,6 @@ import com.microsoft.azure.serializer.AzureJacksonMapperAdapter; import com.microsoft.rest.RestClient; import com.microsoft.rest.ServiceClient; -import com.microsoft.rest.UserAgentInterceptor; -import com.microsoft.rest.retry.RetryHandler; -import com.microsoft.rest.serializer.JacksonMapperAdapter; - -import java.net.CookieManager; -import java.net.CookiePolicy; - -import okhttp3.JavaNetCookieJar; -import okhttp3.OkHttpClient; -import retrofit2.Retrofit; /** * ServiceClient is the abstraction for accessing REST operations and their payload data types. diff --git a/client-runtime/src/main/java/com/microsoft/rest/BaseUrlInterceptor.java b/client-runtime/src/main/java/com/microsoft/rest/BaseUrlHandler.java similarity index 50% rename from client-runtime/src/main/java/com/microsoft/rest/BaseUrlInterceptor.java rename to client-runtime/src/main/java/com/microsoft/rest/BaseUrlHandler.java index e715cfe08538..4b46bf5de1dc 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/BaseUrlInterceptor.java +++ b/client-runtime/src/main/java/com/microsoft/rest/BaseUrlHandler.java @@ -19,22 +19,41 @@ /** * User agent interceptor for putting a 'User-Agent' header in the request. */ -public class BaseUrlInterceptor implements Interceptor { +public class BaseUrlHandler implements Interceptor { + private final String rawUrl; private String baseUrl; - public BaseUrlInterceptor() { + public BaseUrlHandler(String rawUrl) { + this.rawUrl = rawUrl; + this.baseUrl = null; } - public void setBaseUrl(String baseUrl) { - this.baseUrl = baseUrl; + public String baseUrl() { + if (this.baseUrl == null) { + return rawUrl; + } + return this.baseUrl; + } + + public void setBaseUrl(String... replacements) { + if (replacements.length % 2 != 0) { + throw new IllegalArgumentException("Must provide a replacement value for each pattern"); + } + baseUrl = rawUrl; + for (int i = 0; i < replacements.length; i += 2) { + baseUrl = baseUrl.replace(replacements[i], replacements[i+1]); + } } @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); if (baseUrl != null) { + HttpUrl baseHttpUrl = HttpUrl.parse(baseUrl); HttpUrl newUrl = request.url().newBuilder() - .host(baseUrl) + .host(baseHttpUrl.host()) + .scheme(baseHttpUrl.scheme()) + .port(baseHttpUrl.port()) .build(); request = request.newBuilder() .url(newUrl) diff --git a/client-runtime/src/main/java/com/microsoft/rest/CustomHeadersInterceptor.java b/client-runtime/src/main/java/com/microsoft/rest/CustomHeadersInterceptor.java index b49da885c2cd..00903b93a9e0 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/CustomHeadersInterceptor.java +++ b/client-runtime/src/main/java/com/microsoft/rest/CustomHeadersInterceptor.java @@ -13,6 +13,7 @@ import okhttp3.Response; import java.io.IOException; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -55,7 +56,8 @@ public CustomHeadersInterceptor(String key, String value) { * @return the interceptor instance itself. */ public CustomHeadersInterceptor replaceHeader(String name, String value) { - this.headers.put(name, Collections.singletonList(value)); + this.headers.put(name, new ArrayList()); + this.headers.get(name).add(value); return this; } @@ -68,11 +70,10 @@ public CustomHeadersInterceptor replaceHeader(String name, String value) { * @return the interceptor instance itself. */ public CustomHeadersInterceptor addHeader(String name, String value) { - if (this.headers.containsKey(name)) { - this.headers.get(name).add(value); - } else { - this.headers.put(name, Collections.singletonList(value)); + if (!this.headers.containsKey(name)) { + this.headers.put(name, new ArrayList()); } + this.headers.get(name).add(value); return this; } diff --git a/client-runtime/src/main/java/com/microsoft/rest/RestClient.java b/client-runtime/src/main/java/com/microsoft/rest/RestClient.java index 4342a513e2e0..448da4e6a2fc 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/RestClient.java +++ b/client-runtime/src/main/java/com/microsoft/rest/RestClient.java @@ -17,73 +17,141 @@ import okhttp3.Interceptor; import okhttp3.JavaNetCookieJar; import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; import retrofit2.Retrofit; /** * An instance of this class stores the client information for making REST calls. */ public class RestClient { + /** The {@link okhttp3.OkHttpClient} object. */ private OkHttpClient httpClient; + /** The {@link retrofit2.Retrofit} object. */ private Retrofit retrofit; + /** The credentials to authenticate. */ private ServiceClientCredentials credentials; + /** The interceptor to handle custom headers. */ private CustomHeadersInterceptor customHeadersInterceptor; - private BaseUrlInterceptor baseUrlInterceptor; + /** The interceptor to handle base URL. */ + private BaseUrlHandler baseUrlHandler; + /** The adapter to a Jackson {@link com.fasterxml.jackson.databind.ObjectMapper}. */ private JacksonMapperAdapter mapperAdapter; private RestClient(OkHttpClient httpClient, Retrofit retrofit, ServiceClientCredentials credentials, CustomHeadersInterceptor customHeadersInterceptor, - BaseUrlInterceptor baseUrlInterceptor, + BaseUrlHandler baseUrlHandler, JacksonMapperAdapter mapperAdapter) { this.httpClient = httpClient; this.retrofit = retrofit; this.credentials = credentials; this.customHeadersInterceptor = customHeadersInterceptor; - this.baseUrlInterceptor = baseUrlInterceptor; + this.baseUrlHandler = baseUrlHandler; this.mapperAdapter = mapperAdapter; } + /** + * Get the headers interceptor. + * + * @return the headers interceptor. + */ public CustomHeadersInterceptor headers() { return customHeadersInterceptor; } + /** + * Get the adapter to {@link com.fasterxml.jackson.databind.ObjectMapper}. + * + * @return the Jackson mapper adapter. + */ public JacksonMapperAdapter mapperAdapter() { return mapperAdapter; } + /** + * Get the http client. + * + * @return the {@link OkHttpClient} object. + */ public OkHttpClient httpClient() { return httpClient; } + /** + * Get the retrofit instance. + * + * @return the {@link Retrofit} object. + */ public Retrofit retrofit() { return retrofit; } + /** + * Get the base URL currently set. If it's a customizable URL, the updated + * URL instead of the raw one might be returned. + * + * @return the base URL. + * @see {@link RestClient#setBaseUrl(String...)} + */ public String baseUrl() { - return retrofit.baseUrl().url().toString(); + return baseUrlHandler.baseUrl(); } - public void baseUrl(String baseUrl) { - baseUrlInterceptor.setBaseUrl(baseUrl); + /** + * Handles dynamic replacements on base URL. The arguments must be in pairs + * with the string in raw URL to replace as replacements[i] and the dynamic + * part as replacements[i+1]. E.g. {subdomain}.microsoft.com can be set + * dynamically by calling setBaseUrl("{subdomain}", "azure"). + * + * @param replacements the string replacements in pairs. + */ + public void setBaseUrl(String... replacements) { + baseUrlHandler.setBaseUrl(replacements); } + /** + * Get the credentials attached to this REST client. + * + * @return the credentials. + */ public ServiceClientCredentials credentials() { return this.credentials; } + /** + * The builder class for building a REST client. + */ public static class Builder { + /** The builder to build an {@link OkHttpClient}. */ private OkHttpClient.Builder httpClientBuilder; + /** The builder to build a {@link Retrofit}. */ private Retrofit.Builder retrofitBuilder; + /** The credentials to authenticate. */ private ServiceClientCredentials credentials; + /** The interceptor to handle custom headers. */ private CustomHeadersInterceptor customHeadersInterceptor; - private BaseUrlInterceptor baseUrlInterceptor; + /** The interceptor to handle base URL. */ + private BaseUrlHandler baseUrlHandler; + /** The adapter to a Jackson {@link com.fasterxml.jackson.databind.ObjectMapper}. */ private JacksonMapperAdapter mapperAdapter; + /** + * Creates an instance of the builder with a base URL to the service. + * + * @param baseUrl the dynamic base URL with varialbes wrapped in "{" and "}". + */ public Builder(String baseUrl) { this(baseUrl, new OkHttpClient.Builder(), new Retrofit.Builder()); } + /** + * Creates an instance of the builder with a base URL and 2 custom builders. + * + * @param baseUrl the dynamic base URL with varialbes wrapped in "{" and "}". + * @param httpClientBuilder the builder to build an {@link OkHttpClient}. + * @param retrofitBuilder the builder to build a {@link Retrofit}. + */ public Builder(String baseUrl, OkHttpClient.Builder httpClientBuilder, Retrofit.Builder retrofitBuilder) { if (baseUrl == null) { throw new IllegalArgumentException("baseUrl == null"); @@ -97,28 +165,45 @@ public Builder(String baseUrl, OkHttpClient.Builder httpClientBuilder, Retrofit. CookieManager cookieManager = new CookieManager(); cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL); customHeadersInterceptor = new CustomHeadersInterceptor(); - baseUrlInterceptor = new BaseUrlInterceptor(); + baseUrlHandler = new BaseUrlHandler(baseUrl); // Set up OkHttp client this.httpClientBuilder = httpClientBuilder .cookieJar(new JavaNetCookieJar(cookieManager)) .addInterceptor(new RetryHandler()) - .addInterceptor(new UserAgentInterceptor()) - .addInterceptor(customHeadersInterceptor) - .addInterceptor(baseUrlInterceptor); + .addInterceptor(new UserAgentInterceptor()); // Set up rest adapter this.retrofitBuilder = retrofitBuilder.baseUrl(baseUrl); } + /** + * Sets the base URL. + * + * @param baseUrl the dynamic base URL. + * @return the builder itself for chaining. + */ public Builder withBaseUrl(String baseUrl) { this.retrofitBuilder.baseUrl(baseUrl); + this.baseUrlHandler = new BaseUrlHandler(baseUrl); return this; } + /** + * Sets the user agent header. + * + * @param userAgent the user agent header. + * @return the builder itself for chaining. + */ public Builder withUserAgent(String userAgent) { this.httpClientBuilder.addInterceptor(new UserAgentInterceptor(userAgent)); return this; } + /** + * Sets the mapper adapter. + * + * @param mapperAdapter an adapter to a Jackson mapper. + * @return the builder itself for chaining. + */ public Builder withMapperAdapter(JacksonMapperAdapter mapperAdapter) { if (mapperAdapter != null) { this.mapperAdapter = mapperAdapter; @@ -127,6 +212,12 @@ public Builder withMapperAdapter(JacksonMapperAdapter mapperAdapter) { return this; } + /** + * Sets the credentials. + * + * @param credentials the credentials object. + * @return the builder itself for chaining. + */ public Builder withCredentials(ServiceClientCredentials credentials) { this.credentials = credentials; if (credentials != null) { @@ -135,18 +226,43 @@ public Builder withCredentials(ServiceClientCredentials credentials) { return this; } + /** + * Sets the log level. + * + * @param logLevel the {@link okhttp3.logging.HttpLoggingInterceptor.Level} enum. + * @return the builder itself for chaining. + */ + public Builder withLogLevel(HttpLoggingInterceptor.Level logLevel) { + this.httpClientBuilder.addInterceptor(new HttpLoggingInterceptor().setLevel(logLevel)); + return this; + } + + /** + * Add an interceptor the Http client pipeline. + * + * @param interceptor the interceptor to add. + * @return the builder itself for chaining. + */ public Builder withInterceptor(Interceptor interceptor) { this.httpClientBuilder.addInterceptor(interceptor); return this; } + /** + * Build a RestClient with all the current configurations. + * + * @return a {@link RestClient}. + */ public RestClient build() { - OkHttpClient httpClient = httpClientBuilder.build(); + OkHttpClient httpClient = httpClientBuilder + .addInterceptor(baseUrlHandler) + .addInterceptor(customHeadersInterceptor) + .build(); return new RestClient(httpClient, retrofitBuilder.client(httpClient).build(), credentials, customHeadersInterceptor, - baseUrlInterceptor, + baseUrlHandler, mapperAdapter); } } From 8009399a8f5fc4efa18c92871cf7e9d6415e7f00 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Wed, 27 Apr 2016 14:47:37 -0700 Subject: [PATCH 38/42] Address checkstyle errors --- .../com/microsoft/rest/BaseUrlHandler.java | 27 ++++++++++++++++--- .../java/com/microsoft/rest/RestClient.java | 2 +- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/client-runtime/src/main/java/com/microsoft/rest/BaseUrlHandler.java b/client-runtime/src/main/java/com/microsoft/rest/BaseUrlHandler.java index 4b46bf5de1dc..f04cbc17edd8 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/BaseUrlHandler.java +++ b/client-runtime/src/main/java/com/microsoft/rest/BaseUrlHandler.java @@ -13,21 +13,32 @@ import okhttp3.Interceptor; import okhttp3.Request; import okhttp3.Response; -import okhttp3.internal.Version; -import retrofit2.BaseUrl; /** - * User agent interceptor for putting a 'User-Agent' header in the request. + * An instance of class handles dynamic base URLs in the HTTP pipeline. */ public class BaseUrlHandler implements Interceptor { + /** The URL template for the dynamic URL. */ private final String rawUrl; + /** The base URL after applying the variable replacements. */ private String baseUrl; + /** + * Creates an instance of this class with a URL template. + * + * @param rawUrl the URL template with variables wrapped in "{" and "}". + */ public BaseUrlHandler(String rawUrl) { this.rawUrl = rawUrl; this.baseUrl = null; } + /** + * Gets the base URL. + * + * @return the URL template if it's not a dynamic URL or variables in a + * dynamic URL haven't been set. The compiled URL otherwise. + */ public String baseUrl() { if (this.baseUrl == null) { return rawUrl; @@ -35,13 +46,21 @@ public String baseUrl() { return this.baseUrl; } + /** + * Handles dynamic replacements on base URL. The arguments must be in pairs + * with the string in raw URL to replace as replacements[i] and the dynamic + * part as replacements[i+1]. E.g. {subdomain}.microsoft.com can be set + * dynamically by calling setBaseUrl("{subdomain}", "azure"). + * + * @param replacements the string replacements in pairs. + */ public void setBaseUrl(String... replacements) { if (replacements.length % 2 != 0) { throw new IllegalArgumentException("Must provide a replacement value for each pattern"); } baseUrl = rawUrl; for (int i = 0; i < replacements.length; i += 2) { - baseUrl = baseUrl.replace(replacements[i], replacements[i+1]); + baseUrl = baseUrl.replace(replacements[i], replacements[i + 1]); } } diff --git a/client-runtime/src/main/java/com/microsoft/rest/RestClient.java b/client-runtime/src/main/java/com/microsoft/rest/RestClient.java index 448da4e6a2fc..ffc52643040d 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/RestClient.java +++ b/client-runtime/src/main/java/com/microsoft/rest/RestClient.java @@ -23,7 +23,7 @@ /** * An instance of this class stores the client information for making REST calls. */ -public class RestClient { +public final class RestClient { /** The {@link okhttp3.OkHttpClient} object. */ private OkHttpClient httpClient; /** The {@link retrofit2.Retrofit} object. */ From f1585bd793573f6af03657a2bccc9f5a85fcfe4f Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Thu, 12 May 2016 17:07:09 -0700 Subject: [PATCH 39/42] Use SNAPSHOT runtime as dependency --- azure-android-client-authentication/build.gradle | 4 ++-- azure-client-authentication/build.gradle | 4 ++-- azure-client-runtime/build.gradle | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/azure-android-client-authentication/build.gradle b/azure-android-client-authentication/build.gradle index 0884db281a5a..82a0cc5107a0 100644 --- a/azure-android-client-authentication/build.gradle +++ b/azure-android-client-authentication/build.gradle @@ -42,7 +42,7 @@ dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.microsoft.aad:adal:1.1.11' - compile 'com.microsoft.rest:client-runtime:1.0.0-beta1' + compile 'com.microsoft.rest:client-runtime:1.0.0-SNAPSHOT' testCompile 'junit:junit:4.12' testCompile 'junit:junit-dep:4.11' deployerJars "org.apache.maven.wagon:wagon-ftp:2.10" @@ -116,4 +116,4 @@ artifacts { archives sourcesJar archives javadocJar archives file: file("${projectDir}/.gitrevision") -} \ No newline at end of file +} diff --git a/azure-client-authentication/build.gradle b/azure-client-authentication/build.gradle index a04020e1fd37..eaac35660cce 100644 --- a/azure-client-authentication/build.gradle +++ b/azure-client-authentication/build.gradle @@ -20,7 +20,7 @@ checkstyle { dependencies { compile 'com.microsoft.azure:adal4j:1.1.2' - compile 'com.microsoft.rest:client-runtime:1.0.0-beta1' + compile 'com.microsoft.rest:client-runtime:1.0.0-SNAPSHOT' testCompile 'junit:junit:4.12' testCompile 'junit:junit-dep:4.11' deployerJars "org.apache.maven.wagon:wagon-ftp:2.10" @@ -105,4 +105,4 @@ test { reports.html.destination = file("${projectDir}/../../../TestResults/JavaAzureRuntime") } -tasks.compileJava.dependsOn 'clean' \ No newline at end of file +tasks.compileJava.dependsOn 'clean' diff --git a/azure-client-runtime/build.gradle b/azure-client-runtime/build.gradle index 3d90bc184cff..dcdaddcea285 100644 --- a/azure-client-runtime/build.gradle +++ b/azure-client-runtime/build.gradle @@ -20,7 +20,7 @@ checkstyle { } dependencies { - compile 'com.microsoft.rest:client-runtime:1.0.0-beta1' + compile 'com.microsoft.rest:client-runtime:1.0.0-SNAPSHOT' testCompile 'junit:junit:4.12' testCompile 'junit:junit-dep:4.11' deployerJars "org.apache.maven.wagon:wagon-ftp:2.10" From 52021390011a2cefc0c538be1dd543fc46b2ae9a Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Wed, 18 May 2016 20:51:16 -0700 Subject: [PATCH 40/42] Fix styles and tests --- .../java/com/microsoft/rest/UserAgentInterceptor.java | 10 ++++++++++ .../test/java/com/microsoft/rest/UserAgentTests.java | 11 +++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/client-runtime/src/main/java/com/microsoft/rest/UserAgentInterceptor.java b/client-runtime/src/main/java/com/microsoft/rest/UserAgentInterceptor.java index 7705592ba9f7..ac4a5ec5a73c 100644 --- a/client-runtime/src/main/java/com/microsoft/rest/UserAgentInterceptor.java +++ b/client-runtime/src/main/java/com/microsoft/rest/UserAgentInterceptor.java @@ -35,10 +35,20 @@ public UserAgentInterceptor() { this.userAgent = DEFAULT_USER_AGENT_HEADER; } + /** + * Overwrite the User-Agent header. + * + * @param userAgent the new user agent value. + */ public void setUserAgent(String userAgent) { this.userAgent = userAgent; } + /** + * Append a text to the User-Agent header. + * + * @param userAgent the user agent value to append. + */ public void appendUserAgent(String userAgent) { this.userAgent += " " + userAgent; } diff --git a/client-runtime/src/test/java/com/microsoft/rest/UserAgentTests.java b/client-runtime/src/test/java/com/microsoft/rest/UserAgentTests.java index 7949ad843365..35970714e3a8 100644 --- a/client-runtime/src/test/java/com/microsoft/rest/UserAgentTests.java +++ b/client-runtime/src/test/java/com/microsoft/rest/UserAgentTests.java @@ -8,18 +8,17 @@ package com.microsoft.rest; import com.microsoft.rest.serializer.JacksonMapperAdapter; -import okhttp3.Interceptor; -import okhttp3.OkHttpClient; -import okhttp3.Protocol; -import okhttp3.Request; -import okhttp3.Response; -import retrofit2.Retrofit; import org.junit.Assert; import org.junit.Test; import java.io.IOException; +import okhttp3.Interceptor; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; + public class UserAgentTests { @Test public void defaultUserAgentTests() throws Exception { From 1b17bc988c7aec46eb98392c8aa23bf54f62cba9 Mon Sep 17 00:00:00 2001 From: Dave Sescleifer Date: Thu, 2 Jun 2016 12:14:48 -0700 Subject: [PATCH 41/42] Renamed setXXX() to withXXX() for non-top level methods --- .../src/main/java/com/microsoft/azure/AzureClient.java | 2 +- .../src/main/java/com/microsoft/azure/Resource.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java b/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java index f6eaecdb4467..ce28cf8f55d1 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/AzureClient.java @@ -730,7 +730,7 @@ public Integer getLongRunningOperationRetryTimeout() { * * @param longRunningOperationRetryTimeout the time in milliseconds. */ - public void setLongRunningOperationRetryTimeout(Integer longRunningOperationRetryTimeout) { + public void withLongRunningOperationRetryTimeout(Integer longRunningOperationRetryTimeout) { this.longRunningOperationRetryTimeout = longRunningOperationRetryTimeout; } diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/Resource.java b/azure-client-runtime/src/main/java/com/microsoft/azure/Resource.java index f108f9edbc93..b679fc29897e 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/Resource.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/Resource.java @@ -85,7 +85,7 @@ public String location() { * * @param location the location value to set */ - public void setLocation(String location) { + public void withLocation(String location) { this.location = location; } @@ -103,7 +103,7 @@ public Map getTags() { * * @param tags the tags value to set */ - public void setTags(Map tags) { + public void withTags(Map tags) { this.tags = tags; } } \ No newline at end of file From 9c4442d4d185d451777566feca197cc9f9a24127 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Mon, 6 Jun 2016 15:40:47 -0700 Subject: [PATCH 42/42] Address checkstyle errors --- .../src/main/java/com/microsoft/azure/DAGNode.java | 7 +++++++ .../src/main/java/com/microsoft/azure/DAGraph.java | 7 +++++++ .../src/main/java/com/microsoft/azure/Graph.java | 7 +++++++ .../src/main/java/com/microsoft/azure/Node.java | 7 +++++++ .../src/main/java/com/microsoft/azure/TaskGroup.java | 7 +++++++ .../src/main/java/com/microsoft/azure/TaskGroupBase.java | 7 +++++++ .../src/main/java/com/microsoft/azure/TaskItem.java | 7 +++++++ .../azure/{DAGraphTest.java => DAGraphTests.java} | 9 ++++++++- 8 files changed, 57 insertions(+), 1 deletion(-) rename azure-client-runtime/src/test/java/com/microsoft/azure/{DAGraphTest.java => DAGraphTests.java} (96%) diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java b/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java index 438e4d5c8b75..ccc700618e58 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java @@ -1,3 +1,10 @@ +/** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + */ + package com.microsoft.azure; import java.util.ArrayList; diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java b/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java index 388d5599c59c..8b10bde8b3e3 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java @@ -1,3 +1,10 @@ +/** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + */ + package com.microsoft.azure; import java.util.ArrayDeque; diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/Graph.java b/azure-client-runtime/src/main/java/com/microsoft/azure/Graph.java index a4f2c03cde59..0cf8e2a7d231 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/Graph.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/Graph.java @@ -1,3 +1,10 @@ +/** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + */ + package com.microsoft.azure; import java.util.HashMap; diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/Node.java b/azure-client-runtime/src/main/java/com/microsoft/azure/Node.java index e7c4a83768b0..3dc61d8065f6 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/Node.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/Node.java @@ -1,3 +1,10 @@ +/** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + */ + package com.microsoft.azure; import java.util.ArrayList; diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroup.java b/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroup.java index cf522afe9e92..94b4628ff70a 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroup.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroup.java @@ -1,3 +1,10 @@ +/** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + */ + package com.microsoft.azure; /** diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java b/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java index e939e9ae2666..d0dc430edc3a 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java @@ -1,3 +1,10 @@ +/** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + */ + package com.microsoft.azure; /** diff --git a/azure-client-runtime/src/main/java/com/microsoft/azure/TaskItem.java b/azure-client-runtime/src/main/java/com/microsoft/azure/TaskItem.java index bd40a810a5fe..7df830f69bb9 100644 --- a/azure-client-runtime/src/main/java/com/microsoft/azure/TaskItem.java +++ b/azure-client-runtime/src/main/java/com/microsoft/azure/TaskItem.java @@ -1,3 +1,10 @@ +/** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + */ + package com.microsoft.azure; /** diff --git a/azure-client-runtime/src/test/java/com/microsoft/azure/DAGraphTest.java b/azure-client-runtime/src/test/java/com/microsoft/azure/DAGraphTests.java similarity index 96% rename from azure-client-runtime/src/test/java/com/microsoft/azure/DAGraphTest.java rename to azure-client-runtime/src/test/java/com/microsoft/azure/DAGraphTests.java index 8c1e12dd7011..e368b04c89db 100644 --- a/azure-client-runtime/src/test/java/com/microsoft/azure/DAGraphTest.java +++ b/azure-client-runtime/src/test/java/com/microsoft/azure/DAGraphTests.java @@ -1,3 +1,10 @@ +/** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * + */ + package com.microsoft.azure; import org.junit.Assert; @@ -6,7 +13,7 @@ import java.util.ArrayList; import java.util.List; -public class DAGraphTest { +public class DAGraphTests { @Test public void testDAGraphGetNext() { /**