/**
* 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.google.common.base.Function;
import com.google.common.collect.Lists;
import com.microsoft.azure.management.apigeneration.LangDefinition;
import com.microsoft.azure.management.apigeneration.Method;
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.Sku;
import com.microsoft.azure.management.redis.ScheduleEntry;
import com.microsoft.azure.management.redis.SkuFamily;
import com.microsoft.azure.management.redis.SkuName;
import com.microsoft.azure.management.resources.fluentcore.arm.models.HasId;
import com.microsoft.azure.management.resources.fluentcore.arm.models.implementation.GroupableResourceImpl;
import com.microsoft.azure.management.resources.fluentcore.utils.SdkContext;
import com.microsoft.azure.management.resources.fluentcore.utils.Utils;
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 RedisAccessKeys cachedAccessKeys;
private RedisCreateParametersInner createParameters;
private RedisUpdateParametersInner updateParameters;
private Map<DayOfWeek, ScheduleEntry> scheduleEntries;
RedisCacheImpl(String name,
RedisResourceInner innerModel,
final RedisManager redisManager) {
super(name, innerModel, redisManager);
this.createParameters = new RedisCreateParametersInner();
this.scheduleEntries = new TreeMap<>();
}
@Override
public String provisioningState() {
return this.inner().provisioningState();
}
@Override
public String hostName() {
return this.inner().hostName();
}
@Override
public int port() {
return Utils.toPrimitiveInt(this.inner().port());
}
@Override
public int sslPort() {
return Utils.toPrimitiveInt(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 Utils.toPrimitiveInt(this.inner().shardCount());
}
@Override
public String subnetId() {
return this.inner().subnetId();
}
@Override
public String staticIP() {
return this.inner().staticIP();
}
@Override
public Map<String, String> redisConfiguration() {
return Collections.unmodifiableMap(this.inner().redisConfiguration());
}
@Override
@Method
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.manager().inner().redis().listKeys(this.resourceGroupName(), this.name());
cachedAccessKeys = new RedisAccessKeysImpl(response);
return cachedAccessKeys;
}
@Override
public RedisAccessKeys regenerateKey(RedisKeyType keyType) {
RedisAccessKeysInner response =
this.manager().inner().redis().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.manager().inner().redis().forceReboot(this.resourceGroupName(), this.name(), parameters);
}
@Override
public void forceReboot(RebootType rebootType, int shardId) {
RedisRebootParametersInner parameters = new RedisRebootParametersInner()
.withRebootType(rebootType)
.withShardId(shardId);
this.manager().inner().redis().forceReboot(this.resourceGroupName(), this.name(), parameters);
}
@Override
public void importData(List<String> files) {
ImportRDBParametersInner parameters = new ImportRDBParametersInner()
.withFiles(files);
this.manager().inner().redis().importData(this.resourceGroupName(), this.name(), parameters);
}
@Override
public void importData(List<String> files, String fileFormat) {
ImportRDBParametersInner parameters = new ImportRDBParametersInner()
.withFiles(files)
.withFormat(fileFormat);
this.manager().inner().redis().importData(this.resourceGroupName(), this.name(), parameters);
}
@Override
public void exportData(String containerSASUrl, String prefix) {
ExportRDBParametersInner parameters = new ExportRDBParametersInner()
.withContainer(containerSASUrl)
.withPrefix(prefix);
this.manager().inner().redis().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.manager().inner().redis().exportData(this.resourceGroupName(), this.name(), parameters);
}
@Override
protected Observable<RedisResourceInner> getInnerAsync() {
return this.manager().inner().redis().getByResourceGroupAsync(this.resourceGroupName(), this.name());
}
@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<String, String> 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<String, String>());
}
createParameters.redisConfiguration().put(key, value);
} else {
if (updateParameters.redisConfiguration() == null) {
updateParameters.withRedisConfiguration(new TreeMap<String, String>());
}
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(HasId 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> scheduleEntries) {
this.scheduleEntries.clear();
for (ScheduleEntry entry : scheduleEntries) {
this.withPatchSchedule(entry);
}
return this;
}
@Override
public RedisCacheImpl withPatchSchedule(ScheduleEntry scheduleEntry) {
this.scheduleEntries.put(scheduleEntry.dayOfWeek(), scheduleEntry);
return this;
}
@Override
public List<ScheduleEntry> listPatchSchedules() {
RedisPatchScheduleInner patchSchedules = this.manager().inner().patchSchedules().get(resourceGroupName(), name());
if (patchSchedules != null) {
return Lists.transform(patchSchedules.scheduleEntries(),
new Function<ScheduleEntryInner, ScheduleEntry>() {
public ScheduleEntry apply(ScheduleEntryInner entryInner) {
return new ScheduleEntry(entryInner);
}
});
}
return null;
}
@Override
public void deletePatchSchedule() {
this.manager().inner().patchSchedules().delete(resourceGroupName(), name());
}
private void updatePatchSchedules() {
if (this.scheduleEntries != null && !this.scheduleEntries.isEmpty()) {
RedisPatchScheduleInner parameters = new RedisPatchScheduleInner()
.withScheduleEntries(new ArrayList<ScheduleEntryInner>());
for (ScheduleEntry entry : this.scheduleEntries.values()) {
parameters.scheduleEntries().add(new ScheduleEntryInner()
.withDayOfWeek(entry.dayOfWeek())
.withMaintenanceWindow(entry.maintenanceWindow())
.withStartHourUtc(entry.startHourUtc()));
}
this.manager().inner().patchSchedules().createOrUpdate(resourceGroupName(), name(), parameters.scheduleEntries());
}
}
@Override
public RedisCacheImpl update() {
this.updateParameters = new RedisUpdateParametersInner();
this.scheduleEntries = new TreeMap<>();
return super.update();
}
@Override
public Observable<RedisCache> updateResourceAsync() {
final RedisCacheImpl self = this;
return this.manager().inner().redis().updateAsync(resourceGroupName(), name(), updateParameters)
.map(innerToFluentMap(this))
.doOnNext(new Action1<RedisCache>() {
@Override
public void call(RedisCache redisCache) {
while (!redisCache.provisioningState().equalsIgnoreCase("Succeeded")) {
SdkContext.sleep(30 * 1000);
RedisResourceInner innerResource = self.manager().inner().redis().getByResourceGroup(resourceGroupName(), name());
((RedisCacheImpl) redisCache).setInner(innerResource);
self.setInner(innerResource);
}
updatePatchSchedules();
}
});
}
@Override
public Observable<RedisCache> createResourceAsync() {
createParameters.withLocation(this.regionName());
createParameters.withTags(this.inner().getTags());
return this.manager().inner().redis().createAsync(this.resourceGroupName(), this.name(), createParameters)
.map(innerToFluentMap(this))
.doOnNext(new Action1<RedisCache>() {
@Override
public void call(RedisCache redisCache) {
updatePatchSchedules();
}
});
}
}