Skip to content

Commit ebc2ab5

Browse files
authored
THRIFT-5345: Allow the ServerContext to be Unwrapped Programmatically
Client: Java Patch: David Mollitor
1 parent 55016bf commit ebc2ab5

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

lib/java/src/org/apache/thrift/server/ServerContext.java

+26-3
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,32 @@
1818
*/
1919

2020
/**
21-
* Interface for storing server's connection context
21+
* Interface for storing server's connection context.
2222
*/
23-
2423
package org.apache.thrift.server;
2524

26-
public interface ServerContext {}
25+
public interface ServerContext {
26+
27+
/**
28+
* Returns an object that implements the given interface to allow access to
29+
* application specific contexts.
30+
*
31+
* @param iface A Class defining an interface that the result must implement
32+
* @return an object that implements the interface
33+
* @throws RuntimeException If the context cannot be unwrapped to the provided
34+
* class
35+
*/
36+
<T> T unwrap(Class<T> iface);
37+
38+
/**
39+
* Returns true if this server context is a wrapper for the provided
40+
* application specific context interface argument or returns false otherwise.
41+
*
42+
* @param iface a Class defining the underlying context
43+
* @return true if this implements the interface can be unwrapped to the
44+
* provided class
45+
* @throws RuntimeException if an error occurs while determining whether the
46+
* provided class can be unwrapped from this context.
47+
*/
48+
boolean isWrapperFor(Class<?> iface);
49+
}

lib/java/test/org/apache/thrift/test/TestServer.java

+20-2
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,24 @@ public void setConnectionId(int connectionId) {
8181
this.connectionId = connectionId;
8282
}
8383

84+
@Override
85+
public <T> T unwrap(Class<T> iface) {
86+
try {
87+
if (isWrapperFor(iface)) {
88+
return iface.cast(this);
89+
} else {
90+
throw new RuntimeException("The context is not a wrapper for " + iface.getName());
91+
}
92+
} catch (Exception e) {
93+
throw new RuntimeException("The context is not a wrapper and does not implement the interface");
94+
}
95+
}
96+
97+
@Override
98+
public boolean isWrapperFor(Class<?> iface) {
99+
return iface.isInstance(this);
100+
}
101+
84102
}
85103

86104
static class TestServerEventHandler implements TServerEventHandler {
@@ -99,12 +117,12 @@ public ServerContext createContext(TProtocol input, TProtocol output) {
99117
}
100118

101119
public void deleteContext(ServerContext serverContext, TProtocol input, TProtocol output) {
102-
TestServerContext ctx = (TestServerContext)serverContext;
120+
TestServerContext ctx = serverContext.unwrap(TestServerContext.class);
103121
System.out.println("TServerEventHandler.deleteContext - connection #"+ctx.getConnectionId()+" terminated");
104122
}
105123

106124
public void processContext(ServerContext serverContext, TTransport inputTransport, TTransport outputTransport) {
107-
TestServerContext ctx = (TestServerContext)serverContext;
125+
TestServerContext ctx = serverContext.unwrap(TestServerContext.class);
108126
System.out.println("TServerEventHandler.processContext - connection #"+ctx.getConnectionId()+" is ready to process next request");
109127
}
110128

0 commit comments

Comments
 (0)