Search in sources :

Example 1 with EntryEvent

use of org.apache.ignite.internal.metastorage.server.EntryEvent in project ignite-3 by apache.

the class WatchCursor method next.

/**
 * {@inheritDoc}
 */
@Override
public WatchEvent next() {
    storage.lock().readLock().lock();
    try {
        if (!hasNext()) {
            throw new NoSuchElementException();
        }
        List<EntryEvent> evts = new ArrayList<>();
        long lastSeenRevision = currentRevision;
        // Iterate over the keys of the current revision and get all matching entries.
        for (; nativeIterator.isValid(); nativeIterator.next()) {
            byte[] rocksKey = nativeIterator.key();
            byte[] rocksValue = nativeIterator.value();
            long revision = revisionFromRocksKey(rocksKey);
            lastSeenRevision = revision;
            if (revision > currentRevision) {
                // There are no more keys for the current revision
                break;
            }
            byte[] key = rocksKeyToBytes(rocksKey);
            if (predicate.test(key)) {
                Value val = bytesToValue(rocksValue);
                Entry newEntry;
                if (val.tombstone()) {
                    newEntry = Entry.tombstone(key, revision, val.updateCounter());
                } else {
                    newEntry = new Entry(key, val.bytes(), revision, val.updateCounter());
                }
                Entry oldEntry = storage.doGet(key, revision - 1, false);
                evts.add(new EntryEvent(oldEntry, newEntry));
            }
        }
        currentHasNext = false;
        // Go to the next revision
        currentRevision = lastSeenRevision > currentRevision ? lastSeenRevision : currentRevision + 1;
        checkIterator(nativeIterator);
        return new WatchEvent(evts);
    } finally {
        storage.lock().readLock().unlock();
    }
}
Also used : Entry(org.apache.ignite.internal.metastorage.server.Entry) EntryEvent(org.apache.ignite.internal.metastorage.server.EntryEvent) ArrayList(java.util.ArrayList) Value(org.apache.ignite.internal.metastorage.server.Value) RocksStorageUtils.bytesToValue(org.apache.ignite.internal.metastorage.server.persistence.RocksStorageUtils.bytesToValue) WatchEvent(org.apache.ignite.internal.metastorage.server.WatchEvent) NoSuchElementException(java.util.NoSuchElementException)

Example 2 with EntryEvent

use of org.apache.ignite.internal.metastorage.server.EntryEvent 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 + ']';
        }
    }
}
Also used : WriteCommand(org.apache.ignite.raft.client.WriteCommand) GetAndRemoveCommand(org.apache.ignite.internal.metastorage.common.command.GetAndRemoveCommand) RemoveCommand(org.apache.ignite.internal.metastorage.common.command.RemoveCommand) StatementResult(org.apache.ignite.internal.metastorage.server.StatementResult) CursorNextCommand(org.apache.ignite.internal.metastorage.common.command.cursor.CursorNextCommand) GetAndPutCommand(org.apache.ignite.internal.metastorage.common.command.GetAndPutCommand) ArrayList(java.util.ArrayList) Cursor(org.apache.ignite.internal.util.Cursor) InvokeCommand(org.apache.ignite.internal.metastorage.common.command.InvokeCommand) MultiInvokeCommand(org.apache.ignite.internal.metastorage.common.command.MultiInvokeCommand) Entry(org.apache.ignite.internal.metastorage.server.Entry) IgniteUuid(org.apache.ignite.lang.IgniteUuid) EntryEvent(org.apache.ignite.internal.metastorage.server.EntryEvent) CursorCloseCommand(org.apache.ignite.internal.metastorage.common.command.cursor.CursorCloseCommand) Iterator(java.util.Iterator) List(java.util.List) ArrayList(java.util.ArrayList) WatchEvent(org.apache.ignite.internal.metastorage.server.WatchEvent) PutAllCommand(org.apache.ignite.internal.metastorage.common.command.PutAllCommand) GetAndPutAllCommand(org.apache.ignite.internal.metastorage.common.command.GetAndPutAllCommand) WatchExactKeysCommand(org.apache.ignite.internal.metastorage.common.command.WatchExactKeysCommand) GetAndRemoveCommand(org.apache.ignite.internal.metastorage.common.command.GetAndRemoveCommand) IgniteInternalException(org.apache.ignite.lang.IgniteInternalException) CursorsCloseCommand(org.apache.ignite.internal.metastorage.common.command.cursor.CursorsCloseCommand) GetAndRemoveAllCommand(org.apache.ignite.internal.metastorage.common.command.GetAndRemoveAllCommand) RemoveAllCommand(org.apache.ignite.internal.metastorage.common.command.RemoveAllCommand) MultipleEntryResponse(org.apache.ignite.internal.metastorage.common.command.MultipleEntryResponse) MultiInvokeCommand(org.apache.ignite.internal.metastorage.common.command.MultiInvokeCommand) IgniteInternalException(org.apache.ignite.lang.IgniteInternalException) NoSuchElementException(java.util.NoSuchElementException) WatchRangeKeysCommand(org.apache.ignite.internal.metastorage.common.command.WatchRangeKeysCommand) RangeCommand(org.apache.ignite.internal.metastorage.common.command.RangeCommand) StatementResultInfo(org.apache.ignite.internal.metastorage.common.StatementResultInfo) GetAndRemoveAllCommand(org.apache.ignite.internal.metastorage.common.command.GetAndRemoveAllCommand) GetAndPutAllCommand(org.apache.ignite.internal.metastorage.common.command.GetAndPutAllCommand) Collection(java.util.Collection) GetAndPutCommand(org.apache.ignite.internal.metastorage.common.command.GetAndPutCommand) PutCommand(org.apache.ignite.internal.metastorage.common.command.PutCommand) SingleEntryResponse(org.apache.ignite.internal.metastorage.common.command.SingleEntryResponse) NoSuchElementException(java.util.NoSuchElementException)

Example 3 with EntryEvent

use of org.apache.ignite.internal.metastorage.server.EntryEvent in project ignite-3 by apache.

the class ItMetaStorageServiceTest method testWatchOnUpdate.

@Test
public void testWatchOnUpdate() throws Exception {
    org.apache.ignite.internal.metastorage.server.WatchEvent expectedEvent = new org.apache.ignite.internal.metastorage.server.WatchEvent(List.of(new org.apache.ignite.internal.metastorage.server.EntryEvent(new org.apache.ignite.internal.metastorage.server.Entry(new byte[] { 2 }, new byte[] { 20 }, 1, 1), new org.apache.ignite.internal.metastorage.server.Entry(new byte[] { 2 }, new byte[] { 21 }, 2, 4)), new org.apache.ignite.internal.metastorage.server.EntryEvent(new org.apache.ignite.internal.metastorage.server.Entry(new byte[] { 3 }, new byte[] { 20 }, 1, 2), new org.apache.ignite.internal.metastorage.server.Entry(new byte[] { 3 }, new byte[] {}, 2, 5)), new org.apache.ignite.internal.metastorage.server.EntryEvent(new org.apache.ignite.internal.metastorage.server.Entry(new byte[] { 4 }, new byte[] { 20 }, 1, 3), new org.apache.ignite.internal.metastorage.server.Entry(new byte[] { 4 }, new byte[] {}, 3, 6))));
    ByteArray keyFrom = new ByteArray(new byte[] { 1 });
    ByteArray keyTo = new ByteArray(new byte[] { 10 });
    long rev = 2;
    when(mockStorage.watch(keyFrom.bytes(), keyTo.bytes(), rev)).thenAnswer(invocation -> {
        var cursor = mock(Cursor.class);
        when(cursor.hasNext()).thenReturn(true);
        when(cursor.next()).thenReturn(expectedEvent);
        return cursor;
    });
    CountDownLatch latch = new CountDownLatch(1);
    IgniteUuid watchId = metaStorageSvc.watch(keyFrom, keyTo, rev, new WatchListener() {

        @Override
        public boolean onUpdate(@NotNull WatchEvent event) {
            Collection<EntryEvent> expectedEvents = expectedEvent.entryEvents();
            Collection<org.apache.ignite.internal.metastorage.client.EntryEvent> actualEvents = event.entryEvents();
            assertEquals(expectedEvents.size(), actualEvents.size());
            Iterator<EntryEvent> expectedIterator = expectedEvents.iterator();
            Iterator<org.apache.ignite.internal.metastorage.client.EntryEvent> actualIterator = actualEvents.iterator();
            while (expectedIterator.hasNext() && actualIterator.hasNext()) {
                org.apache.ignite.internal.metastorage.server.EntryEvent expectedEntryEvent = expectedIterator.next();
                org.apache.ignite.internal.metastorage.client.EntryEvent actualEntryEvent = actualIterator.next();
                assertArrayEquals(expectedEntryEvent.oldEntry().key(), actualEntryEvent.oldEntry().key().bytes());
                assertArrayEquals(expectedEntryEvent.oldEntry().value(), actualEntryEvent.oldEntry().value());
                assertArrayEquals(expectedEntryEvent.entry().key(), actualEntryEvent.newEntry().key().bytes());
                assertArrayEquals(expectedEntryEvent.entry().value(), actualEntryEvent.newEntry().value());
            }
            latch.countDown();
            return true;
        }

        @Override
        public void onError(@NotNull Throwable e) {
            // Within given test it's not expected to get here.
            fail();
        }
    }).get();
    latch.await();
    metaStorageSvc.stopWatch(watchId).get();
}
Also used : NotNull(org.jetbrains.annotations.NotNull) IgniteUuid(org.apache.ignite.lang.IgniteUuid) EntryEvent(org.apache.ignite.internal.metastorage.server.EntryEvent) ByteArray(org.apache.ignite.lang.ByteArray) EntryEvent(org.apache.ignite.internal.metastorage.server.EntryEvent) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.jupiter.api.Test)

Aggregations

EntryEvent (org.apache.ignite.internal.metastorage.server.EntryEvent)3 ArrayList (java.util.ArrayList)2 NoSuchElementException (java.util.NoSuchElementException)2 Entry (org.apache.ignite.internal.metastorage.server.Entry)2 WatchEvent (org.apache.ignite.internal.metastorage.server.WatchEvent)2 IgniteUuid (org.apache.ignite.lang.IgniteUuid)2 Collection (java.util.Collection)1 Iterator (java.util.Iterator)1 List (java.util.List)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 StatementResultInfo (org.apache.ignite.internal.metastorage.common.StatementResultInfo)1 GetAndPutAllCommand (org.apache.ignite.internal.metastorage.common.command.GetAndPutAllCommand)1 GetAndPutCommand (org.apache.ignite.internal.metastorage.common.command.GetAndPutCommand)1 GetAndRemoveAllCommand (org.apache.ignite.internal.metastorage.common.command.GetAndRemoveAllCommand)1 GetAndRemoveCommand (org.apache.ignite.internal.metastorage.common.command.GetAndRemoveCommand)1 InvokeCommand (org.apache.ignite.internal.metastorage.common.command.InvokeCommand)1 MultiInvokeCommand (org.apache.ignite.internal.metastorage.common.command.MultiInvokeCommand)1 MultipleEntryResponse (org.apache.ignite.internal.metastorage.common.command.MultipleEntryResponse)1 PutAllCommand (org.apache.ignite.internal.metastorage.common.command.PutAllCommand)1 PutCommand (org.apache.ignite.internal.metastorage.common.command.PutCommand)1