001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019package org.apache.oozie.sla; 020 021import java.util.Date; 022 023import org.apache.oozie.AppType; 024import org.apache.oozie.client.event.SLAEvent; 025import org.apache.oozie.lock.LockToken; 026import org.apache.oozie.service.JobsConcurrencyService; 027import org.apache.oozie.service.MemoryLocksService; 028import org.apache.oozie.service.Services; 029import org.apache.oozie.sla.service.SLAService; 030import org.apache.oozie.util.LogUtils; 031import org.apache.oozie.util.XLog; 032 033/** 034 * Class used by SLAService to store SLA objects and perform calculations and 035 * sla decisions 036 */ 037public class SLACalcStatus extends SLAEvent { 038 039 public static String SLA_ENTITYKEY_PREFIX = "sla-"; 040 private SLARegistrationBean regBean; 041 private String jobStatus; 042 private SLAStatus slaStatus; 043 private EventStatus eventStatus; 044 private Date actualStart; 045 private Date actualEnd; 046 private long actualDuration = -1; 047 private Date lastModifiedTime; 048 private byte eventProcessed; 049 private LockToken lock; 050 051 private XLog LOG; 052 053 public SLACalcStatus(SLARegistrationBean reg) { 054 this(); 055 setSLARegistrationBean(reg); 056 LOG = LogUtils.setLogPrefix(LOG, this); 057 } 058 059 public SLACalcStatus(SLASummaryBean summary, SLARegistrationBean regBean) { 060 this(); 061 SLARegistrationBean reg = new SLARegistrationBean(); 062 reg.setNotificationMsg(regBean.getNotificationMsg()); 063 reg.setUpstreamApps(regBean.getUpstreamApps()); 064 reg.setAlertContact(regBean.getAlertContact()); 065 reg.setAlertEvents(regBean.getAlertEvents()); 066 reg.setJobData(regBean.getJobData()); 067 reg.setId(summary.getId()); 068 reg.setAppType(summary.getAppType()); 069 reg.setUser(summary.getUser()); 070 reg.setAppName(summary.getAppName()); 071 reg.setParentId(summary.getParentId()); 072 reg.setNominalTime(summary.getNominalTime()); 073 reg.setExpectedStart(summary.getExpectedStart()); 074 reg.setExpectedEnd(summary.getExpectedEnd()); 075 reg.setExpectedDuration(summary.getExpectedDuration()); 076 setSLARegistrationBean(reg); 077 setActualStart(summary.getActualStart()); 078 setActualEnd(summary.getActualEnd()); 079 setActualDuration(summary.getActualDuration()); 080 setSLAStatus(summary.getSLAStatus()); 081 setJobStatus(summary.getJobStatus()); 082 setEventStatus(summary.getEventStatus()); 083 setLastModifiedTime(summary.getLastModifiedTime()); 084 setEventProcessed(summary.getEventProcessed()); 085 LOG = LogUtils.setLogPrefix(LOG, this); 086 } 087 088 /** 089 * copy constructor 090 * @return SLACalcStatus 091 */ 092 public SLACalcStatus(SLACalcStatus a) { 093 this(); 094 setSLARegistrationBean(a.getSLARegistrationBean()); 095 setJobStatus(a.getJobStatus()); 096 setSLAStatus(a.getSLAStatus()); 097 setEventStatus(a.getEventStatus()); 098 setActualStart(a.getActualStart()); 099 setActualEnd(a.getActualEnd()); 100 setActualDuration(a.getActualDuration()); 101 setEventProcessed(a.getEventProcessed()); 102 LOG = LogUtils.setLogPrefix(LOG, this); 103 } 104 105 public SLACalcStatus() { 106 setMsgType(MessageType.SLA); 107 setLastModifiedTime(new Date()); 108 LOG = XLog.getLog(getClass()); 109 } 110 111 public SLARegistrationBean getSLARegistrationBean() { 112 return regBean; 113 } 114 115 public void setSLARegistrationBean(SLARegistrationBean slaBean) { 116 this.regBean = slaBean; 117 } 118 119 @Override 120 public String getId() { 121 return regBean.getId(); 122 } 123 124 public void setId(String id) { 125 regBean.setId(id); 126 } 127 128 @Override 129 public Date getActualStart() { 130 return actualStart; 131 } 132 133 public void setActualStart(Date actualStart) { 134 this.actualStart = actualStart; 135 } 136 137 @Override 138 public Date getActualEnd() { 139 return actualEnd; 140 } 141 142 public void setActualEnd(Date actualEnd) { 143 this.actualEnd = actualEnd; 144 } 145 146 @Override 147 public long getActualDuration() { 148 return actualDuration; 149 } 150 151 public void setActualDuration(long actualDuration) { 152 this.actualDuration = actualDuration; 153 } 154 155 @Override 156 public String getJobStatus() { 157 return jobStatus; 158 } 159 160 public void setJobStatus(String status) { 161 this.jobStatus = status; 162 } 163 164 @Override 165 public SLAStatus getSLAStatus() { 166 return slaStatus; 167 } 168 169 public void setSLAStatus(SLAStatus slaStatus) { 170 this.slaStatus = slaStatus; 171 } 172 173 @Override 174 public EventStatus getEventStatus() { 175 return eventStatus; 176 } 177 178 public void setEventStatus(EventStatus es) { 179 this.eventStatus = es; 180 } 181 182 public void setLastModifiedTime(Date lastModifiedTime) { 183 this.lastModifiedTime = lastModifiedTime; 184 } 185 186 /** 187 * Get which type of sla event has been processed needed when calculator 188 * periodically loops to update all jobs' sla 189 * 190 * @return byte 1st bit set (from LSB) = start processed 191 * 2nd bit set = duration processed 192 * 3rd bit set = end processed 193 * only 4th bit set = everything processed 194 */ 195 public byte getEventProcessed() { 196 return eventProcessed; 197 } 198 199 public void setEventProcessed(int eventProcessed) { 200 this.eventProcessed = (byte) eventProcessed; 201 } 202 203 @Override 204 public String getParentId() { 205 return regBean.getParentId(); 206 } 207 208 @Override 209 public AppType getAppType() { 210 return regBean.getAppType(); 211 } 212 213 @Override 214 public String getAppName() { 215 return regBean.getAppName(); 216 } 217 218 @Override 219 public Date getNominalTime() { 220 return regBean.getNominalTime(); 221 } 222 223 @Override 224 public Date getExpectedStart() { 225 return regBean.getExpectedStart(); 226 } 227 228 @Override 229 public Date getExpectedEnd() { 230 return regBean.getExpectedEnd(); 231 } 232 233 @Override 234 public long getExpectedDuration() { 235 return regBean.getExpectedDuration(); 236 } 237 238 @Override 239 public String getNotificationMsg() { 240 return regBean.getNotificationMsg(); 241 } 242 243 @Override 244 public String getAlertEvents() { 245 return regBean.getAlertEvents(); 246 } 247 248 @Override 249 public String getAlertContact() { 250 return regBean.getAlertContact(); 251 } 252 253 @Override 254 public String getUpstreamApps() { 255 return regBean.getUpstreamApps(); 256 } 257 258 @Override 259 public String getJobData() { 260 return regBean.getJobData(); 261 } 262 263 @Override 264 public String getUser() { 265 return regBean.getUser(); 266 } 267 268 @Override 269 public String getSlaConfig() { 270 return regBean.getSlaConfig(); 271 } 272 273 @Override 274 public MessageType getMsgType() { 275 return regBean.getMsgType(); 276 } 277 278 @Override 279 public Date getLastModifiedTime() { 280 return lastModifiedTime; 281 } 282 283 public String getEntityKey() { 284 return SLA_ENTITYKEY_PREFIX + this.getId(); 285 } 286 /** 287 * Obtain an exclusive lock on the {link #getEntityKey}. 288 * <p/> 289 * A timeout of {link #getLockTimeOut} is used when trying to obtain the lock. 290 * 291 * @throws InterruptedException thrown if an interruption happened while trying to obtain the lock 292 */ 293 public void acquireLock() throws InterruptedException { 294 // only get ZK lock when multiple servers running 295 if (Services.get().get(JobsConcurrencyService.class).isHighlyAvailableMode()) { 296 lock = Services.get().get(MemoryLocksService.class).getWriteLock(getEntityKey(), getLockTimeOut()); 297 if (lock == null) { 298 LOG.debug("Could not aquire lock for [{0}]", getEntityKey()); 299 } 300 else { 301 LOG.debug("Acquired lock for [{0}]", getEntityKey()); 302 } 303 } 304 else { 305 lock = new DummyToken(); 306 } 307 } 308 309 private static class DummyToken implements LockToken { 310 @Override 311 public void release() { 312 } 313 } 314 315 public boolean isLocked() { 316 boolean locked = false; 317 if(lock != null) { 318 locked = true; 319 } 320 return locked; 321 } 322 323 public void releaseLock(){ 324 if (lock != null) { 325 lock.release(); 326 lock = null; 327 LOG.debug("Released lock for [{0}]", getEntityKey()); 328 } 329 } 330 331 public long getLockTimeOut() { 332 return Services.get().getConf().getLong(SLAService.CONF_SLA_CALC_LOCK_TIMEOUT, 5 * 1000); 333 } 334 335}