ClusterStartLevelController.java 7.89 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.servlet.Servlet
 *  javax.servlet.ServletException
 *  org.apache.felix.scr.annotations.Activate
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.ConfigurationPolicy
 *  org.apache.felix.scr.annotations.Deactivate
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.Service
 *  org.osgi.framework.Bundle
 *  org.osgi.framework.BundleContext
 *  org.osgi.framework.FrameworkEvent
 *  org.osgi.framework.FrameworkListener
 *  org.osgi.service.http.HttpContext
 *  org.osgi.service.http.HttpService
 *  org.osgi.service.http.NamespaceException
 *  org.osgi.service.startlevel.StartLevel
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.jcrclustersupport.impl.startlevel;

import com.day.cq.jcrclustersupport.ClusterAware;
import com.day.cq.jcrclustersupport.impl.startlevel.UnavailableServlet;
import java.util.Dictionary;
import java.util.Map;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.ConfigurationPolicy;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkEvent;
import org.osgi.framework.FrameworkListener;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;
import org.osgi.service.startlevel.StartLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/*
 * This class specifies class file version 49.0 but uses Java 6 signatures.  Assumed Java 6.
 */
@Component(metatype=1, name="com.day.cq.jcrclustersupport.ClusterStartLevelController", policy=ConfigurationPolicy.REQUIRE)
@Service(value={ClusterAware.class})
public class ClusterStartLevelController
implements ClusterAware,
FrameworkListener {
    private static final boolean START_LEVEL_CONTROLLER_ENABLE = true;
    @Property(boolValue={1})
    private static final String PROP_START_LEVEL_CONTROLLER_ENABLE = "cluster.level.enable";
    private static final int MASTER_START_LEVEL = 30;
    @Property(intValue={30})
    private static final String PROP_MASTER_START_LEVEL = "cluster.master.level";
    private static final int SLAVE_START_LEVEL = 15;
    @Property(intValue={15})
    private static final String PROP_SLAVE_START_LEVEL = "cluster.slave.level";
    private final Logger log;
    @Reference
    private StartLevel startLevelService;
    @Reference
    private HttpService httpService;
    private boolean isMaster;
    private int defaultFrameworkStartLevel;
    private int currentStartLevel;
    private boolean enabled;
    private int masterStartLevel;
    private int slaveStartLevel;
    private Servlet unavailableServlet;

    public ClusterStartLevelController() {
        this.log = LoggerFactory.getLogger(this.getClass());
        this.isMaster = false;
    }

    @Activate
    private void activate(BundleContext bundleContext, Map<String, Object> config) {
        String fbs = bundleContext.getProperty("org.osgi.framework.startlevel.beginning");
        try {
            this.defaultFrameworkStartLevel = Integer.parseInt(fbs);
        }
        catch (NumberFormatException nfe) {
            this.defaultFrameworkStartLevel = -1;
        }
        this.currentStartLevel = this.startLevelService.getStartLevel();
        this.enabled = PropertiesUtil.toBoolean(config.get("cluster.level.enable"), true);
        if (this.enabled) {
            int cfgMasterLevel = PropertiesUtil.toInteger(config.get("cluster.master.level"), 30);
            int cfgSlaveLevel = PropertiesUtil.toInteger(config.get("cluster.slave.level"), 15);
            if (cfgSlaveLevel < this.startLevelService.getBundleStartLevel(bundleContext.getBundle())) {
                this.log.info("activate: Setting bundle start level to {}", (Object)cfgSlaveLevel);
                this.startLevelService.setBundleStartLevel(bundleContext.getBundle(), cfgSlaveLevel);
            }
            this.masterStartLevel = Math.max(Math.max(cfgMasterLevel, this.defaultFrameworkStartLevel), this.slaveStartLevel);
            this.slaveStartLevel = cfgSlaveLevel;
            this.log.info("configure: Setting Start Levels for Master={}; Slave={}", new Object[]{this.masterStartLevel, this.slaveStartLevel});
        } else {
            this.log.info("configure: Cluster Start Level Controller disabled");
        }
        bundleContext.addFrameworkListener((FrameworkListener)this);
    }

    @Deactivate
    private void deactivate(BundleContext bundleContext) {
        bundleContext.removeFrameworkListener((FrameworkListener)this);
    }

    @Override
    public void unbindRepository() {
        this.setMaster(false);
    }

    @Override
    public void bindRepository(String repositoryId, String clusterId, boolean isMaster) {
        this.setMaster(isMaster);
    }

    public void frameworkEvent(FrameworkEvent event) {
        if (event.getType() == 1 || event.getType() == 8) {
            this.currentStartLevel = this.startLevelService.getStartLevel();
            this.log.info("frameworkEvent: Framework attained start level {}", (Object)this.currentStartLevel);
            if (this.enabled) {
                this.registerUnavailableServlet();
            }
        }
    }

    private void setMaster(boolean isMaster) {
        this.isMaster = isMaster;
        if (this.enabled) {
            int targetStartLevel = isMaster ? this.masterStartLevel : this.slaveStartLevel;
            this.unregisterUnavailableServlet();
            if (this.currentStartLevel != targetStartLevel) {
                this.log.info("setMaster: Switching start level to {}; current is {}", new Object[]{targetStartLevel, this.currentStartLevel});
                this.startLevelService.setStartLevel(targetStartLevel);
            } else {
                this.log.info("setMaster: Framework currently at targetted start level {}", (Object)targetStartLevel);
                this.registerUnavailableServlet();
            }
        } else {
            this.log.info("setMaster: Cluster Start Level Controller disabled; not managing start levels");
        }
    }

    private void registerUnavailableServlet() {
        if (this.unavailableServlet == null && !this.isMaster) {
            try {
                UnavailableServlet s = new UnavailableServlet();
                this.httpService.registerServlet("/", (Servlet)s, null, null);
                this.unavailableServlet = s;
            }
            catch (ServletException e) {
                this.log.error("registerUnavailableServlet: Unexpected exception", (Throwable)e);
            }
            catch (NamespaceException e) {
                this.log.warn("registerUnavailableServlet: Cannot register default servlet", (Throwable)e);
            }
        }
    }

    private void unregisterUnavailableServlet() {
        if (this.unavailableServlet != null) {
            this.httpService.unregister("/");
            this.unavailableServlet = null;
        }
    }

    protected void bindStartLevelService(StartLevel startLevel) {
        this.startLevelService = startLevel;
    }

    protected void unbindStartLevelService(StartLevel startLevel) {
        if (this.startLevelService == startLevel) {
            this.startLevelService = null;
        }
    }

    protected void bindHttpService(HttpService httpService) {
        this.httpService = httpService;
    }

    protected void unbindHttpService(HttpService httpService) {
        if (this.httpService == httpService) {
            this.httpService = null;
        }
    }
}