001package com.nimbusds.infinispan.persistence.dynamodb.config; 002 003 004import java.util.Base64; 005import java.util.Properties; 006import java.util.Set; 007 008import com.amazonaws.regions.Regions; 009import com.codahale.metrics.MetricRegistry; 010import org.infinispan.commons.CacheConfigurationException; 011import org.infinispan.configuration.cache.AbstractStoreConfigurationBuilder; 012import org.infinispan.configuration.cache.PersistenceConfigurationBuilder; 013 014 015/** 016 * DynamoDB store configuration builder. 017 * 018 * <p>Used by the Infinispan ConfigurationBuilder to implement fluent 019 * configuration for the DynamoDB CacheLoader / CacheWriter. Methods should use 020 * the fluent style, rather than the setter/getter style and should return an 021 * instance of this object. 022 */ 023public class DynamoDBStoreConfigurationBuilder 024 extends AbstractStoreConfigurationBuilder<DynamoDBStoreConfiguration,DynamoDBStoreConfigurationBuilder> 025 implements DynamoDBStoreConfigurationChildBuilder<DynamoDBStoreConfigurationBuilder> { 026 027 028 /** 029 * Creates a new DynamoDB store configuration builder. 030 * 031 * @param builder The general persistence configuration builder. 032 */ 033 public DynamoDBStoreConfigurationBuilder(final PersistenceConfigurationBuilder builder) { 034 super(builder, DynamoDBStoreConfiguration.attributeDefinitionSet()); 035 } 036 037 038 @Override 039 public DynamoDBStoreConfiguration create() { 040 // This method should construct a new instance of a 041 // DynamoDBStoreConfiguration object. There will be one 042 // instance per cache. 043 return new DynamoDBStoreConfiguration( 044 this.attributes.protect(), 045 this.async.create(), 046 this.singleton().create()); 047 } 048 049 050 @Override 051 public DynamoDBStoreConfigurationBuilder endpoint(final String endpoint) { 052 053 this.attributes.attribute(DynamoDBStoreConfiguration.ENDPOINT).set(endpoint); 054 return this; 055 } 056 057 058 @Override 059 public DynamoDBStoreConfigurationBuilder region(final Regions region) { 060 061 this.attributes.attribute(DynamoDBStoreConfiguration.REGION).set(region); 062 return this; 063 } 064 065 066 @Override 067 public DynamoDBStoreConfigurationBuilder itemTransformerClass(final Class itemTransformerClass) { 068 069 this.attributes.attribute(DynamoDBStoreConfiguration.ITEM_TRANSFORMER).set(itemTransformerClass); 070 return this; 071 } 072 073 074 @Override 075 public DynamoDBStoreConfigurationBuilder queryExecutorClass(final Class queryExecutorClass) { 076 077 this.attributes.attribute(DynamoDBStoreConfiguration.QUERY_EXECUTOR).set(queryExecutorClass); 078 return this; 079 } 080 081 082 @Override 083 public DynamoDBStoreConfigurationBuilder indexedAttributes(final Set<String> indexAttributes) { 084 085 this.attributes.attribute(DynamoDBStoreConfiguration.INDEXED_ATTRIBUTES).set(indexAttributes); 086 return this; 087 } 088 089 090 @Override 091 public DynamoDBStoreConfigurationBuilder consistentReads(final boolean enable) { 092 093 this.attributes.attribute(DynamoDBStoreConfiguration.CONSISTENT_READS).set(enable); 094 return this; 095 } 096 097 098 @Override 099 public DynamoDBStoreConfigurationBuilder readCapacity(long readCapacity) { 100 101 this.attributes.attribute(DynamoDBStoreConfiguration.READ_CAPACITY).set(readCapacity); 102 return this; 103 } 104 105 106 @Override 107 public DynamoDBStoreConfigurationBuilder writeCapacity(long writeCapacity) { 108 109 this.attributes.attribute(DynamoDBStoreConfiguration.WRITE_CAPACITY).set(writeCapacity); 110 return this; 111 } 112 113 114 @Override 115 public DynamoDBStoreConfigurationBuilder tableWithEncryptionAtRest(boolean encryptionAtRest) { 116 117 this.attributes.attribute(DynamoDBStoreConfiguration.ENCRYPTION_AT_REST).set(encryptionAtRest); 118 return this; 119 } 120 121 122 @Override 123 public DynamoDBStoreConfigurationBuilder tablePrefix(final String tablePrefix) { 124 125 this.attributes.attribute(DynamoDBStoreConfiguration.TABLE_PREFIX).set(tablePrefix); 126 return this; 127 } 128 129 @Override 130 public DynamoDBStoreConfigurationBuilder metricRegistry(final MetricRegistry metricRegistry) { 131 132 this.attributes.attribute(DynamoDBStoreConfiguration.METRIC_REGISTRY).set(metricRegistry); 133 return this; 134 } 135 136 137 @Override 138 public DynamoDBStoreConfigurationBuilder applyRangeKey(final String rangeKeyName) { 139 140 this.attributes.attribute(DynamoDBStoreConfiguration.APPLY_RANGE_KEY).set(rangeKeyName); 141 return this; 142 } 143 144 145 @Override 146 public DynamoDBStoreConfigurationBuilder rangeKeyValue(final String rangeKeyValue) { 147 148 this.attributes.attribute(DynamoDBStoreConfiguration.RANGE_KEY_VALUE).set(rangeKeyValue); 149 return this; 150 } 151 152 153 @Override 154 public DynamoDBStoreConfigurationBuilder enableStream(final boolean enable) { 155 156 this.attributes.attribute(DynamoDBStoreConfiguration.ENABLE_STREAM).set(enable); 157 return this; 158 } 159 160 161 @Override 162 public DynamoDBStoreConfigurationBuilder enableContinuousBackups(final boolean enable) { 163 164 this.attributes.attribute(DynamoDBStoreConfiguration.ENABLE_CONTINUOUS_BACKUPS).set(enable); 165 return this; 166 } 167 168 169 @Override 170 public DynamoDBStoreConfigurationBuilder enableTTL(final boolean enable) { 171 172 this.attributes.attribute(DynamoDBStoreConfiguration.ENABLE_TTL).set(enable); 173 return this; 174 } 175 176 177 @Override 178 public DynamoDBStoreConfigurationBuilder purgeLimit(final int purgeLimit) { 179 180 this.attributes.attribute(DynamoDBStoreConfiguration.PURGE_LIMIT).set(purgeLimit); 181 return this; 182 } 183 184 185 @Override 186 public DynamoDBStoreConfigurationBuilder httpProxyHost(final String host) { 187 188 this.attributes.attribute(DynamoDBStoreConfiguration.HTTP_PROXY_HOST).set(host); 189 return this; 190 } 191 192 193 @Override 194 public DynamoDBStoreConfigurationBuilder httpProxyPort(final int port) { 195 196 this.attributes.attribute(DynamoDBStoreConfiguration.HTTP_PROXY_PORT).set(port); 197 return this; 198 } 199 200 201 @Override 202 public DynamoDBStoreConfigurationBuilder hmacSHA256Key(final String key) { 203 204 this.attributes.attribute(DynamoDBStoreConfiguration.HMAC_SHA_256_KEY).set(key); 205 return this; 206 } 207 208 209 @Override 210 public DynamoDBStoreConfigurationBuilder withProperties(final Properties properties) { 211 212 return properties(properties); 213 } 214 215 216 @Override 217 public void validate() { 218 219 super.validate(); 220 221 if (this.attributes.attribute(DynamoDBStoreConfiguration.ITEM_TRANSFORMER).get() == null) { 222 throw new CacheConfigurationException("A DynamoDB store item transformer class must be specified"); 223 } 224 225 if (this.attributes.attribute(DynamoDBStoreConfiguration.QUERY_EXECUTOR) != null 226 && this.attributes.attribute(DynamoDBStoreConfiguration.INDEXED_ATTRIBUTES) == null) { 227 228 throw new CacheConfigurationException("The indexed attributes must be specified if a query executor is set"); 229 } 230 231 if (this.attributes.attribute(DynamoDBStoreConfiguration.QUERY_EXECUTOR) == null 232 && this.attributes.attribute(DynamoDBStoreConfiguration.INDEXED_ATTRIBUTES) != null) { 233 234 throw new CacheConfigurationException("The query executor must be set if indexed attributes are specified"); 235 } 236 237 String rangeKeyName = this.attributes.attribute(DynamoDBStoreConfiguration.APPLY_RANGE_KEY).get(); 238 String rangeKeyValue = this.attributes.attribute(DynamoDBStoreConfiguration.RANGE_KEY_VALUE).get(); 239 240 if (rangeKeyName != null && ! rangeKeyName.trim().isEmpty()) { 241 242 if (rangeKeyValue == null || rangeKeyValue.trim().isEmpty()) { 243 throw new CacheConfigurationException("A range key value must be specified"); 244 } 245 } 246 247 if (this.attributes.attribute(DynamoDBStoreConfiguration.HMAC_SHA_256_KEY).get() != null) { 248 249 byte[] keyBytes = Base64.getDecoder().decode(this.attributes.attribute(DynamoDBStoreConfiguration.HMAC_SHA_256_KEY).get()); 250 251 if (keyBytes.length < (256 / 8)) { 252 throw new CacheConfigurationException("The HMAC SHA-256 key must be at least 256 bits long"); 253 } 254 } 255 } 256 257 258 @Override 259 public DynamoDBStoreConfigurationBuilder self() { 260 return this; 261 } 262}