/* * 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.ChannelHandler.Sharable; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import org.opendaylight.usc.manager.UscRouteBrokerService; import org.opendaylight.usc.manager.cluster.UscRouteIdentifier; import org.opendaylight.usc.plugin.exception.UscChannelException; import org.opendaylight.usc.plugin.exception.UscConnectionException; import org.opendaylight.usc.plugin.exception.UscException; import org.opendaylight.usc.plugin.exception.UscSessionException; import org.opendaylight.usc.plugin.model.UscChannelImpl; import org.opendaylight.usc.plugin.model.UscSessionImpl; import org.opendaylight.usc.util.UscServiceUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.util.concurrent.SettableFuture; /** * This Netty handler is automatically installed in the client channel pipeline * to facilitate the throwing of any exceptions that are encountered in the USC * session into the client state. */ @Sharable public class UscExceptionHandler extends SimpleChannelInboundHandler<UscException> { private static final Logger log = LoggerFactory.getLogger(UscExceptionHandler.class); private final UscPlugin plugin; private UscRouteBrokerService broker; public UscExceptionHandler(UscPlugin plugin) { this.plugin = plugin; } @Override protected void channelRead0(ChannelHandlerContext ctx, UscException ex) throws Exception { log.trace("UscExceptionHandler channelRead0" + ex); final Throwable t = ex.getCause(); Channel channel = ctx.channel(); UscRouteIdentifier routeId = ctx.channel().attr(UscPlugin.ROUTE_IDENTIFIER).get(); if (routeId != null) { // this is a channel using remote channel if (broker == null) { broker = UscServiceUtils.getService(UscRouteBrokerService.class); } if (broker != null) { broker.removeLocalSession(routeId); } else { log.error( "Broker service is null! Can't check if it is remote channel message, failed to proccess this exception {}.", ex); } return; } SettableFuture<UscSessionImpl> tmp = channel.attr(UscPlugin.SESSION).get(); if (tmp != null) { UscSessionImpl session = tmp.get(); UscChannelImpl connection = session.getChannel(); // connection is down if (t instanceof UscConnectionException) { plugin.getConnectionManager().removeConnection(connection); } else if (t instanceof UscChannelException) { // TODO ; } else if (t instanceof UscSessionException) { connection.removeSession(session.getSessionId()); } } throw ex; } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { UscConnectionException ex = new UscConnectionException("The channel is closed."); UscRouteIdentifier routeId = ctx.channel().attr(UscPlugin.ROUTE_IDENTIFIER).get(); if (routeId != null) { // this is a channel using remote channel if (broker == null) { broker = UscServiceUtils.getService(UscRouteBrokerService.class); } if (broker != null) { broker.removeLocalSession(routeId); } else { log.error( "Broker service is null! Can't check if it is remote channel message, failed to proccess this exception {}.", ex); } return; } throw ex; } }