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

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

/*
 * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
 * Copyright (c) 2024 PANTHEON.tech, s.r.o.
 *
 * 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 java.util.Objects.requireNonNull;
import static org.opendaylight.infrautils.diagstatus.ServiceState.STARTING;

import com.google.common.collect.ImmutableSet;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.infrautils.diagstatus.DiagStatusService;
import org.opendaylight.infrautils.diagstatus.ServiceDescriptor;
import org.opendaylight.infrautils.diagstatus.ServiceRegistration;
import org.opendaylight.infrautils.diagstatus.ServiceState;
import org.opendaylight.infrautils.diagstatus.ServiceStatusProvider;
import org.opendaylight.infrautils.diagstatus.ServiceStatusSummary;
import org.opendaylight.infrautils.ready.SystemReadyMonitor;
import org.opendaylight.infrautils.ready.SystemState;
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.component.annotations.ReferencePolicyOption;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * DiagStatusServiceImpl is the core class having the functionality for tracking the registered services
 * and aggregating the status of the same.
 * @author Faseela K
 */
@Singleton
@Component(immediate = true, service = DiagStatusService.class)
public final class DiagStatusServiceImpl implements DiagStatusService, AutoCloseable {
    private static final Logger LOG = LoggerFactory.getLogger(DiagStatusServiceImpl.class);

    private final ConcurrentHashMap statusMap = new ConcurrentHashMap<>();
    private final SystemReadyMonitor systemReadyMonitor;

    private volatile List serviceStatusProviders;

    @Inject
    @Activate
    public DiagStatusServiceImpl(@Reference SystemReadyMonitor systemReadyMonitor,
            @Reference(policyOption = ReferencePolicyOption.GREEDY, updated = "setServiceStatusProviders")
            List serviceStatusProviders) {
        this.systemReadyMonitor = requireNonNull(systemReadyMonitor);
        LOG.info("Diagnostic Status Service started");
        setServiceStatusProviders(serviceStatusProviders);
    }

    synchronized void setServiceStatusProviders(List serviceStatusProviders) {
        this.serviceStatusProviders = List.copyOf(serviceStatusProviders);
    }

    @PreDestroy
    @Deactivate
    @Override
    public synchronized void close() {
        serviceStatusProviders = List.of();
        LOG.info("Diagnostic Status Service stopped");
    }

    @Override
    public ServiceRegistration register(String serviceIdentifier) {
        statusMap.put(serviceIdentifier, new ServiceDescriptor(serviceIdentifier, STARTING, "INITIALIZING"));
        return new ServiceRegistration() {
            @Override
            public void report(ServiceDescriptor serviceDescriptor) {
                var checked = requireNonNull(serviceDescriptor);
                var prev = statusMap.computeIfPresent(serviceIdentifier, (key, value) -> checked);
                if (prev == null) {
                    throw new IllegalStateException("Service already unregistered");
                }
            }

            @Override
            public void close() {
                statusMap.remove(serviceIdentifier);
            }
        };
    }

    @Override
    public ServiceDescriptor getServiceDescriptor(String serviceIdentifier) {
        updateServiceStatusMap();
        return statusMap.get(serviceIdentifier);
    }

    @Override
    public ImmutableSet getAllServiceDescriptors() {
        updateServiceStatusMap();
        return ImmutableSet.copyOf(statusMap.values());
    }

    @Override
    public ServiceStatusSummary getServiceStatusSummary() {
        var systemState = systemReadyMonitor.getSystemState();
        var serviceDescriptors = getAllServiceDescriptors();
        return new ServiceStatusSummary(isOperational(systemState, serviceDescriptors),
                systemState, systemReadyMonitor.getFailureCause(), serviceDescriptors);
    }

    // because other projects implementing ServiceStatusProvider may not run FindBugs, we null check anyway
    private void updateServiceStatusMap() {
        for (var serviceStatusProvider : serviceStatusProviders) {
            var serviceDescriptor = serviceStatusProvider.getServiceDescriptor();
            if (serviceDescriptor != null) {
                statusMap.put(serviceDescriptor.getModuleServiceName(), serviceDescriptor);
            } else {
                LOG.warn("ServiceStatusProvider getServiceDescriptor() returned null: {}", serviceStatusProvider);
            }
        }
    }

    private static boolean isOperational(SystemState systemState, Collection serviceDescriptors) {
        return systemState == SystemState.ACTIVE && serviceDescriptors.stream()
            .allMatch(serviceDescriptor -> serviceDescriptor.getServiceState() == ServiceState.OPERATIONAL);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy