package org.ovirt.engine.core.extensions.mgr;
import org.ovirt.engine.api.extensions.Base;
import org.ovirt.engine.api.extensions.ExtMap;
import org.ovirt.engine.api.extensions.Extension;
import org.slf4j.Logger;
public class ExtensionProxy implements Extension {
private final ClassLoader classLoader;
private final Extension proxied;
private final ExtMap context;
private void dumpMap(String prefix, ExtMap map) {
Logger logger = context.get(ExtensionsManager.TRACE_LOG_CONTEXT_KEY);
if (logger.isTraceEnabled()) {
logger.trace(prefix + " BEGIN");
logger.trace(map.toString());
logger.trace(prefix + " END");
}
}
public ExtensionProxy(ClassLoader classLoader, Extension proxied) {
this.classLoader = classLoader;
this.proxied = proxied;
this.context = new ExtMap();
}
public ClassLoader getClassLoader() {
return classLoader;
}
public Extension getExtension() {
return proxied;
}
public ExtMap getContext() {
return context;
}
@Override
public void invoke(ExtMap input, ExtMap output) {
input.putIfAbsent(Base.InvokeKeys.CONTEXT, context);
dumpMap("Invoke Input", input);
ClassLoader savedClassLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(classLoader);
proxied.invoke(input, output);
} catch (Throwable e) {
output.mput(
Base.InvokeKeys.RESULT,
Base.InvokeResult.FAILED
).mput(
Base.InvokeKeys.MESSAGE,
String.format(
"Exception: %s: %s",
e.getClass(),
e.getMessage()
)
).mput(
ExtensionsManager.CAUSE_OUTPUT_KEY,
e
);
} finally {
Thread.currentThread().setContextClassLoader(savedClassLoader);
}
dumpMap("Invoke Output", output);
}
public ExtMap invoke(ExtMap input, boolean allowUnsupported, boolean allowFail) {
ExtMap output = new ExtMap();
invoke(input, output);
String message = output.get(Base.InvokeKeys.MESSAGE);
switch(output.<Integer>get(Base.InvokeKeys.RESULT, Base.InvokeResult.FAILED)) {
case Base.InvokeResult.SUCCESS:
break;
case Base.InvokeResult.UNSUPPORTED:
if (!allowUnsupported) {
throw new ExtensionInvokeCommandUnsupportedException(
message == null ? "Unsupported command" : message,
input,
output
);
}
break;
case Base.InvokeResult.FAILED:
default:
if (!allowFail) {
throw new ExtensionInvokeCommandFailedException(
message == null ? "Invoke failed" : message,
input,
output,
output.get(ExtensionsManager.CAUSE_OUTPUT_KEY)
);
}
break;
}
return output;
}
public ExtMap invoke(ExtMap input, boolean allowUnsupported) {
return invoke(input, allowUnsupported, false);
}
public ExtMap invoke(ExtMap input) {
return invoke(input, false, false);
}
}