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.setup;
35
36 import info.magnolia.cms.beans.config.ContentRepository;
37 import info.magnolia.cms.core.Content;
38 import info.magnolia.cms.core.HierarchyManager;
39 import info.magnolia.cms.core.ItemType;
40 import info.magnolia.module.DefaultModuleVersionHandler;
41 import info.magnolia.module.InstallContext;
42 import info.magnolia.module.cache.RegisterWorkspaceForCacheFlushingTask;
43 import info.magnolia.module.delta.AbstractRepositoryTask;
44 import info.magnolia.module.delta.ArrayDelegateTask;
45 import info.magnolia.module.delta.BackupTask;
46 import info.magnolia.module.delta.BootstrapConditionally;
47 import info.magnolia.module.delta.BootstrapResourcesTask;
48 import info.magnolia.module.delta.BootstrapSingleResource;
49 import info.magnolia.module.delta.CheckAndModifyPropertyValueTask;
50 import info.magnolia.module.delta.Condition;
51 import info.magnolia.module.delta.CreateNodeTask;
52 import info.magnolia.module.delta.DeltaBuilder;
53 import info.magnolia.module.delta.FilterOrderingTask;
54 import info.magnolia.module.delta.MoveNodeTask;
55 import info.magnolia.module.delta.NewPropertyTask;
56 import info.magnolia.module.delta.NodeExistsDelegateTask;
57 import info.magnolia.module.delta.PropertyExistsDelegateTask;
58 import info.magnolia.module.delta.RemoveNodeTask;
59 import info.magnolia.module.delta.RemovePropertyTask;
60 import info.magnolia.module.delta.SetPropertyTask;
61 import info.magnolia.module.delta.Task;
62 import info.magnolia.module.delta.TaskExecutionException;
63 import info.magnolia.module.delta.WarnTask;
64 import info.magnolia.module.delta.WebXmlConditionsUtil;
65
66 import java.util.ArrayList;
67 import java.util.List;
68
69 import javax.jcr.RepositoryException;
70
71
72
73
74
75
76
77 public class CacheModuleVersionHandler extends DefaultModuleVersionHandler {
78
79 public CacheModuleVersionHandler() {
80 super();
81 final List<Condition> conditions = new ArrayList<Condition>();
82 final WebXmlConditionsUtil u = new WebXmlConditionsUtil(conditions);
83 u.servletIsRemoved("CacheServlet");
84 u.servletIsRemoved("CacheGeneratorServlet");
85 register(DeltaBuilder.update("3.5.0", "").addConditions(conditions)
86
87
88 );
89
90 final NodeExistsDelegateTask addFilterIfNotExisting = new NodeExistsDelegateTask("Check cache filter", "A bug in previous 3.5 releases made it possible for the cache filter to be removed. This task readds it if necessary.",
91 ContentRepository.CONFIG, "/server/filters/cache", null, new ArrayDelegateTask("",
92 new BootstrapSingleResource("", "", "/mgnl-bootstrap/cache/config.server.filters.cache.xml"),
93 new FilterOrderingTask("cache", new String[]{"i18n"}),
94 new WarnTask("", "The cache filter was not found, and was just added. If you removed it on purpose, you should consider disabling it instead.")));
95
96 register(DeltaBuilder.update("3.5.9", "")
97 .addTask(addFilterIfNotExisting)
98 );
99
100 register(DeltaBuilder.update("3.6", "New cache API and configuration.")
101 .addTask(new BackupTask("config", "/modules/cache/config", true))
102 .addTask(new BootstrapResourcesTask("New configuration", "Bootstraps new default cache configuration.") {
103 protected String[] getResourcesToBootstrap(final InstallContext installContext) {
104 return new String[]{
105 "/mgnl-bootstrap/cache/config.modules.cache.config.configurations.default.xml",
106 "/mgnl-bootstrap/cache/config.modules.cache.config.cacheFactory.xml"
107 };
108 }
109 })
110 .addTask(new ArrayDelegateTask("New cache filter", "Replaces the old cache filter with info.magnolia.module.cache.filter.CacheFilter.",
111 new CheckAndModifyPropertyValueTask("", "", ContentRepository.CONFIG, "/server/filters/cache", "class", "info.magnolia.cms.cache.CacheFilter", "info.magnolia.module.cache.filter.CacheFilter"),
112 new NewPropertyTask("", "", ContentRepository.CONFIG, "/server/filters/cache", "cacheConfigurationName", "default")
113 ))
114 .addTask(new FilterOrderingTask("cache", "The cache filter should now be placed before the i18n filter.", new String[]{"context", "multipartRequest", "activation"}))
115 .addTask(new ArrayDelegateTask("New gzip filter", "Adds the new gzip filter.",
116 new BootstrapSingleResource("", "", "/mgnl-bootstrap/cache/config.server.filters.gzip.xml"),
117 new FilterOrderingTask("gzip", new String[]{"cache"})
118 ))
119 );
120
121 register(DeltaBuilder.update("3.6.2", "Updated executors and filter configuration.")
122 .addTask(new BootstrapResourcesTask("Updated configuration", "Bootstraps new default cache configuration.") {
123 protected String[] getResourcesToBootstrap(final InstallContext installContext) {
124 return new String[]{
125 "/mgnl-bootstrap/cache/setup/config.modules.cache.config.configurations.default.executors.store.cacheContent.compressible.xml",
126 "/mgnl-bootstrap/cache/setup/config.modules.cache.config.configurations.default.executors.store.serveContent.xml"
127 };
128 }
129 })
130 .addTask(new FilterOrderingTask("cache", "The gzip filter should now be placed before the cache filter.", new String[]{"gzip"}))
131 );
132
133 register(DeltaBuilder.update("3.6.4", "Update gzip and cache compression configuration.").addTasks(getTasksFor364()));
134
135 register(DeltaBuilder.update("4.1", "New flush policy configuration.").addTask(
136 new ArrayDelegateTask("New flush policy configuration", "Sets up the new flush policy configuration.",
137
138 new MoveNodeTask("","", ContentRepository.CONFIG, "/modules/cache/config/configurations/default/flushPolicy","/modules/cache/config/configurations/default/tmp", false),
139
140 new CreateNodeTask("","", ContentRepository.CONFIG, "/modules/cache/config/configurations/default", "flushPolicy", ItemType.CONTENTNODE.getSystemName()),
141 new SetPropertyTask(ContentRepository.CONFIG,"/modules/cache/config/configurations/default/flushPolicy", "class", "info.magnolia.module.cache.DelegateFlushPolicy"),
142 new CreateNodeTask("","", ContentRepository.CONFIG, "/modules/cache/config/configurations/default/flushPolicy", "policies", ItemType.CONTENTNODE.getSystemName()),
143
144 new MoveNodeTask("","", ContentRepository.CONFIG, "/modules/cache/config/configurations/default/tmp","/modules/cache/config/configurations/default/flushPolicy/policies/flushAll", false)
145 )));
146
147 register(DeltaBuilder.update("4.3", "Makes cache aware of different sites and locales used to access the content")
148 .addTask(new NodeExistsDelegateTask("Check cache filter", "Reorder i18n filter prior to cache filter to allow cache access to i18n information.",
149 ContentRepository.CONFIG, "/server/filters/cache", new FilterOrderingTask("cache", new String[]{"i18n"}),
150 new WarnTask("", "The cache filter was not found. If you removed it on purpose, you should consider disabling it instead.")))
151 .addTask(new PropertyExistsDelegateTask("Cache policy re-configuration", "Removes no longer used multihost property from default cache policy.", ContentRepository.CONFIG, "/modules/cache/config/configurations/default/cachePolicy", "multiplehosts", new RemovePropertyTask("", "", ContentRepository.CONFIG, "/modules/cache/config/configurations/default/cachePolicy", "multiplehosts")))
152 .addTask(new ArrayDelegateTask("Cache Flushing","Adds new commands to flush the cache.",
153 new BootstrapSingleResource("", "", "/mgnl-bootstrap/cache/config.modules.cache.commands.cache.flushAll.xml"),
154 new BootstrapSingleResource("", "", "/mgnl-bootstrap/cache/config.modules.cache.commands.cache.flushByUUID.xml")))
155 .addTask(new BootstrapSingleResource("Cache Flushing", "Adds cache configuration for uuid-key caching.", "/mgnl-bootstrap/cache/config.modules.cache.config.configurations.uuid-key-mapping.xml"))
156 );
157
158 register(DeltaBuilder.update("4.3.1", "Disables server side re-caching of requests with no-cache header (shift reload)")
159 .addTask(new NewPropertyTask("Disabling no-cache requests", "Disable server side re-caching of requests with no-cache header (shift reload)", "config", "/modules/cache/config/configurations/default/cachePolicy", "refreshOnNoCacheRequests", "false"))
160 .addTask(new WarnTask("Warning", "Server side re-caching of requests with no-cache header (shift reload) were disabled. This can be changed at /modules/cache/config/configurations/default/cachePolicy/refreshOnNoCacheRequests"))
161 );
162 register(DeltaBuilder.update("4.3.2", "Make waiting for cache entry configurable")
163 .addTask(new NewPropertyTask("Set cache new entry timeout", "Makes sure incoming requests are not waiting for cache entries to be created longer then specified timeout", ContentRepository.CONFIG, "/modules/cache/config/cacheFactory", "blockingTimeout", "4000"))
164 );
165 register(DeltaBuilder.update("4.3.7", "Adds cache tools")
166 .addTask(new BootstrapConditionally("Cache tools", "Bootstrap for cache tools", "/mgnl-bootstrap/cache/config.modules.cache.commands.cache.flushNamedCache.xml", new WarnTask("Cache tools", "Skipped installation of the Cache Tools menu since such entry already exists.")))
167 .addTask(new BootstrapConditionally("Cache tools", "Bootstrap for cache tools", "/mgnl-bootstrap/cache/admincentral/config.modules.adminInterface.config.menu.tools.cacheTools.xml", new WarnTask("Cache tools", "Skipped installation of the Cache Tools menu since such entry already exists.")))
168 .addTask(new BootstrapConditionally("Cache tools", "Bootstrap for cache tools", "/mgnl-bootstrap/cache/config.modules.cache.pages.xml", new WarnTask("Cache tools", "Skipped installation of the Cache Tools menu since such entry already exists.")))
169 );
170 }
171
172 private List<Task> getTasksFor364() {
173 List<Task> list = new ArrayList<Task>();
174
175 list.add(new BootstrapResourcesTask("Updated configuration", "Bootstraps cache compression configuration.") {
176 protected String[] getResourcesToBootstrap(final InstallContext installContext) {
177 return new String[]{"/mgnl-bootstrap/cache/config.modules.cache.config.compression.xml"};
178 }
179 });
180
181
182 list.add(new DefaultCompressibleContentTypesCondition("Cache cleanup", "Removes obsolete cache compression list in favor of new global configuration.",
183 new RemoveNodeTask("Remove obsolete compression list configuration.", "Removes cache executor specific compression list configuration in favor of using one global list for both cache and gzip.", ContentRepository.CONFIG, "/modules/cache/config/configurations/default/executors/store/cacheContent/compressible"),
184 new WarnTask("Warning", "The compression list configuration have been relocated to /modules/cache/compression/voters/contentType, since you have modified the default configuration, please make sure your customization is applied also to new configuration."),
185 "/modules/cache/config/configurations/default/executors/store/cacheContent/compressible"));
186
187
188 list.add(new DefaultCompressibleContentTypesCondition("GZip cleanup", "Removes obsolete gzip bypass in favor of new global configuration.",
189 new RemoveNodeTask("Remove obsolete bypass.", "Removes content type bypass from gzip filter.", ContentRepository.CONFIG, "/server/filters/gzip/bypasses/contentType"),
190 new WarnTask("Warning", "The list of compressible types have been relocated to /modules/cache/compression/voters/contentType, since you have modified the default configuration, please make sure your customization is applied also to new configuration."),
191 "/server/filters/gzip/bypasses/contentType/allowed"));
192
193
194 list.add(new AbstractRepositoryTask("Add bypass", "Adds new bypass for GZip filter using global configuration.") {
195 protected void doExecute(InstallContext installContext) throws RepositoryException, TaskExecutionException {
196 final HierarchyManager hm = installContext.getHierarchyManager(ContentRepository.CONFIG);
197 Content content = hm.createContent("/server/filters/gzip/bypasses", "deletageBypass", ItemType.CONTENTNODE.getSystemName());
198 content.setNodeData("class","info.magnolia.voting.voters.VoterSet");
199 content.setNodeData("delegatePath","/modules/cache/config/compression/voters");
200 }
201 });
202
203 list.add(new AbstractRepositoryTask("Cache Flushing", "Migrate old cache flushing configuration to new location." ) {
204 protected void doExecute(InstallContext installContext) throws RepositoryException, TaskExecutionException {
205 final String reposPath= "/modules/cache/config/repositories";
206 final HierarchyManager hm = installContext.getHierarchyManager(ContentRepository.CONFIG);
207 if (!hm.isExist(reposPath)) {
208 return;
209 }
210 Content cnt = hm.getContent(reposPath);
211 for (Content c : cnt.getChildren()) {
212 if (c.hasNodeData("name")) {
213 new RegisterWorkspaceForCacheFlushingTask(c.getName()).execute(installContext);
214 }
215 }
216 cnt.delete();
217 }});
218 return list;
219 }
220
221 protected List<Task> getExtraInstallTasks(InstallContext installContext) {
222 final List<Task> tasks = new ArrayList<Task>();
223 tasks.add(new FilterOrderingTask("gzip", new String[]{"context", "multipartRequest", "activation"}));
224 tasks.add(new FilterOrderingTask("cache", new String[]{"gzip", "i18n"}));
225 return tasks;
226 }
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263 }