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