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

org.ow2.petals.microkernel.transport.platform.nio.monitoring.TcpTransporterMonitoringImpl Maven / Gradle / Ivy

There is a newer version: 4.3.0
Show newest version
/**
 * Copyright (c) 2016 Linagora
 * 
 * This program/library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This program/library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program/library; If not, see http://www.gnu.org/licenses/
 * for the GNU Lesser General Public License version 2.1.
 */
package org.ow2.petals.microkernel.transport.platform.nio.monitoring;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import org.objectweb.fractal.fraclet.annotations.Component;
import org.objectweb.fractal.fraclet.annotations.Interface;
import org.objectweb.fractal.fraclet.annotations.Lifecycle;
import org.objectweb.fractal.fraclet.annotations.Requires;
import org.objectweb.fractal.fraclet.types.Step;
import org.ow2.petals.microkernel.api.configuration.ConfigurationService;
import org.ow2.petals.microkernel.api.configuration.ContainerConfiguration;
import org.ow2.petals.microkernel.transport.local.Constants;
import org.ow2.petals.microkernel.transport.platform.nio.client.NioClientObjectPool;
import org.ow2.petals.microkernel.transport.platform.nio.selector.NioServer;
import org.ow2.petals.probes.api.KeyedProbesFactory;
import org.ow2.petals.probes.api.KeyedProbesFactoryBuilder;
import org.ow2.petals.probes.api.enums.ExecutionStatus;
import org.ow2.petals.probes.api.exceptions.MultipleProbesFactoriesFoundException;
import org.ow2.petals.probes.api.exceptions.NoProbesFactoryFoundException;
import org.ow2.petals.probes.api.exceptions.ProbeKeyMissingException;
import org.ow2.petals.probes.api.exceptions.ProbeNotInitializedException;
import org.ow2.petals.probes.api.exceptions.ProbeNotStartedException;
import org.ow2.petals.probes.api.key.ProbeKey;
import org.ow2.petals.probes.api.key.StringProbeKey;
import org.ow2.petals.probes.api.probes.KeyedCounterProbe;
import org.ow2.petals.probes.api.probes.KeyedCounterProbeWithExecutionStatus;
import org.ow2.petals.probes.api.probes.KeyedGaugeProbe;

import com.ebmwebsourcing.easycommons.log.LoggingUtil;

/**
 * TCP transporter monitoring service implementation.
 * 
 * @author Christophe DENEUX - Linagora
 * 
 */
@Component(provides = { @Interface(name = "service", signature = TcpTransporterMonitoring.class) })
public class TcpTransporterMonitoringImpl implements TcpTransporterMonitoring {

    /**
     * All connections to remote containers are pooled into a keyed-pool. The key is the name of the remote container.
     */
    @Requires(name = NioClientObjectPool.NIO_CLIENT_OBJECT_ITF)
    private NioClientObjectPool clientConnections;

    @Requires(name = NioServer.NIO_SERVER_ITF)
    private NioServer server;

    /**
     * The Configuration service fractal component
     */
    @Requires(name = "configuration")
    private ConfigurationService configurationService;

    /**
     * The logger.
     */
    private final LoggingUtil log = new LoggingUtil(Logger.getLogger(Constants.FRACTAL_COMPONENT_LOGGER_NAME));

    /**
     * The probe counting outgoing messages sent by this transporter from the current container to a remote container.
     */
    private final KeyedCounterProbeWithExecutionStatus deliveredOutgoingMessagesCount;

    /**
     * The probe counting incoming messages received by the transporter of the current container from a remote container
     */
    private final KeyedCounterProbeWithExecutionStatus deliveredIncomingMessagesCount;

    /**
     * The probe counting outgoing connections established from the current container to remote containers, per remote
     * container, since the last start of the transporter.
     */
    private final KeyedCounterProbe outgoingConnectionCounter;

    /**
     * The probe sensor about outgoing ACTIVE connections currently established from the current container to remote
     * containers.
     */
    private final CurrentOutgoingActiveConnectionsGaugeSensor currentOutgoingActiveConnectionSensor;

    /**
     * The probe sensor about outgoing IDLE connections currently established from the current container to remote
     * containers.
     */
    private final CurrentOutgoingIdleConnectionsGaugeSensor currentOutgoingIdleConnectionSensor;

    /**
     * The probe counting outgoing ACTIVE connections currently established from the current container to remote
     * containers, per remote container.
     */
    private final KeyedGaugeProbe currentOutgoingActiveConnectionGauge;

    /**
     * The probe counting outgoing IDLE connections currently established from the current container to remote
     * containers, per remote container.
     */
    private final KeyedGaugeProbe currentOutgoingIdleConnectionGauge;

    /**
     * The probe counting incoming connections established from a remote container to the current container, per remote
     * container, since the last start of the transporter.
     */
    private final KeyedCounterProbe incomingConnectionCounter;

    /**
     * The probe sensor about incoming ACTIVE connections currently established from a remote container to the current
     * container.
     */
    private final CurrentIncomingActiveConnectionsGaugeSensor currentIncomingActiveConnectionSensor;

    /**
     * The probe sensor about incoming IDLE connections currently established from a remote container to the current
     * container.
     */
    private final CurrentIncomingIdleConnectionsGaugeSensor currentIncomingIdleConnectionSensor;

    /**
     * The probe counting incoming ACTIVE connections currently established from a remote container to the current
     * container, per remote container.
     */
    private final KeyedGaugeProbe currentIncomingActiveConnectionGauge;

    /**
     * The probe counting incoming IDLE connections currently established from a remote container to the current
     * container, per remote container.
     */
    private final KeyedGaugeProbe currentIncomingIdleConnectionGauge;

    public TcpTransporterMonitoringImpl() throws MultipleProbesFactoriesFoundException, NoProbesFactoryFoundException {
        final KeyedProbesFactoryBuilder probesExchangeFactoryBuilder = new KeyedProbesFactoryBuilder();
        final KeyedProbesFactory probesExchangeFactory = probesExchangeFactoryBuilder
                .getKeyedProbesFactory();
        this.deliveredOutgoingMessagesCount = probesExchangeFactory.createKeyedCounterProbeWithExecutionStatus();
        this.deliveredIncomingMessagesCount = probesExchangeFactory.createKeyedCounterProbeWithExecutionStatus();


        final KeyedProbesFactoryBuilder probesContainerFactoryBuilder = new KeyedProbesFactoryBuilder();
        final KeyedProbesFactory probesContainerFactory = probesContainerFactoryBuilder
                .getKeyedProbesFactory();
        this.outgoingConnectionCounter = probesContainerFactory.createKeyedCounterProbe();
        this.currentOutgoingActiveConnectionSensor = new CurrentOutgoingActiveConnectionsGaugeSensor();
        this.currentOutgoingActiveConnectionGauge = probesContainerFactory
                .createKeyedGaugeProbe(this.currentOutgoingActiveConnectionSensor);
        this.currentOutgoingIdleConnectionSensor = new CurrentOutgoingIdleConnectionsGaugeSensor();
        this.currentOutgoingIdleConnectionGauge = probesContainerFactory
                .createKeyedGaugeProbe(this.currentOutgoingIdleConnectionSensor);

        this.incomingConnectionCounter = probesContainerFactory.createKeyedCounterProbe();
        this.currentIncomingActiveConnectionSensor = new CurrentIncomingActiveConnectionsGaugeSensor();
        this.currentIncomingActiveConnectionGauge = probesContainerFactory
                .createKeyedGaugeProbe(this.currentIncomingActiveConnectionSensor);
        this.currentIncomingIdleConnectionSensor = new CurrentIncomingIdleConnectionsGaugeSensor();
        this.currentIncomingIdleConnectionGauge = probesContainerFactory
                .createKeyedGaugeProbe(this.currentIncomingIdleConnectionSensor);
    }

    @Override
    public ProbeKey incPendingOutgoingMessagesProbe(final String container) {

        final ProbeKey messageSentProbeKey = new StringProbeKey(container);
        try {
            this.deliveredOutgoingMessagesCount.incPending(messageSentProbeKey);
        } catch (final ProbeNotStartedException e) {
            this.log.warning(
                    "Probe counting outgoing messages delivered by TCP transporter is not started. Values of probe could be incorrect.");
        }
        return messageSentProbeKey;
    }

    @Override
    public void endsPendingOutgoingMessagesProbe(final ProbeKey probeKey, final ExecutionStatus status) {

        try {
            this.deliveredOutgoingMessagesCount.move(probeKey, status);
        } catch (final ProbeNotStartedException e) {
            this.log.warning(
                    "Probe counting outgoing messages delivered by TCP transporter is not started. Values of probe could be incorrect.");
        } catch (final ProbeKeyMissingException e) {
            this.log.warning("Probe key missing. Values of probe counting message exchanges could be incorrect.");
        }
    }

    @Override
    public Map getOutgoingMessagesCount() {
        try {
            final Map results = this.deliveredOutgoingMessagesCount.getConvertedValues();

            // Add metrics for remote containers for which no exchange occurs
            final List containers = new ArrayList<>();
            for (final ContainerConfiguration containerCfg : this.configurationService.getContainersConfiguration()) {
                containers.add(containerCfg.getName());
            }
            final Iterator itResults = results.keySet().iterator();
            while (itResults.hasNext()) {
                containers.remove(itResults.next()[0]);
            }
            for (final String container : containers) {
                results.put(new String[] { container, "PENDING" }, Long.valueOf(0));
                results.put(new String[] { container, "SUCCEEDED" }, Long.valueOf(0));
                results.put(new String[] { container, "ERROR" }, Long.valueOf(0));
            }

            return results;
        } catch (final ProbeNotInitializedException e) {
            this.log.warning(
                    "Probe counting outgoing messages delivered by TCP transporter is not initialized. No value available.");
            return Collections.emptyMap();
        }
    }

    @Override
    public void incPendingIncomingMessagesProbe(final String container) {

        final ProbeKey messageSentProbeKey = new StringProbeKey(container);
        try {
            this.deliveredIncomingMessagesCount.incPending(messageSentProbeKey);
        } catch (final ProbeNotStartedException e) {
            this.log.warning(
                    "Probe counting incoming messages delivered by TCP transporter is not started. Values of probe could be incorrect.");
        }
    }

    @Override
    public void endsPendingIncomingMessagesProbe(final String container, final ExecutionStatus status) {

        try {
            this.deliveredIncomingMessagesCount.move(new StringProbeKey(container), status);
        } catch (final ProbeNotStartedException e) {
            this.log.warning(
                    "Probe counting incoming messages delivered by TCP transporter is not started. Values of probe could be incorrect.");
        } catch (final ProbeKeyMissingException e) {
            this.log.warning("Probe key missing. Values of probe counting message exchanges could be incorrect.");
        }
    }

    @Override
    public void newOutgoingConnection(final String containerName) {
        try {
            this.outgoingConnectionCounter.inc(new StringProbeKey(containerName));
        } catch (final ProbeNotStartedException e) {
            this.log.warning("Probe counting outgoing established connections is not initialized. No value available.");
        }
    }

    @Override
    public void pickOutgoingConnectionNumbers(final String container) {
        try {
            final StringProbeKey containerProbeKey = new StringProbeKey(container);
            this.currentOutgoingActiveConnectionGauge.pick(containerProbeKey);
            this.currentOutgoingIdleConnectionGauge.pick(containerProbeKey);
        } catch (final ProbeNotStartedException e) {
            this.log.warning("Probe counting outgoing connections is not started. Values of probe could be incorrect.");
        }
    }

    @Override
    public void newIncomingConnection(final String containerIpAddress) {
        try {
            this.incomingConnectionCounter.inc(new StringProbeKey(containerIpAddress));
        } catch (final ProbeNotStartedException e) {
            this.log.warning("Probe counting incoming established connections is not initialized. No value available.");
        }
    }

    @Override
    public void pickIncomingConnectionNumbers(final String containerIpAddress) {
        try {
            final StringProbeKey containerProbeKey = new StringProbeKey(containerIpAddress);
            this.currentIncomingActiveConnectionGauge.pick(containerProbeKey);
            this.currentIncomingIdleConnectionGauge.pick(containerProbeKey);
        } catch (final ProbeNotStartedException e) {
            this.log.warning("Probe counting incoming connections is not started. Values of probe could be incorrect.");
        }
    }

    @Override
    public Map getIncomingMessagesCount() {
        try {
            final Map results = this.deliveredIncomingMessagesCount.getConvertedValues();

            // Add metrics for remote containers for which no exchange occurs
            final List containers = new ArrayList<>();
            for (final ContainerConfiguration containerCfg : this.configurationService.getContainersConfiguration()) {
                try {
                    containers.add(InetAddress.getByName(containerCfg.getHost()).getHostAddress());
                } catch (final UnknownHostException e) {
                    this.log.warning("This exception should not occur", e);
                }
            }
            final Iterator itResults = results.keySet().iterator();
            while (itResults.hasNext()) {
                containers.remove(itResults.next()[0]);
            }
            for (final String container : containers) {
                results.put(new String[] { container, "PENDING" }, Long.valueOf(0));
                results.put(new String[] { container, "SUCCEEDED" }, Long.valueOf(0));
                results.put(new String[] { container, "ERROR" }, Long.valueOf(0));
            }

            return results;
        } catch (final ProbeNotInitializedException e) {
            this.log.warning(
                    "Probe counting incoming messages delivered by TCP transporter is not initialized. No value available.");
            return Collections.emptyMap();
        }
    }

    @Override
    public Map getEstablishedOutgoingConnections() {
        try {
            return this.outgoingConnectionCounter.getConvertedValues();
        } catch (final ProbeNotInitializedException e) {
            this.log.warning("Probe counting outgoing connections is not initialized. No value available.");
            return Collections.emptyMap();
        }
    }

    @Override
    public Map getOutgoingActiveConnectionsCurrent() {
        try {
            return this.currentOutgoingActiveConnectionGauge.getConvertedInstantValues();
        } catch (final ProbeNotStartedException e) {
            this.log.warning("Probe counting outgoing active connections is not started. No value available.");
            return Collections.emptyMap();
        }
    }

    @Override
    public Map getOutgoingIdleConnectionsCurrent() {
        try {
            return this.currentOutgoingIdleConnectionGauge.getConvertedInstantValues();
        } catch (final ProbeNotStartedException e) {
            this.log.warning("Probe counting outgoing idle connections is not started. No value available.");
            return Collections.emptyMap();
        }
    }

    @Override
    public Map getOutgoingActiveConnectionsMax() {
        try {
            return this.currentOutgoingActiveConnectionGauge.getConvertedMaxValues();
        } catch (final ProbeNotInitializedException e) {
            this.log.warning("Probe counting outgoing active connections is not initialized. No value available.");
            return Collections.emptyMap();
        }
    }

    @Override
    public Map getOutgoingIdleConnectionsMax() {
        try {
            return this.currentOutgoingActiveConnectionGauge.getConvertedMaxValues();
        } catch (final ProbeNotInitializedException e) {
            this.log.warning("Probe counting outgoing active connections is not initialized. No value available.");
            return Collections.emptyMap();
        }
    }

    @Override
    public Map getOutgoingConnectionsMax() {
        final Map outgoingConnectionsMax = new HashMap();
        final int max = this.clientConnections.getNumMax();
        for (final ContainerConfiguration container : this.configurationService.getContainersConfiguration()) {
            outgoingConnectionsMax.put(new String[] { container.getName() }, Long.valueOf(max));
        }
        outgoingConnectionsMax.put(new String[] { this.configurationService.getContainerConfiguration().getName() },
                Long.valueOf(max));
        return outgoingConnectionsMax;
    }

    @Override
    public Map getOutgoingConnectionsMin() {
        final Map outgoingConnectionsMin = new HashMap();
        final int minIdle = this.clientConnections.getNumMinIdle();
        for (final ContainerConfiguration container : this.configurationService.getContainersConfiguration()) {
            outgoingConnectionsMin.put(new String[] { container.getName() }, Long.valueOf(minIdle));
        }
        outgoingConnectionsMin.put(new String[] { this.configurationService.getContainerConfiguration().getName() },
                Long.valueOf(minIdle));
        return outgoingConnectionsMin;
    }

    @Override
    public Map getEstablishedIncomingConnections() {
        try {
            return this.incomingConnectionCounter.getConvertedValues();
        } catch (final ProbeNotInitializedException e) {
            this.log.warning("Probe counting incoming connections is not initialized. No value available.");
            return Collections.emptyMap();
        }
    }

    @Override
    public Map getIncomingActiveConnectionsCurrent() {
        try {
            return this.currentIncomingActiveConnectionGauge.getConvertedInstantValues();
        } catch (final ProbeNotStartedException e) {
            this.log.warning("Probe counting incoming active connections is not started. No value available.");
            return Collections.emptyMap();
        }
    }

    @Override
    public Map getIncomingIdleConnectionsCurrent() {
        try {
            return this.currentIncomingIdleConnectionGauge.getConvertedInstantValues();
        } catch (final ProbeNotStartedException e) {
            this.log.warning("Probe counting incoming idle connections is not started. No value available.");
            return Collections.emptyMap();
        }
    }

    @Override
    public Map getIncomingActiveConnectionsMax() {
        try {
            return this.currentIncomingActiveConnectionGauge.getConvertedMaxValues();
        } catch (final ProbeNotInitializedException e) {
            this.log.warning("Probe counting incoming active connections is not initialized. No value available.");
            return Collections.emptyMap();
        }
    }

    @Override
    public Map getIncomingIdleConnectionsMax() {
        try {
            return this.currentIncomingActiveConnectionGauge.getConvertedMaxValues();
        } catch (final ProbeNotInitializedException e) {
            this.log.warning("Probe counting incoming active connections is not initialized. No value available.");
            return Collections.emptyMap();
        }
    }

    @Lifecycle(step = Step.START)
    public void start() throws Exception {
        this.log.start();

        this.currentOutgoingActiveConnectionSensor.setClientConnectionPool(this.clientConnections);
        this.currentOutgoingIdleConnectionSensor.setClientConnectionPool(this.clientConnections);
        this.currentIncomingActiveConnectionSensor.setNioServer(this.server);
        this.currentIncomingIdleConnectionSensor.setNioServer(this.server);

        this.deliveredOutgoingMessagesCount.init();
        this.deliveredIncomingMessagesCount.init();
        this.outgoingConnectionCounter.init();
        this.incomingConnectionCounter.init();
        this.currentOutgoingActiveConnectionGauge.init();
        this.currentIncomingActiveConnectionGauge.init();
        this.currentOutgoingIdleConnectionGauge.init();
        this.currentIncomingIdleConnectionGauge.init();

        this.deliveredOutgoingMessagesCount.start();
        this.deliveredIncomingMessagesCount.start();
        this.outgoingConnectionCounter.start();
        this.incomingConnectionCounter.start();
        this.currentOutgoingActiveConnectionGauge.start();
        this.currentIncomingActiveConnectionGauge.start();
        this.currentOutgoingIdleConnectionGauge.start();
        this.currentIncomingIdleConnectionGauge.start();

        this.log.end();
    }

    @Lifecycle(step = Step.STOP)
    public void stop() {
        this.log.start();

        try {
            this.deliveredOutgoingMessagesCount.stop();
            this.deliveredIncomingMessagesCount.stop();
            this.outgoingConnectionCounter.stop();
            this.incomingConnectionCounter.stop();
            this.currentOutgoingActiveConnectionGauge.stop();
            this.currentIncomingActiveConnectionGauge.stop();
            this.currentOutgoingIdleConnectionGauge.stop();
            this.currentIncomingIdleConnectionGauge.stop();

            this.deliveredOutgoingMessagesCount.shutdown();
            this.deliveredIncomingMessagesCount.shutdown();
            this.outgoingConnectionCounter.shutdown();
            this.incomingConnectionCounter.shutdown();
            this.currentOutgoingActiveConnectionGauge.shutdown();
            this.currentIncomingActiveConnectionGauge.shutdown();
            this.currentOutgoingIdleConnectionGauge.shutdown();
            this.currentIncomingIdleConnectionGauge.shutdown();
        } catch (final Exception e) {
            this.log.warning("Can't stop and/or shutdown the counter ", e);
        }

        this.log.end();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy