All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.internet2.middleware.grouper.grouperUi.beans.api.GuiDaemonJob Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright 2018 Internet2
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package edu.internet2.middleware.grouper.grouperUi.beans.api;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import edu.internet2.middleware.grouper.ui.util.GrouperUiConfig;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.quartz.CronTrigger;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;

import edu.internet2.middleware.grouper.app.daemon.GrouperDaemonConfiguration;
import edu.internet2.middleware.grouper.app.loader.GrouperLoader;
import edu.internet2.middleware.grouper.app.loader.GrouperLoaderConfig;
import edu.internet2.middleware.grouper.app.loader.GrouperLoaderType;
import edu.internet2.middleware.grouper.app.loader.db.Hib3GrouperLoaderLog;
import edu.internet2.middleware.grouper.changeLog.ChangeLogConsumer;
import edu.internet2.middleware.grouper.changeLog.ChangeLogEntry;
import edu.internet2.middleware.grouper.grouperUi.beans.json.GuiResponseJs;
import edu.internet2.middleware.grouper.grouperUi.beans.json.GuiScreenAction;
import edu.internet2.middleware.grouper.grouperUi.beans.json.GuiScreenAction.GuiMessageType;
import edu.internet2.middleware.grouper.grouperUi.beans.ui.AdminContainer;
import edu.internet2.middleware.grouper.grouperUi.beans.ui.GrouperRequestContainer;
import edu.internet2.middleware.grouper.grouperUi.beans.ui.TextContainer;
import edu.internet2.middleware.grouper.hibernate.HibUtils;
import edu.internet2.middleware.grouper.hibernate.HibernateSession;
import edu.internet2.middleware.grouper.internal.dao.QueryOptions;
import edu.internet2.middleware.grouper.j2ee.status.DaemonJobStatus;
import edu.internet2.middleware.grouper.misc.GrouperDAOFactory;
import edu.internet2.middleware.grouper.ui.util.GrouperUiUtils;
import edu.internet2.middleware.grouper.util.GrouperUtil;
import net.redhogs.cronparser.CronExpressionDescriptor;

/**
 * @author shilen
 */
public class GuiDaemonJob implements Serializable, Comparable {

  private static final Log LOG = edu.internet2.middleware.grouper.util.GrouperUtil.getLog(GuiDaemonJob.class);

  /**
   * 
   */
  private static final long serialVersionUID = 4685545018479996910L;
  
  /**
   * job name of loader job
   */
  private String jobName;
  
  /**
   * schedule for job
   */
  private String schedule;
  
  /**
   * state of job for Ui, may contain html
   */
  private String stateDescription;

  /**
   * state of job, RUNNING, ENABLED, or DISABLED
   */
  private String state;

  /**
   * next fire time
   */
  private String nextFireTime;
  
  /**
   * prev fire time based on quartz data
   */
  private String prevFireTime;
  
  /**
   * Whether to show this additional action
   */
  private boolean showMoreActionsRunNow;
  
  /**
   * Whether to show this additional action
   */
  private boolean showMoreActionsEnable;
  
  /**
   * Whether to show this additional action
   */
  private boolean showMoreActionsDisable;
  
  /**
   * Last status based on loader log
   */
  private String lastRunStatus;
  
  /**
   * Last host based on loader log
   */
  private String lastRunHost;
  
  /**
   * Last start time based on loader log
   */
  private String lastRunStartTime;
  
  /**
   * last summary based on loader log
   */
  private String lastRunSummary;
  
  
  /**
   * last running time based on loader log
   */
  private String lastRunTotalTime;
  
  /**
   * additional information about change log jobs
   */
  private String changeLogInfo;
  
  /**
   * overall status description
   */
  private String overallStatusDescription;
  
  /**
   * overall status
   */
  private String overallStatus;
  
  private boolean isMultiple;
  
  private boolean isLoader;

  private boolean isEnabled;
  
  public String getEditQueryParam() {
    GrouperLoaderType loaderType = GrouperLoaderType.typeForThisName(jobName);
   
    if (loaderType == GrouperLoaderType.SQL_SIMPLE 
        || loaderType == GrouperLoaderType.SQL_GROUP_LIST
        || loaderType == GrouperLoaderType.LDAP_GROUP_LIST 
        || loaderType == GrouperLoaderType.LDAP_GROUPS_FROM_ATTRIBUTES 
        || loaderType == GrouperLoaderType.LDAP_SIMPLE) {
      
      int uuidIndexStart = jobName.lastIndexOf("__");
    
      String grouperLoaderGroupUuid = jobName.substring(uuidIndexStart+2, jobName.length());
      return "groupId="+grouperLoaderGroupUuid;
    }
    
    if (loaderType == GrouperLoaderType.ATTR_SQL_SIMPLE) {
      int uuidIndexStart = jobName.lastIndexOf("__");
      String grouperLoaderAttributeDefUuid = jobName.substring(uuidIndexStart+2, jobName.length());
      return "attributeDefId="+grouperLoaderAttributeDefUuid;
    }
    
    throw new RuntimeException(jobName +" is not a loder job.");
    
  }
  
  /**
   * @param jobName
   */
  public GuiDaemonJob(String jobName) {

    try {
      Scheduler scheduler = GrouperLoader.schedulerFactory().getScheduler();
      String simpleDateFormatString = GrouperUiConfig.retrieveConfig().propertyValueString("uiV2.admin.daemonJob.extendedSchedule.dateFormat", "yyyy-MM-dd HH:mm:ss z");
      SimpleDateFormat sdf = new SimpleDateFormat(simpleDateFormatString);

      this.setJobName(jobName);
      
      GrouperLoaderType loaderType = GrouperLoaderType.typeForThisName(jobName);
      if (loaderType != GrouperLoaderType.ATTR_SQL_SIMPLE
          && loaderType != GrouperLoaderType.LDAP_GROUP_LIST
          && loaderType != GrouperLoaderType.LDAP_GROUPS_FROM_ATTRIBUTES
          && loaderType != GrouperLoaderType.LDAP_SIMPLE
          && loaderType != GrouperLoaderType.SQL_SIMPLE
          && loaderType != GrouperLoaderType.SQL_GROUP_LIST) {
        try {
          GrouperDaemonConfiguration grouperDaemonConfig = GrouperDaemonConfiguration.retrieveImplementationFromJobName(jobName);
          this.isMultiple = grouperDaemonConfig.isMultiple();
        } catch (Exception e) {
          GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs();
          AdminContainer adminContainer = GrouperRequestContainer.retrieveFromRequestOrCreate().getAdminContainer();
          adminContainer.setDaemonJobName(jobName);
          guiResponseJs.addAction(GuiScreenAction.newMessage(GuiMessageType.error, TextContainer.retrieveFromRequest().getText().get("daemonJobConfigNotFound")));
          LOG.error("Error: cant find daemon config from job name '" + jobName + "'", e);
        }
      } else {
        this.isLoader = true;
      }
      
      Date nextFireTime = null;
      Date prevFireTime = null;
      
      this.isEnabled = false;
      Date startTimeIfRunning = GrouperLoader.internal_getJobStartTimeIfRunning(jobName);
      boolean isRunning = startTimeIfRunning != null;
      
      List triggers = scheduler.getTriggersOfJob(new JobKey(jobName));
      StringBuilder schedule = new StringBuilder();
  
      for (Trigger trigger : triggers) {
        
        Date currPrevFireTime = trigger.getPreviousFireTime();
        if (currPrevFireTime != null) {
          if (prevFireTime == null || currPrevFireTime.after(prevFireTime)) {
            prevFireTime = currPrevFireTime;
          }
        }
        
        Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
        if (triggerState == Trigger.TriggerState.COMPLETE) {
          // looks like this trigger is done so skip it
          continue;
        }
        
        if (triggerState != Trigger.TriggerState.PAUSED) {
          this.isEnabled = true;
        }
        
        if (schedule.length() > 0) {
          schedule.append("

"); } Date currNextFireTime = trigger.getNextFireTime(); if (currNextFireTime != null) { if (nextFireTime == null || currNextFireTime.before(nextFireTime)) { nextFireTime = currNextFireTime; } } if (trigger instanceof SimpleTrigger) { int repeatCount = ((SimpleTrigger)trigger).getRepeatCount(); if (repeatCount == 0) { schedule.append("ONE TIME: "); Date startAt = ((SimpleTrigger)trigger).getStartTime(); if (startAt != null) { schedule.append(sdf.format(startAt)); } } else { if (repeatCount == -1) { schedule.append("INTERVAL: "); } else { schedule.append("INTERVAL (COUNT ").append(repeatCount).append("): "); } Long intervalSecondsMillis = ((SimpleTrigger)trigger).getRepeatInterval(); Long intervalSeconds = intervalSecondsMillis / 1000; schedule.append(intervalSeconds).append(" ").append(TextContainer.retrieveFromRequest().getText().get("grouperLoaderSqlScheduleIntervalSeconds")); schedule.append("
" + GrouperUiUtils.convertSecondsToString(intervalSeconds.intValue())); } } else if (trigger instanceof CronTrigger) { schedule.append("CRON: "); String cron = ((CronTrigger)trigger).getCronExpression(); schedule.append(GrouperUiUtils.escapeHtml(cron, true)).append("
"); if (!StringUtils.isEmpty(cron)) { try { schedule.append(GrouperUiUtils.escapeHtml(CronExpressionDescriptor.getDescription(cron), true)); } catch (Exception e) { LOG.error("Cant parse cron string:" + cron, e); schedule.append(TextContainer.retrieveFromRequest().getText().get("adminDaemonJobsCronDescriptionError")); } } } else { LOG.warn("Unsupported trigger: " + trigger.getKey().getName()); } } this.setSchedule(schedule.toString()); if (this.isEnabled && nextFireTime != null) { this.setNextFireTime(sdf.format(nextFireTime)); } if (prevFireTime != null) { // if it's currently running, the time there is more accurate if (isRunning) { this.setPrevFireTime(sdf.format(startTimeIfRunning)); } else { this.setPrevFireTime(sdf.format(prevFireTime)); } } if (isRunning) { Long timeRunningSeconds = (System.currentTimeMillis() - startTimeIfRunning.getTime()) / 1000; String currentState = TextContainer.retrieveFromRequest().getText().get("adminDaemonJobsStateRunning") + "
" + GrouperUiUtils.convertSecondsToString(timeRunningSeconds.intValue()); this.setStateDescription(currentState); this.setState("RUNNING"); } else if (this.isEnabled) { this.setStateDescription(TextContainer.retrieveFromRequest().getText().get("adminDaemonJobsStateEnabled")); this.setState("ENABLED"); } else { this.setStateDescription(TextContainer.retrieveFromRequest().getText().get("adminDaemonJobsStateDisabled")); this.setState("DISABLED"); } // the job wont run if isJobRunning, so add that here, dont show the button if so if (!isRunning && this.isEnabled && !GrouperLoader.isJobRunning(jobName, false)) { this.setShowMoreActionsRunNow(true); } if (this.isEnabled) { this.setShowMoreActionsDisable(true); } else { this.setShowMoreActionsEnable(true); } { boolean checkSubJobs = jobName.equals("CHANGE_LOG_changeLogTempToChangeLog") || (jobName.startsWith(GrouperLoaderType.GROUPER_CHANGE_LOG_CONSUMER_PREFIX) && GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("changeLog.consumer." + jobName.substring(GrouperLoaderType.GROUPER_CHANGE_LOG_CONSUMER_PREFIX.length()) + ".longRunning", false)); List criterionList = new ArrayList(); if (checkSubJobs) { Set jobNames = new LinkedHashSet(); jobNames.add(jobName); jobNames.add("subjobFor_" + jobName); criterionList.add(Restrictions.in("jobName", jobNames)); } else { criterionList.add(Restrictions.eq("jobName", jobName)); } criterionList.add(Restrictions.ne("status", "STARTED")); QueryOptions queryOptions = QueryOptions.create("lastUpdated", false, 1, 1); Criterion allCriteria = HibUtils.listCrit(criterionList); List loaderLogs = HibernateSession.byCriteriaStatic() .options(queryOptions).list(Hib3GrouperLoaderLog.class, allCriteria); if (loaderLogs.size() > 0) { Hib3GrouperLoaderLog firstLoaderLog = loaderLogs.get(0); this.setLastRunStatus(firstLoaderLog.getStatus()); this.setLastRunHost(firstLoaderLog.getHost()); if (firstLoaderLog.getStartedTime() != null) { this.setLastRunStartTime(sdf.format(new Date(firstLoaderLog.getStartedTime().getTime()))); } if (firstLoaderLog.getMillis() != null) { this.setLastRunTotalTime(GrouperUiUtils.convertSecondsToString((firstLoaderLog.getMillis() / 1000))); } this.setLastRunSummary(firstLoaderLog.getTotalCount() + " total records, " + firstLoaderLog.getInsertCount() + " inserts, " + firstLoaderLog.getDeleteCount() + " deletes, " + firstLoaderLog.getUpdateCount() + " updates"); } } { GrouperLoaderType grouperLoaderType = GrouperLoaderType.typeForThisName(jobName); int minutesSinceLastSuccess = DaemonJobStatus.getMinutesSinceLastSuccess(jobName, grouperLoaderType); DaemonJobStatus daemonJobStatus = new DaemonJobStatus(jobName, minutesSinceLastSuccess); boolean isSuccess = daemonJobStatus.isSuccess(); Long lastSuccess = daemonJobStatus.getLastSuccess(); if (isSuccess) { this.setOverallStatus("SUCCESS"); this.setOverallStatusDescription("Found a success on " + GrouperUtil.dateStringValue(lastSuccess) + " in grouper_loader_log for job name: " + jobName + " which is within the threshold of " + minutesSinceLastSuccess + " minutes"); } else { if (this.isEnabled) { this.setOverallStatus("ERROR"); } else { this.setOverallStatus("DISABLED"); } if (lastSuccess == null) { this.setOverallStatusDescription("Can't find a success in grouper_loader_log for job name: " + jobName); } else { this.setOverallStatusDescription("Found most recent success on " + GrouperUtil.dateStringValue(lastSuccess) + " in grouper_loader_log for job name: " + jobName + " which is NOT within the threshold of " + minutesSinceLastSuccess + " minutes"); } } } this.setChangeLogInfo("N/A"); if (jobName.startsWith(GrouperLoaderType.GROUPER_CHANGE_LOG_CONSUMER_PREFIX)) { Long max = ChangeLogEntry.maxSequenceNumber(false); if (max != null) { String consumerName = jobName.substring(GrouperLoaderType.GROUPER_CHANGE_LOG_CONSUMER_PREFIX.length()); ChangeLogConsumer changeLogConsumer = GrouperDAOFactory.getFactory().getChangeLogConsumer().findByName(consumerName, false); if (changeLogConsumer != null && changeLogConsumer.getLastSequenceProcessed() != null) { long diff = max - changeLogConsumer.getLastSequenceProcessed(); if (diff < 0) { diff = 0; // in case one of the numbers is cached? } this.setChangeLogInfo(TextContainer.retrieveFromRequest().getText().get("daemonJobsChangeLogPendingInQueue") + " " + diff); } } } if (jobName.equals("CHANGE_LOG_changeLogTempToChangeLog")) { Long count = HibernateSession.byHqlStatic().createQuery("select count(*) from ChangeLogEntryTemp").uniqueResult(Long.class); this.setChangeLogInfo(TextContainer.retrieveFromRequest().getText().get("daemonJobsChangeLogPendingInQueue") + " " + count); } } catch (SchedulerException e) { throw new RuntimeException(e); } } /** * @see java.lang.Comparable#compareTo(java.lang.Object) */ @Override public int compareTo(GuiDaemonJob o) { if (o == null) { return -1; } if (StringUtils.equals(this.getJobName(), o.getJobName())) { return 0; } if (o.getJobName() == null) { return -1; } if (this.getJobName() == null) { return 1; } return this.getJobName().compareTo(o.getJobName()); } /** * @return the jobName */ public String getJobName() { return jobName; } /** * @param jobName the jobName to set */ public void setJobName(String jobName) { this.jobName = jobName; } /** * @return the schedule */ public String getSchedule() { return schedule; } /** * @param schedule the schedule to set */ public void setSchedule(String schedule) { this.schedule = schedule; } /** * @return the nextFireTime */ public String getNextFireTime() { return nextFireTime; } /** * @param nextFireTime the nextFireTime to set */ public void setNextFireTime(String nextFireTime) { this.nextFireTime = nextFireTime; } /** * @return the state */ public String getStateDescription() { return stateDescription; } /** * @param stateDescription the state to set */ public void setStateDescription(String stateDescription) { this.stateDescription = stateDescription; } /** * * @return state of job; can be RUNNING, ENABLED, or DISABLED */ public String getState() { return state; } /** * * @param state state of job; can be RUNNING, ENABLED, or DISABLED */ public void setState(String state) { this.state = state; } /** * @return the prevFireTime */ public String getPrevFireTime() { return prevFireTime; } /** * @param prevFireTime the prevFireTime to set */ public void setPrevFireTime(String prevFireTime) { this.prevFireTime = prevFireTime; } /** * @return the showMoreActionsRunNow */ public boolean isShowMoreActionsRunNow() { return showMoreActionsRunNow; } /** * @param showMoreActionsRunNow the showMoreActionsRunNow to set */ public void setShowMoreActionsRunNow(boolean showMoreActionsRunNow) { this.showMoreActionsRunNow = showMoreActionsRunNow; } /** * @return the showMoreActionsEnable */ public boolean isShowMoreActionsEnable() { return showMoreActionsEnable; } /** * @param showMoreActionsEnable the showMoreActionsEnable to set */ public void setShowMoreActionsEnable(boolean showMoreActionsEnable) { this.showMoreActionsEnable = showMoreActionsEnable; } /** * @return the showMoreActionsDisable */ public boolean isShowMoreActionsDisable() { return showMoreActionsDisable; } /** * @param showMoreActionsDisable the showMoreActionsDisable to set */ public void setShowMoreActionsDisable(boolean showMoreActionsDisable) { this.showMoreActionsDisable = showMoreActionsDisable; } /** * @return the lastRunStatus */ public String getLastRunStatus() { return lastRunStatus; } /** * @param lastRunStatus the lastRunStatus to set */ public void setLastRunStatus(String lastRunStatus) { this.lastRunStatus = lastRunStatus; } /** * @return the lastRunHost */ public String getLastRunHost() { return lastRunHost; } /** * @param lastRunHost the lastRunHost to set */ public void setLastRunHost(String lastRunHost) { this.lastRunHost = lastRunHost; } /** * @return the lastRunSummary */ public String getLastRunSummary() { return lastRunSummary; } /** * @param lastRunSummary the lastRunSummary to set */ public void setLastRunSummary(String lastRunSummary) { this.lastRunSummary = lastRunSummary; } /** * @return the lastRunTotalTime */ public String getLastRunTotalTime() { return lastRunTotalTime; } /** * @param lastRunTotalTime the lastRunTotalTime to set */ public void setLastRunTotalTime(String lastRunTotalTime) { this.lastRunTotalTime = lastRunTotalTime; } /** * @return the lastRunStartTime */ public String getLastRunStartTime() { return lastRunStartTime; } /** * @param lastRunStartTime the lastRunStartTime to set */ public void setLastRunStartTime(String lastRunStartTime) { this.lastRunStartTime = lastRunStartTime; } /** * @return the changeLogInfo */ public String getChangeLogInfo() { return changeLogInfo; } /** * @param changeLogInfo the changeLogInfo to set */ public void setChangeLogInfo(String changeLogInfo) { this.changeLogInfo = changeLogInfo; } /** * @return the overallStatusDescription */ public String getOverallStatusDescription() { return overallStatusDescription; } /** * @param overallStatusDescription the overallStatusDescription to set */ public void setOverallStatusDescription(String overallStatusDescription) { this.overallStatusDescription = overallStatusDescription; } /** * @return the overallStatus */ public String getOverallStatus() { return overallStatus; } /** * @param overallStatus the overallStatus to set */ public void setOverallStatus(String overallStatus) { this.overallStatus = overallStatus; } /** * @return */ public boolean isMultiple() { return isMultiple; } public boolean isEditable() { try { GrouperDaemonConfiguration grouperDaemonConfig = GrouperDaemonConfiguration.retrieveImplementationFromJobName(jobName); return grouperDaemonConfig != null && grouperDaemonConfig.isEditableOnUiFromWizard(); } catch (Exception e) { LOG.error("Error: cant find daemon config from job name '" + jobName + "'", e); } return false; } public boolean isLoader() { return isLoader; } public boolean isEnabled() { return isEnabled; } /** * if needs failsafe approval */ private boolean failsafeNeedsApproval; /** * if needs failsafe approval * @param theFailsafeNeed */ public void assignFailsafeNeedsApproval(boolean theFailsafeNeed) { this.failsafeNeedsApproval = theFailsafeNeed; } public boolean isFailsafeNeedsApproval() { return this.failsafeNeedsApproval; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy