Skip to content

Package: ThriftHttpClientFilter

ThriftHttpClientFilter

nameinstructionbranchcomplexitylinemethod
ThriftHttpClientFilter(String)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
ThriftHttpClientFilter(String, Map)
M: 41 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 9 C: 0
0%
M: 1 C: 0
0%
handleRead(FilterChainContext)
M: 20 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
handleWrite(FilterChainContext)
M: 109 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 23 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * Copyright (c) 2014, 2017 Oracle and/or its affiliates. All rights reserved.
3: *
4: * This program and the accompanying materials are made available under the
5: * terms of the Eclipse Public License v. 2.0, which is available at
6: * http://www.eclipse.org/legal/epl-2.0.
7: *
8: * This Source Code may also be made available under the following Secondary
9: * Licenses when the conditions for such availability set forth in the
10: * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11: * version 2 with the GNU Classpath Exception, which is available at
12: * https://www.gnu.org/software/classpath/license.html.
13: *
14: * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15: */
16:
17: package org.glassfish.grizzly.thrift.http;
18:
19: import java.io.IOException;
20: import java.net.InetSocketAddress;
21: import java.util.HashMap;
22: import java.util.Map;
23: import java.util.Map.Entry;
24:
25: import org.glassfish.grizzly.Buffer;
26: import org.glassfish.grizzly.filterchain.FilterChainContext;
27: import org.glassfish.grizzly.filterchain.NextAction;
28: import org.glassfish.grizzly.http.HttpBaseFilter;
29: import org.glassfish.grizzly.http.HttpContent;
30: import org.glassfish.grizzly.http.HttpRequestPacket;
31: import org.glassfish.grizzly.http.Method;
32: import org.glassfish.grizzly.http.Protocol;
33: import org.glassfish.grizzly.http.util.Header;
34:
35: /**
36: * ThriftHttpClientFilter is a client-side filter for Thrift RPC processors over
37: * HTTP.
38: * <p>
39: * Usages:
40: *
41: * <pre>
42: * {@code
43: * final FilterChainBuilder clientFilterChainBuilder = FilterChainBuilder.stateless();
44: * clientFilterChainBuilder.add(new TransportFilter()).add(new HttpClientFilter()).add(new ThriftHttpClientFilter("/yourUriPath")).add(new ThriftClientFilter());
45: * <p>
46: * final TCPNIOTransport transport = TCPNIOTransportBuilder.newInstance().build();
47: * transport.setProcessor(clientFilterChainBuilder.build());
48: * transport.start();
49: * Future<Connection> future = transport.connect(ip, port);
50: * final Connection connection = future.get(10, TimeUnit.SECONDS);
51: * <p>
52: * final TTransport ttransport = TGrizzlyClientTransport.create(connection);
53: * final TProtocol tprotocol = new TBinaryProtocol(ttransport);
54: * user-generated.thrift.Client client = new user-generated.thrift.Client(tprotocol);
55: * client.ping();
56: * // execute more works
57: * // ...
58: * // release
59: * ttransport.close();
60: * connection.close();
61: * transport.shutdownNow();
62: * }
63: * </pre>
64: *
65: * @author Bongjae Chang
66: */
67: public class ThriftHttpClientFilter extends HttpBaseFilter {
68:
69: private static final String THRIFT_HTTP_CONTENT_TYPE = "application/x-thrift";
70:
71: private final String uriPath;
72: private final Map<String, String> headers = new HashMap<>();
73:
74: public ThriftHttpClientFilter(final String uriPath, Map<String, String> headers) {
75: this.uriPath = uriPath;
76:
77: this.headers.put(Header.Connection.toString(), "keep-alive");
78: this.headers.put(Header.Accept.toString(), "*/*");
79: this.headers.put(Header.UserAgent.toString(), "grizzly-thrift");
80:
81:• if (headers != null && !headers.isEmpty()) {
82: this.headers.putAll(headers);
83: }
84: }
85:
86: public ThriftHttpClientFilter(final String uriPath) {
87: this(uriPath, null);
88: }
89:
90: @Override
91: public NextAction handleRead(FilterChainContext ctx) throws IOException {
92: final HttpContent httpContent = ctx.getMessage();
93:• if (httpContent == null) {
94: throw new IOException("httpContent should not be null");
95: }
96: final Buffer responseBodyBuffer = httpContent.getContent();
97: ctx.setMessage(responseBodyBuffer);
98: return ctx.getInvokeAction();
99: }
100:
101: @Override
102: public NextAction handleWrite(FilterChainContext ctx) throws IOException {
103: final Buffer requestBodyBuffer = ctx.getMessage();
104:• if (requestBodyBuffer == null) {
105: throw new IOException("request body's buffer should not be null");
106: }
107:
108: final HttpRequestPacket.Builder builder = HttpRequestPacket.builder();
109: builder.method(Method.POST);
110: builder.protocol(Protocol.HTTP_1_1);
111: builder.uri(uriPath);
112: final InetSocketAddress peerAddress = (InetSocketAddress) ctx.getConnection().getPeerAddress();
113: final String httpHost = peerAddress.getHostName() + ':' + peerAddress.getPort();
114: builder.host(httpHost);
115: final long contentLength = requestBodyBuffer.remaining();
116:• if (contentLength >= 0) {
117: builder.contentLength(contentLength);
118: } else {
119: builder.chunked(true);
120: }
121: builder.contentType(THRIFT_HTTP_CONTENT_TYPE);
122:• for (Entry<String, String> entry : headers.entrySet()) {
123: builder.header(entry.getKey(), entry.getValue());
124: }
125: final HttpRequestPacket requestPacket = builder.build();
126:
127: final HttpContent content = requestPacket.httpContentBuilder().content(requestBodyBuffer).build();
128: content.setLast(true);
129: ctx.setMessage(content);
130:
131: return ctx.getInvokeAction();
132: }
133: }