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}