use of org.opensearch.transport.RequestHandlerRegistry in project OpenSearch by opensearch-project.
the class MockTransportService method addUnresponsiveRule.
/**
* Adds a rule that will cause ignores each send request, simulating an unresponsive node
* and failing to connect once the rule was added.
*
* @param duration the amount of time to delay sending and connecting.
*/
public void addUnresponsiveRule(TransportAddress transportAddress, final TimeValue duration) {
final long startTime = System.currentTimeMillis();
Supplier<TimeValue> delaySupplier = () -> new TimeValue(duration.millis() - (System.currentTimeMillis() - startTime));
transport().addConnectBehavior(transportAddress, new StubbableTransport.OpenConnectionBehavior() {
private CountDownLatch stopLatch = new CountDownLatch(1);
@Override
public void openConnection(Transport transport, DiscoveryNode discoveryNode, ConnectionProfile profile, ActionListener<Transport.Connection> listener) {
TimeValue delay = delaySupplier.get();
if (delay.millis() <= 0) {
original.openConnection(discoveryNode, profile, listener);
return;
}
// TODO: Replace with proper setting
TimeValue connectingTimeout = TransportSettings.CONNECT_TIMEOUT.getDefault(Settings.EMPTY);
try {
if (delay.millis() < connectingTimeout.millis()) {
stopLatch.await(delay.millis(), TimeUnit.MILLISECONDS);
original.openConnection(discoveryNode, profile, listener);
} else {
stopLatch.await(connectingTimeout.millis(), TimeUnit.MILLISECONDS);
listener.onFailure(new ConnectTransportException(discoveryNode, "UNRESPONSIVE: simulated"));
}
} catch (InterruptedException e) {
listener.onFailure(new ConnectTransportException(discoveryNode, "UNRESPONSIVE: simulated"));
}
}
@Override
public void clearCallback() {
stopLatch.countDown();
}
});
transport().addSendBehavior(transportAddress, new StubbableTransport.SendRequestBehavior() {
private final Queue<Runnable> requestsToSendWhenCleared = new LinkedBlockingDeque<>();
private boolean cleared = false;
@Override
public void sendRequest(Transport.Connection connection, long requestId, String action, TransportRequest request, TransportRequestOptions options) throws IOException {
// delayed sending - even if larger then the request timeout to simulated a potential late response from target node
TimeValue delay = delaySupplier.get();
if (delay.millis() <= 0) {
connection.sendRequest(requestId, action, request, options);
return;
}
// poor mans request cloning...
RequestHandlerRegistry reg = MockTransportService.this.getRequestHandler(action);
BytesStreamOutput bStream = new BytesStreamOutput();
request.writeTo(bStream);
final TransportRequest clonedRequest = reg.newRequest(bStream.bytes().streamInput());
final RunOnce runnable = new RunOnce(new AbstractRunnable() {
@Override
public void onFailure(Exception e) {
logger.debug("failed to send delayed request", e);
}
@Override
protected void doRun() throws IOException {
connection.sendRequest(requestId, action, clonedRequest, options);
}
});
// store the request to send it once the rule is cleared.
synchronized (this) {
if (cleared) {
runnable.run();
} else {
requestsToSendWhenCleared.add(runnable);
threadPool.schedule(runnable, delay, ThreadPool.Names.GENERIC);
}
}
}
@Override
public void clearCallback() {
synchronized (this) {
assert cleared == false;
cleared = true;
requestsToSendWhenCleared.forEach(Runnable::run);
}
}
});
}
Aggregations