/** * Copyright (c) 2009 - 2012 Red Hat, Inc. * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package org.candlepin.controller; import org.candlepin.common.config.Configuration; import org.candlepin.common.exceptions.SuspendedException; import org.candlepin.config.ConfigProperties; import org.candlepin.model.CandlepinModeChange; import org.candlepin.model.CandlepinModeChange.Mode; import org.candlepin.model.CandlepinModeChange.Reason; import com.google.inject.Inject; import com.google.inject.Singleton; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xnap.commons.i18n.I18n; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * This class drives Suspend Mode functionality. Suspend Mode is a * mode where Candlepin stops serving requests and only responds to * Status resource. * * @author fnguyen */ @Singleton public class ModeManagerImpl implements ModeManager { private static Logger log = LoggerFactory.getLogger(ModeManagerImpl.class); private CandlepinModeChange cpMode = new CandlepinModeChange( new Date(), Mode.NORMAL, Reason.STARTUP); private List<ModeChangeListener> listeners = new ArrayList<ModeChangeListener>(); private Configuration config; private I18n i18n; @Inject public ModeManagerImpl(Configuration config, I18n i18n) { this.config = config; this.i18n = i18n; } @Override public CandlepinModeChange getLastCandlepinModeChange() { return cpMode; } @Override public void enterMode(Mode m, Reason reason) { /** * When suspend mode is disabled, the Candlepin should never get into Suspend Mode. * Candlepin is starting always in NORMAL mode, so disalowing the transition here should * guarantee that. * * In fact, this method enterMode shouldn't be even called when SUSPEND mode is disabled. * So this check here is more of a defensive programming approach. */ if (!config.getBoolean(ConfigProperties.SUSPEND_MODE_ENABLED)) { log.debug("Suspend mode is disabled, ignoring mode transition"); return; } if (reason == null) { String noReasonErrorString = "No reason supplied when trying to change CandlepinModeChange."; log.error(noReasonErrorString); throw new IllegalArgumentException(noReasonErrorString); } log.info("Entering new mode {} for reason {}", m, reason); Mode previousMode = cpMode.getMode(); if (previousMode != m) { fireModeChangeEvent(m); } if (m.equals(Mode.SUSPEND)) { log.warn("Candlepin is entering suspend mode for the following reason: {}", reason); } cpMode = new CandlepinModeChange(new Date(), m, reason); } @Override public void throwRestEasyExceptionIfInSuspendMode() { if (getLastCandlepinModeChange().getMode() == Mode.SUSPEND) { log.debug("Mode manager detected SUSPEND mode and will throw SuspendException"); throw new SuspendedException(i18n.tr("Candlepin is in Suspend mode, " + "please check /status resource to get more details")); } } @Override public void registerModeChangeListener(ModeChangeListener l) { log.debug("Registering ModeChangeListener {} ", l.getClass().getSimpleName()); listeners.add(l); } private void fireModeChangeEvent(Mode newMode) { log.debug("Mode changed event fired {}", newMode); for (ModeChangeListener l : listeners) { l.modeChanged(newMode); } } private Integer getLastModeActiveTimeSeconds() { return (int) ((new Date().getTime() - cpMode.getChangeTime().getTime()) / 1000); } }