Repository: jclouds Updated Branches: refs/heads/2.1.x ca063d8bf -> 951b6b440
JCLOUDS-1441: Enables support for ARM regions in China Adds new china regions Fixes pattern matching for China provider oauth string Modifies test for oauth string overrides jclouds.oauth.resource property for tests Graph and Vault API Endpoints need to be configurable jclouds.oauth.resource is not mandatory Adapted Endpoints for APIs GraphRBAC and Vault Adds unit test for china oauth endpoint check Minor fix to regular expression Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/951b6b44 Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/951b6b44 Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/951b6b44 Branch: refs/heads/2.1.x Commit: 951b6b440334bc9ff76ee6fcad8520cd67e4dda3 Parents: ca063d8 Author: Dani Estevez <[email protected]> Authored: Fri Aug 10 12:15:44 2018 -0400 Committer: Dani Estevez <[email protected]> Committed: Thu Sep 6 10:40:42 2018 -0400 ---------------------------------------------------------------------- .../arm/config/AzureComputeHttpApiModule.java | 16 ++- .../arm/config/AzureOAuthConfigFactory.java | 11 +- .../azurecompute/arm/config/GraphRBAC.java | 13 +- .../azurecompute/arm/config/OAuthResource.java | 5 +- .../jclouds/azurecompute/arm/domain/Region.java | 2 + .../azurecompute/arm/features/GraphRBACApi.java | 2 +- .../azurecompute/arm/features/VaultApi.java | 123 ++++++++++--------- .../arm/config/IsChinaEndpointTest.java | 38 ++++++ .../arm/config/ParseTenantIdTest.java | 7 +- .../internal/BaseAzureComputeApiLiveTest.java | 3 +- 10 files changed, 146 insertions(+), 74 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds/blob/951b6b44/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeHttpApiModule.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeHttpApiModule.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeHttpApiModule.java index c01fc0a..10a981e 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeHttpApiModule.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeHttpApiModule.java @@ -54,7 +54,12 @@ import com.google.inject.name.Named; public class AzureComputeHttpApiModule extends HttpApiModule<AzureComputeApi> { private static final Pattern OAUTH_TENANT_PATTERN = Pattern - .compile("https://login.microsoft(?:online)?.com/([^/]+)/oauth2/token"); + .compile("https://login.(microsoft(?:online)?.com|chinacloudapi.cn)/([^/]+)/oauth2/token"); + + private static final Pattern CHINA_OAUTH_ENDPOINT_PATTERN = Pattern + .compile("https://login.chinacloudapi.cn/([^/]+)/oauth2/token"); + + public static final String IS_CHINA_ENDPOINT = "jclouds.isChinaEndpoint"; @Override protected void bindErrorHandlers() { @@ -92,7 +97,14 @@ public class AzureComputeHttpApiModule extends HttpApiModule<AzureComputeApi> { if (!m.matches()) { throw new IllegalArgumentException("Could not parse tenantId from: " + oauthEndpoint); } - return m.group(1); + return m.group(2); + } + + @Provides + @Singleton + @Named(IS_CHINA_ENDPOINT) + protected final boolean isChinaEndpoint(@Named("oauth.endpoint") final String oauthEndpoint) { + return CHINA_OAUTH_ENDPOINT_PATTERN.matcher(oauthEndpoint).matches(); } @Provides http://git-wip-us.apache.org/repos/asf/jclouds/blob/951b6b44/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureOAuthConfigFactory.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureOAuthConfigFactory.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureOAuthConfigFactory.java index 9128b59..7b946b5 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureOAuthConfigFactory.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureOAuthConfigFactory.java @@ -16,6 +16,7 @@ */ package org.jclouds.azurecompute.arm.config; +import static org.jclouds.azurecompute.arm.config.AzureComputeHttpApiModule.IS_CHINA_ENDPOINT; import static org.jclouds.oauth.v2.config.OAuthProperties.AUDIENCE; import static org.jclouds.oauth.v2.config.OAuthProperties.RESOURCE; @@ -29,7 +30,7 @@ import com.google.inject.name.Named; public class AzureOAuthConfigFactory implements OAuthConfigFactory { private final OAuthScopes scopes; - + @Named(AUDIENCE) @Inject(optional = true) private String audience; @@ -38,6 +39,10 @@ public class AzureOAuthConfigFactory implements OAuthConfigFactory { @Inject(optional = true) private String resource; + @Named(IS_CHINA_ENDPOINT) + @Inject(optional = true) + private boolean isChinaEndpoint; + @Inject AzureOAuthConfigFactory(OAuthScopes scopes) { this.scopes = scopes; @@ -54,7 +59,9 @@ public class AzureOAuthConfigFactory implements OAuthConfigFactory { .getAnnotation(OAuthResource.class); } } - String oauthResource = customResource != null ? customResource.value() : resource; + String oauthResource = customResource == null ? + resource : + (isChinaEndpoint ? customResource.chinaEndpoint() : customResource.value()); return OAuthConfig.create(scopes.forRequest(input), audience, oauthResource); } } http://git-wip-us.apache.org/repos/asf/jclouds/blob/951b6b44/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/GraphRBAC.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/GraphRBAC.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/GraphRBAC.java index a7f8b4f..11b13c7 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/GraphRBAC.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/GraphRBAC.java @@ -16,13 +16,15 @@ */ package org.jclouds.azurecompute.arm.config; +import static org.jclouds.azurecompute.arm.config.AzureComputeHttpApiModule.IS_CHINA_ENDPOINT; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.net.URI; - import javax.inject.Inject; +import javax.inject.Named; import javax.inject.Qualifier; import com.google.common.base.Supplier; @@ -35,19 +37,22 @@ import com.google.common.base.Supplier; @Qualifier public @interface GraphRBAC { - String ENDPOINT = "https://graph.windows.net/"; + String STANDARD_ENDPOINT = "https://graph.windows.net/"; + String CHINA_ENDPOINT = "https://graph.chinacloudapi.cn/"; static class GraphRBACForTenant implements Supplier<URI> { private final String tenantId; + private final boolean isChinaEndpoint; @Inject - GraphRBACForTenant(@Tenant String tenantId) { + GraphRBACForTenant(@Tenant String tenantId, @Named(IS_CHINA_ENDPOINT) boolean isChinaEndpoint) { this.tenantId = tenantId; + this.isChinaEndpoint = isChinaEndpoint; } @Override public URI get() { - return URI.create(GraphRBAC.ENDPOINT + tenantId); + return URI.create((isChinaEndpoint ? CHINA_ENDPOINT : STANDARD_ENDPOINT) + tenantId); } } http://git-wip-us.apache.org/repos/asf/jclouds/blob/951b6b44/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/OAuthResource.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/OAuthResource.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/OAuthResource.java index 6e5a2df..e034964 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/OAuthResource.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/OAuthResource.java @@ -20,7 +20,6 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; - import javax.inject.Qualifier; /** @@ -30,6 +29,8 @@ import javax.inject.Qualifier; @Target(value = { ElementType.TYPE, ElementType.METHOD }) @Qualifier public @interface OAuthResource { - + String value(); + + String chinaEndpoint(); } http://git-wip-us.apache.org/repos/asf/jclouds/blob/951b6b44/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Region.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Region.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Region.java index ea607a0..b448ca3 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Region.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Region.java @@ -60,7 +60,9 @@ public enum Region { SOUTH_INDIA("South India", "IN-TN"), WEST_INDIA("West India", "IN-MH"), CHINA_EAST("China East", "CN-SH"), + CHINA_EAST_2("China East 2", "CN-SH"), CHINA_NORTH("China North", "CN-BJ"), + CHINA_NORTH_2("China North 2", "CN-BJ"), CANADA_CENTRAL("Canada Central", "CA-ON"), CANADA_EAST("Canada East", "CA-QC"), FRANCE_CENTRAL("France Central", "FR-IDF"), http://git-wip-us.apache.org/repos/asf/jclouds/blob/951b6b44/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/GraphRBACApi.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/GraphRBACApi.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/GraphRBACApi.java index fe2bccc..38de117 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/GraphRBACApi.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/GraphRBACApi.java @@ -37,7 +37,7 @@ import com.google.inject.name.Named; @RequestFilters({ OAuthFilter.class, ApiVersionFilter.class }) @Consumes(MediaType.APPLICATION_JSON) @Endpoint(GraphRBAC.class) -@OAuthResource(GraphRBAC.ENDPOINT) +@OAuthResource(value = GraphRBAC.STANDARD_ENDPOINT, chinaEndpoint = GraphRBAC.CHINA_ENDPOINT) public interface GraphRBACApi { @Named("servicePrincipal:get") http://git-wip-us.apache.org/repos/asf/jclouds/blob/951b6b44/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/VaultApi.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/VaultApi.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/VaultApi.java index 5ae39ba..3165b17 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/VaultApi.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/VaultApi.java @@ -19,7 +19,6 @@ package org.jclouds.azurecompute.arm.features; import java.net.URI; import java.util.List; import java.util.Map; - import javax.inject.Named; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -30,8 +29,6 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.core.MediaType; -import com.google.common.base.Function; - import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404; import org.jclouds.Fallbacks.FalseOnNotFoundOr404; import org.jclouds.Fallbacks.NullOnNotFoundOr404; @@ -75,15 +72,21 @@ import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.Fallback; import org.jclouds.rest.annotations.MapBinder; import org.jclouds.rest.annotations.PATCH; +import org.jclouds.rest.annotations.ParamParser; import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.SelectJson; import org.jclouds.rest.binders.BindToJsonPayload; -import org.jclouds.rest.annotations.ParamParser; + +import com.google.common.base.Function; @RequestFilters({ OAuthFilter.class, ApiVersionFilter.class }) @Consumes(MediaType.APPLICATION_JSON) public interface VaultApi { + + String VAULT_API_STANDARD_ENDPOINT = "https://vault.azure.net"; + String VAULT_API_CHINA_ENDPOINT = "https://vault.azure.cn"; + static class PrependSlashOrEmptyString implements Function<Object, String> { public String apply(Object from) { if ((from == null) || (from.toString().length() == 0)) { @@ -146,14 +149,14 @@ public interface VaultApi { @GET @Fallback(EmptyListOnNotFoundOr404.class) @Path("/keys") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) List<Key> listKeys(@EndpointParam URI keyVaultUri); @Named("key:create") @POST @MapBinder(BindToJsonPayload.class) @Path("/keys/{keyName}/create") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) KeyBundle createKey(@EndpointParam URI vaultBaseUrl, @PathParam("keyName") String keyName, @Nullable @PayloadParam("attributes") KeyAttributes attributes, @Nullable @PayloadParam("crv") String curveName, @Nullable @PayloadParam("key_ops") List<String> keyOps, @@ -164,7 +167,7 @@ public interface VaultApi { @PUT @MapBinder(BindToJsonPayload.class) @Path("/keys/{keyName}") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) KeyBundle importKey(@EndpointParam URI vaultBaseUrl, @PathParam("keyName") String keyName, @PayloadParam("Hsm") boolean hsm, @Nullable @PayloadParam("attributes") KeyAttributes attributes, @Nullable @PayloadParam("key") JsonWebKey key, @Nullable @PayloadParam("tags") Map<String, String> tags); @@ -173,14 +176,14 @@ public interface VaultApi { @GET @Path("/keys/{keyName}") @Fallback(NullOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) KeyBundle getKey(@EndpointParam URI vaultBaseUrl, @PathParam("keyName") String keyName); @Named("key:delete") @DELETE @Path("/keys/{keyName}") @Fallback(NullOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) DeletedKeyBundle deleteKey(@EndpointParam URI vaultBaseUrl, @PathParam("keyName") String keyName); @Named("key:get_versions") @@ -188,14 +191,14 @@ public interface VaultApi { @SelectJson("value") @Path("/keys/{keyName}/versions") @Fallback(EmptyListOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) List<Key> getKeyVersions(@EndpointParam URI vaultBaseUrl, @PathParam("keyName") String keyName); @Named("key:update") @PATCH @MapBinder(BindToJsonPayload.class) @Path("/keys/{keyName}{keyVersion}") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) KeyBundle updateKey(@EndpointParam URI vaultBaseUrl, @PathParam("keyName") String keyName, @Nullable @PathParam("keyVersion") @ParamParser(PrependSlashOrEmptyString.class) String keyVersion, @@ -207,14 +210,14 @@ public interface VaultApi { @POST @SelectJson("value") @Path("/keys/{keyName}/backup") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) String backupKey(@EndpointParam URI vaultBaseUrl, @PathParam("keyName") String keyName); @Named("key:restore") @POST @MapBinder(BindToJsonPayload.class) @Path("/keys/restore") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) KeyBundle restoreKey(@EndpointParam URI vaultBaseUrl, @PayloadParam("value") String keyInfo); // Soft-delete key operations @@ -223,27 +226,27 @@ public interface VaultApi { @SelectJson("value") @Path("/deletedkeys") @Fallback(EmptyListOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) List<DeletedKeyBundle> listDeletedKeys(@EndpointParam URI vaultBaseUrl); @Named("key:get_deleted") @GET @Path("/deletedkeys/{keyName}") @Fallback(NullOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) DeletedKeyBundle getDeletedKey(@EndpointParam URI vaultBaseUrl, @PathParam("keyName") String keyName); @Named("key:recover_deleted") @POST @Path("/deletedkeys/{keyName}/recover") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) KeyBundle recoverDeletedKey(@EndpointParam URI vaultBaseUrl, @PathParam("keyName") String keyName); @Named("key:purge_deleted") @DELETE @Path("/deletedkeys/{keyName}") @Fallback(FalseOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) boolean purgeDeletedKey(@EndpointParam URI vaultBaseUrl, @PathParam("keyName") String keyName); // Key cryptographic operations @@ -251,7 +254,7 @@ public interface VaultApi { @POST @Path("/keys/{keyName}{keyVersion}/encrypt") @MapBinder(BindToJsonPayload.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) KeyOperationResult encrypt(@EndpointParam URI vaultBaseUrl, @PathParam("keyName") String keyName, @Nullable @PathParam("keyVersion") @ParamParser(PrependSlashOrEmptyString.class) String keyVersion, @@ -262,7 +265,7 @@ public interface VaultApi { @POST @Path("/keys/{keyName}{keyVersion}/decrypt") @MapBinder(BindToJsonPayload.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) KeyOperationResult decrypt(@EndpointParam URI vaultBaseUrl, @PathParam("keyName") String keyName, @Nullable @PathParam("keyVersion") @ParamParser(PrependSlashOrEmptyString.class) String keyVersion, @@ -273,7 +276,7 @@ public interface VaultApi { @POST @Path("/keys/{keyName}{keyVersion}/sign") @MapBinder(BindToJsonPayload.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) KeyOperationResult sign(@EndpointParam URI vaultBaseUrl, @PathParam("keyName") String keyName, @Nullable @PathParam("keyVersion") @ParamParser(PrependSlashOrEmptyString.class) String keyVersion, @@ -284,7 +287,7 @@ public interface VaultApi { @POST @Path("/keys/{keyName}{keyVersion}/verify") @MapBinder(BindToJsonPayload.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) boolean verify(@EndpointParam URI vaultBaseUrl, @PathParam("keyName") String keyName, @Nullable @PathParam("keyVersion") @ParamParser(PrependSlashOrEmptyString.class) String keyVersion, @@ -296,7 +299,7 @@ public interface VaultApi { @POST @Path("/keys/{keyName}{keyVersion}/wrapkey") @MapBinder(BindToJsonPayload.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) KeyOperationResult wrap(@EndpointParam URI vaultBaseUrl, @PathParam("keyName") String keyName, @Nullable @PathParam("keyVersion") @ParamParser(PrependSlashOrEmptyString.class) String keyVersion, @@ -307,7 +310,7 @@ public interface VaultApi { @POST @Path("/keys/{keyName}{keyVersion}/unwrapkey") @MapBinder(BindToJsonPayload.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) KeyOperationResult unwrap(@EndpointParam URI vaultBaseUrl, @PathParam("keyName") String keyName, @Nullable @PathParam("keyVersion") @ParamParser(PrependSlashOrEmptyString.class) String keyVersion, @@ -320,14 +323,14 @@ public interface VaultApi { @GET @Fallback(EmptyListOnNotFoundOr404.class) @Path("/secrets") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) List<Secret> listSecrets(@EndpointParam URI keyVaultUri); @Named("secret:set") @PUT @MapBinder(BindToJsonPayload.class) @Path("/secrets/{secretName}") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) SecretBundle setSecret(@EndpointParam URI keyVaultUri, @PathParam("secretName") String secretName, @Nullable @PayloadParam("attributes") SecretAttributes attributes, @Nullable @PayloadParam("contentType") String contentType, @@ -337,7 +340,7 @@ public interface VaultApi { @GET @Path("/secrets/{secretName}{secretVersion}") @Fallback(NullOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) SecretBundle getSecret(@EndpointParam URI vaultBaseUrl, @PathParam("secretName") String secretName, @Nullable @PathParam("secretVersion") @ParamParser(PrependSlashOrEmptyString.class) String secretVersion); @@ -346,7 +349,7 @@ public interface VaultApi { @DELETE @Path("/secrets/{secretName}") @Fallback(NullOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) DeletedSecretBundle deleteSecret(@EndpointParam URI vaultBaseUrl, @PathParam("secretName") String secretName); @Named("secret:get_versions") @@ -354,14 +357,14 @@ public interface VaultApi { @SelectJson("value") @Path("/secrets/{secretName}/versions") @Fallback(EmptyListOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) List<Secret> getSecretVersions(@EndpointParam URI vaultBaseUrl, @PathParam("secretName") String secretName); @Named("secret:update") @PATCH @MapBinder(BindToJsonPayload.class) @Path("/secrets/{secretName}{secretVersion}") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) SecretBundle updateSecret(@EndpointParam URI vaultBaseUrl, @PathParam("secretName") String secretName, @Nullable @PathParam("secretVersion") @ParamParser(PrependSlashOrEmptyString.class) String secretVersion, @@ -373,14 +376,14 @@ public interface VaultApi { @POST @SelectJson("value") @Path("/secrets/{secretName}/backup") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) String backupSecret(@EndpointParam URI vaultBaseUrl, @PathParam("secretName") String secretName); @Named("secret:restore") @POST @MapBinder(BindToJsonPayload.class) @Path("/secrets/restore") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) SecretBundle restoreSecret(@EndpointParam URI vaultBaseUrl, @PayloadParam("value") String secretInfo); // Soft-delete secret operations @@ -389,27 +392,27 @@ public interface VaultApi { @SelectJson("value") @Path("/deletedsecrets") @Fallback(EmptyListOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) List<DeletedSecretBundle> listDeletedSecrets(@EndpointParam URI vaultBaseUrl); @Named("secret:get_deleted") @GET @Path("/deletedsecrets/{secretName}") @Fallback(NullOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) DeletedSecretBundle getDeletedSecret(@EndpointParam URI vaultBaseUrl, @PathParam("secretName") String secretName); @Named("secret:recover_deleted") @POST @Path("/deletedsecrets/{secretName}/recover") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) SecretBundle recoverDeletedSecret(@EndpointParam URI vaultBaseUrl, @PathParam("secretName") String secretName); @Named("secret:purge_deleted") @DELETE @Path("/deletedsecrets/{secretName}") @Fallback(FalseOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) boolean purgeDeletedSecret(@EndpointParam URI vaultBaseUrl, @PathParam("secretName") String secretName); // Certificate operations @@ -417,7 +420,7 @@ public interface VaultApi { @POST @MapBinder(BindToJsonPayload.class) @Path("/certificates/{certificateName}/create") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) CertificateOperation createCertificate(@EndpointParam URI vaultBaseUrl, @PathParam("certificateName") String certificateName, @Nullable @PayloadParam("attributes") CertificateAttributes attributes, @@ -428,7 +431,7 @@ public interface VaultApi { @GET @Path("/certificates/{certificateName}{certificateVersion}") @Fallback(NullOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) CertificateBundle getCertificate(@EndpointParam URI vaultBaseUrl, @PathParam("certificateName") String certificateName, @Nullable @PathParam("certificateVersion") @ParamParser(PrependSlashOrEmptyString.class) String certificateVersion); @@ -437,7 +440,7 @@ public interface VaultApi { @DELETE @Path("/certificates/{certificateName}") @Fallback(NullOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) DeletedCertificateBundle deleteCertificate(@EndpointParam URI vaultBaseUrl, @PathParam("certificateName") String certificateName); @@ -446,7 +449,7 @@ public interface VaultApi { @SelectJson("value") @Path("/certificates") @Fallback(EmptyListOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) List<Certificate> getCertificates(@EndpointParam URI vaultBaseUrl); @Named("certificate:list_deleted") @@ -454,21 +457,21 @@ public interface VaultApi { @SelectJson("value") @Path("/deletedcertificates") @Fallback(EmptyListOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) List<DeletedCertificate> getDeletedCertificates(@EndpointParam URI vaultBaseUrl); @Named("certificate:get_deleted") @GET @Path("/deletedcertificates/{certificateName}") @Fallback(NullOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) DeletedCertificateBundle getDeletedCertificate(@EndpointParam URI vaultBaseUrl, @PathParam("certificateName") String certificateName); @Named("certificate:recover_deleted") @POST @Path("/deletedcertificates/{certificateName}/recover") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) CertificateBundle recoverDeletedCertificate(@EndpointParam URI vaultBaseUrl, @PathParam("certificateName") String certificateName); @@ -476,7 +479,7 @@ public interface VaultApi { @DELETE @Path("/deletedcertificates/{certificateName}") @Fallback(FalseOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) boolean purgeDeletedCertificate(@EndpointParam URI vaultBaseUrl, @PathParam("certificateName") String certificateName); @Named("certificate:get_versions") @@ -484,7 +487,7 @@ public interface VaultApi { @SelectJson("value") @Path("/certificates/{certificateName}/versions") @Fallback(EmptyListOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) List<Certificate> getCertificateVersions(@EndpointParam URI vaultBaseUrl, @PathParam("certificateName") String certificateName); @@ -492,7 +495,7 @@ public interface VaultApi { @PATCH @MapBinder(BindToJsonPayload.class) @Path("/certificates/{certificateName}{certificateVersion}") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) CertificateBundle updateCertificate(@EndpointParam URI vaultBaseUrl, @PathParam("certificateName") String certificateName, @Nullable @PathParam("certificateVersion") @ParamParser(PrependSlashOrEmptyString.class) String certificateVersion, @@ -504,7 +507,7 @@ public interface VaultApi { @POST @MapBinder(BindToJsonPayload.class) @Path("/certificates/{certificateName}/import") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) CertificateBundle importCertificate(@EndpointParam URI vaultBaseUrl, @PathParam("certificateName") String certificateName, @Nullable @PayloadParam("attributes") CertificateAttributes attributes, @@ -515,7 +518,7 @@ public interface VaultApi { @POST @MapBinder(BindToJsonPayload.class) @Path("/certificates/{certificateName}/pending/merge") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) CertificateBundle mergeCertificate(@EndpointParam URI vaultBaseUrl, @PathParam("certificateName") String certificateName, @Nullable @PayloadParam("attributes") CertificateAttributes attributes, @@ -525,7 +528,7 @@ public interface VaultApi { @GET @Path("/certificates/{certificateName}/pending") @Fallback(NullOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) CertificateOperation getCertificateOperation(@EndpointParam URI vaultBaseUrl, @PathParam("certificateName") String certificateName); @@ -533,7 +536,7 @@ public interface VaultApi { @PATCH @Path("/certificates/{certificateName}/pending") @MapBinder(BindToJsonPayload.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) CertificateOperation updateCertificateOperation(@EndpointParam URI vaultBaseUrl, @PathParam("certificateName") String certificateName, @PayloadParam("cancellation_requested") boolean cancellationRequested); @@ -542,7 +545,7 @@ public interface VaultApi { @DELETE @Path("/certificates/{certificateName}/pending") @Fallback(NullOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) CertificateOperation deleteCertificateOperation(@EndpointParam URI vaultBaseUrl, @PathParam("certificateName") String certificateName); @@ -550,7 +553,7 @@ public interface VaultApi { @PUT @Path("/certificates/issuers/{issuerName}") @MapBinder(BindToJsonPayload.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) IssuerBundle setCertificateIssuer(@EndpointParam URI vaultBaseUrl, @PathParam("issuerName") String issuerName, @Nullable @PayloadParam("attributes") IssuerAttributes attributes, @Nullable @PayloadParam("credentials") IssuerCredentials credentials, @@ -562,21 +565,21 @@ public interface VaultApi { @SelectJson("value") @Path("/certificates/issuers") @Fallback(EmptyListOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) List<CertificateIssuer> getCertificateIssuers(@EndpointParam URI vaultBaseUrl); @Named("certificate:get_issuer") @GET @Path("/certificates/issuers/{issuerName}") @Fallback(NullOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) IssuerBundle getCertificateIssuer(@EndpointParam URI vaultBaseUrl, @PathParam("issuerName") String issuerName); @Named("certificate:update_issuer") @PATCH @Path("/certificates/issuers/{issuerName}") @MapBinder(BindToJsonPayload.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) IssuerBundle updateCertificateIssuer(@EndpointParam URI vaultBaseUrl, @PathParam("issuerName") String issuerName, @Nullable @PayloadParam("attributes") IssuerAttributes attributes, @Nullable @PayloadParam("credentials") IssuerCredentials credentials, @@ -587,35 +590,35 @@ public interface VaultApi { @DELETE @Path("/certificates/issuers/{issuerName}") @Fallback(NullOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) IssuerBundle deleteCertificateIssuer(@EndpointParam URI vaultBaseUrl, @PathParam("issuerName") String issuerName); @Named("certificate:get_contacts") @GET @Path("/certificates/contacts") @Fallback(NullOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) Contacts getCertificateContacts(@EndpointParam URI vaultBaseUrl); @Named("certificate:set_contacts") @PUT @Path("/certificates/contacts") @MapBinder(BindToJsonPayload.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) Contacts setCertificateContacts(@EndpointParam URI vaultBaseUrl, @PayloadParam("contacts") List<Contact> contacts); @Named("certificate:delete_contacts") @DELETE @Path("/certificates/contacts") @Fallback(NullOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) Contacts deleteCertificateContacts(@EndpointParam URI vaultBaseUrl); @Named("certificate:get_policy") @GET @Path("/certificates/{certificateName}/policy") @Fallback(NullOnNotFoundOr404.class) - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) CertificatePolicy getCertificatePolicy(@EndpointParam URI vaultBaseUrl, @PathParam("certificateName") String certificateName); @@ -623,7 +626,7 @@ public interface VaultApi { @PATCH @MapBinder(BindToJsonPayload.class) @Path("/certificates/{certificateName}/policy") - @OAuthResource("https://vault.azure.net") + @OAuthResource(value = VAULT_API_STANDARD_ENDPOINT, chinaEndpoint = VAULT_API_CHINA_ENDPOINT) CertificatePolicy updateCertificatePolicy(@EndpointParam URI vaultBaseUrl, @PathParam("certificateName") String certificateName, @Nullable @PayloadParam("attributes") CertificateAttributes attributes, http://git-wip-us.apache.org/repos/asf/jclouds/blob/951b6b44/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/config/IsChinaEndpointTest.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/config/IsChinaEndpointTest.java b/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/config/IsChinaEndpointTest.java new file mode 100644 index 0000000..35d9820 --- /dev/null +++ b/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/config/IsChinaEndpointTest.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.azurecompute.arm.config; + +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import org.testng.annotations.Test; + +@Test(groups = "unit", testName = "IsChinaEndpointTest") +public class IsChinaEndpointTest { + + @Test + public void testIsChinaEndpoint() { + AzureComputeHttpApiModule module = new AzureComputeHttpApiModule(); + + assertTrue(module.isChinaEndpoint("https://login.chinacloudapi.cn/tenantId/oauth2/token")); + assertFalse(module.isChinaEndpoint("http://login.chinacloudapi.cn/tenantId/oauth2/token")); + assertFalse(module.isChinaEndpoint("https://login.chinacloudapi.cn/otherpaths/not/oauth")); + assertFalse(module.isChinaEndpoint("https://login.microsoftonline.com/tenantId/oauth2/token")); + assertFalse(module.isChinaEndpoint("https://login.microsoft.com/otherpaths/not/oauth")); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/951b6b44/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/config/ParseTenantIdTest.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/config/ParseTenantIdTest.java b/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/config/ParseTenantIdTest.java index 5894505..2fafdc9 100644 --- a/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/config/ParseTenantIdTest.java +++ b/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/config/ParseTenantIdTest.java @@ -30,12 +30,15 @@ public class ParseTenantIdTest { assertEquals(module.provideTenant("https://login.microsoftonline.com/tenantId/oauth2/token"), "tenantId"); assertEquals(module.provideTenant("https://login.microsoft.com/tenant2/oauth2/token"), "tenant2"); - + assertEquals(module.provideTenant("https://login.chinacloudapi.cn/tenantId/oauth2/token"), "tenantId"); + assertEquals(module.provideTenant("https://login.chinacloudapi.cn/tenant2/oauth2/token"), "tenant2"); + assertInvalid(module, "https://login.microsoftonline.com/a/b/c/oauth2/token"); assertInvalid(module, "https://login.microsoft.com/a/b/c/oauth2/token"); assertInvalid(module, "https://login.microsoftonline.com//oauth2/token"); assertInvalid(module, "https://login.microsoft.com//oauth2/token"); - assertInvalid(module, "https://login.microsoftabc.com/tenant/oauth2/token"); + assertInvalid(module, "https://login.chinacloudapi.cn/a/b/c/oauth2/token"); + assertInvalid(module, "https://login.chinacloudapi.cn//oauth2/token"); } private static void assertInvalid(AzureComputeHttpApiModule module, String endpoint) { http://git-wip-us.apache.org/repos/asf/jclouds/blob/951b6b44/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/BaseAzureComputeApiLiveTest.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/BaseAzureComputeApiLiveTest.java b/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/BaseAzureComputeApiLiveTest.java index 11bed4d..50f2e41 100644 --- a/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/BaseAzureComputeApiLiveTest.java +++ b/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/BaseAzureComputeApiLiveTest.java @@ -17,7 +17,6 @@ package org.jclouds.azurecompute.arm.internal; import static com.google.common.base.Preconditions.checkNotNull; - import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED; import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_CERTIFICATE_DELETE_STATUS; import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_CERTIFICATE_OPERATION_STATUS; @@ -28,6 +27,7 @@ import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_K import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_SECRET_DELETE_STATUS; import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_SECRET_RECOVERABLE_STATUS; import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE; +import static org.jclouds.oauth.v2.config.OAuthProperties.RESOURCE; import static org.jclouds.util.Predicates2.retry; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; @@ -166,6 +166,7 @@ public class BaseAzureComputeApiLiveTest extends BaseApiLiveTest<AzureComputeApi // for oauth AzureLiveTestUtils.defaultProperties(properties); checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint"); + setIfTestSystemPropertyPresent(properties, RESOURCE); return properties; }
