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

org.opendaylight.infrautils.diagstatus.internal.DiagStatusServiceMBeanImpl Maven / Gradle / Ivy

/*
 * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. 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.diagstatus.internal;

import static org.opendaylight.infrautils.diagstatus.ServiceState.ERROR;
import static org.opendaylight.infrautils.diagstatus.ServiceState.UNREGISTERED;

import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.management.InstanceNotFoundException;
import javax.management.JMException;
import javax.management.MBeanRegistrationException;
import javax.management.StandardMBean;
import org.opendaylight.infrautils.diagstatus.DiagStatusService;
import org.opendaylight.infrautils.diagstatus.DiagStatusServiceMBean;
import org.opendaylight.infrautils.diagstatus.MBeanUtils;
import org.opendaylight.infrautils.diagstatus.ServiceDescriptor;
import org.opendaylight.infrautils.diagstatus.ServiceState;
import org.opendaylight.infrautils.diagstatus.ServiceStatusSummary;
import org.opendaylight.infrautils.ready.SystemReadyMonitor;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Singleton
@Component(immediate = true, service = DiagStatusServiceMBean.class)
// In case you are wondering: yes, this is published to OSGi registry for the sake of diagstatus-shell. Not the grandest
// of ideas but it works for now.
public final class DiagStatusServiceMBeanImpl extends StandardMBean implements DiagStatusServiceMBean, AutoCloseable {
    private static final Logger LOG = LoggerFactory.getLogger(DiagStatusServiceMBeanImpl.class);

    private final DiagStatusService diagStatusService;
    private final SystemReadyMonitor systemReadyMonitor;

    @Inject
    @Activate
    public DiagStatusServiceMBeanImpl(@Reference DiagStatusService diagStatusService,
            @Reference SystemReadyMonitor systemReadyMonitor) throws JMException {
        super(DiagStatusServiceMBean.class);
        this.diagStatusService = diagStatusService;
        this.systemReadyMonitor = systemReadyMonitor;
        MBeanUtils.registerServerMBean(this, JMX_OBJECT_NAME);
        LOG.info("Diagnostic Status Service management started");
    }

    @Override
    @Deactivate
    @PreDestroy
    public void close() throws InstanceNotFoundException, MBeanRegistrationException {
        MBeanUtils.unregisterServerMBean(this, JMX_OBJECT_NAME);
        LOG.info("Diagnostic Status Service management stopped");
    }

    @Override
    public String acquireServiceStatus() {
        var sb = new StringBuilder();
        ServiceStatusSummary summary = diagStatusService.getServiceStatusSummary();
        sb.append("System is operational: ").append(summary.isOperational()).append('\n');
        sb.append("System ready state: ").append(summary.getSystemReadyState()).append('\n');
        for (ServiceDescriptor status : summary.getStatusSummary()) {
            sb.append("ServiceName          : ").append(status.getModuleServiceName()).append('\n');
            if (status.getServiceState() != null) {
                sb.append("Last Reported Status : ").append(status.getServiceState().name()).append('\n');
            }
            if (status.getStatusDesc() != null) {
                sb.append("Reported Status Desc : ").append(status.getStatusDesc()).append('\n');
            }
            if (status.getStatusTimestamp() != null) {
                sb.append("Status Timestamp     : ").append(status.getStatusTimestamp()).append('\n');
            }
            if (status.getErrorCause() != null && status.getErrorCause().isPresent()) {
                sb.append("Error Cause          : ")
                    .append(Throwables.getStackTraceAsString(status.getErrorCause().orElseThrow()))
                    .append('\n');
            }
            sb.append('\n');
        }
        return sb.append('\n').toString();
    }

    @Override
    public String acquireServiceStatusDetailed() {
        // not so detailed as acquireServiceStatus()
        var sb = new StringBuilder();
        ServiceStatusSummary summary = diagStatusService.getServiceStatusSummary();
        sb.append("System is operational: ").append(summary.isOperational()).append('\n');
        sb.append("System ready state: ").append(systemReadyMonitor.getSystemState()).append('\n');
        for (ServiceDescriptor status : summary.getStatusSummary()) {
            sb.append("  ")
                // the magic is the max String length of ServiceState enum values, plus padding
                .append("%-20s%-15s".formatted(status.getModuleServiceName(), ": " + status.getServiceState()));
            if (!Strings.isNullOrEmpty(status.getStatusDesc())) {
                sb.append(" (").append(status.getStatusDesc()).append(")");
            }
            // intentionally using Throwable.toString() instead of Throwables.getStackTraceAsString to keep CLI brief
            status.getErrorCause().ifPresent(cause -> sb.append(cause.toString()));
            sb.append('\n');
        }
        return sb.toString();
    }

    @Override
    public String acquireServiceStatusBrief() {
        String errorState = "ERROR - ";
        var sb = new StringBuilder();
        ServiceStatusSummary summary = diagStatusService.getServiceStatusSummary();
        sb.append("System is operational: ").append(summary.isOperational()).append('\n');
        sb.append("System ready state: ").append(summary.getSystemReadyState()).append('\n');
        for (ServiceDescriptor stat : summary.getStatusSummary()) {
            ServiceState state = stat.getServiceState();
            if (state.equals(ERROR) || state.equals(UNREGISTERED)) {
                sb.append(errorState).append(stat.getModuleServiceName()).append(" ");
            }
        }
        return sb.toString();
    }

    @Override
    public ImmutableMap acquireServiceStatusMap() {
        var mapBuilder = ImmutableMap.builder();
        var summary = diagStatusService.getServiceStatusSummary();
        for (var status : summary.getStatusSummary()) {
            var state = status.getServiceState();
            if (state == null) {
                mapBuilder.put(status.getModuleServiceName(), ServiceState.UNREGISTERED.name());
            } else {
                mapBuilder.put(status.getModuleServiceName(), state.name());
            }
        }
        return mapBuilder.build();
    }

    @Override
    public String acquireServiceStatusAsJSON() {
        return diagStatusService.getServiceStatusSummary().toJSON();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy