View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shardingsphere.globalclock.type.tso.provider.redis;
19  
20  import com.google.common.base.Strings;
21  import org.apache.shardingsphere.globalclock.type.tso.provider.TSOProvider;
22  import redis.clients.jedis.Jedis;
23  import redis.clients.jedis.JedisPool;
24  import redis.clients.jedis.JedisPoolConfig;
25  
26  import java.util.Properties;
27  import java.util.concurrent.atomic.AtomicBoolean;
28  
29  /**
30   * Redis TSO provider.
31   */
32  public final class RedisTSOProvider implements TSOProvider {
33      
34      private static final String CSN_KEY = "csn";
35      
36      private static final long ERROR_CSN = 0L;
37      
38      private static final long INIT_CSN = Integer.MAX_VALUE;
39      
40      private final AtomicBoolean initialized = new AtomicBoolean(false);
41      
42      private JedisPool jedisPool;
43      
44      @Override
45      public void init(final Properties props) {
46          if (initialized.compareAndSet(false, true)) {
47              createJedisPool(props);
48              checkJedisPool();
49              initCSN();
50          }
51      }
52      
53      private void createJedisPool(final Properties props) {
54          JedisPoolConfig config = new JedisPoolConfig();
55          config.setMaxIdle(Integer.parseInt(getValue(props, RedisTSOPropertyKey.MAX_IDLE)));
56          config.setMaxTotal(Integer.parseInt(getValue(props, RedisTSOPropertyKey.MAX_TOTAL)));
57          jedisPool = new JedisPool(config, getValue(props, RedisTSOPropertyKey.HOST), Integer.parseInt(getValue(props, RedisTSOPropertyKey.PORT)),
58                  Integer.parseInt(getValue(props, RedisTSOPropertyKey.TIMEOUT_INTERVAL)), getValue(props, RedisTSOPropertyKey.PASSWORD));
59      }
60      
61      private String getValue(final Properties props, final RedisTSOPropertyKey propertyKey) {
62          return props.containsKey(propertyKey.getKey()) ? props.getProperty(propertyKey.getKey()) : propertyKey.getDefaultValue();
63      }
64      
65      private void checkJedisPool() {
66          try (Jedis jedis = jedisPool.getResource()) {
67              jedis.ping();
68          }
69      }
70      
71      private void initCSN() {
72          try (Jedis jedis = jedisPool.getResource()) {
73              String originalCSN = jedis.get(CSN_KEY);
74              if (Strings.isNullOrEmpty(originalCSN) || String.valueOf(ERROR_CSN).equals(originalCSN)) {
75                  jedis.set(CSN_KEY, String.valueOf(INIT_CSN));
76              }
77          }
78      }
79      
80      @Override
81      public long getCurrentTimestamp() {
82          try (Jedis jedis = jedisPool.getResource()) {
83              // TODO use redis lock to instead of reg center's lock. lock here #35041
84              return Long.parseLong(jedis.get(CSN_KEY));
85          }
86      }
87      
88      @Override
89      public long getNextTimestamp() {
90          try (Jedis jedis = jedisPool.getResource()) {
91              return jedis.incr(CSN_KEY);
92              // TODO use redis lock to instead of reg center's lock. unlock here #35041
93          }
94      }
95      
96      @Override
97      public String getType() {
98          return "TSO.redis";
99      }
100 }