Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
import com.vaadin.flow.internal.Range;
import com.vaadin.flow.internal.StateNode;
import com.vaadin.flow.shared.Registration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import elemental.json.Json;
Expand All @@ -65,6 +67,7 @@ public class DataCommunicator<T> implements Serializable {
public static final int DEFAULT_PAGE_INCREASE_COUNT = 4;

private static final int DEFAULT_PAGE_SIZE = 50;
private static final int MAXIMUM_ALLOWED_PAGES = 10;

private final DataGenerator<T> dataGenerator;
private final ArrayUpdater arrayUpdater;
Expand Down Expand Up @@ -317,7 +320,16 @@ public DataCommunicator(DataGenerator<T> dataGenerator,
* the end of the requested range
*/
public void setRequestedRange(int start, int length) {
requestedRange = Range.withLength(start, length);
final int maximumAllowedItems = getMaximumAllowedItems();
if (length > maximumAllowedItems) {
getLogger().warn(String.format(
"Attempted to fetch more items from server than allowed "
+ "in one go: number of items requested '%d', maximum "
+ "items allowed '%d'.",
length, maximumAllowedItems));
}
requestedRange = Range.withLength(start,
Math.min(length, maximumAllowedItems));

requestFlush();
}
Expand Down Expand Up @@ -968,10 +980,9 @@ protected Stream<T> fetchFromProvider(int offset, int limit) {
}

if (stream.isParallel()) {
LoggerFactory.getLogger(DataCommunicator.class)
.debug("Data provider {} has returned "
+ "parallel stream on 'fetch' call",
getDataProvider().getClass());
getLogger().debug(
"Data provider {} has returned parallel stream on 'fetch' call",
getDataProvider().getClass());
stream = stream.collect(Collectors.toList()).stream();
assert !stream.isParallel();
}
Expand Down Expand Up @@ -1363,6 +1374,10 @@ private void removeFilteringAndSorting() {
DataViewUtils::removeComponentFilterAndSortComparator);
}

private int getMaximumAllowedItems() {
return MAXIMUM_ALLOWED_PAGES * pageSize;
}

private static class Activation implements Serializable {
private final List<String> activeKeys;
private final boolean sizeRecheckNeeded;
Expand All @@ -1385,4 +1400,8 @@ public static Activation empty() {
}
}

private static Logger getLogger() {
return LoggerFactory.getLogger(DataCommunicator.class);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -1520,6 +1520,53 @@ public void reset() {
3, listenerInvocationCounter.get());
}

@Test
public void setRequestedRange_defaultPageSize_tooMuchItemsRequested_maxItemsAllowedRequested() {
DataProvider<Item, Object> dataProvider = Mockito
.spy(createDataProvider(1000));
dataCommunicator.setDataProvider(dataProvider, null);
// Paging is disabled for easier check of requested amount of items
dataCommunicator.setPagingEnabled(false);
// More than allowed (500) items requested
dataCommunicator.setRequestedRange(0, 501);
fakeClientCommunication();

ArgumentCaptor<Query> queryCaptor = ArgumentCaptor
.forClass(Query.class);
Mockito.verify(dataProvider, Mockito.times(1))
.fetch(queryCaptor.capture());

Assert.assertEquals(
"Expected the requested items count to be limited"
+ " to allowed threshold",
500, queryCaptor.getValue().getLimit());
}

@Test
public void setRequestedRange_customPageSize_customPageSizeConsidered_itemsRequested() {
int newPageSize = 300;
dataCommunicator.setPageSize(newPageSize);

DataProvider<Item, Object> dataProvider = Mockito
.spy(createDataProvider(1000));
dataCommunicator.setDataProvider(dataProvider, null);
// Paging is disabled for easier check of requested amount of items
dataCommunicator.setPagingEnabled(false);
dataCommunicator.setRequestedRange(0, newPageSize * 2);
fakeClientCommunication();

ArgumentCaptor<Query> queryCaptor = ArgumentCaptor
.forClass(Query.class);

Mockito.verify(dataProvider, Mockito.times(1))
.fetch(queryCaptor.capture());

Assert.assertEquals(
"Expected two pages with page size = 300 to be "
+ "requested and not limited",
600, queryCaptor.getValue().getLimit());
}

@Tag("test-component")
private static class TestComponent extends Component {

Expand Down