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.util.concurrent.Future;
32 import java.util.concurrent.atomic.AtomicBoolean;
33
34 import org.apache.hc.core5.annotation.Contract;
35 import org.apache.hc.core5.annotation.ThreadingBehavior;
36 import org.apache.hc.core5.concurrent.BasicFuture;
37 import org.apache.hc.core5.concurrent.FutureCallback;
38 import org.apache.hc.core5.concurrent.FutureContribution;
39 import org.apache.hc.core5.http.ConnectionClosedException;
40 import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
41 import org.apache.hc.core5.http.nio.AsyncPushConsumer;
42 import org.apache.hc.core5.http.nio.AsyncRequestProducer;
43 import org.apache.hc.core5.http.nio.AsyncResponseConsumer;
44 import org.apache.hc.core5.http.nio.HandlerFactory;
45 import org.apache.hc.core5.http.nio.command.RequestExecutionCommand;
46 import org.apache.hc.core5.http.nio.command.ShutdownCommand;
47 import org.apache.hc.core5.http.nio.support.BasicClientExchangeHandler;
48 import org.apache.hc.core5.http.protocol.HttpContext;
49 import org.apache.hc.core5.io.CloseMode;
50 import org.apache.hc.core5.io.ModalCloseable;
51 import org.apache.hc.core5.reactor.Command;
52 import org.apache.hc.core5.reactor.IOSession;
53 import org.apache.hc.core5.util.Asserts;
54
55
56
57
58
59
60 @Contract(threading = ThreadingBehavior.SAFE_CONDITIONAL)
61 public final class ClientSessionEndpoint implements ModalCloseable {
62
63 private final IOSession ioSession;
64 private final AtomicBoolean closed;
65
66 public ClientSessionEndpoint(final IOSession ioSession) {
67 super();
68 this.ioSession = ioSession;
69 this.closed = new AtomicBoolean(false);
70 }
71
72 public void execute(final Command command, final Command.Priority priority) {
73 ioSession.enqueue(command, priority);
74 if (!ioSession.isOpen()) {
75 command.cancel();
76 }
77 }
78
79 public void execute(
80 final AsyncClientExchangeHandler exchangeHandler,
81 final HandlerFactory<AsyncPushConsumer> pushHandlerFactory,
82 final HttpContext context) {
83 Asserts.check(!closed.get(), "Connection is already closed");
84 final Command executionCommand = new RequestExecutionCommand(exchangeHandler, pushHandlerFactory, null, context);
85 ioSession.enqueue(executionCommand, Command.Priority.NORMAL);
86 if (!ioSession.isOpen()) {
87 exchangeHandler.failed(new ConnectionClosedException());
88 }
89 }
90
91 public void execute(
92 final AsyncClientExchangeHandler exchangeHandler,
93 final HttpContext context) {
94 execute(exchangeHandler, null, context);
95 }
96
97 public <T> Future<T> execute(
98 final AsyncRequestProducer requestProducer,
99 final AsyncResponseConsumer<T> responseConsumer,
100 final HandlerFactory<AsyncPushConsumer> pushHandlerFactory,
101 final HttpContext context,
102 final FutureCallback<T> callback) {
103 Asserts.check(!closed.get(), "Connection is already closed");
104 final BasicFuture<T> future = new BasicFuture<>(callback);
105 execute(new BasicClientExchangeHandler<>(requestProducer, responseConsumer,
106 new FutureContribution<T>(future) {
107
108 @Override
109 public void completed(final T result) {
110 future.completed(result);
111 }
112
113 }),
114 pushHandlerFactory, context);
115 return future;
116 }
117
118 public <T> Future<T> execute(
119 final AsyncRequestProducer requestProducer,
120 final AsyncResponseConsumer<T> responseConsumer,
121 final HttpContext context,
122 final FutureCallback<T> callback) {
123 return execute(requestProducer, responseConsumer, null, context, callback);
124 }
125
126 public <T> Future<T> execute(
127 final AsyncRequestProducer requestProducer,
128 final AsyncResponseConsumer<T> responseConsumer,
129 final FutureCallback<T> callback) {
130 return execute(requestProducer, responseConsumer, null, null, callback);
131 }
132
133 public boolean isOpen() {
134 return !closed.get() && ioSession.isOpen();
135 }
136
137 @Override
138 public void close(final CloseMode closeMode) {
139 if (closed.compareAndSet(false, true)) {
140 if (closeMode == CloseMode.GRACEFUL) {
141 ioSession.enqueue(ShutdownCommand.GRACEFUL, Command.Priority.NORMAL);
142 } else {
143 ioSession.close(closeMode);
144 }
145 }
146 }
147
148 @Override
149 public void close() throws IOException {
150 if (closed.compareAndSet(false, true)) {
151 ioSession.enqueue(ShutdownCommand.GRACEFUL, Command.Priority.IMMEDIATE);
152 }
153 }
154
155 @Override
156 public String toString() {
157 return ioSession.toString();
158 }
159
160 }