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.scheduler;
35
36 import info.magnolia.cms.security.SilentSessionOp;
37 import info.magnolia.commands.CommandsManager;
38 import info.magnolia.commands.chain.Command;
39 import info.magnolia.context.Context;
40 import info.magnolia.context.MgnlContext;
41 import info.magnolia.context.SimpleContext;
42 import info.magnolia.context.SystemContext;
43 import info.magnolia.init.MagnoliaConfigurationProperties;
44 import info.magnolia.objectfactory.Components;
45 import info.magnolia.ui.api.message.Message;
46 import info.magnolia.ui.api.message.MessageType;
47 import info.magnolia.ui.framework.message.MessagesManager;
48
49 import java.util.Map;
50
51 import javax.inject.Inject;
52 import javax.jcr.Node;
53 import javax.jcr.RepositoryException;
54 import javax.jcr.Session;
55
56 import org.apache.commons.lang.StringUtils;
57 import org.quartz.Job;
58 import org.quartz.JobExecutionContext;
59 import org.quartz.JobExecutionException;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
62
63
64
65
66
67 public class CommandJob implements Job {
68
69 private static Logger log = LoggerFactory.getLogger(CommandJob.class);
70 private MessagesManager messagesManager;
71
72 @Inject
73 public CommandJob(MessagesManager messagesManager) {
74 this.messagesManager = messagesManager;
75 }
76
77
78
79
80 @Deprecated
81 public CommandJob() {
82 this.messagesManager = Components.getComponent(MessagesManager.class);
83 }
84
85
86
87
88 @Override
89 public void execute(JobExecutionContext jobCtx) throws JobExecutionException {
90 log.info("Starting job [{}]...", jobCtx.getJobDetail().getName());
91 Map jobData = jobCtx.getJobDetail().getJobDataMap();
92
93 String instanceClusterId = Components.getComponent(MagnoliaConfigurationProperties.class).getProperty("magnolia.clusterid");
94 String jobClusterId = null;
95
96 if (jobData.containsKey(SchedulerConsts.CONFIG_JOB_PARAMS) && jobData.get(SchedulerConsts.CONFIG_JOB_PARAMS) != null) {
97 jobClusterId = (String) ((Map) jobData.get(SchedulerConsts.CONFIG_JOB_PARAMS)).get("clusterId");
98 }
99
100 String catalogName = (String) jobData.get(SchedulerConsts.CONFIG_JOB_COMMAND_CATALOG);
101 String cmdName = (String) jobData.get(SchedulerConsts.CONFIG_JOB_COMMAND);
102
103 if (StringUtils.isBlank(jobClusterId) || jobClusterId.equals(instanceClusterId)) {
104 try {
105
106 MgnlContext.setInstance(new SimpleContext(Components.getComponent(SystemContext.class)));
107
108 Command cmd = Components.getComponent(CommandsManager.class).getCommand(catalogName, cmdName);
109 if (cmd == null) {
110 String errorMessage = "Can't find command [" + cmdName + "] for job in catalog [{" + catalogName + "}]";
111 logAndSendErrorMessage(errorMessage, new Exception());
112 return;
113 }
114
115 Context ctx = new SimpleContext();
116
117 if (jobData.containsKey(SchedulerConsts.CONFIG_JOB_PARAMS) && jobData.get(SchedulerConsts.CONFIG_JOB_PARAMS) != null) {
118 ctx.putAll((Map) jobData.get(SchedulerConsts.CONFIG_JOB_PARAMS));
119
120 if (!ctx.containsKey(Context.ATTRIBUTE_UUID) && ctx.containsKey(Context.ATTRIBUTE_PATH) && ctx.containsKey(Context.ATTRIBUTE_REPOSITORY)) {
121 String uuid = getNodeUUID(ctx);
122 if (uuid != null) {
123 ctx.put(Context.ATTRIBUTE_UUID, uuid);
124 }
125 }
126 }
127
128 cmd.execute(ctx);
129 log.info("Job executed successfully [{}]", jobCtx.getJobDetail().getName());
130 } catch (Exception e) {
131 String errorMessage = "Can't execute command " + catalogName + "-" + cmdName;
132 logAndSendErrorMessage(errorMessage, e);
133 throw new JobExecutionException(errorMessage, e, false);
134 } finally {
135 MgnlContext.setInstance(null);
136 }
137 } else {
138 log.info("Job " + cmdName + " from catalog " + catalogName + " will be executed only in cluster node: " + jobClusterId);
139 }
140 }
141
142 private void logAndSendErrorMessage(String errorMessage, Exception exception) {
143 log.error(errorMessage, exception);
144 Message message = new Message(MessageType.ERROR, "Scheduler error", errorMessage);
145 messagesManager.sendLocalMessage(message);
146 }
147
148 private String getNodeUUID(Context ctx) {
149 final String path = ctx.getAttribute(Context.ATTRIBUTE_PATH);
150 final String repository = ctx.getAttribute(Context.ATTRIBUTE_REPOSITORY);
151 if (StringUtils.isBlank(path) || StringUtils.isBlank(repository)) {
152 log.debug("Parameters path and repository cannot be empty.");
153 return null;
154 }
155
156 return MgnlContext.doInSystemContext(new SilentSessionOp<String>(repository) {
157
158 @Override
159 public String exec() {
160 Session session = null;
161 try {
162 session = MgnlContext.getJCRSession(repository);
163 } catch (RepositoryException e) {
164 log.debug("failed to retrieve repository " + repository + " with " + e.getMessage(), e);
165 return null;
166 }
167 try {
168 return doExec(session);
169 } catch (Throwable t) {
170 log.debug("Failed to execute " + toString() + " session operation with " + t.getMessage(), t);
171 return null;
172 }
173 }
174
175 @Override
176 public String doExec(Session session) throws Throwable {
177 if (session.itemExists(path)) {
178 Node node = session.getNode(path);
179 return node.getIdentifier();
180 }
181 log.debug("Node [{}] does not exist in repository [{}]", path, repository);
182 return null;
183 }
184
185 @Override
186 public String toString() {
187 return "get node [ " + repository + ":" + path + "] uuid";
188 }
189 });
190 }
191 }