use of org.apache.ignite.raft.client.WriteCommand in project ignite-3 by apache.
the class ItJraftCounterServerTest method testApplyWithFailure.
/**
* Tests if a raft group become unavailable in case of a critical error.
*/
@Test
public void testApplyWithFailure() throws Exception {
listenerFactory = () -> new CounterListener() {
@Override
public void onWrite(Iterator<CommandClosure<WriteCommand>> iterator) {
Iterator<CommandClosure<WriteCommand>> wrapper = new Iterator<>() {
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public CommandClosure<WriteCommand> next() {
CommandClosure<WriteCommand> cmd = iterator.next();
IncrementAndGetCommand command = (IncrementAndGetCommand) cmd.command();
if (command.delta() == 10) {
throw new IgniteInternalException("Very bad");
}
return cmd;
}
};
super.onWrite(wrapper);
}
};
startCluster();
RaftGroupService client1 = clients.get(0);
RaftGroupService client2 = clients.get(1);
client1.refreshLeader().get();
client2.refreshLeader().get();
NodeImpl leader = servers.stream().map(s -> ((NodeImpl) s.raftGroupService(COUNTER_GROUP_0).getRaftNode())).filter(n -> n.getState() == STATE_LEADER).findFirst().orElse(null);
assertNotNull(leader);
long val1 = applyIncrements(client1, 1, 5);
long val2 = applyIncrements(client2, 1, 7);
assertEquals(sum(5), val1);
assertEquals(sum(7), val2);
long val3 = applyIncrements(client1, 6, 9);
assertEquals(sum(9), val3);
try {
client1.<Long>run(new IncrementAndGetCommand(10)).get();
fail();
} catch (Exception e) {
// Expected.
Throwable cause = e.getCause();
assertTrue(cause instanceof RaftException);
}
NodeImpl finalLeader = leader;
waitForCondition(() -> finalLeader.getState() == STATE_ERROR, 5_000);
// Client can't switch to new leader, because only one peer in the list.
try {
client1.<Long>run(new IncrementAndGetCommand(11)).get();
} catch (Exception e) {
boolean isValid = e.getCause() instanceof TimeoutException;
if (!isValid) {
LOG.error("Got unexpected exception", e);
}
assertTrue(isValid, "Expecting the timeout");
}
}
use of org.apache.ignite.raft.client.WriteCommand in project ignite-3 by apache.
the class ItJraftCounterServerTest method testClientCatchExceptionFromSm.
/**
* Tests that users related exceptions from SM are propagated to the client.
*/
@Test
public void testClientCatchExceptionFromSm() throws Exception {
listenerFactory = () -> new CounterListener() {
@Override
public void onWrite(Iterator<CommandClosure<WriteCommand>> iterator) {
while (iterator.hasNext()) {
CommandClosure<WriteCommand> clo = iterator.next();
IncrementAndGetCommand cmd0 = (IncrementAndGetCommand) clo.command();
clo.result(new RuntimeException("Expected message"));
}
}
@Override
public void onRead(Iterator<CommandClosure<ReadCommand>> iterator) {
while (iterator.hasNext()) {
CommandClosure<ReadCommand> clo = iterator.next();
assert clo.command() instanceof GetValueCommand;
clo.result(new RuntimeException("Another expected message"));
}
}
};
startCluster();
RaftGroupService client1 = clients.get(0);
RaftGroupService client2 = clients.get(1);
client1.refreshLeader().get();
client2.refreshLeader().get();
NodeImpl leader = servers.stream().map(s -> ((NodeImpl) s.raftGroupService(COUNTER_GROUP_0).getRaftNode())).filter(n -> n.getState() == STATE_LEADER).findFirst().orElse(null);
assertNotNull(leader);
try {
client1.<Long>run(new IncrementAndGetCommand(3)).get();
fail();
} catch (Exception e) {
// Expected.
Throwable cause = e.getCause();
assertTrue(cause instanceof RuntimeException);
assertEquals(cause.getMessage(), "Expected message");
}
try {
client1.<Long>run(new GetValueCommand()).get();
fail();
} catch (Exception e) {
// Expected.
Throwable cause = e.getCause();
assertTrue(cause instanceof RuntimeException);
assertEquals(cause.getMessage(), "Another expected message");
}
}
use of org.apache.ignite.raft.client.WriteCommand in project ignite-3 by apache.
the class ActionRequestProcessor method handleRequest.
/**
* {@inheritDoc}
*/
@Override
public void handleRequest(RpcContext rpcCtx, ActionRequest request) {
Node node = rpcCtx.getNodeManager().get(request.groupId(), new PeerId(rpcCtx.getLocalAddress()));
if (node == null) {
rpcCtx.sendResponse(factory.errorResponse().errorCode(RaftError.UNKNOWN.getNumber()).build());
return;
}
JraftServerImpl.DelegatingStateMachine fsm = (JraftServerImpl.DelegatingStateMachine) node.getOptions().getFsm();
// Apply a filter before commiting to STM.
CompletableFuture<Void> fut = fsm.getListener().onBeforeApply(request.command());
if (fut != null) {
fut.handle(new BiFunction<Void, Throwable, Void>() {
@Override
public Void apply(Void ignored, Throwable err) {
if (err == null) {
if (request.command() instanceof WriteCommand) {
applyWrite(node, request, rpcCtx);
} else {
applyRead(node, request, rpcCtx);
}
} else {
sendSMError(rpcCtx, err, false);
}
return null;
}
});
} else {
if (request.command() instanceof WriteCommand) {
applyWrite(node, request, rpcCtx);
} else {
applyRead(node, request, rpcCtx);
}
}
}
use of org.apache.ignite.raft.client.WriteCommand in project ignite-3 by apache.
the class MetaStorageListener method onWrite.
/**
* {@inheritDoc}
*/
@Override
public void onWrite(Iterator<CommandClosure<WriteCommand>> iter) {
while (iter.hasNext()) {
CommandClosure<WriteCommand> clo = iter.next();
WriteCommand command = clo.command();
if (command instanceof PutCommand) {
PutCommand putCmd = (PutCommand) command;
storage.put(putCmd.key(), putCmd.value());
clo.result(null);
} else if (command instanceof GetAndPutCommand) {
GetAndPutCommand getAndPutCmd = (GetAndPutCommand) command;
Entry e = storage.getAndPut(getAndPutCmd.key(), getAndPutCmd.value());
clo.result(new SingleEntryResponse(e.key(), e.value(), e.revision(), e.updateCounter()));
} else if (command instanceof PutAllCommand) {
PutAllCommand putAllCmd = (PutAllCommand) command;
storage.putAll(putAllCmd.keys(), putAllCmd.values());
clo.result(null);
} else if (command instanceof GetAndPutAllCommand) {
GetAndPutAllCommand getAndPutAllCmd = (GetAndPutAllCommand) command;
Collection<Entry> entries = storage.getAndPutAll(getAndPutAllCmd.keys(), getAndPutAllCmd.vals());
List<SingleEntryResponse> resp = new ArrayList<>(entries.size());
for (Entry e : entries) {
resp.add(new SingleEntryResponse(e.key(), e.value(), e.revision(), e.updateCounter()));
}
clo.result(new MultipleEntryResponse(resp));
} else if (command instanceof RemoveCommand) {
RemoveCommand rmvCmd = (RemoveCommand) command;
storage.remove(rmvCmd.key());
clo.result(null);
} else if (command instanceof GetAndRemoveCommand) {
GetAndRemoveCommand getAndRmvCmd = (GetAndRemoveCommand) command;
Entry e = storage.getAndRemove(getAndRmvCmd.key());
clo.result(new SingleEntryResponse(e.key(), e.value(), e.revision(), e.updateCounter()));
} else if (command instanceof RemoveAllCommand) {
RemoveAllCommand rmvAllCmd = (RemoveAllCommand) command;
storage.removeAll(rmvAllCmd.keys());
clo.result(null);
} else if (command instanceof GetAndRemoveAllCommand) {
GetAndRemoveAllCommand getAndRmvAllCmd = (GetAndRemoveAllCommand) command;
Collection<Entry> entries = storage.getAndRemoveAll(getAndRmvAllCmd.keys());
List<SingleEntryResponse> resp = new ArrayList<>(entries.size());
for (Entry e : entries) {
resp.add(new SingleEntryResponse(e.key(), e.value(), e.revision(), e.updateCounter()));
}
clo.result(new MultipleEntryResponse(resp));
} else if (command instanceof InvokeCommand) {
InvokeCommand cmd = (InvokeCommand) command;
boolean res = storage.invoke(toCondition(cmd.condition()), toOperations(cmd.success()), toOperations(cmd.failure()));
clo.result(res);
} else if (command instanceof MultiInvokeCommand) {
MultiInvokeCommand cmd = (MultiInvokeCommand) command;
StatementResult res = storage.invoke(toIf(cmd.iif()));
clo.result(new StatementResultInfo(res.bytes()));
} else if (command instanceof RangeCommand) {
RangeCommand rangeCmd = (RangeCommand) command;
IgniteUuid cursorId = rangeCmd.getCursorId();
Cursor<Entry> cursor = (rangeCmd.revUpperBound() != -1) ? storage.range(rangeCmd.keyFrom(), rangeCmd.keyTo(), rangeCmd.revUpperBound()) : storage.range(rangeCmd.keyFrom(), rangeCmd.keyTo());
cursors.put(cursorId, new CursorMeta(cursor, CursorType.RANGE, rangeCmd.requesterNodeId()));
clo.result(cursorId);
} else if (command instanceof CursorNextCommand) {
CursorNextCommand cursorNextCmd = (CursorNextCommand) command;
CursorMeta cursorDesc = cursors.get(cursorNextCmd.cursorId());
if (cursorDesc == null) {
clo.result(new NoSuchElementException("Corresponding cursor on the server side is not found."));
return;
}
try {
if (cursorDesc.type() == CursorType.RANGE) {
Entry e = (Entry) cursorDesc.cursor().next();
clo.result(new SingleEntryResponse(e.key(), e.value(), e.revision(), e.updateCounter()));
} else if (cursorDesc.type() == CursorType.WATCH) {
WatchEvent evt = (WatchEvent) cursorDesc.cursor().next();
List<SingleEntryResponse> resp = new ArrayList<>(evt.entryEvents().size() * 2);
for (EntryEvent e : evt.entryEvents()) {
Entry o = e.oldEntry();
Entry n = e.entry();
resp.add(new SingleEntryResponse(o.key(), o.value(), o.revision(), o.updateCounter()));
resp.add(new SingleEntryResponse(n.key(), n.value(), n.revision(), n.updateCounter()));
}
clo.result(new MultipleEntryResponse(resp));
}
} catch (NoSuchElementException e) {
clo.result(e);
}
} else if (command instanceof CursorCloseCommand) {
CursorCloseCommand cursorCloseCmd = (CursorCloseCommand) command;
CursorMeta cursorDesc = cursors.remove(cursorCloseCmd.cursorId());
if (cursorDesc == null) {
clo.result(null);
return;
}
try {
cursorDesc.cursor().close();
} catch (Exception e) {
throw new IgniteInternalException(e);
}
clo.result(null);
} else if (command instanceof WatchRangeKeysCommand) {
WatchRangeKeysCommand watchCmd = (WatchRangeKeysCommand) command;
IgniteUuid cursorId = watchCmd.getCursorId();
Cursor<WatchEvent> cursor = storage.watch(watchCmd.keyFrom(), watchCmd.keyTo(), watchCmd.revision());
cursors.put(cursorId, new CursorMeta(cursor, CursorType.WATCH, watchCmd.requesterNodeId()));
clo.result(cursorId);
} else if (command instanceof WatchExactKeysCommand) {
WatchExactKeysCommand watchCmd = (WatchExactKeysCommand) command;
IgniteUuid cursorId = watchCmd.getCursorId();
Cursor<WatchEvent> cursor = storage.watch(watchCmd.keys(), watchCmd.revision());
cursors.put(cursorId, new CursorMeta(cursor, CursorType.WATCH, watchCmd.requesterNodeId()));
clo.result(cursorId);
} else if (command instanceof CursorsCloseCommand) {
CursorsCloseCommand cursorsCloseCmd = (CursorsCloseCommand) command;
Iterator<CursorMeta> cursorsIter = cursors.values().iterator();
while (cursorsIter.hasNext()) {
CursorMeta cursorDesc = cursorsIter.next();
if (cursorDesc.requesterNodeId().equals(cursorsCloseCmd.nodeId())) {
try {
cursorDesc.cursor().close();
} catch (Exception e) {
throw new IgniteInternalException(e);
}
cursorsIter.remove();
}
}
clo.result(null);
} else {
assert false : "Command was not found [cmd=" + command + ']';
}
}
}
Aggregations