org.opendaylight.usc.plugin.UscConnectionManager.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.usc.plugin.UscConnectionManager.java

Source

/*
 * Copyright (c) 2015 Huawei, 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.usc.plugin;

import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;

import java.util.concurrent.ConcurrentHashMap;

import org.opendaylight.usc.manager.UscRouteBrokerService;
import org.opendaylight.usc.manager.cluster.UscRemoteChannelIdentifier;
import org.opendaylight.usc.manager.cluster.message.UscRemoteChannelEventMessage;
import org.opendaylight.usc.manager.monitor.evt.UscChannelCloseEvent;
import org.opendaylight.usc.manager.monitor.evt.UscChannelCreateEvent;
import org.opendaylight.usc.plugin.model.UscChannel;
import org.opendaylight.usc.plugin.model.UscChannelImpl;
import org.opendaylight.usc.plugin.model.UscDevice;
import org.opendaylight.usc.util.UscServiceUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.annotations.VisibleForTesting;

/**
 * This class manages the collection of connections (channels) that are
 * currently established to this controller node.
 */
public class UscConnectionManager {

    private static final Logger log = LoggerFactory.getLogger(UscConnectionManager.class);

    private final UscPlugin plugin;
    private UscRouteBrokerService brokerService = null;

    /**
     * Map from host name to agentChannel
     */
    private final ConcurrentHashMap<UscDevice, UscChannelImpl> connections = new ConcurrentHashMap<>();

    protected UscConnectionManager(UscPlugin plugin) {
        this.plugin = plugin;
        brokerService = UscServiceUtils.getService(UscRouteBrokerService.class);
    }

    public UscChannelImpl getConnection(UscDevice device, UscChannel.ChannelType type) throws Exception {
        UscChannelImpl connection = connections.get(device);
        log.trace("device is" + device + ",type is " + type + ",Connections is " + connections);
        if (connection == null) {
            /*
             * Channel channel = null; try { channel =
             * plugin.connectToAgent(device); }catch(Exception e) {
             * log.warn(e.getMessage()); channel =
             * plugin.connectToDeviceDirectly(device); }
             * 
             * return addConnection(device, channel, false, type);
             */
            return addConnection(device, plugin.connectToAgent(device), false, type);
        } else {
            return connection;
        }
    }

    protected UscChannelImpl addConnection(final UscDevice device, final Channel channel, final boolean isCallHome,
            final UscChannel.ChannelType type) {
        // standard idiom for double-checked locking
        UscChannelImpl connection = connections.get(device);
        if (connection == null) {
            final UscChannelImpl newConnection = new UscChannelImpl(plugin, device, channel, isCallHome, type);
            connection = connections.putIfAbsent(device, newConnection);
            if (connection == null) {
                channel.closeFuture().addListener(new ChannelFutureListener() {
                    @Override
                    public void operationComplete(ChannelFuture future) throws Exception {
                        removeConnection(newConnection);
                        log.trace("agentChannel for device " + device + " closed");
                    }
                });
                if (brokerService != null) {
                    UscRemoteChannelIdentifier remoteChannel = new UscRemoteChannelIdentifier(
                            newConnection.getDevice().getInetAddress(), newConnection.getType());
                    brokerService.broadcastMessage(new UscRemoteChannelEventMessage(remoteChannel,
                            UscRemoteChannelEventMessage.ChannelEventType.CREATE));
                } else {
                    log.warn("Broker service is null, can't send broadcast for adding channel message("
                            + newConnection.getDevice().getInetAddress() + ")!");
                }
                plugin.sendEvent(new UscChannelCreateEvent(newConnection));
                connection = newConnection;
            } else {
                // previous entry exists; put failed; close the new channel
                channel.close();
            }
        }
        return connection;
    }

    public boolean removeConnection(UscChannelImpl connection) {
        // don't re-close the connection here since we should only reach this
        // point after the connection has been closed
        boolean isRemoved = connections.remove(connection.getDevice(), connection);
        if (isRemoved) {
            connection.removeAllSessions();
            plugin.sendEvent(new UscChannelCloseEvent(connection));
        }
        return isRemoved;
    }

    @VisibleForTesting
    public int getConnectionCount() {
        return connections.size();
    }

    @VisibleForTesting
    public int getSessionCount() {
        return connections.values().stream().mapToInt(UscChannelImpl::getSessionCount).sum();
    }

    @Override
    public String toString() {
        return connections.toString();
    }
}