001package com.nimbusds.infinispan.persistence.sql;
002
003
004import java.util.Properties;
005
006import com.nimbusds.common.config.ConfigurationException;
007import com.nimbusds.common.config.LoggableConfiguration;
008import com.thetransactioncompany.util.PropertyParseException;
009import com.thetransactioncompany.util.PropertyRetriever;
010import net.jcip.annotations.Immutable;
011import org.infinispan.commons.configuration.BuiltBy;
012import org.infinispan.commons.configuration.ConfigurationFor;
013import org.infinispan.commons.util.StringPropertyReplacer;
014import org.infinispan.configuration.cache.AbstractStoreConfiguration;
015import org.infinispan.configuration.cache.AsyncStoreConfiguration;
016import org.infinispan.configuration.cache.SingletonStoreConfiguration;
017import org.jooq.SQLDialect;
018
019
020/**
021 * SQL store configuration.
022 *
023 * <p>Example SQL store configuration:
024 *
025 * <pre>
026 * sqlStore.recordTransformer = com.nimbusds.infinispan.persistence.sql.UserEntityTransformer
027 * sqlStore.sqlDialect = H2
028 * </pre>
029 */
030@Immutable
031@BuiltBy(SQLStoreConfigurationBuilder.class)
032@ConfigurationFor(SQLStore.class)
033public class SQLStoreConfiguration extends AbstractStoreConfiguration implements LoggableConfiguration {
034        
035        
036        /**
037         * The name of the class for transforming between Infinispan entries
038         * (key / value pair and optional metadata) and a corresponding SQL
039         * record.
040         *
041         * <p>See {@link SQLRecordTransformer}.
042         *
043         * <p>Property key: sqlStore.recordTransformer
044         */
045        public final String recordTransformer;
046        
047        
048        /**
049         * The SQL dialect.
050         *
051         * <p>Property key: sqlStore.sqlDialect
052         */
053        public final SQLDialect sqlDialect;
054
055
056        /**
057         * Creates a new SQL store configuration from the specified properties.
058         * All other settings assume defaults.
059         *
060         * @param properties The SQL store specific configuration properties.
061         *                   Must not be {@code null}.
062         */
063        public SQLStoreConfiguration(final Properties properties) {
064
065                this(
066                        false, // purgeOnStartup
067                        false, // fetchPersistentState
068                        false, // ignoreModifications
069                        null,  // AsyncStoreConfiguration
070                        null,  // SingletonStoreConfiguration
071                        false, // preload
072                        true, // shared
073                        properties);
074        }
075
076
077        /**
078         * Creates a new SQL store configuration.
079         *
080         * @param purgeOnStartup       If {@code true} the cache store will be
081         *                             purged when it starts up.
082         * @param fetchPersistentState If {@code true} the persistent state
083         *                             be fetched when joining a cluster.
084         * @param ignoreModifications  If {@code true} any operation that
085         *                             modifies the cache (put, remove, clear,
086         *                             store...etc) won't be applied to the
087         *                             cache store. This means that the cache
088         *                             store could become out of sync with the
089         *                             cache.
090         * @param async                Configuration for the async cache
091         *                             loader.
092         * @param singletonStore       Configuration for a singleton store.
093         * @param preload              If {@code true} when the cache starts
094         *                             data stored in the cache loader will be
095         *                             pre-loaded into memory.
096         * @param shared               If {@code true} the cache store is
097         *                             shared among all cache instances.
098         * @param properties           The SQL store specific configuration
099         *                             properties. Must not be {@code null}.
100         */
101        public SQLStoreConfiguration(final boolean purgeOnStartup,
102                                     final boolean fetchPersistentState,
103                                     final boolean ignoreModifications,
104                                     final AsyncStoreConfiguration async,
105                                     final SingletonStoreConfiguration singletonStore,
106                                     final boolean preload,
107                                     final boolean shared,
108                                     final Properties properties) {
109
110                super(
111                        purgeOnStartup,
112                        fetchPersistentState,
113                        ignoreModifications,
114                        async,
115                        singletonStore,
116                        preload,
117                        shared,
118                        properties);
119
120                if (properties == null || properties.isEmpty()) {
121                        throw new ConfigurationException("Missing SQL store configuration properties, check the service documentation");
122                }
123                
124                // Interpolate with system properties where ${sysPropName} is found
125                Properties interpolatedProps = new Properties();
126                for (String name: properties.stringPropertyNames()) {
127                        interpolatedProps.setProperty(name, StringPropertyReplacer.replaceProperties(properties.getProperty(name)));
128                }
129                
130                PropertyRetriever pr = new PropertyRetriever(interpolatedProps);
131                
132                try {
133                        recordTransformer = pr.getString("sqlStore.recordTransformer");
134                        
135                        sqlDialect = SQLDialect.valueOf(SQLDialect.class, pr.getString("sqlStore.sqlDialect").toUpperCase());
136                        
137                } catch (PropertyParseException e) {
138                        throw new ConfigurationException(e.getMessage() +
139                                ": Property: " + e.getPropertyKey() +
140                                ": Value: " + e.getPropertyValue());
141                }
142        }
143
144
145        @Override
146        public void log() {
147                
148                Loggers.MAIN_LOG.info("[IS0000] Infinispan SQL store: Record transformer class: {} ", recordTransformer);
149                Loggers.MAIN_LOG.info("[IS0001] Infinispan SQL store: SQL dialect: {} ", sqlDialect);
150                Loggers.MAIN_LOG.info("[IS0002] Infinispan SQL store: JDBC URL: {} ", properties().getProperty("jdbcUrl"));
151        }
152}