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

org.opendaylight.infrautils.ready.karaf.internal.KarafSystemReady Maven / Gradle / Ivy

/*
 * Copyright (c) 2017 Red Hat, Inc. and others. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.infrautils.ready.karaf.internal;

import static org.opendaylight.infrautils.ready.SystemState.FAILURE;

import com.google.common.annotations.VisibleForTesting;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import org.opendaylight.infrautils.ready.SystemReadyMonitor;
import org.opendaylight.infrautils.ready.spi.DelegatingSystemReadyMonitorMXBean;
import org.opendaylight.infrautils.ready.spi.SimpleSystemReadyMonitor;
import org.opendaylight.infrautils.utils.concurrent.ThreadFactoryProvider;
import org.opendaylight.odlparent.bundles.diag.DiagProvider;
import org.opendaylight.odlparent.bundlestest.lib.SystemStateFailureException;
import org.opendaylight.odlparent.bundlestest.lib.TestBundleDiag;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * {@link SystemReadyMonitor} implementation for an OSGi Karaf environment. This
 * relies on odlparent.bundlestest.lib, which internally uses Karaf specific API
 * to get Blueprint status, in addition to basic OSGi bundle status.
 *
 * @author Michael Vorburger.ch
 * @author Faseela K
 */
@Component(immediate = true, service = SystemReadyMonitor.class, configurationPid = "org.opendaylight.infrautils.ready")
@Designate(ocd = KarafSystemReady.Config.class)
public final class KarafSystemReady extends SimpleSystemReadyMonitor {
    @ObjectClassDefinition()
    public @interface Config {
        @AttributeDefinition(name = "system-ready-timeout-seconds")
        int systemReadyTimeout() default 300;
    }

    private static final Logger LOG = LoggerFactory.getLogger(KarafSystemReady.class);

    private final ThreadFactory threadFactory = ThreadFactoryProvider.builder()
                                                    .namePrefix("SystemReadyService")
                                                    .logger(LOG)
                                                    .build().get();

    private final DelegatingSystemReadyMonitorMXBean mbean = new DelegatingSystemReadyMonitorMXBean(this);

    private final Config config;
    private final TestBundleDiag testBundleDiag;

    @Activate
    public KarafSystemReady(@Reference DiagProvider diagProvider, Config newConfig) {
        this.config = newConfig;
        mbean.registerMBean();
        testBundleDiag = new TestBundleDiag(diagProvider);
        LOG.info("Now starting to provide full system readiness status updates (see TestBundleDiag's logs)...");
        threadFactory.newThread(this::runCheckBundleDiag).start();
    }

    @Deactivate
    void deactivate() {
        this.mbean.unregisterMBean();
    }

    @SuppressWarnings("checkstyle:IllegalCatch") // below
    @SuppressFBWarnings(value = "THROWS_METHOD_THROWS_RUNTIMEEXCEPTION", justification = "Re-thrown")
    private void runCheckBundleDiag() {
        try {
            // 5 minutes really ought to be enough for the whole circus to completely boot up?!
            testBundleDiag.checkBundleDiagInfos(config.systemReadyTimeout(), TimeUnit.SECONDS,
                (timeInfo, bundleDiagInfos) -> {
                    LOG.info("checkBundleDiagInfos: Elapsed time {}s, remaining time {}s, {}",
                        timeInfo.getElapsedTimeInMS() / 1000, timeInfo.getRemainingTimeInMS() / 1000,
                        // INFRAUTILS-17: getSummaryText() instead getFullDiagnosticText() because people found log
                        //                confusing
                        bundleDiagInfos.getSummaryText());
                });

        } catch (SystemStateFailureException e) {
            LOG.error("Failed, some bundles did not start (SystemReadyListeners are not called)", e);
            setSystemState(FAILURE);
            setSystemFailureCause(e);
            // We do not re-throw this

        } catch (RuntimeException throwable) {
            // It's exceptionally OK to catch RuntimeException here,
            // because we do want to set the currentFullSystemStatus
            LOG.error("Boot failed; not all SystemReadyListeners were not called, SystemState FAILURE", throwable);
            setSystemState(FAILURE);
            setSystemFailureCause(throwable);
            // and now we do re-throw it!
            throw throwable;
        }

        ready();
    }

    @VisibleForTesting
    DelegatingSystemReadyMonitorMXBean getMbean() {
        return mbean;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy