/* * Copyright 2015 Netflix, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package io.reactivex.netty.channel.events; import io.reactivex.netty.events.EventListener; import io.reactivex.netty.events.EventPublisher; import io.reactivex.netty.events.EventSource; import io.reactivex.netty.events.ListenersHolder; import rx.Subscription; import rx.functions.Action1; import rx.functions.Action2; import rx.functions.Action3; import rx.functions.Action4; import rx.functions.Action5; import java.util.concurrent.TimeUnit; /** * A publisher which is both {@link EventSource} and {@link EventListener} for connection events. * * @param <T> Type of listener to expect. */ public final class ConnectionEventPublisher<T extends ConnectionEventListener> extends ConnectionEventListener implements EventSource<T>, EventPublisher { private final Action2<T, Long> bytesReadAction = new Action2<T, Long>() { @Override public void call(T l, Long bytesRead) { l.onByteRead(bytesRead); } }; private final Action2<T, Long> bytesWrittenAction = new Action2<T, Long>() { @Override public void call(T l, Long bytesWritten) { l.onByteWritten(bytesWritten); } }; private final Action1<T> flushStartAction = new Action1<T>() { @Override public void call(T l) { l.onFlushStart(); } }; private final Action3<T, Long, TimeUnit> flushCompleteAction = new Action3<T, Long, TimeUnit>() { @Override public void call(T l, Long duration, TimeUnit timeUnit) { l.onFlushComplete(duration, timeUnit); } }; private final Action1<T> writeStartAction = new Action1<T>() { @Override public void call(T l) { l.onWriteStart(); } }; private final Action3<T, Long, TimeUnit> writeSuccessAction = new Action3<T, Long, TimeUnit>() { @Override public void call(T l, Long duration, TimeUnit timeUnit) { l.onWriteSuccess(duration, timeUnit); } }; private final Action4<T, Long, TimeUnit, Throwable> writeFailedAction = new Action4<T, Long, TimeUnit, Throwable>() { @Override public void call(T l, Long duration, TimeUnit timeUnit, Throwable t) { l.onWriteFailed(duration, timeUnit, t); } }; private final Action1<T> closeStartAction = new Action1<T>() { @Override public void call(T l) { l.onConnectionCloseStart(); } }; private final Action3<T, Long, TimeUnit> closeSuccessAction = new Action3<T, Long, TimeUnit>() { @Override public void call(T l, Long duration, TimeUnit timeUnit) { l.onConnectionCloseSuccess(duration, timeUnit); } }; private final Action4<T, Long, TimeUnit, Throwable> closeFailedAction = new Action4<T, Long, TimeUnit, Throwable>() { @Override public void call(T l, Long duration, TimeUnit timeUnit, Throwable t) { l.onConnectionCloseFailed(duration, timeUnit, t); } }; private final Action2<T, Object> customEventAction = new Action2<T, Object>() { @Override public void call(T l, Object event) { l.onCustomEvent(event); } }; private final Action3<T, Throwable, Object> customEventErrorAction = new Action3<T, Throwable, Object>() { @Override public void call(T l, Throwable throwable, Object event) { l.onCustomEvent(event, throwable); } }; private final Action4<T, Long, TimeUnit, Object> customEventDurationAction = new Action4<T, Long, TimeUnit, Object>() { @Override public void call(T l, Long duration, TimeUnit timeUnit, Object event) { l.onCustomEvent(event, duration, timeUnit); } }; private final Action5<T, Long, TimeUnit, Throwable, Object> customEventDurationErrAction = new Action5<T, Long, TimeUnit, Throwable, Object>() { @Override public void call(T l, Long duration, TimeUnit timeUnit, Throwable throwable, Object event) { l.onCustomEvent(event, duration, timeUnit, throwable); } }; private final ListenersHolder<T> listeners; public ConnectionEventPublisher() { listeners = new ListenersHolder<>(); } public ConnectionEventPublisher(ConnectionEventPublisher<T> toCopy) { listeners = toCopy.listeners.copy(); } @Override public void onByteRead(final long bytesRead) { listeners.invokeListeners(bytesReadAction, bytesRead); } @Override public void onByteWritten(long bytesWritten) { listeners.invokeListeners(bytesWrittenAction, bytesWritten); } @Override public void onFlushStart() { listeners.invokeListeners(flushStartAction); } @Override public void onFlushComplete(final long duration, final TimeUnit timeUnit) { listeners.invokeListeners(flushCompleteAction, duration, timeUnit); } @Override public void onWriteStart() { listeners.invokeListeners(writeStartAction); } @Override public void onWriteSuccess(final long duration, final TimeUnit timeUnit) { listeners.invokeListeners(writeSuccessAction, duration, timeUnit); } @Override public void onWriteFailed(final long duration, final TimeUnit timeUnit, final Throwable throwable) { listeners.invokeListeners(writeFailedAction, duration, timeUnit, throwable); } @Override public void onConnectionCloseStart() { listeners.invokeListeners(closeStartAction); } @Override public void onConnectionCloseSuccess(final long duration, final TimeUnit timeUnit) { listeners.invokeListeners(closeSuccessAction, duration, timeUnit); } @Override public void onConnectionCloseFailed(final long duration, final TimeUnit timeUnit, final Throwable throwable) { listeners.invokeListeners(closeFailedAction, duration, timeUnit, throwable); } @Override public void onCustomEvent(Object event) { listeners.invokeListeners(customEventAction, event); } @Override public void onCustomEvent(Object event, long duration, TimeUnit timeUnit) { listeners.invokeListeners(customEventDurationAction, duration, timeUnit, event); } @Override public void onCustomEvent(Object event, long duration, TimeUnit timeUnit, Throwable throwable) { listeners.invokeListeners(customEventDurationErrAction, duration, timeUnit, throwable, event); } @Override public void onCustomEvent(Object event, Throwable throwable) { listeners.invokeListeners(customEventErrorAction, throwable, event); } @Override public Subscription subscribe(T listener) { return listeners.subscribe(listener); } @Override public boolean publishingEnabled() { return listeners.publishingEnabled(); } public ConnectionEventPublisher<T> copy() { return new ConnectionEventPublisher<>(this); } /*Visible for testing*/ ListenersHolder<T> getListeners() { return listeners; } }