Msm54RolloutConfigUpgrade.java
10.1 KB
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/*
* Decompiled with CFR 0_118.
*
* Could not load the following classes:
* com.day.cq.commons.jcr.JcrUtil
* javax.jcr.Item
* javax.jcr.Node
* javax.jcr.NodeIterator
* javax.jcr.Property
* javax.jcr.RepositoryException
* javax.jcr.Session
* javax.jcr.Workspace
* javax.jcr.query.Query
* javax.jcr.query.QueryManager
* javax.jcr.query.QueryResult
* org.slf4j.Logger
* org.slf4j.LoggerFactory
*/
package com.day.cq.compat.codeupgrade.impl.cq54;
import com.day.cq.commons.jcr.JcrUtil;
import com.day.cq.compat.codeupgrade.internal.api.ProgressInfoProvider;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.jcr.Item;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Workspace;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class Msm54RolloutConfigUpgrade
implements ProgressInfoProvider {
private final Logger log;
static final String CQ_LIVE_SYNC_ACTION_NAME = "cq:LiveSyncAction";
static final String CQ_ROLLOUT_CONFIG_ID_53 = "cq:rolloutConfigId53";
static final String ROLLOUT_CONFIG_RESOURCE_TYPE = "wcm/msm/components/rolloutconfig";
static final String ROLLOUT_CONFIGS_PATH = "/etc/msm/rolloutconfigs";
static final String NEW_CONFIGS_NODE_NAME = "53upgrade";
static final String NEW_CONFIGS_PATH = "/etc/msm/rolloutconfigs/53upgrade";
private final String BACKUP_ROOT;
static final String PROP_UPDATE_CONTENT_STATUS = "updateContent/status";
static final String PROP_NOTIFY_TARGET = "notify/target";
static final String PROP_MANDATORY_TARGET = "mandatory/target";
static final String PROP_WORKFLOW_TARGET = "workflow/target";
int newConfigNumber;
int ignoredCount;
int upgradedCount;
private String progressInfo;
Msm54RolloutConfigUpgrade() {
this.log = LoggerFactory.getLogger(this.getClass());
this.BACKUP_ROOT = "/var/upgrade/" + this.getClass().getSimpleName() + "/backup/" + Msm54RolloutConfigUpgrade.getBackupNodeName();
}
@Override
public String getProgressInfo() {
return this.progressInfo;
}
void setProgressInfo(String info) {
this.progressInfo = info;
this.log.info(this.progressInfo);
}
void doUpgrade(Session s) throws Exception {
String statement = "select * from [cq:LiveSyncConfig]";
this.setProgressInfo("Searching for nodes to upgrade");
this.log.info("Executing query '{}' to find nodes to upgrade", (Object)"select * from [cq:LiveSyncConfig]");
NodeIterator it = s.getWorkspace().getQueryManager().createQuery("select * from [cq:LiveSyncConfig]", "JCR-SQL2").execute().getNodes();
int counter = 0;
while (it.hasNext()) {
this.setProgressInfo("" + counter + " nodes checked, " + this.upgradedCount + " upgraded");
++counter;
ConfigNodesPair cnp = new ConfigNodesPair(it.nextNode());
if (!cnp.needsUpgrade()) {
++this.ignoredCount;
this.log.info("Rollout config does not need upgrading, not modified: {}", (Object)cnp.getMainPath());
continue;
}
++this.upgradedCount;
this.upgrade(s, cnp);
}
this.setProgressInfo("Done executing upgrades, " + this.upgradedCount + " config nodes upgraded, " + this.ignoredCount + " nodes ignored");
}
private void upgrade(Session s, ConfigNodesPair cnp) throws RepositoryException {
String configId = this.getConfigId(cnp);
this.log.info("Upgrading rollout config {} (Id={})", (Object)cnp.getMainPath(), (Object)configId);
String cfgPath = this.findConfigPath(s, configId);
boolean created = false;
if (cfgPath == null) {
created = true;
cfgPath = this.createConfig(s, configId);
}
cnp.configNode.setProperty("cq:rolloutConfigs", new String[]{cfgPath});
cnp.configNode.getProperty("cq:trigger").remove();
Object[] arrobject = new Object[3];
arrobject[0] = created ? "newly created" : "existing";
arrobject[1] = cfgPath;
arrobject[2] = cnp.configNode.getPath();
this.log.info("Rollout config node upgraded, using {} config {} for {}", arrobject);
String srcPath = cnp.actionNode.getPath();
String backupPath = this.BACKUP_ROOT + srcPath;
String backupFolder = this.BACKUP_ROOT + cnp.actionNode.getParent().getPath();
JcrUtil.createPath((String)backupFolder, (String)"nt:unstructured", (Session)s);
s.save();
s.getWorkspace().move(srcPath, backupPath);
this.log.info("Unused rollout config node {} moved to {}", (Object)srcPath, (Object)backupPath);
}
String getIdString(Node n, String propertyPath) throws RepositoryException {
if (n.hasProperty(propertyPath)) {
return propertyPath + "=" + n.getProperty(propertyPath).getString() + "#";
}
return "#";
}
String getConfigId(ConfigNodesPair cnp) throws RepositoryException {
StringBuilder sb = new StringBuilder();
sb.append(this.getIdString(cnp.configNode, "cq:trigger"));
sb.append(this.getIdString(cnp.actionNode, "updateContent/status"));
sb.append(this.getIdString(cnp.actionNode, "notify/target"));
sb.append(this.getIdString(cnp.actionNode, "mandatory/target"));
sb.append(this.getIdString(cnp.actionNode, "workflow/target"));
return sb.toString();
}
String findConfigPath(Session s, String configId) throws RepositoryException {
String result = null;
String statement = "SELECT * FROM 'nt:base' WHERE [sling:resourceType]='wcm/msm/components/rolloutconfig' AND [cq:rolloutConfigId53]='" + configId + "'" + " AND ISDESCENDANTNODE([" + "/etc/msm/rolloutconfigs" + "])";
NodeIterator it = s.getWorkspace().getQueryManager().createQuery(statement, "JCR-SQL2").execute().getNodes();
if (it.hasNext()) {
result = it.nextNode().getParent().getPath();
if (it.hasNext()) {
throw new RepositoryException("More than one node found for query " + statement);
}
}
return result;
}
Map<String, String> parseConfigId(String configId) {
String[] parts;
HashMap<String, String> result = new HashMap<String, String>();
for (String part : parts = configId.split("#")) {
String[] pair = part.split("=");
if (pair.length != 2) continue;
result.put(pair[0], pair[1]);
}
return result;
}
Node getActionNode(Node content, String childName) throws RepositoryException {
Node n = null;
n = content.hasNode(childName) ? content.getNode(childName) : content.addNode(childName, "cq:LiveSyncAction");
return n;
}
String createConfig(Session s, String configId) throws RepositoryException {
Node base = null;
if (s.itemExists("/etc/msm/rolloutconfigs/53upgrade")) {
base = (Node)s.getItem("/etc/msm/rolloutconfigs/53upgrade");
} else {
base = s.getNode("/etc/msm/rolloutconfigs").addNode("53upgrade", "sling:Folder");
s.save();
}
Node cfgNode = base.addNode("" + ++this.newConfigNumber + "_53upgrade_" + System.currentTimeMillis(), "cq:Page");
Node content = cfgNode.addNode("jcr:content", "nt:unstructured");
content.setProperty("sling:resourceType", "wcm/msm/components/rolloutconfig");
content.setProperty("cq:defaultView", "html");
content.setProperty("cq:lastModified", Calendar.getInstance());
content.setProperty("cq:lastModifiedBy", s.getUserID());
content.setProperty("cq:template", "/libs/wcm/msm/templates/rolloutconfig");
content.setProperty("jcr:title", cfgNode.getName());
content.setProperty("jcr:description", "Compatibility rollout config created by " + this.getClass().getSimpleName());
Map<String, String> cfgMap = this.parseConfigId(configId);
content.setProperty("cq:trigger", cfgMap.get("cq:trigger"));
if ("true".equals(cfgMap.get("updateContent/status"))) {
this.getActionNode(content, "contentUpdate").setProperty("enabled", true);
this.getActionNode(content, "contentCopy").setProperty("enabled", true);
this.getActionNode(content, "contentDelete").setProperty("enabled", true);
this.getActionNode(content, "referencesUpdate").setProperty("enabled", true);
this.getActionNode(content, "orderChildren").setProperty("enabled", true);
}
if ("true".equals(cfgMap.get("notify/target"))) {
this.getActionNode(content, "notify").setProperty("enabled", true);
}
if (cfgMap.get("mandatory/target") != null) {
this.getActionNode(content, "mandatory").setProperty("target", cfgMap.get("mandatory/target"));
}
if (cfgMap.get("workflow/target") != null) {
this.getActionNode(content, "workflow").setProperty("target", cfgMap.get("workflow/target"));
}
content.setProperty("cq:rolloutConfigId53", configId);
s.save();
return cfgNode.getPath();
}
static String getBackupNodeName() {
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-S");
return fmt.format(new Date());
}
static class ConfigNodesPair {
final Node configNode;
final Node actionNode;
ConfigNodesPair(Node liveSyncConfigNode) throws RepositoryException {
this.configNode = liveSyncConfigNode;
Node parent = this.configNode.getParent();
this.actionNode = parent.hasNode("cq:LiveSyncAction") ? parent.getNode("cq:LiveSyncAction") : null;
}
String getMainPath() throws RepositoryException {
return this.configNode.getPath();
}
boolean needsUpgrade() {
return this.actionNode != null;
}
}
}