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
29
30
31
32
33
34
35
36 package org.waarp.gateway.kernel.rest.client;
37
38 import com.fasterxml.jackson.databind.JsonNode;
39 import com.fasterxml.jackson.databind.node.ObjectNode;
40 import io.netty.buffer.ByteBuf;
41 import io.netty.buffer.Unpooled;
42 import io.netty.channel.Channel;
43 import io.netty.channel.ChannelHandlerContext;
44 import io.netty.channel.SimpleChannelInboundHandler;
45 import io.netty.handler.codec.http.HttpContent;
46 import io.netty.handler.codec.http.HttpHeaderNames;
47 import io.netty.handler.codec.http.HttpObject;
48 import io.netty.handler.codec.http.HttpResponse;
49 import io.netty.handler.codec.http.HttpResponseStatus;
50 import io.netty.handler.codec.http.LastHttpContent;
51 import io.netty.util.AttributeKey;
52 import org.waarp.common.crypto.ssl.WaarpSslUtility;
53 import org.waarp.common.json.JsonHandler;
54 import org.waarp.common.logging.WaarpLogger;
55 import org.waarp.common.logging.WaarpLoggerFactory;
56 import org.waarp.common.utility.WaarpStringUtils;
57 import org.waarp.gateway.kernel.exception.HttpIncorrectRequestException;
58 import org.waarp.gateway.kernel.rest.RestArgument;
59
60 import java.net.ConnectException;
61 import java.nio.channels.ClosedChannelException;
62
63
64
65
66 public class HttpRestClientSimpleResponseHandler
67 extends SimpleChannelInboundHandler<HttpObject> {
68
69
70
71 private static final WaarpLogger logger =
72 WaarpLoggerFactory.getLogger(HttpRestClientSimpleResponseHandler.class);
73
74 public static final AttributeKey<RestFuture> RESTARGUMENT =
75 AttributeKey.valueOf("RestClient.Argument");
76
77 private ByteBuf cumulativeBody;
78 protected JsonNode jsonObject;
79
80 protected void actionFromResponse(final Channel channel) {
81 final RestArgument ra = new RestArgument((ObjectNode) jsonObject);
82 if (jsonObject == null) {
83 logger.warn("Recv: EMPTY");
84 } else {
85 logger.warn(ra.prettyPrint());
86 }
87 final RestFuture restFuture = channel.attr(RESTARGUMENT).get();
88 restFuture.setRestArgument(ra);
89 if (ra.getStatusCode() == HttpResponseStatus.OK.code()) {
90 restFuture.setSuccess();
91 } else {
92 logger.error("Error: " + ra.getStatusMessage());
93 restFuture.cancel();
94 if (channel.isActive()) {
95 WaarpSslUtility.closingSslChannel(channel);
96 }
97 }
98 }
99
100 @Override
101 protected void channelRead0(final ChannelHandlerContext ctx,
102 final HttpObject msg) throws Exception {
103 if (msg instanceof HttpResponse) {
104 final HttpResponse response = (HttpResponse) msg;
105 final HttpResponseStatus status = response.status();
106 logger.debug("{}: {} STATUS: {}", HttpHeaderNames.REFERER,
107 response.headers().get(HttpHeaderNames.REFERER), status);
108 }
109 if (msg instanceof HttpContent) {
110 final HttpContent chunk = (HttpContent) msg;
111 if (chunk instanceof LastHttpContent) {
112 final ByteBuf content = chunk.content();
113 if (content != null && content.isReadable()) {
114 if (cumulativeBody != null) {
115 cumulativeBody = Unpooled.wrappedBuffer(cumulativeBody, content);
116 } else {
117 cumulativeBody = content;
118 }
119 }
120
121 if (cumulativeBody == null) {
122 jsonObject = JsonHandler.createObjectNode();
123 } else {
124 try {
125 final String json = cumulativeBody.toString(WaarpStringUtils.UTF8);
126 jsonObject = JsonHandler.getFromString(json);
127 } catch (final Throwable e2) {
128 logger.warn("Error" + " : {}", e2.getMessage());
129 throw new HttpIncorrectRequestException(e2);
130 }
131 cumulativeBody = null;
132 }
133 actionFromResponse(ctx.channel());
134 } else {
135 final ByteBuf content = chunk.content();
136 if (content != null && content.isReadable()) {
137 if (cumulativeBody != null) {
138 cumulativeBody = Unpooled.wrappedBuffer(cumulativeBody, content);
139 } else {
140 cumulativeBody = content;
141 }
142 }
143 }
144 }
145 }
146
147 @Override
148 public void exceptionCaught(final ChannelHandlerContext ctx,
149 final Throwable cause) {
150 final RestFuture restFuture = ctx.channel().attr(RESTARGUMENT).get();
151 if (cause instanceof ClosedChannelException) {
152 restFuture.setFailure(cause);
153 logger.debug("Close before ending");
154 return;
155 } else if (cause instanceof ConnectException) {
156 restFuture.setFailure(cause);
157 if (ctx.channel().isActive()) {
158 logger.debug("Will close");
159 WaarpSslUtility.closingSslChannel(ctx.channel());
160 }
161 return;
162 }
163 restFuture.setFailure(cause);
164 logger.error("Error", cause);
165 WaarpSslUtility.closingSslChannel(ctx.channel());
166 }
167
168 }