View Javadoc
1   /*
2    * Copyright 2012 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.channel;
17  
18  import io.netty.buffer.ByteBuf;
19  import io.netty.util.concurrent.DefaultEventExecutorGroup;
20  import io.netty.util.concurrent.EventExecutor;
21  import io.netty.util.concurrent.EventExecutorGroup;
22  
23  import java.net.ConnectException;
24  import java.net.SocketAddress;
25  import java.nio.ByteBuffer;
26  import java.nio.channels.SocketChannel;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.Map.Entry;
30  import java.util.NoSuchElementException;
31  
32  
33  /**
34   * A list of {@link ChannelHandler}s which handles or intercepts inbound events and outbound operations of a
35   * {@link Channel}.  {@link ChannelPipeline} implements an advanced form of the
36   * <a href="http://www.oracle.com/technetwork/java/interceptingfilter-142169.html">Intercepting Filter</a> pattern
37   * to give a user full control over how an event is handled and how the {@link ChannelHandler}s in a pipeline
38   * interact with each other.
39   *
40   * <h3>Creation of a pipeline</h3>
41   *
42   * Each channel has its own pipeline and it is created automatically when a new channel is created.
43   *
44   * <h3>How an event flows in a pipeline</h3>
45   *
46   * The following diagram describes how I/O events are processed by {@link ChannelHandler}s in a {@link ChannelPipeline}
47   * typically. An I/O event is handled by a {@link ChannelHandler} and is forwarded by the {@link ChannelHandler} which
48   * handled the event to the {@link ChannelHandler} which is placed right next to it. A {@link ChannelHandler} can also
49   * trigger an arbitrary I/O event if necessary.  To forward or trigger an event, a {@link ChannelHandler} calls the
50   * event propagation methods defined in {@link ChannelHandlerContext}, such as
51   * {@link ChannelHandlerContext#fireChannelRead(Object)} and {@link ChannelHandlerContext#write(Object)}.
52   * <pre>
53   *                                                 I/O Request
54   *                                            via {@link Channel} or
55   *                                        {@link ChannelHandlerContext}
56   *                                                      |
57   *  +---------------------------------------------------+---------------+
58   *  |                           ChannelPipeline         |               |
59   *  |                                                  \|/              |
60   *  |    +----------------------------------------------+----------+    |
61   *  |    |                   ChannelHandler  N                     |    |
62   *  |    +----------+-----------------------------------+----------+    |
63   *  |              /|\                                  |               |
64   *  |               |                                  \|/              |
65   *  |    +----------+-----------------------------------+----------+    |
66   *  |    |                   ChannelHandler N-1                    |    |
67   *  |    +----------+-----------------------------------+----------+    |
68   *  |              /|\                                  .               |
69   *  |               .                                   .               |
70   *  | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
71   *  |          [method call]                      [method call]         |
72   *  |               .                                   .               |
73   *  |               .                                  \|/              |
74   *  |    +----------+-----------------------------------+----------+    |
75   *  |    |                   ChannelHandler  2                     |    |
76   *  |    +----------+-----------------------------------+----------+    |
77   *  |              /|\                                  |               |
78   *  |               |                                  \|/              |
79   *  |    +----------+-----------------------------------+----------+    |
80   *  |    |                   ChannelHandler  1                     |    |
81   *  |    +----------+-----------------------------------+----------+    |
82   *  |              /|\                                  |               |
83   *  +---------------+-----------------------------------+---------------+
84   *                  |                                  \|/
85   *  +---------------+-----------------------------------+---------------+
86   *  |               |                                   |               |
87   *  |       [ Socket.read() ]                    [ Socket.write() ]     |
88   *  |                                                                   |
89   *  |  Netty Internal I/O Threads (Transport Implementation)            |
90   *  +-------------------------------------------------------------------+
91   * </pre>
92   * An inbound event is handled by the {@link ChannelHandler}s in the bottom-up direction as shown on the left side of
93   * the diagram.  An inbound event is usually triggered by the I/O thread on the bottom of the diagram so that the
94   * {@link ChannelHandler}s are notified when the state of a {@link Channel} changes (e.g. newly established connections
95   * and closed connections) or the inbound data was read from a remote peer.  If an inbound event goes beyond the
96   * {@link ChannelHandler} at the top of the diagram, it is discarded and logged, depending on your loglevel.
97   *
98   * <p>
99   * An outbound event is handled by the {@link ChannelHandler}s in the top-down direction as shown on the right side of
100  * the diagram.  An outbound event is usually triggered by your code that requests an outbound I/O operation, such as
101  * a write request and a connection attempt.  If an outbound event goes beyond the {@link ChannelHandler} at the
102  * bottom of the diagram, it is handled by an I/O thread associated with the {@link Channel}. The I/O thread often
103  * performs the actual output operation such as {@link SocketChannel#write(ByteBuffer)}.
104  * <p>
105  *
106  * <h3>Forwarding an event to the next handler</h3>
107  *
108  * As explained briefly above, a {@link ChannelHandler} has to invoke the event propagation methods in
109  * {@link ChannelHandlerContext} to forward an event to its next handler.  Those methods include:
110  * <ul>
111  * <li>Inbound event propagation methods:
112  *     <ul>
113  *     <li>{@link ChannelHandlerContext#fireChannelRegistered()}</li>
114  *     <li>{@link ChannelHandlerContext#fireChannelActive()}</li>
115  *     <li>{@link ChannelHandlerContext#fireChannelRead(Object)}</li>
116  *     <li>{@link ChannelHandlerContext#fireChannelReadComplete()}</li>
117  *     <li>{@link ChannelHandlerContext#fireExceptionCaught(Throwable)}</li>
118  *     <li>{@link ChannelHandlerContext#fireUserEventTriggered(Object)}</li>
119  *     <li>{@link ChannelHandlerContext#fireChannelWritabilityChanged()}</li>
120  *     <li>{@link ChannelHandlerContext#fireChannelInactive()}</li>
121  *     </ul>
122  * </li>
123  * <li>Outbound event propagation methods:
124  *     <ul>
125  *     <li>{@link ChannelHandlerContext#bind(SocketAddress, ChannelPromise)}</li>
126  *     <li>{@link ChannelHandlerContext#connect(SocketAddress, SocketAddress, ChannelPromise)}</li>
127  *     <li>{@link ChannelHandlerContext#write(Object, ChannelPromise)}</li>
128  *     <li>{@link ChannelHandlerContext#flush()}</li>
129  *     <li>{@link ChannelHandlerContext#read()}</li>
130  *     <li>{@link ChannelHandlerContext#disconnect(ChannelPromise)}</li>
131  *     <li>{@link ChannelHandlerContext#close(ChannelPromise)}</li>
132  *     </ul>
133  * </li>
134  * </ul>
135  *
136  * and the following example shows how the event propagation is usually done:
137  *
138  * <pre>
139  * public class MyInboundHandler extends {@link ChannelHandlerAdapter} {
140  *     {@code @Override}
141  *     public void channelActive({@link ChannelHandlerContext} ctx) {
142  *         System.out.println("Connected!");
143  *         ctx.fireChannelActive();
144  *     }
145  * }
146  *
147  * public clas MyOutboundHandler extends {@link ChannelHandlerAdapter} {
148  *     {@code @Override}
149  *     public void close({@link ChannelHandlerContext} ctx, {@link ChannelPromise} promise) {
150  *         System.out.println("Closing ..");
151  *         ctx.close(promise);
152  *     }
153  * }
154  * </pre>
155  *
156  * <h3>Building a pipeline</h3>
157  * <p>
158  * A user is supposed to have one or more {@link ChannelHandler}s in a pipeline to receive I/O events (e.g. read) and
159  * to request I/O operations (e.g. write and close).  For example, a typical server will have the following handlers
160  * in each channel's pipeline, but your mileage may vary depending on the complexity and characteristics of the
161  * protocol and business logic:
162  *
163  * <ol>
164  * <li>Protocol Decoder - translates binary data (e.g. {@link ByteBuf}) into a Java object.</li>
165  * <li>Protocol Encoder - translates a Java object into binary data.</li>
166  * <li>Business Logic Handler - performs the actual business logic (e.g. database access).</li>
167  * </ol>
168  *
169  * and it could be represented as shown in the following example:
170  *
171  * <pre>
172  * static final {@link EventExecutorGroup} group = new {@link DefaultEventExecutorGroup}(16);
173  * ...
174  *
175  * {@link ChannelPipeline} pipeline = ch.pipeline();
176  *
177  * pipeline.addLast("decoder", new MyProtocolDecoder());
178  * pipeline.addLast("encoder", new MyProtocolEncoder());
179  *
180  * // Tell the pipeline to run MyBusinessLogicHandler's event handler methods
181  * // in a different thread than an I/O thread so that the I/O thread is not blocked by
182  * // a time-consuming task.
183  * // If your business logic is fully asynchronous or finished very quickly, you don't
184  * // need to specify a group.
185  * pipeline.addLast(group, "handler", new MyBusinessLogicHandler());
186  * </pre>
187  *
188  * <h3>Thread safety</h3>
189  * <p>
190  * A {@link ChannelHandler} can be added or removed at any time because a {@link ChannelPipeline} is thread safe.
191  * For example, you can insert an encryption handler when sensitive information is about to be exchanged, and remove it
192  * after the exchange.
193  */
194 public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>> {
195 
196     /**
197      * Inserts a {@link ChannelHandler} at the first position of this pipeline.
198      *
199      * @param name     the name of the handler to insert first. {@code null} to let the name auto-generated.
200      * @param handler  the handler to insert first
201      *
202      * @throws IllegalArgumentException
203      *         if there's an entry with the same name already in the pipeline
204      * @throws NullPointerException
205      *         if the specified handler is {@code null}
206      */
207     ChannelPipeline addFirst(String name, ChannelHandler handler);
208 
209     /**
210      * Inserts a {@link ChannelHandler} at the first position of this pipeline.
211      *
212      * @param group    the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
213      *                 methods
214      * @param name     the name of the handler to insert first. {@code null} to let the name auto-generated.
215      * @param handler  the handler to insert first
216      *
217      * @throws IllegalArgumentException
218      *         if there's an entry with the same name already in the pipeline
219      * @throws NullPointerException
220      *         if the specified handler is {@code null}
221      */
222     ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler);
223 
224     /**
225      * Inserts a {@link ChannelHandler} at the first position of this pipeline.
226      *
227      * @param invoker  the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods
228      * @param name     the name of the handler to insert first. {@code null} to let the name auto-generated.
229      * @param handler  the handler to insert first
230      *
231      * @throws IllegalArgumentException
232      *         if there's an entry with the same name already in the pipeline
233      * @throws NullPointerException
234      *         if the specified handler is {@code null}
235      */
236     ChannelPipeline addFirst(ChannelHandlerInvoker invoker, String name, ChannelHandler handler);
237 
238     /**
239      * Appends a {@link ChannelHandler} at the last position of this pipeline.
240      *
241      * @param name     the name of the handler to append. {@code null} to let the name auto-generated.
242      * @param handler  the handler to append
243      *
244      * @throws IllegalArgumentException
245      *         if there's an entry with the same name already in the pipeline
246      * @throws NullPointerException
247      *         if the specified handler is {@code null}
248      */
249     ChannelPipeline addLast(String name, ChannelHandler handler);
250 
251     /**
252      * Appends a {@link ChannelHandler} at the last position of this pipeline.
253      *
254      * @param group    the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
255      *                 methods
256      * @param name     the name of the handler to append. {@code null} to let the name auto-generated.
257      * @param handler  the handler to append
258      *
259      * @throws IllegalArgumentException
260      *         if there's an entry with the same name already in the pipeline
261      * @throws NullPointerException
262      *         if the specified handler is {@code null}
263      */
264     ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);
265 
266     /**
267      * Appends a {@link ChannelHandler} at the last position of this pipeline.
268      *
269      * @param invoker  the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods
270      * @param name     the name of the handler to append. {@code null} to let the name auto-generated.
271      * @param handler  the handler to append
272      *
273      * @throws IllegalArgumentException
274      *         if there's an entry with the same name already in the pipeline
275      * @throws NullPointerException
276      *         if the specified handler is {@code null}
277      */
278     ChannelPipeline addLast(ChannelHandlerInvoker invoker, String name, ChannelHandler handler);
279 
280     /**
281      * Inserts a {@link ChannelHandler} before an existing handler of this
282      * pipeline.
283      *
284      * @param baseName  the name of the existing handler
285      * @param name      the name of the handler to insert before. {@code null} to let the name auto-generated.
286      * @param handler   the handler to insert before
287      *
288      * @throws NoSuchElementException
289      *         if there's no such entry with the specified {@code baseName}
290      * @throws IllegalArgumentException
291      *         if there's an entry with the same name already in the pipeline
292      * @throws NullPointerException
293      *         if the specified baseName or handler is {@code null}
294      */
295     ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler);
296 
297     /**
298      * Inserts a {@link ChannelHandler} before an existing handler of this
299      * pipeline.
300      *
301      * @param group     the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
302      *                  methods
303      * @param baseName  the name of the existing handler
304      * @param name      the name of the handler to insert before. {@code null} to let the name auto-generated.
305      * @param handler   the handler to insert before
306      *
307      * @throws NoSuchElementException
308      *         if there's no such entry with the specified {@code baseName}
309      * @throws IllegalArgumentException
310      *         if there's an entry with the same name already in the pipeline
311      * @throws NullPointerException
312      *         if the specified baseName or handler is {@code null}
313      */
314     ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
315 
316     /**
317      * Inserts a {@link ChannelHandler} before an existing handler of this
318      * pipeline.
319      *
320      * @param invoker   the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods
321      * @param baseName  the name of the existing handler
322      * @param name      the name of the handler to insert before. {@code null} to let the name auto-generated.
323      * @param handler   the handler to insert before
324      *
325      * @throws NoSuchElementException
326      *         if there's no such entry with the specified {@code baseName}
327      * @throws IllegalArgumentException
328      *         if there's an entry with the same name already in the pipeline
329      * @throws NullPointerException
330      *         if the specified baseName or handler is {@code null}
331      */
332     ChannelPipeline addBefore(ChannelHandlerInvoker invoker, String baseName, String name, ChannelHandler handler);
333 
334     /**
335      * Inserts a {@link ChannelHandler} after an existing handler of this
336      * pipeline.
337      *
338      * @param baseName  the name of the existing handler
339      * @param name      the name of the handler to insert after. {@code null} to let the name auto-generated.
340      * @param handler   the handler to insert after
341      *
342      * @throws NoSuchElementException
343      *         if there's no such entry with the specified {@code baseName}
344      * @throws IllegalArgumentException
345      *         if there's an entry with the same name already in the pipeline
346      * @throws NullPointerException
347      *         if the specified baseName or handler is {@code null}
348      */
349     ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler);
350 
351     /**
352      * Inserts a {@link ChannelHandler} after an existing handler of this
353      * pipeline.
354      *
355      * @param group     the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
356      *                  methods
357      * @param baseName  the name of the existing handler
358      * @param name      the name of the handler to insert after. {@code null} to let the name auto-generated.
359      * @param handler   the handler to insert after
360      *
361      * @throws NoSuchElementException
362      *         if there's no such entry with the specified {@code baseName}
363      * @throws IllegalArgumentException
364      *         if there's an entry with the same name already in the pipeline
365      * @throws NullPointerException
366      *         if the specified baseName or handler is {@code null}
367      */
368     ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
369 
370     /**
371      * Inserts a {@link ChannelHandler} after an existing handler of this
372      * pipeline.
373      *
374      * @param invoker   the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods
375      * @param baseName  the name of the existing handler
376      * @param name      the name of the handler to insert after. {@code null} to let the name auto-generated.
377      * @param handler   the handler to insert after
378      *
379      * @throws NoSuchElementException
380      *         if there's no such entry with the specified {@code baseName}
381      * @throws IllegalArgumentException
382      *         if there's an entry with the same name already in the pipeline
383      * @throws NullPointerException
384      *         if the specified baseName or handler is {@code null}
385      */
386     ChannelPipeline addAfter(ChannelHandlerInvoker invoker, String baseName, String name, ChannelHandler handler);
387 
388     /**
389      * Inserts a {@link ChannelHandler}s at the first position of this pipeline.
390      *
391      * @param handlers  the handlers to insert first
392      *
393      */
394     ChannelPipeline addFirst(ChannelHandler... handlers);
395 
396     /**
397      * Inserts a {@link ChannelHandler}s at the first position of this pipeline.
398      *
399      * @param group     the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}s
400      *                  methods.
401      * @param handlers  the handlers to insert first
402      *
403      */
404     ChannelPipeline addFirst(EventExecutorGroup group, ChannelHandler... handlers);
405 
406     /**
407      * Inserts a {@link ChannelHandler}s at the first position of this pipeline.
408      *
409      * @param invoker   the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods
410      * @param handlers  the handlers to insert first
411      *
412      */
413     ChannelPipeline addFirst(ChannelHandlerInvoker invoker, ChannelHandler... handlers);
414 
415     /**
416      * Inserts a {@link ChannelHandler}s at the last position of this pipeline.
417      *
418      * @param handlers  the handlers to insert last
419      *
420      */
421     ChannelPipeline addLast(ChannelHandler... handlers);
422 
423     /**
424      * Inserts a {@link ChannelHandler}s at the last position of this pipeline.
425      *
426      * @param group     the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}s
427      *                  methods.
428      * @param handlers  the handlers to insert last
429      *
430      */
431     ChannelPipeline addLast(EventExecutorGroup group, ChannelHandler... handlers);
432 
433     /**
434      * Inserts a {@link ChannelHandler}s at the last position of this pipeline.
435      *
436      * @param invoker   the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods
437      * @param handlers  the handlers to insert last
438      *
439      */
440     ChannelPipeline addLast(ChannelHandlerInvoker invoker, ChannelHandler... handlers);
441 
442     /**
443      * Removes the specified {@link ChannelHandler} from this pipeline.
444      *
445      * @param  handler          the {@link ChannelHandler} to remove
446      *
447      * @throws NoSuchElementException
448      *         if there's no such handler in this pipeline
449      * @throws NullPointerException
450      *         if the specified handler is {@code null}
451      */
452     ChannelPipeline remove(ChannelHandler handler);
453 
454     /**
455      * Removes the {@link ChannelHandler} with the specified name from this pipeline.
456      *
457      * @param  name             the name under which the {@link ChannelHandler} was stored.
458      *
459      * @return the removed handler
460      *
461      * @throws NoSuchElementException
462      *         if there's no such handler with the specified name in this pipeline
463      * @throws NullPointerException
464      *         if the specified name is {@code null}
465      */
466     ChannelHandler remove(String name);
467 
468     /**
469      * Removes the {@link ChannelHandler} of the specified type from this pipeline.
470      *
471      * @param <T>           the type of the handler
472      * @param handlerType   the type of the handler
473      *
474      * @return the removed handler
475      *
476      * @throws NoSuchElementException
477      *         if there's no such handler of the specified type in this pipeline
478      * @throws NullPointerException
479      *         if the specified handler type is {@code null}
480      */
481     <T extends ChannelHandler> T remove(Class<T> handlerType);
482 
483     /**
484      * Removes the first {@link ChannelHandler} in this pipeline.
485      *
486      * @return the removed handler
487      *
488      * @throws NoSuchElementException
489      *         if this pipeline is empty
490      */
491     ChannelHandler removeFirst();
492 
493     /**
494      * Removes the last {@link ChannelHandler} in this pipeline.
495      *
496      * @return the removed handler
497      *
498      * @throws NoSuchElementException
499      *         if this pipeline is empty
500      */
501     ChannelHandler removeLast();
502 
503     /**
504      * Replaces the specified {@link ChannelHandler} with a new handler in this pipeline.
505      *
506      * @param  oldHandler    the {@link ChannelHandler} to be replaced
507      * @param  newName       the name under which the replacement should be added.
508      *                       {@code null} to use the same name with the handler being replaced.
509      * @param  newHandler    the {@link ChannelHandler} which is used as replacement
510      *
511      * @return itself
512 
513      * @throws NoSuchElementException
514      *         if the specified old handler does not exist in this pipeline
515      * @throws IllegalArgumentException
516      *         if a handler with the specified new name already exists in this
517      *         pipeline, except for the handler to be replaced
518      * @throws NullPointerException
519      *         if the specified old handler or new handler is {@code null}
520      */
521     ChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler);
522 
523     /**
524      * Replaces the {@link ChannelHandler} of the specified name with a new handler in this pipeline.
525      *
526      * @param  oldName       the name of the {@link ChannelHandler} to be replaced
527      * @param  newName       the name under which the replacement should be added.
528      *                       {@code null} to use the same name with the handler being replaced.
529      * @param  newHandler    the {@link ChannelHandler} which is used as replacement
530      *
531      * @return the removed handler
532      *
533      * @throws NoSuchElementException
534      *         if the handler with the specified old name does not exist in this pipeline
535      * @throws IllegalArgumentException
536      *         if a handler with the specified new name already exists in this
537      *         pipeline, except for the handler to be replaced
538      * @throws NullPointerException
539      *         if the specified old handler or new handler is {@code null}
540      */
541     ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler);
542 
543     /**
544      * Replaces the {@link ChannelHandler} of the specified type with a new handler in this pipeline.
545      *
546      * @param  oldHandlerType   the type of the handler to be removed
547      * @param  newName          the name under which the replacement should be added.
548      *                          {@code null} to use the same name with the handler being replaced.
549      * @param  newHandler       the {@link ChannelHandler} which is used as replacement
550      *
551      * @return the removed handler
552      *
553      * @throws NoSuchElementException
554      *         if the handler of the specified old handler type does not exist
555      *         in this pipeline
556      * @throws IllegalArgumentException
557      *         if a handler with the specified new name already exists in this
558      *         pipeline, except for the handler to be replaced
559      * @throws NullPointerException
560      *         if the specified old handler or new handler is {@code null}
561      */
562     <T extends ChannelHandler> T replace(Class<T> oldHandlerType, String newName,
563                                          ChannelHandler newHandler);
564 
565     /**
566      * Returns the first {@link ChannelHandler} in this pipeline.
567      *
568      * @return the first handler.  {@code null} if this pipeline is empty.
569      */
570     ChannelHandler first();
571 
572     /**
573      * Returns the context of the first {@link ChannelHandler} in this pipeline.
574      *
575      * @return the context of the first handler.  {@code null} if this pipeline is empty.
576      */
577     ChannelHandlerContext firstContext();
578 
579     /**
580      * Returns the last {@link ChannelHandler} in this pipeline.
581      *
582      * @return the last handler.  {@code null} if this pipeline is empty.
583      */
584     ChannelHandler last();
585 
586     /**
587      * Returns the context of the last {@link ChannelHandler} in this pipeline.
588      *
589      * @return the context of the last handler.  {@code null} if this pipeline is empty.
590      */
591     ChannelHandlerContext lastContext();
592 
593     /**
594      * Returns the {@link ChannelHandler} with the specified name in this
595      * pipeline.
596      *
597      * @return the handler with the specified name.
598      *         {@code null} if there's no such handler in this pipeline.
599      */
600     ChannelHandler get(String name);
601 
602     /**
603      * Returns the {@link ChannelHandler} of the specified type in this
604      * pipeline.
605      *
606      * @return the handler of the specified handler type.
607      *         {@code null} if there's no such handler in this pipeline.
608      */
609     <T extends ChannelHandler> T get(Class<T> handlerType);
610 
611     /**
612      * Returns the context object of the specified {@link ChannelHandler} in
613      * this pipeline.
614      *
615      * @return the context object of the specified handler.
616      *         {@code null} if there's no such handler in this pipeline.
617      */
618     ChannelHandlerContext context(ChannelHandler handler);
619 
620     /**
621      * Returns the context object of the {@link ChannelHandler} with the
622      * specified name in this pipeline.
623      *
624      * @return the context object of the handler with the specified name.
625      *         {@code null} if there's no such handler in this pipeline.
626      */
627     ChannelHandlerContext context(String name);
628 
629     /**
630      * Returns the context object of the {@link ChannelHandler} of the
631      * specified type in this pipeline.
632      *
633      * @return the context object of the handler of the specified type.
634      *         {@code null} if there's no such handler in this pipeline.
635      */
636     ChannelHandlerContext context(Class<? extends ChannelHandler> handlerType);
637 
638     /**
639      * Returns the {@link Channel} that this pipeline is attached to.
640      *
641      * @return the channel. {@code null} if this pipeline is not attached yet.
642      */
643     Channel channel();
644 
645     /**
646      * Returns the {@link List} of the handler names.
647      */
648     List<String> names();
649 
650     /**
651      * Converts this pipeline into an ordered {@link Map} whose keys are
652      * handler names and whose values are handlers.
653      */
654     Map<String, ChannelHandler> toMap();
655 
656     /**
657      * A {@link Channel} was registered to its {@link EventLoop}.
658      *
659      * This will result in having the  {@link ChannelHandler#channelRegistered(ChannelHandlerContext)} method
660      * called of the next  {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
661      * {@link Channel}.
662      */
663     ChannelPipeline fireChannelRegistered();
664 
665     /**
666      * A {@link Channel} was unregistered from its {@link EventLoop}.
667      *
668      * This will result in having the  {@link ChannelHandler#channelUnregistered(ChannelHandlerContext)} method
669      * called of the next  {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
670      * {@link Channel}.
671      */
672     ChannelPipeline fireChannelUnregistered();
673 
674     /**
675      * A {@link Channel} is active now, which means it is connected.
676      *
677      * This will result in having the  {@link ChannelHandler#channelActive(ChannelHandlerContext)} method
678      * called of the next  {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
679      * {@link Channel}.
680      */
681     ChannelPipeline fireChannelActive();
682 
683     /**
684      * A {@link Channel} is inactive now, which means it is closed.
685      *
686      * This will result in having the  {@link ChannelHandler#channelInactive(ChannelHandlerContext)} method
687      * called of the next  {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
688      * {@link Channel}.
689      */
690     ChannelPipeline fireChannelInactive();
691 
692     /**
693      * A {@link Channel} received an {@link Throwable} in one of its inbound operations.
694      *
695      * This will result in having the  {@link ChannelHandler#exceptionCaught(ChannelHandlerContext, Throwable)}
696      * method  called of the next  {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
697      * {@link Channel}.
698      */
699     ChannelPipeline fireExceptionCaught(Throwable cause);
700 
701     /**
702      * A {@link Channel} received an user defined event.
703      *
704      * This will result in having the  {@link ChannelHandler#userEventTriggered(ChannelHandlerContext, Object)}
705      * method  called of the next  {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
706      * {@link Channel}.
707      */
708     ChannelPipeline fireUserEventTriggered(Object event);
709 
710     /**
711      * A {@link Channel} received a message.
712      *
713      * This will result in having the {@link ChannelHandler#channelRead(ChannelHandlerContext, Object)}
714      * method  called of the next {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
715      * {@link Channel}.
716      */
717     ChannelPipeline fireChannelRead(Object msg);
718 
719     /**
720      * Triggers an {@link ChannelHandler#channelWritabilityChanged(ChannelHandlerContext)}
721      * event to the next {@link ChannelHandler} in the {@link ChannelPipeline}.
722      */
723     ChannelPipeline fireChannelReadComplete();
724 
725     /**
726      * Triggers an {@link ChannelHandler#channelWritabilityChanged(ChannelHandlerContext)}
727      * event to the next {@link ChannelHandler} in the {@link ChannelPipeline}.
728      */
729     ChannelPipeline fireChannelWritabilityChanged();
730 
731     /**
732      * Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
733      * completes, either because the operation was successful or because of an error.
734      * <p>
735      * This will result in having the
736      * {@link ChannelHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method
737      * called of the next {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
738      * {@link Channel}.
739      */
740     ChannelFuture bind(SocketAddress localAddress);
741 
742     /**
743      * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
744      * completes, either because the operation was successful or because of an error.
745      * <p>
746      * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with
747      * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException}
748      * will be used.
749      * <p>
750      * This will result in having the
751      * {@link ChannelHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
752      * method called of the next {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
753      * {@link Channel}.
754      */
755     ChannelFuture connect(SocketAddress remoteAddress);
756 
757     /**
758      * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the
759      * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
760      * an error.
761      * <p>
762      * This will result in having the
763      * {@link ChannelHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
764      * method called of the next {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
765      * {@link Channel}.
766      */
767     ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress);
768 
769     /**
770      * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes,
771      * either because the operation was successful or because of an error.
772      * <p>
773      * This will result in having the
774      * {@link ChannelHandler#disconnect(ChannelHandlerContext, ChannelPromise)}
775      * method called of the next {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
776      * {@link Channel}.
777      */
778     ChannelFuture disconnect();
779 
780     /**
781      * Request to close the {@link Channel} and notify the {@link ChannelFuture} once the operation completes,
782      * either because the operation was successful or because of
783      * an error.
784      *
785      * After it is closed it is not possible to reuse it again.
786      * <p>
787      * This will result in having the
788      * {@link ChannelHandler#close(ChannelHandlerContext, ChannelPromise)}
789      * method called of the next {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
790      * {@link Channel}.
791      */
792     ChannelFuture close();
793 
794     /**
795      * Request to deregister the {@link Channel} from the previous assigned {@link EventExecutor} and notify the
796      * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
797      * an error.
798      * <p>
799      * This will result in having the
800      * {@link ChannelHandler#deregister(ChannelHandlerContext, ChannelPromise)}
801      * method called of the next {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
802      * {@link Channel}.
803      *
804      */
805     ChannelFuture deregister();
806 
807     /**
808      * Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
809      * completes, either because the operation was successful or because of an error.
810      *
811      * The given {@link ChannelPromise} will be notified.
812      * <p>
813      * This will result in having the
814      * {@link ChannelHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method
815      * called of the next {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
816      * {@link Channel}.
817      */
818     ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise);
819 
820     /**
821      * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
822      * completes, either because the operation was successful or because of an error.
823      *
824      * The given {@link ChannelFuture} will be notified.
825      *
826      * <p>
827      * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with
828      * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException}
829      * will be used.
830      * <p>
831      * This will result in having the
832      * {@link ChannelHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
833      * method called of the next {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
834      * {@link Channel}.
835      */
836     ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise);
837 
838     /**
839      * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the
840      * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
841      * an error.
842      *
843      * The given {@link ChannelPromise} will be notified and also returned.
844      * <p>
845      * This will result in having the
846      * {@link ChannelHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
847      * method called of the next {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
848      * {@link Channel}.
849      */
850     ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise);
851 
852     /**
853      * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes,
854      * either because the operation was successful or because of an error.
855      *
856      * The given {@link ChannelPromise} will be notified.
857      * <p>
858      * This will result in having the
859      * {@link ChannelHandler#disconnect(ChannelHandlerContext, ChannelPromise)}
860      * method called of the next {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
861      * {@link Channel}.
862      */
863     ChannelFuture disconnect(ChannelPromise promise);
864 
865     /**
866      * Request to close the {@link Channel} bound to this {@link ChannelPipeline} and notify the {@link ChannelFuture}
867      * once the operation completes, either because the operation was successful or because of
868      * an error.
869      *
870      * After it is closed it is not possible to reuse it again.
871      * The given {@link ChannelPromise} will be notified.
872      * <p>
873      * This will result in having the
874      * {@link ChannelHandler#close(ChannelHandlerContext, ChannelPromise)}
875      * method called of the next {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
876      * {@link Channel}.
877      */
878     ChannelFuture close(ChannelPromise promise);
879 
880     /**
881      * Request to deregister the {@link Channel} bound this {@link ChannelPipeline} from the previous assigned
882      * {@link EventExecutor} and notify the {@link ChannelFuture} once the operation completes, either because the
883      * operation was successful or because of an error.
884      *
885      * The given {@link ChannelPromise} will be notified.
886      * <p>ChannelOutboundHandler
887      * This will result in having the
888      * {@link ChannelHandler#deregister(ChannelHandlerContext, ChannelPromise)}
889      * method called of the next {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
890      * {@link Channel}.
891      */
892     ChannelFuture deregister(ChannelPromise promise);
893 
894     /**
895      * Request to Read data from the {@link Channel} into the first inbound buffer, triggers an
896      * {@link ChannelHandler#channelRead(ChannelHandlerContext, Object)} event if data was
897      * read, and triggers a
898      * {@link ChannelHandler#channelReadComplete(ChannelHandlerContext) channelReadComplete} event so the
899      * handler can decide to continue reading.  If there's a pending read operation already, this method does nothing.
900      * <p>
901      * This will result in having the
902      * {@link ChannelHandler#read(ChannelHandlerContext)}
903      * method called of the next {@link ChannelHandler} contained in the  {@link ChannelPipeline} of the
904      * {@link Channel}.
905      */
906     ChannelPipeline read();
907 
908     /**
909      * Request to write a message via this {@link ChannelPipeline}.
910      * This method will not request to actual flush, so be sure to call {@link #flush()}
911      * once you want to request to flush all pending data to the actual transport.
912      */
913     ChannelFuture write(Object msg);
914 
915     /**
916      * Request to write a message via this {@link ChannelPipeline}.
917      * This method will not request to actual flush, so be sure to call {@link #flush()}
918      * once you want to request to flush all pending data to the actual transport.
919      */
920     ChannelFuture write(Object msg, ChannelPromise promise);
921 
922     /**
923      * Request to flush all pending messages.
924      */
925     ChannelPipeline flush();
926 
927     /**
928      * Shortcut for call {@link #write(Object, ChannelPromise)} and {@link #flush()}.
929      */
930     ChannelFuture writeAndFlush(Object msg, ChannelPromise promise);
931 
932     /**
933      * Shortcut for call {@link #write(Object)} and {@link #flush()}.
934      */
935     ChannelFuture writeAndFlush(Object msg);
936 }