in java/src/main/java/org/apache/brooklyn/rest/client/BrooklynApi.java [231:282]
private <T> T proxy(Class<T> clazz) {
AggregateClassLoader aggregateClassLoader = AggregateClassLoader.newInstanceWithNoLoaders();
aggregateClassLoader.addLast(clazz.getClassLoader());
aggregateClassLoader.addLast(getClass().getClassLoader());
final T result0 = ProxyBuilder.build(clazz, target)
.executor(clientExecutor)
.classloader(aggregateClassLoader)
.providerFactory(ResteasyProviderFactory.getInstance())
.extractorFactory(new DefaultEntityExtractorFactory())
.requestAttributes(MutableMap.<String, Object>of())
.now();
return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[] { clazz }, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
Object result1 = method.invoke(result0, args);
Class<?> type = String.class;
if (result1 instanceof Response) {
Response resp = (Response)result1;
if(isStatusCodeHealthy(resp.getStatus()) && method.isAnnotationPresent(ApiOperation.class)) {
type = getClassFromMethodAnnotationOrDefault(method, type);
}
// wrap the original response so it self-closes
result1 = BuiltResponsePreservingError.copyResponseAndClose(resp, type);
}
return result1;
} catch (Throwable e) {
if (e instanceof InvocationTargetException) {
// throw the original exception
e = ((InvocationTargetException)e).getTargetException();
}
throw Exceptions.propagate(e);
}
}
private boolean isStatusCodeHealthy(int code) { return (code>=200 && code<=299); }
private Class<?> getClassFromMethodAnnotationOrDefault(Method method, Class<?> def){
Class<?> type;
try{
type = method.getAnnotation(ApiOperation.class).response();
} catch (Exception e) {
type = def;
LOG.debug("Unable to get class from annotation: {}. Defaulting to {}", e.getMessage(), def.getName());
Exceptions.propagateIfFatal(e);
}
return type;
}
});
}