package org.infinispan.util; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; import org.infinispan.commands.ReplicableCommand; import org.infinispan.remoting.inboundhandler.DeliverOrder; import org.infinispan.remoting.responses.Response; import org.infinispan.remoting.rpc.ResponseMode; import org.infinispan.remoting.rpc.RpcManager; import org.infinispan.remoting.rpc.RpcOptions; import org.infinispan.remoting.rpc.RpcOptionsBuilder; import org.infinispan.remoting.transport.Address; import org.infinispan.remoting.transport.Transport; import org.infinispan.util.logging.Log; import org.infinispan.util.logging.LogFactory; /** * Common rpc manager controls * * @author Pedro Ruivo * @since 6.0 */ public abstract class AbstractControlledRpcManager implements RpcManager { protected final Log log = LogFactory.getLog(getClass()); protected final RpcManager realOne; public AbstractControlledRpcManager(RpcManager realOne) { this.realOne = realOne; } @Override public CompletableFuture<Map<Address, Response>> invokeRemotelyAsync(Collection<Address> recipients, ReplicableCommand rpc, RpcOptions options) { log.trace("ControlledRpcManager.invokeRemotelyAsync"); Object argument = beforeInvokeRemotely(rpc); CompletableFuture<Map<Address, Response>> future = realOne.invokeRemotelyAsync(recipients, rpc, options); return future.thenApply(responses -> afterInvokeRemotely(rpc, responses, argument)); } @Override public Map<Address, Response> invokeRemotely(Collection<Address> recipients, ReplicableCommand rpc, RpcOptions options) { log.trace("ControlledRpcManager.invokeRemotely"); Object argument = beforeInvokeRemotely(rpc); Map<Address, Response> responses = realOne.invokeRemotely(recipients, rpc, options); return afterInvokeRemotely(rpc, responses, argument); } @Override public Map<Address, Response> invokeRemotely(Map<Address, ReplicableCommand> rpcs, RpcOptions options) { log.trace("ControlledRpcManager.invokeRemotely"); // TODO: left blank until we need to implement return realOne.invokeRemotely(rpcs, options); } @Override public void sendTo(Address destination, ReplicableCommand command, DeliverOrder deliverOrder) { realOne.sendTo(destination, command, deliverOrder); } @Override public void sendToMany(Collection<Address> destinations, ReplicableCommand command, DeliverOrder deliverOrder) { realOne.sendToMany(destinations, command, deliverOrder); } @Override public Transport getTransport() { return realOne.getTransport(); } @Override public Address getAddress() { return realOne.getAddress(); } @Override public int getTopologyId() { return realOne.getTopologyId(); } @Override public RpcOptionsBuilder getRpcOptionsBuilder(ResponseMode responseMode) { return realOne.getRpcOptionsBuilder(responseMode); } @Override public RpcOptionsBuilder getRpcOptionsBuilder(ResponseMode responseMode, DeliverOrder deliverOrder) { return realOne.getRpcOptionsBuilder(responseMode, deliverOrder); } @Override public RpcOptions getDefaultRpcOptions(boolean sync) { return realOne.getDefaultRpcOptions(sync); } @Override public RpcOptions getDefaultRpcOptions(boolean sync, DeliverOrder deliverOrder) { return realOne.getDefaultRpcOptions(sync, deliverOrder); } @Override public List<Address> getMembers() { return realOne.getMembers(); } /** * method invoked before a remote invocation. * * @param command the command to be invoked remotely */ protected Object beforeInvokeRemotely(ReplicableCommand command) { //no-op by default return null; } /** * method invoked after a successful remote invocation. * * @param command the command invoked remotely. * @param responseMap can be null if not response is expected. * @param argument * @return the new response map */ protected Map<Address, Response> afterInvokeRemotely(ReplicableCommand command, Map<Address, Response> responseMap, Object argument) { return responseMap; } }