/*
* The Alluxio Open Foundation licenses this work under the Apache License, version 2.0
* (the "License"). You may not use this work except in compliance with the License, which is
* available at www.apache.org/licenses/LICENSE-2.0
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied, as more fully set forth in the License.
*
* See the NOTICE file distributed with this work for information regarding copyright ownership.
*/
package alluxio;
import com.google.common.base.Throwables;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelOutboundBuffer;
import io.netty.channel.embedded.EmbeddedChannel;
import java.lang.reflect.Method;
/**
* Special versions of {@link EmbeddedChannel}.
*/
public final class EmbeddedChannels {
private EmbeddedChannels() {} // prevent instantiation
/**
* A customized {@link EmbeddedChannel} that supports empty constructor and supports thread safe
* read/write outbound messages from/to this channel.
*/
public static final class EmbeddedEmptyCtorChannel extends EmbeddedChannel {
public EmbeddedEmptyCtorChannel() {
// Invoke the parent ctor with a dummy handler.
super(new ChannelInboundHandlerAdapter());
// Remove the dummy handler.
pipeline().removeFirst();
}
/**
* Removes first ChannelHandler and adds a new ChannelHandler to pipeline.
*/
public void finishChannelCreation() {
pipeline().removeFirst();
pipeline().addLast(new LastInboundHandler());
}
@Override
protected void doWrite(ChannelOutboundBuffer in) throws Exception {
synchronized (this) {
super.doWrite(in);
}
}
@Override
public Object readOutbound() {
synchronized (this) {
return super.readOutbound();
}
}
private void recordException(Throwable e) {
try {
Method method = getClass().getSuperclass().getDeclaredMethod("recordException");
method.setAccessible(true);
method.invoke(this, e);
} catch (Exception ee) {
throw Throwables.propagate(ee);
}
}
private final class LastInboundHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
inboundMessages().add(msg);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
recordException(cause);
}
}
}
}