1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20 package org.apache.synapse.startup.quartz; 21 22 import java.net.InetAddress; 23 import java.net.UnknownHostException; 24 import java.util.HashSet; 25 import java.util.List; 26 import java.util.Random; 27 import java.util.Set; 28 29 import javax.xml.namespace.QName; 30 31 import org.apache.axiom.om.OMElement; 32 import org.apache.commons.logging.Log; 33 import org.apache.commons.logging.LogFactory; 34 import org.apache.synapse.core.SynapseEnvironment; 35 import org.apache.synapse.SynapseConstants; 36 import org.apache.synapse.SynapseException; 37 import org.apache.synapse.ServerManager; 38 import org.apache.synapse.startup.AbstractStartup; 39 import org.quartz.CronTrigger; 40 import org.quartz.JobDataMap; 41 import org.quartz.JobDetail; 42 import org.quartz.Scheduler; 43 import org.quartz.SchedulerException; 44 import org.quartz.Trigger; 45 import org.quartz.TriggerUtils; 46 import org.quartz.impl.DirectSchedulerFactory; 47 48 /* 49 * This class is instantiated by SimpleQuartzFactory (or by hand) 50 * When it is initialized it creates a Quartz Scheduler with a job and a trigger 51 * The class it starts is always an instance of SimpleQuartzJob 52 * SimpleQuartzJob is there to set the properties and start the actual business-logic class 53 * It wraps up any properties that the job needs as in the JobDetail and JDMap 54 */ 55 public class SimpleQuartz extends AbstractStartup { 56 57 private static final Log log = LogFactory.getLog(SimpleQuartz.class); 58 private static final int THREADPOOLSIZE = 5; 59 60 static { 61 try { 62 DirectSchedulerFactory.getInstance().createVolatileScheduler(THREADPOOLSIZE); 63 } catch (SchedulerException e) { 64 throw new SynapseException("Error initializing scheduler factory", e); 65 } 66 } 67 68 private String cron; 69 private int repeatCount = -1; 70 private long repeatInterval; // in milliseconds 71 private String className; 72 private List pinnedServers; 73 private Scheduler sch; 74 Set xmlProperties = new HashSet(); 75 76 public QName getTagQName() { 77 return SimpleQuartzFactory.TASK; 78 } 79 80 public void destroy() { 81 if (sch != null) { 82 try { 83 sch.shutdown(); 84 } catch (SchedulerException e) { 85 log.warn("Error shutting down scheduler", e); 86 throw new SynapseException("Error shutting down scheduler", e); 87 } 88 } 89 } 90 91 public void init(SynapseEnvironment synapseEnvironment) { 92 93 // this server name given by system property SynapseServerName 94 // otherwise take host-name 95 // else assume localhost 96 String thisServerName = ServerManager.getInstance().getServerName(); 97 if(thisServerName == null || thisServerName.equals("")) { 98 try { 99 InetAddress addr = InetAddress.getLocalHost(); 100 thisServerName = addr.getHostName(); 101 102 } catch (UnknownHostException e) { 103 log.warn("Could not get local host name", e); 104 } 105 106 if(thisServerName == null || thisServerName.equals("")) { 107 thisServerName = "localhost"; 108 } 109 } 110 log.debug("Synapse server name : " + thisServerName); 111 112 // start proxy service if either, 113 // pinned server name list is empty 114 // or pinned server list has this server name 115 List pinnedServers = getPinnedServers(); 116 if(pinnedServers != null && !pinnedServers.isEmpty()) { 117 if(!pinnedServers.contains(thisServerName)) { 118 log.info("Server name not in pinned servers list. Not starting Task : " + getName()); 119 return; 120 } 121 } 122 123 124 try { 125 sch = DirectSchedulerFactory.getInstance().getScheduler(); 126 if (sch == null) { 127 DirectSchedulerFactory.getInstance().createVolatileScheduler(THREADPOOLSIZE); 128 sch = DirectSchedulerFactory.getInstance().getScheduler(); 129 } 130 131 if(sch == null) { 132 throw new NullPointerException("Scheduler is null"); 133 } 134 135 Trigger trigger = null; 136 if (cron == null) { 137 if (repeatCount >= 0) { 138 trigger = TriggerUtils.makeImmediateTrigger(repeatCount - 1, repeatInterval); 139 } else { 140 trigger = TriggerUtils.makeImmediateTrigger(-1, repeatInterval); 141 } 142 143 } else { 144 CronTrigger cronTrig = new CronTrigger(); 145 cronTrig.setCronExpression(cron); 146 trigger = cronTrig; 147 } 148 149 // give the trigger a random name 150 trigger.setName("Trigger" + String.valueOf((new Random()).nextLong())); 151 trigger.setGroup("synapse.simple.quartz"); 152 trigger.setVolatility(true); 153 JobDetail jobDetail = new JobDetail(); 154 155 // Give the job a name 156 jobDetail.setName(name); 157 jobDetail.setGroup("synapse.simple.quartz"); 158 jobDetail.setJobClass(SimpleQuartzJob.class); 159 JobDataMap jdm = new JobDataMap(); 160 jdm.put(SimpleQuartzJob.SYNAPSE_ENVIRONMENT, synapseEnvironment); 161 jdm.put(SimpleQuartzJob.CLASSNAME, className); 162 jdm.put(SimpleQuartzJob.PROPERTIES, xmlProperties); 163 jobDetail.setJobDataMap(jdm); 164 165 sch.scheduleJob(jobDetail, trigger); 166 sch.start(); 167 log.info("Scheduled job " + jobDetail.getFullName() + " for class " + className); 168 169 } catch (Exception e) { 170 log.fatal("Error starting up Scheduler", e); 171 throw new SynapseException("Error starting up Scheduler", e); 172 } 173 174 } 175 176 public String getJobClass() { 177 return className; 178 } 179 180 public void setJobClass(String attributeValue) { 181 className = attributeValue; 182 183 } 184 185 public void setInterval(long l) { 186 repeatInterval = l; 187 188 } 189 190 public long getInterval() { 191 return repeatInterval; 192 } 193 194 public void setCount(int i) { 195 repeatCount = i; 196 } 197 198 public int getCount() { 199 return repeatCount; 200 } 201 202 public void addProperty(OMElement prop) { 203 xmlProperties.add(prop); 204 } 205 206 public Set getProperties() { 207 return xmlProperties; 208 } 209 210 public void setCron(String attributeValue) { 211 cron = attributeValue; 212 213 } 214 215 public String getCron() { 216 return cron; 217 } 218 219 public List getPinnedServers() { 220 return pinnedServers; 221 } 222 223 public void setPinnedServers(List pinnedServers) { 224 this.pinnedServers = pinnedServers; 225 } 226 227 }