package com.breakersoft.plow.service; import java.util.List; import java.util.UUID; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.breakersoft.plow.Action; import com.breakersoft.plow.ActionFull; import com.breakersoft.plow.Filter; import com.breakersoft.plow.FilterableJob; import com.breakersoft.plow.Folder; import com.breakersoft.plow.Job; import com.breakersoft.plow.Matcher; import com.breakersoft.plow.MatcherFull; import com.breakersoft.plow.Project; import com.breakersoft.plow.dao.ActionDao; import com.breakersoft.plow.dao.FilterDao; import com.breakersoft.plow.dao.FolderDao; import com.breakersoft.plow.dao.JobDao; import com.breakersoft.plow.dao.MatcherDao; import com.breakersoft.plow.exceptions.FilterException; import com.breakersoft.plow.thrift.ActionType; import com.breakersoft.plow.thrift.MatcherField; import com.breakersoft.plow.thrift.MatcherType; @Service @Transactional public class FilterServiceImpl implements FilterService { private static final Logger logger = LoggerFactory.getLogger(FilterServiceImpl.class); @Autowired private FilterDao filterDao; @Autowired private MatcherDao matcherDao; @Autowired private ActionDao actionDao; @Autowired private JobDao jobDao; @Autowired private FolderDao folderDao; @Override public Filter createFilter(Project project, String name) { return filterDao.create(project, name); } @Override @Transactional(readOnly=true) public Filter getFilter(UUID id) { return filterDao.get(id); } @Override public void setFilterName(Filter filter, String name) { filterDao.setName(filter, name); } @Override public void setFilterOrder(Filter filter, int order) { filterDao.setOrder(filter, order); } @Override public void increaseFilterOrder(Filter filter) { filterDao.increaseOrder(filter); } @Override public void decreaseFilterOrder(Filter filter) { filterDao.decreaseOrder(filter); } @Override public boolean deleteFilter(Filter filter) { return filterDao.delete(filter); } @Override public Matcher createMatcher(Filter filter, MatcherField field, MatcherType type, String value) { return matcherDao.create(filter, field, type, value); } @Override public boolean deleteMatcher(Matcher matcher) { return matcherDao.delete(matcher); } @Override @Transactional(readOnly=true) public Matcher getMatcher(UUID id) { return matcherDao.get(id); } @Override @Transactional(readOnly=true) public Action getAction(UUID id) { return actionDao.get(id); } @Override public Action createAction(Filter filter, ActionType type, String value) { return actionDao.create(filter, type, value); } @Override public void deleteAction(Action action) { actionDao.delete(action); } @Override public List<MatcherFull> getMatchers(Project project) { return matcherDao.getAllFull(project); } public boolean matchJob(MatcherFull matcher, FilterableJob job) { // Get the value to compare String comp = ""; boolean match = false; switch (matcher.field) { case JOB_NAME: comp = job.getName(); break; case USER: comp = job.username; break; case ATTR: comp = job.attrs.get(matcher.attr); break; default: throw new FilterException("Invalid matcher field: " + matcher.field.toString()); } if (comp == null) { return false; } // Try to make a match. switch (matcher.type) { case CONTAINS: match = comp.contains(matcher.value); break; case NOT_CONTAINS: match = !comp.contains(matcher.value); break; case IS: match = comp.equals(matcher.value); break; case IS_NOT: match = !comp.equals(matcher.value); break; case BEGINS_WITH: match = comp.startsWith(matcher.value); break; case ENDS_WITH: match = comp.endsWith(matcher.value); break; default: throw new FilterException("Invalid matcher type: " + matcher.type.toString()); } return match; } @Override public void filterJob(List<MatcherFull> matchers, FilterableJob job) { for (MatcherFull matcher: matchers) { boolean match = matchJob(matcher, job); if (match) { // Returns true if we should continue matching. if (!applActions(matcher, job)) { return; } } } } public boolean applActions(Matcher matcher, Job job) { List<ActionFull> actions = actionDao.getAllFull(matcher); logger.debug("Applying {} actions to job: {}", actions.size(), job.getName()); for (ActionFull action: actions) { if (action.type.equals(ActionType.STOP_PROCESSING)) { return false; } applyAction(action, job); } return true; } @Override public void applyAction(ActionFull action, Job job) { switch (action.type) { case SET_FOLDER: try { Folder folder = folderDao.get(action.valueAsUUID()); logger.info("Moving {} into folder {}", job, folder); jobDao.updateFolder(job, folder); } catch (Exception e) { logger.debug("Failed to move {} into folder, unexpected " + e, e); } break; case SET_MIN_CORES: logger.info("Setting {} to min cores {}", job, action.valueAsInt()); jobDao.setMinCores(job, action.valueAsInt()); break; case SET_MAX_CORES: logger.info("Setting {} to max cores {}", job, action.valueAsInt()); jobDao.setMaxCores(job, action.valueAsInt()); break; case PAUSE: logger.info("Setting {} to paused: {}", job, action.value); jobDao.setPaused(job, action.valueAsBool()); break; case STOP_PROCESSING: break; default: throw new FilterException("Invalid action type: " + action.type.toString()); } } }