View Javadoc
1   /*
2    *    Copyright 2016-2022 the original author or authors.
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       https://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  package org.mybatis.caches.ignite;
17  
18  import java.io.File;
19  import java.util.concurrent.locks.ReadWriteLock;
20  
21  import org.apache.ibatis.cache.Cache;
22  import org.apache.ibatis.logging.Log;
23  import org.apache.ibatis.logging.LogFactory;
24  import org.apache.ignite.Ignite;
25  import org.apache.ignite.IgniteCache;
26  import org.apache.ignite.IgniteIllegalStateException;
27  import org.apache.ignite.Ignition;
28  import org.apache.ignite.cache.CachePeekMode;
29  import org.apache.ignite.configuration.CacheConfiguration;
30  import org.springframework.beans.factory.BeanDefinitionStoreException;
31  import org.springframework.beans.factory.NoSuchBeanDefinitionException;
32  import org.springframework.beans.factory.support.DefaultListableBeanFactory;
33  import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
34  import org.springframework.core.io.FileSystemResource;
35  
36  /**
37   * Cache adapter for Ignite. Cache is initialized from IGNITE_HOME/config/default-config.xml settings, otherwise default
38   * one is started.
39   *
40   * @author Roman Shtykh
41   */
42  public final class IgniteCacheAdapter implements Cache {
43  
44    /** Logger. */
45    private static final Log log = LogFactory.getLog(IgniteCacheAdapter.class);
46  
47    /** Cache id. */
48    private final String id;
49  
50    /**
51     * {@code ReadWriteLock}.
52     */
53    private final ReadWriteLock readWriteLock = new DummyReadWriteLock();
54  
55    /** Grid instance. */
56    private static final Ignite ignite;
57  
58    /** Cache. */
59    private final IgniteCache<Object, Object> cache;
60  
61    /** Ignite configuration file path. */
62    private static final String CFG_PATH = "config/default-config.xml";
63  
64    static {
65      boolean started = false;
66      try {
67        Ignition.ignite();
68        started = true;
69      } catch (IgniteIllegalStateException e) {
70        log.debug("Using the Ignite instance that has been already started.");
71        log.trace("" + e);
72      }
73      if (started) {
74        ignite = Ignition.ignite();
75      } else {
76        ignite = Ignition.start();
77      }
78    }
79  
80    /**
81     * Constructor.
82     *
83     * @param id
84     *          Cache id.
85     */
86    @SuppressWarnings("unchecked")
87    public IgniteCacheAdapter(String id) {
88      if (id == null) {
89        throw new IllegalArgumentException("Cache instances require an ID");
90      }
91  
92      CacheConfiguration<Object, Object> cacheCfg = null;
93  
94      try {
95        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
96  
97        new XmlBeanDefinitionReader(factory).loadBeanDefinitions(new FileSystemResource(new File(CFG_PATH)));
98  
99        cacheCfg = (CacheConfiguration<Object, Object>) factory.getBean("templateCacheCfg");
100 
101       cacheCfg.setEvictionPolicy(null);
102       cacheCfg.setCacheLoaderFactory(null);
103       cacheCfg.setCacheWriterFactory(null);
104 
105       // overrides template cache name with the specified id.
106       cacheCfg.setName(id);
107     } catch (NoSuchBeanDefinitionException | BeanDefinitionStoreException e) {
108       // initializes the default cache.
109       log.warn("Initializing the default cache. Consider properly configuring '" + CFG_PATH + "' instead.");
110       log.trace("" + e);
111 
112       cacheCfg = new CacheConfiguration<>(id);
113     }
114 
115     cache = ignite.getOrCreateCache(cacheCfg);
116 
117     this.id = id;
118   }
119 
120   @Override
121   public String getId() {
122     return this.id;
123   }
124 
125   @Override
126   public void putObject(Object key, Object value) {
127     cache.put(key, value);
128   }
129 
130   @Override
131   public Object getObject(Object key) {
132     return cache.get(key);
133   }
134 
135   @Override
136   public Object removeObject(Object key) {
137     return cache.remove(key);
138   }
139 
140   @Override
141   public void clear() {
142     cache.clear();
143   }
144 
145   @Override
146   public int getSize() {
147     return cache.size(CachePeekMode.PRIMARY);
148   }
149 
150   @Override
151   public ReadWriteLock getReadWriteLock() {
152     return readWriteLock;
153   }
154 }