public static final String ORIGINAL_OPERATION = "original-operation";
/** {@inheritDoc} */
@Override
public OperationResult execute(final OperationContext context, final ModelNode operation, final ResultHandler resultHandler) throws OperationFailedException {
final PathAddress address = PathAddress.pathAddress(operation.require(ADDRESS_PARAM));
final String operationName = operation.require(ORIGINAL_OPERATION).asString();
// First check if the address is handled by a proxy
final Collection<ProxyController> proxies = context.getRegistry().getProxyControllers(address);
final int size = proxies.size();
if(size > 0) {
final AtomicInteger count = new AtomicInteger(size);
final AtomicInteger status = new AtomicInteger();
final ModelNode failureResult = new ModelNode();
for(final ProxyController proxy : proxies) {
final PathAddress proxyAddress = proxy.getProxyNodeAddress();
final ModelNode newOperation = operation.clone();
newOperation.get(OP_ADDR).set(address.subAddress(proxyAddress.size()).toModelNode());
final Operation operationContext = OperationBuilder.Factory.create(newOperation).build();
proxy.execute(operationContext, new ResultHandler() {
@Override
public void handleResultFragment(String[] location, ModelNode result) {
synchronized(failureResult) {
if(status.get() == 0) {
// Addresses are aggregated as list by the controller
final PathAddress resolved = PathAddress.pathAddress(result);
resultHandler.handleResultFragment(Util.NO_LOCATION, proxyAddress.append(resolved).toModelNode());
}
}
}
@Override
public void handleResultComplete() {
synchronized(failureResult) {
status.compareAndSet(0, 1);
if(count.decrementAndGet() == 0) {
handleComplete();
}
}
}
@Override
public void handleFailed(ModelNode failureDescription) {
synchronized(failureResult) {
if(failureDescription != null) {
failureResult.add(failureDescription);
}
status.compareAndSet(0, 2);
if(count.decrementAndGet() == 0) {
handleComplete();
}
}
}
@Override
public void handleCancellation() {
synchronized(failureResult) {
status.compareAndSet(0, 3);
if(count.decrementAndGet() == 0) {
handleComplete();
}
}
}
private void handleComplete() {
final int s = status.get();
switch(s) {
case 1: resultHandler.handleResultComplete(); break;
case 2: resultHandler.handleFailed(new ModelNode()); break;
case 3: resultHandler.handleCancellation(); break;
default : throw new IllegalStateException();
}
}
});
return new BasicOperationResult();
}
}
final OperationHandler operationHandler = context.getRegistry().getOperationHandler(address, operationName);
if(operationHandler == null) {
resultHandler.handleFailed(new ModelNode().set("no operation handler" + operationName));
return new BasicOperationResult();
}
final Collection<PathAddress> resolved;
if(operationHandler instanceof ModelQueryOperationHandler) {
resolved = PathAddress.resolve(address, context.getSubModel(), operationHandler instanceof ModelAddOperationHandler);
} else {
resolved = context.getRegistry().resolveAddress(address);
}
if(! resolved.isEmpty()) {
for(PathAddress a : resolved) {
// Addresses are aggregated as list by the controller
resultHandler.handleResultFragment(Util.NO_LOCATION, a.toModelNode());
}
}