1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.hc.core5.testing.nio;
29
30 import java.io.IOException;
31 import java.net.SocketAddress;
32 import java.nio.ByteBuffer;
33 import java.nio.channels.ByteChannel;
34 import java.nio.channels.SelectionKey;
35 import java.util.concurrent.locks.Lock;
36
37 import org.apache.hc.core5.annotation.Internal;
38 import org.apache.hc.core5.io.CloseMode;
39 import org.apache.hc.core5.reactor.Command;
40 import org.apache.hc.core5.reactor.IOEventHandler;
41 import org.apache.hc.core5.reactor.IOSession;
42 import org.apache.hc.core5.reactor.ProtocolIOSession;
43 import org.apache.hc.core5.testing.classic.Wire;
44 import org.apache.hc.core5.util.Timeout;
45 import org.slf4j.Logger;
46
47 @Internal
48 public class LoggingIOSession implements IOSession {
49
50 private final Logger log;
51 private final Wire wireLog;
52 private final IOSession session;
53
54 public LoggingIOSession(final IOSession session, final Logger log, final Logger wireLog) {
55 super();
56 this.session = session;
57 this.log = log;
58 this.wireLog = wireLog != null ? new Wire(wireLog, session.getId()) : null;
59 }
60
61 public LoggingIOSession(final ProtocolIOSession session, final Logger log) {
62 this(session, log, null);
63 }
64
65 @Override
66 public String getId() {
67 return session.getId();
68 }
69
70 @Override
71 public Lock getLock() {
72 return this.session.getLock();
73 }
74
75 @Override
76 public void enqueue(final Command command, final Command.Priority priority) {
77 this.session.enqueue(command, priority);
78 if (this.log.isDebugEnabled()) {
79 this.log.debug("{} enqueued {} with priority {}", this.session, command.getClass().getSimpleName(), priority);
80 }
81 }
82
83 @Override
84 public boolean hasCommands() {
85 return this.session.hasCommands();
86 }
87
88 @Override
89 public Command poll() {
90 return this.session.poll();
91 }
92
93 @Override
94 public ByteChannel channel() {
95 return this.session.channel();
96 }
97
98 @Override
99 public SocketAddress getLocalAddress() {
100 return this.session.getLocalAddress();
101 }
102
103 @Override
104 public SocketAddress getRemoteAddress() {
105 return this.session.getRemoteAddress();
106 }
107
108 @Override
109 public int getEventMask() {
110 return this.session.getEventMask();
111 }
112
113 private static String formatOps(final int ops) {
114 final StringBuilder buffer = new StringBuilder(6);
115 buffer.append('[');
116 if ((ops & SelectionKey.OP_READ) > 0) {
117 buffer.append('r');
118 }
119 if ((ops & SelectionKey.OP_WRITE) > 0) {
120 buffer.append('w');
121 }
122 if ((ops & SelectionKey.OP_ACCEPT) > 0) {
123 buffer.append('a');
124 }
125 if ((ops & SelectionKey.OP_CONNECT) > 0) {
126 buffer.append('c');
127 }
128 buffer.append(']');
129 return buffer.toString();
130 }
131
132 @Override
133 public void setEventMask(final int ops) {
134 this.session.setEventMask(ops);
135 if (this.log.isDebugEnabled()) {
136 this.log.debug("{} event mask set {}", this.session, formatOps(ops));
137 }
138 }
139
140 @Override
141 public void setEvent(final int op) {
142 this.session.setEvent(op);
143 if (this.log.isDebugEnabled()) {
144 this.log.debug("{} event set {}", this.session, formatOps(op));
145 }
146 }
147
148 @Override
149 public void clearEvent(final int op) {
150 this.session.clearEvent(op);
151 if (this.log.isDebugEnabled()) {
152 this.log.debug("{} event cleared {}", this.session, formatOps(op));
153 }
154 }
155
156 @Override
157 public void close() {
158 if (this.log.isDebugEnabled()) {
159 this.log.debug("{} close", this.session);
160 }
161 this.session.close();
162 }
163
164 @Override
165 public Status getStatus() {
166 return this.session.getStatus();
167 }
168
169 @Override
170 public boolean isOpen() {
171 return session.isOpen();
172 }
173
174 @Override
175 public void close(final CloseMode closeMode) {
176 if (this.log.isDebugEnabled()) {
177 this.log.debug("{} shutdown {}", this.session, closeMode);
178 }
179 this.session.close(closeMode);
180 }
181
182 @Override
183 public Timeout getSocketTimeout() {
184 return this.session.getSocketTimeout();
185 }
186
187 @Override
188 public void setSocketTimeout(final Timeout timeout) {
189 if (this.log.isDebugEnabled()) {
190 this.log.debug("{} set timeout {}", this.session, timeout);
191 }
192 this.session.setSocketTimeout(timeout);
193 }
194
195 @Override
196 public int read(final ByteBuffer dst) throws IOException {
197 final int bytesRead = session.read(dst);
198 if (log.isDebugEnabled()) {
199 log.debug("{} {} bytes read", session, bytesRead);
200 }
201 if (bytesRead > 0 && wireLog.isEnabled()) {
202 final ByteBuffer b = dst.duplicate();
203 final int p = b.position();
204 b.limit(p);
205 b.position(p - bytesRead);
206 wireLog.input(b);
207 }
208 return bytesRead;
209 }
210
211 @Override
212 public int write(final ByteBuffer src) throws IOException {
213 final int byteWritten = session.write(src);
214 if (log.isDebugEnabled()) {
215 log.debug("{} {} bytes written", session, byteWritten);
216 }
217 if (byteWritten > 0 && wireLog.isEnabled()) {
218 final ByteBuffer b = src.duplicate();
219 final int p = b.position();
220 b.limit(p);
221 b.position(p - byteWritten);
222 wireLog.output(b);
223 }
224 return byteWritten;
225 }
226
227 @Override
228 public void updateReadTime() {
229 this.session.updateReadTime();
230 }
231
232 @Override
233 public void updateWriteTime() {
234 this.session.updateWriteTime();
235 }
236
237 @Override
238 public long getLastReadTime() {
239 return this.session.getLastReadTime();
240 }
241
242 @Override
243 public long getLastWriteTime() {
244 return this.session.getLastWriteTime();
245 }
246
247 @Override
248 public long getLastEventTime() {
249 return this.session.getLastEventTime();
250 }
251
252 @Override
253 public IOEventHandler getHandler() {
254 return this.session.getHandler();
255 }
256
257 @Override
258 public void upgrade(final IOEventHandler handler) {
259 if (this.log.isDebugEnabled()) {
260 this.log.debug("{} protocol upgrade: {}", this.session, handler != null ? handler.getClass() : null);
261 }
262 this.session.upgrade(handler);
263 }
264
265 @Override
266 public String toString() {
267 return this.session.toString();
268 }
269
270 }