Package org.hudsonci.events.ready

Source Code of org.hudsonci.events.ready.ReadyDetector

/**
* The MIT License
*
* Copyright (c) 2010-2011 Sonatype, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package org.hudsonci.events.ready;

import org.hudsonci.events.EventPublisher;

import hudson.init.InitMilestone;
import hudson.model.Hudson;
import hudson.security.HudsonFilter;
import hudson.stapler.WebAppController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.servlet.Filter;
import java.lang.reflect.Field;

import static com.google.common.base.Preconditions.checkNotNull;

/**
* Detects when the system is ready for work and publishes a {@link ReadyEvent}.
*
* @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
* @since 2.1.0
*/
@Named
@Singleton
public class ReadyDetector
    extends Thread
{
    private static final Logger log = LoggerFactory.getLogger(ReadyDetector.class);

    private final EventPublisher publisher;

    private final Hudson hudson;

    private final WebAppController controller;

    @Inject
    public ReadyDetector(final EventPublisher publisher, final Hudson hudson) {
        this.publisher = checkNotNull(publisher);
        this.hudson = checkNotNull(hudson);
        this.controller = WebAppController.get();
        setDaemon(true);
    }

    public void run() {
        while (true) {
            if (isReady()) {
                publisher.publish(new ReadyEvent(hudson));
                log.info("Hudson is ready.");
                break;
            }
            else {
                try {
                    Thread.sleep(500);
                }
                catch (InterruptedException e) {
                    log.warn("Interrupted while waiting for initialization; ignoring", e);
                }
            }
        }
    }

    private boolean isReady() {
        // Hudson does not give us a nice InitMilestone when its really ready,
        // but if its not yet COMPLETED, don't bother trying to figure out more
        if (hudson.getInitLevel() != InitMilestone.COMPLETED) {
            return false;
        }

        HudsonFilter filter = HudsonFilter.get(hudson.servletContext);
        if (filter == null) {
            return false;
        }

        // Need to get access to the filter's filter field to see if its actually initialized or not
        // it does not expose it directly, so we have to use reflection to force access

        Filter delegate = getDelegate(filter);
        if (delegate == null) {
            return false;
        }

        // At this point we _should_ be ready, see if the app root object is installed... fingers crossed!
        try {
            Object app = controller.current(); // FIXME: This may actually be the only check needed?
            return app instanceof hudson.model.Hudson;
        } catch (IllegalStateException e) {
            return false; // context not yet available
        }
    }

    private Filter getDelegate(final HudsonFilter filter) {
        assert filter != null;
        try {
            Field field = filter.getClass().getDeclaredField("filter");
            field.setAccessible(true);
            return (Filter) field.get(filter);
        }
        catch (Exception e) {
            throw new Error("Failed to access HudsonFilter.filter delegate", e);
        }
    }
}
TOP

Related Classes of org.hudsonci.events.ready.ReadyDetector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.