1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.cache.ehcache3.setup;
35
36 import info.magnolia.jcr.util.NodeTypes;
37 import info.magnolia.jcr.util.NodeUtil;
38 import info.magnolia.jcr.util.PropertyUtil;
39 import info.magnolia.module.InstallContext;
40 import info.magnolia.module.cache.ehcache3.EhCache3Factory;
41 import info.magnolia.module.cache.ehcache3.configuration.EhCache3ConfigurationBuilder;
42 import info.magnolia.module.cache.ehcache3.configuration.EhCache3Expiry;
43 import info.magnolia.module.cache.ehcache3.configuration.Ehcache3ResourcePoolBuilder;
44 import info.magnolia.module.cache.ehcache3.configuration.Ehcache3ResourcePoolsBuilder;
45 import info.magnolia.module.delta.AbstractRepositoryTask;
46 import info.magnolia.module.delta.RemoveNodeTask;
47 import info.magnolia.module.delta.TaskExecutionException;
48
49 import java.io.Serializable;
50
51 import javax.jcr.Node;
52 import javax.jcr.NodeIterator;
53 import javax.jcr.Property;
54 import javax.jcr.RepositoryException;
55 import javax.jcr.Session;
56
57 import org.ehcache.config.ResourceType;
58 import org.ehcache.config.units.EntryUnit;
59 import org.ehcache.config.units.MemoryUnit;
60
61
62
63
64 public class MigrateEhCache2ConfigurationTask extends AbstractRepositoryTask {
65
66 private static final String[] NOT_SUPPORTED_PROPERTIES = new String[]{
67 "diskSpoolBufferSizeMB",
68 "diskExpiryThreadIntervalSeconds",
69 "memoryStoreEvictionPolicy",
70 "timeToIdleSeconds",
71 };
72
73 public MigrateEhCache2ConfigurationTask() {
74 super("EhCache persistence settings", "Migrates Ehcache 2.x config to Ehcache 3.x");
75 }
76
77 @Override
78 protected void doExecute(InstallContext ctx) throws RepositoryException, TaskExecutionException {
79 final Session session = ctx.getConfigJCRSession();
80 final Node ehCacheFactory = session.getNode("/modules/cache/config/cacheFactory/delegateFactories/ehcache/");
81 final Property factoryClass = PropertyUtil.getPropertyOrNull(ehCacheFactory, "class");
82 if (!"info.magnolia.module.cache.ehcache.EhCacheFactory".equals(factoryClass.getString())) {
83 ctx.warn(String.format("Cannot migrate EhCache 2.x to EhCache3.x, expected {%s/%s}} but got {%s}", "/modules/cache/config/cacheFactory/class", "info.magnolia.module.cache.ehcache.EhCacheFactory", factoryClass.getString()));
84 return;
85 }
86 factoryClass.setValue(EhCache3Factory.class.getName());
87
88 NodeUtil.renameNode(ehCacheFactory, "ehcache3");
89
90 NodeIterator cachesIterator = ehCacheFactory.getNode("caches").getNodes();
91 while (cachesIterator.hasNext()) {
92 final Node cache = cachesIterator.nextNode();
93 cache.setProperty("class", EhCache3ConfigurationBuilder.class.getName());
94 cache.setProperty("keyType", Serializable.class.getName());
95 cache.setProperty("valueType", Serializable.class.getName());
96
97 final Node expiry = cache.addNode("expiry", NodeTypes.ContentNode.NAME);
98 expiry.setProperty("class", EhCache3Expiry.class.getName());
99 final String timeToLiveSeconds = getValueAndRemove(cache, "timeToLiveSeconds", null);
100 final String eternal = getValueAndRemove(cache, "eternal", Boolean.FALSE.toString());
101 if (Boolean.FALSE.toString().equals(eternal) && timeToLiveSeconds != null) {
102 expiry.setProperty("create", Long.valueOf(timeToLiveSeconds));
103 }
104 final Node resourcePoolsBuilder = cache.addNode("resourcePoolsBuilder", NodeTypes.ContentNode.NAME);
105 resourcePoolsBuilder.setProperty("class", Ehcache3ResourcePoolsBuilder.class.getName());
106 final Node resourcePools = resourcePoolsBuilder.addNode("pools", NodeTypes.ContentNode.NAME);
107
108 final Node heap = resourcePools.addNode("heap", NodeTypes.ContentNode.NAME);
109 heap.setProperty("class", Ehcache3ResourcePoolBuilder.class.getName());
110 heap.setProperty("resourceType", ResourceType.Core.HEAP.name());
111 heap.setProperty("resourceUnit", EntryUnit.ENTRIES.name());
112 heap.setProperty("size", Long.valueOf(getValueAndRemove(cache, "maxElementsInMemory", "10000")));
113
114 final Boolean overflowToOffHeap = Boolean.valueOf(getValueAndRemove(cache, "overflowToOffHeap", Boolean.FALSE.toString()));
115 if (overflowToOffHeap) {
116 final String maxBytesLocalOffHeap = getValueAndRemove(cache, "maxBytesLocalOffHeap", null);
117 final Node offHeap = resourcePools.addNode("offheap", NodeTypes.ContentNode.NAME);
118 offHeap.setProperty("class", Ehcache3ResourcePoolBuilder.class.getName());
119 offHeap.setProperty("resourceType", ResourceType.Core.OFFHEAP.name());
120 offHeap.setProperty("resourceUnit", MemoryUnit.MB.name());
121 offHeap.setProperty("size", Long.valueOf(maxBytesLocalOffHeap) / 1000000);
122 }
123
124
125 for (String property : NOT_SUPPORTED_PROPERTIES) {
126 getValueAndRemove(cache, property, null);
127 }
128
129 final Node persistence = cache.getNode("persistence");
130 final String strategy = getValueAndRemove(persistence, "strategy", "LOCALTEMPSWAP").toUpperCase();
131 persistence.remove();
132 if ("DISTRIBUTED".equals(strategy)) {
133 ctx.warn(String.format("You are using {DISTRIBUTED} persistence. You have to extend {%s} and set up a clustered cache manager according to {%s} to support distributed configuration.", "info.magnolia.module.cache.ehcache3.EhCache3Factory.init()", "http://www.ehcache.org/documentation/3.3/clustered-cache.html#creating-a-cache-manager-with-clustering-capabilities"));
134 } else if (!"NONE".equals(strategy)) {
135 final Node disk = resourcePools.addNode("disk", NodeTypes.ContentNode.NAME);
136 disk.setProperty("class", Ehcache3ResourcePoolBuilder.class.getName());
137 disk.setProperty("persistent", Boolean.TRUE);
138 disk.setProperty("resourceType", ResourceType.Core.DISK.name());
139 disk.setProperty("resourceUnit", MemoryUnit.MB.name());
140 disk.setProperty("size", Long.valueOf(getValueAndRemove(cache, "maxElementsOnDisk", "10000000")) / 10000);
141 }
142 }
143 new RemoveNodeTask("", "/modules/ehcache").execute(ctx);
144 }
145
146 private String getValueAndRemove(Node node, String propertyName, String defaultValue) throws RepositoryException {
147 String value = defaultValue;
148 if (node.hasProperty(propertyName)) {
149 final Property maxElementsInMemoryProperty = node.getProperty(propertyName);
150 value = maxElementsInMemoryProperty.getString();
151 maxElementsInMemoryProperty.remove();
152 }
153 return value;
154 }
155 }