muttakin2301/ccr_train_1000 huggingface dataset:
Code review comment: Hi @rsvoboda I wonder if updating `QuarkusIntegrationTestExtension` is too early, it is fine as it is, but `DevServicesContext` has only been introduced in `main` so removing the ability to the support the injection of `QuarkusIntegrationTest.Context` is early, not sure how much it is used but I can imagine the users seeing theor integration tests starting failing with `2.3.x`, just occurred to me this morning... I think adding a note that it is deprecated to the 2.3 migration guide is what is needed at this stage 

Code before review:
private void injectTestContext(Object testInstance) {
Class<?> c = testInstance.getClass();
while (c != Object.class) {
for (Field f : c.getDeclaredFields()) {
if (f.getType().equals(DevServicesContext.class)) {
try {
f.setAccessible(true);
f.set(testInstance, createTestContext());
return;
} catch (Exception e) {
throw new RuntimeException("Unable to set field '" + f.getName()
+ "' with the proper test context", e);
}
} else if (DevServicesContext.ContextAware.class.isAssignableFrom(f.getType())) {
f.setAccessible(true);
try {
DevServicesContext.ContextAware val = (DevServicesContext.ContextAware) f.get(testInstance);
val.setIntegrationTestContext(createTestContext());
} catch (Exception e) {
throw new RuntimeException("Unable to inject context into field " + f.getName(), e);
}
}
}
c = c.getSuperclass();
}
}

Line under review: } catch (Exception e) {

Code after addressing the review:
private void injectTestContext(Object testInstance) {
Class<?> c = testInstance.getClass();
while (c != Object.class) {
for (Field f : c.getDeclaredFields()) {
if (f.getType().equals(DevServicesContext.class)) {
try {
f.setAccessible(true);
f.set(testInstance, createTestContext());
return;
} catch (Exception e) {
throw new RuntimeException("Unable to set field '" + f.getName()
+ "' with the proper test context", e);
}
} else if (DevServicesContext.ContextAware.class.isAssignableFrom(f.getType())) {
f.setAccessible(true);
try {
DevServicesContext.ContextAware val = (DevServicesContext.ContextAware) f.get(testInstance);
val.setIntegrationTestContext(createTestContext());
} catch (Exception e) {
throw new RuntimeException("Unable to inject context into field " + f.getName(), e);
}
}
}
c = c.getSuperclass();
}
}
Code review comment: > I'm still not convinced about this test. It's reimplementing production code in many aspects. For example exception handling (this exception ignoring during cancelation/closing) and threading model from Task/StreamTask, so at any time we modify those, this test has a chance to fail.  I guess the reimplementing production code refers to processRecoveredBufferTask which will consumed the recovered buffers and verify the data. This test actually only focuses on RecoveredInputChannel#readRecoveredState method, so as long as the related interaction processes is not changed, this test is still valid, no matter with how the upper component handles the CancelTaskException (ignore or throw it) .  In general the unit tests should avoid touching more components to bring potential fragile if some changes future. From this aspect, maybe the ITCase is more suitable for this scenario as you said. But unit tests still have somehow meanings to work on the respective methods directly, then it might has more chances to cover all the potential cases.

Code before review:
private Callable<Void> readRecoveredStateTask(RecoveredInputChannel inputChannel, ChannelStateReader reader, boolean verifyRelease) {
return () -> {
try {
inputChannel.readRecoveredState(reader);
} catch (Throwable t) {
assertTrue("The expected exception should only happen in the case of released channel.", verifyRelease && inputChannel.isReleased());
}
return null;
};
}

Line under review: assertTrue("The expected exception should only happen in the case of released channel.", verifyRelease && inputChannel.isReleased());

Code after addressing the review:
private Callable<Void> readRecoveredStateTask(RecoveredInputChannel inputChannel, ChannelStateReader reader, boolean verifyRelease) {
return () -> {
try {
inputChannel.readRecoveredState(reader);
} catch (Throwable t) {
if (!(verifyRelease && inputChannel.isReleased())) {
throw new AssertionError("Exceptions are expected here only if the input channel was released", t);
}
}
return null;
};
}
Code review comment: Can we assert the exception message here?

Code before review:
public void testReadBuildJsonForNonExistingBuildFile() {
Path buildFilePath = PROJECT_UTILS_RESOURCES.resolve("xyz").resolve(ProjectConstants.BUILD_FILE);
Assert.assertThrows(IOException.class, () -> {
ProjectUtils.readBuildJson(buildFilePath);
});
}

Line under review: Path buildFilePath = PROJECT_UTILS_RESOURCES.resolve("xyz").resolve(ProjectConstants.BUILD_FILE);

Code after addressing the review:
public void testReadBuildJsonForNonExistingBuildFile() {
Path buildFilePath = PROJECT_UTILS_RESOURCES.resolve("xyz").resolve(ProjectConstants.BUILD_FILE);
Assert.assertThrows(IOException.class, () -> {
ProjectUtils.readBuildJson(buildFilePath);
});
}
Code review comment: +1. We can lookup the parents of the `tokenAtCursor` and check if there's a class/object as a parent. Probably move that logic to a separate method.

Code before review:
public static Optional<Range> prepareRename(PrepareRenameContext context) {
fillTokenInfoAtCursor(context);
context.checkCancelled();
Token tokenAtCursor = TokensUtil.findTokenAtPosition(context, context.getCursorPosition())
.filter(token -> token instanceof IdentifierToken)
.or(() -> {
Position originalPos = context.getCursorPosition();
Position newPos = new Position(originalPos.getLine(), originalPos.getCharacter() - 1);
return TokensUtil.findTokenAtPosition(context, newPos);
})
.orElse(null);
if (!(tokenAtCursor instanceof IdentifierToken) || CommonUtil.isKeyword(tokenAtCursor.text())
|| CommonUtil.SELF_KW.equals(tokenAtCursor.text())) {
return Optional.empty();
}
Optional<Document> document = context.currentDocument();
if (document.isEmpty()) {
return Optional.empty();
}
Range cursorPosRange = new Range(context.getCursorPosition(), context.getCursorPosition());
NonTerminalNode nodeAtCursor = CommonUtil.findNode(cursorPosRange, document.get().syntaxTree());
if (onImportDeclarationNode(context, nodeAtCursor)) {
return Optional.empty();
}
return Optional.of(CommonUtil.toRange(tokenAtCursor.lineRange()));
}

Line under review: || CommonUtil.SELF_KW.equals(tokenAtCursor.text())) {

Code after addressing the review:
public static Optional<Range> prepareRename(PrepareRenameContext context) {
fillTokenInfoAtCursor(context);
context.checkCancelled();
Token tokenAtCursor = TokensUtil.findTokenAtPosition(context, context.getCursorPosition())
.filter(token -> token instanceof IdentifierToken)
.or(() -> {
Position originalPos = context.getCursorPosition();
Position newPos = new Position(originalPos.getLine(), originalPos.getCharacter() - 1);
return TokensUtil.findTokenAtPosition(context, newPos);
})
.orElse(null);
if (!(tokenAtCursor instanceof IdentifierToken) || CommonUtil.isKeyword(tokenAtCursor.text())
|| isSelfClassSymbol(context)) {
return Optional.empty();
}
Optional<Document> document = context.currentDocument();
if (document.isEmpty()) {
return Optional.empty();
}
Range cursorPosRange = new Range(context.getCursorPosition(), context.getCursorPosition());
NonTerminalNode nodeAtCursor = CommonUtil.findNode(cursorPosRange, document.get().syntaxTree());
if (onImportDeclarationNode(context, nodeAtCursor)) {
return Optional.empty();
}
return Optional.of(CommonUtil.toRange(tokenAtCursor.lineRange()));
}
Code review comment: Maybe this whole block could be simplified via  ``` for (PartitionTrackerEntry<JobID, TaskExecutorPartitionInfo> partitionTrackerEntry : partitionTrackerEntries) { 			final TaskExecutorPartitionInfo metaInfo = partitionTrackerEntry.getMetaInfo(); 			clusterPartitions.computeIfAbsent( 				metaInfo.getIntermediateDataSetId(), 				ignored -> new PartitionEntry(metaInfo.getNumberOfPartitions())) 				.addPartition(partitionTrackerEntry.getResultPartitionId()); 		} ```  If doing computations with side effects I would choose explicit loops instead of the stream API. For the stream API, computations should be side effect free.

Code before review:
public void promoteJobPartitions(Collection<ResultPartitionID> partitionsToPromote) {
if (partitionsToPromote.isEmpty()) {
return;
}
final Collection<PartitionTrackerEntry<JobID, TaskExecutorPartitionInfo>> partitionTrackerEntries = stopTrackingPartitions(partitionsToPromote);
partitionTrackerEntries.forEach(
partitionTrackerEntry -> clusterPartitions.compute(partitionTrackerEntry.getMetaInfo().getIntermediateDataSetId(), (key, existingEntry) -> {
if (existingEntry == null) {
final Set<ResultPartitionID> newSet = new HashSet<>();
newSet.add(partitionTrackerEntry.getResultPartitionId());
return new PartitionEntry(newSet , partitionTrackerEntry.getMetaInfo().getNumberOfPartitions());
} else {
existingEntry.addPartition(partitionTrackerEntry.getResultPartitionId());
return existingEntry;
}
})
);
}

Line under review: );

Code after addressing the review:
public void promoteJobPartitions(Collection<ResultPartitionID> partitionsToPromote) {
if (partitionsToPromote.isEmpty()) {
return;
}
final Collection<PartitionTrackerEntry<JobID, TaskExecutorPartitionInfo>> partitionTrackerEntries = stopTrackingPartitions(partitionsToPromote);
for (PartitionTrackerEntry<JobID, TaskExecutorPartitionInfo> partitionTrackerEntry : partitionTrackerEntries) {
final TaskExecutorPartitionInfo dataSetMetaInfo = partitionTrackerEntry.getMetaInfo();
final DataSetEntry dataSetEntry = clusterPartitions.computeIfAbsent(
dataSetMetaInfo.getIntermediateDataSetId(),
ignored -> new DataSetEntry(dataSetMetaInfo.getNumberOfPartitions()));
dataSetEntry.addPartition(partitionTrackerEntry.getResultPartitionId());
}
}
Code review comment: maybe a simple recursive algorithm is better

Code before review:
private boolean isBottomJoin(LogicalJoin join) {
if (join.left() instanceof LogicalProject) {
LogicalProject project = (LogicalProject) join.left();
if (project.child() instanceof LogicalJoin) {
return false;
}
}
if (join.right() instanceof LogicalProject) {
LogicalProject project = (LogicalProject) join.left();
if (project.child() instanceof LogicalJoin) {
return false;
}
}
if (join.left() instanceof LogicalJoin || join.right() instanceof LogicalJoin) {
return false;
}
return true;
}

Line under review: }

Code after addressing the review:
private boolean isBottomJoin(LogicalJoin join) {
if (join.left() instanceof LogicalProject) {
LogicalProject project = (LogicalProject) join.left();
if (project.child() instanceof LogicalJoin) {
return false;
}
}
if (join.right() instanceof LogicalProject) {
LogicalProject project = (LogicalProject) join.left();
if (project.child() instanceof LogicalJoin) {
return false;
}
}
if (join.left() instanceof LogicalJoin || join.right() instanceof LogicalJoin) {
return false;
}
return true;
}
Code review comment: Just heard back: we do this when the swagger specification marks a field as `base64url`. I don't think it should be much of a performance issue, I wouldn't expect people to access this field an overwhelming amount of times.

Code before review:
public byte[] getData() {
if (this.data == null) {
return null;
}
return this.data.decodedBytes();
}

Line under review: return this.data.decodedBytes();

Code after addressing the review:
public byte[] getData() {
return ByteExtensions.clone(this.data);
}
Code review comment: maybe we need to check left child and right child slots on the different side of the equation

Code before review:
public Void visitLogicalFilter(LogicalFilter<Plan> filter, Void context) {
Plan child = filter.child();
if (child instanceof LogicalJoin) {
conjuncts.addAll(ExpressionUtils.extractConjunct(filter.getPredicates()));
}
child.accept(this, context);
return null;
}

Line under review: conjuncts.addAll(ExpressionUtils.extractConjunct(filter.getPredicates()));

Code after addressing the review:
public Void visitLogicalFilter(LogicalFilter<Plan> filter, Void context) {
Plan child = filter.child();
if (child instanceof LogicalJoin) {
conjuncts.addAll(ExpressionUtils.extractConjunct(filter.getPredicates()));
}
child.accept(this, context);
return null;
}
Code review comment: and then I will do the check at this line.

Code before review:
public BinaryStringData next() {
if (!hasNext()) {
return null;
}
final Object str = elementGetter.getElementOrNull(arrayData, currentPos);
currentPos++;
if (str == null && nullReplacement.length != 0 && nullReplacement[0] != null) {
return (BinaryStringData) nullReplacement[0];
}
return (BinaryStringData) str;
}

Line under review: if (str == null && nullReplacement.length != 0 && nullReplacement[0] != null) {

Code after addressing the review:
public BinaryStringData next() {
if (!hasNext()) {
return null;
}
final Object str = elementGetter.getElementOrNull(arrayData, currentPos);
currentPos++;
if (str == null && nullReplacement != null) {
return nullReplacement;
}
return (BinaryStringData) str;
}
Code review comment: I'll add `e` to the `warnf`.

Code before review:
protected Manifest readManifest() {
final ClassPathResource mf = getResource("META-INF/MANIFEST.MF");
if (mf != null) {
try {
return new Manifest(new ByteArrayInputStream(mf.getData()));
} catch (IOException e) {
log.warnf("Failed to parse manifest for %s", toString());
}
}
return null;
}

Line under review: log.warnf("Failed to parse manifest for %s", toString());

Code after addressing the review:
protected Manifest readManifest() {
final ClassPathResource mf = getResource("META-INF/MANIFEST.MF");
if (mf != null) {
try {
return new Manifest(new ByteArrayInputStream(mf.getData()));
} catch (IOException e) {
log.warnf("Failed to parse manifest for %s", toString(), e);
}
}
return null;
}
Code review comment: susceptible to SQL injection attack.

Code before review:
public Mono<Integer> readMinThroughput() {
return this.read().flatMap(cosmosContainerResponse -> database.getDocClientWrapper()
.queryOffers("select * from c where c.offerResourceId = '"
+ cosmosContainerResponse.resourceSettings().resourceId() + "'", new FeedOptions())
.single()).flatMap(offerFeedResponse -> {
if (offerFeedResponse.results().isEmpty()) {
return Mono.error(BridgeInternal.createCosmosClientException(HttpConstants.StatusCodes.BADREQUEST,
"No offers found for the resource"));
}
return database.getDocClientWrapper().readOffer(offerFeedResponse.results().get(0).selfLink())
.single();
}).map(cosmosOfferResponse -> Integer.parseInt(cosmosOfferResponse.getResponseHeaders().get(HttpConstants.HttpHeaders.OFFER_MIN_THROUGHPUT)));
}

Line under review: + cosmosContainerResponse.resourceSettings().resourceId() + "'", new FeedOptions())

Code after addressing the review:
public Mono<Integer> readMinThroughput() {
return this.read().flatMap(cosmosContainerResponse -> database.getDocClientWrapper()
.queryOffers(
new SqlQuerySpec("select * from c where c.offerResourceId = @OFFER_RESOURCE_ID",
new SqlParameterList(new SqlParameter("@OFFER_RESOURCE_ID", cosmosContainerResponse.resourceSettings().resourceId()))), new FeedOptions())
.single()).flatMap(offerFeedResponse -> {
if (offerFeedResponse.results().isEmpty()) {
return Mono.error(BridgeInternal.createCosmosClientException(HttpConstants.StatusCodes.BADREQUEST,
"No offers found for the resource"));
}
return database.getDocClientWrapper().readOffer(offerFeedResponse.results().get(0).selfLink())
.single();
}).map(cosmosOfferResponse -> Integer.parseInt(cosmosOfferResponse.getResponseHeaders().get(HttpConstants.HttpHeaders.OFFER_MIN_THROUGHPUT)));
}
Code review comment: with guava (use vendor if so) this can be simpler, but that's not blocking at all for this PR `return Strings.isNullOrEmpty(options.getTwister2Home());`

Code before review:
private boolean isLocalMode(Twister2PipelineOptions options) {
if (options.getTwister2Home() == null || "".equals(options.getTwister2Home())) {
return true;
} else {
return false;
}
}

Line under review: if (options.getTwister2Home() == null || "".equals(options.getTwister2Home())) {

Code after addressing the review:
private boolean isLocalMode(Twister2PipelineOptions options) {
if (options.getTwister2Home() == null || "".equals(options.getTwister2Home())) {
return true;
} else {
return false;
}
}
Code review comment: It looks there is already existing `StorageAccountSkuType.STANDARD_GRS`.

Code before review:
public Mono<FunctionApp> createAsync() {
if (this.isInCreateMode()) {
if (inner().serverFarmId() == null) {
withNewConsumptionPlan();
}
if (currentStorageAccount == null && storageAccountToSet == null && storageAccountCreatable == null) {
withNewStorageAccount(
this.manager().sdkContext().randomResourceName(name(), 20),
StorageAccountSkuType.fromSkuName(com.azure.resourcemanager.storage.models.SkuName.STANDARD_GRS));
}
}
return super.createAsync();
}

Line under review: StorageAccountSkuType.fromSkuName(com.azure.resourcemanager.storage.models.SkuName.STANDARD_GRS));

Code after addressing the review:
public Mono<FunctionApp> createAsync() {
if (this.isInCreateMode()) {
if (inner().serverFarmId() == null) {
withNewConsumptionPlan();
}
if (currentStorageAccount == null && storageAccountToSet == null && storageAccountCreatable == null) {
withNewStorageAccount(
this.manager().sdkContext().randomResourceName(name(), 20),
StorageAccountSkuType.STANDARD_GRS);
}
}
return super.createAsync();
}
Code review comment: And we can call `groupInformationFromGraph.setGroupIds(...)` and `groupInformationFromGraph.setGroupNames(...)` here instead of set in each test. 

Code before review:
public void setup() {
groupInformationFromGraph = new GroupInformation();
allowedGroupIds = groupInformationFromGraph.getGroupsId();
allowedGroupNames = groupInformationFromGraph.getGroupsName();
this.autoCloseable = MockitoAnnotations.openMocks(this);
properties.setUserGroup(userGroup);
properties.setGraphMembershipUri("https:
Mockito.lenient().when(accessToken.getTokenValue()).thenReturn("fake-access-token");
userService = new AADOAuth2UserService(properties, graphClient);
}

Line under review: allowedGroupIds = groupInformationFromGraph.getGroupsId();

Code after addressing the review:
public void setup() {
this.autoCloseable = MockitoAnnotations.openMocks(this);
GroupInformation groupInformationFromGraph = new GroupInformation();
Set<String> groupNamesFromGraph = new HashSet<>();
Set<String> groupIdsFromGraph = new HashSet<>();
groupNamesFromGraph.add("group1");
groupNamesFromGraph.add("group2");
groupIdsFromGraph.add(GROUP_ID_1);
groupIdsFromGraph.add(GROUP_ID_2);
groupInformationFromGraph.setGroupsIds(groupIdsFromGraph);
groupInformationFromGraph.setGroupsNames(groupNamesFromGraph);
properties.setUserGroup(userGroup);
properties.setGraphMembershipUri("https:
Mockito.lenient().when(accessToken.getTokenValue())
.thenReturn("fake-access-token");
Mockito.lenient().when(graphClient.getGroupInformation(accessToken.getTokenValue()))
.thenReturn(groupInformationFromGraph);
}
Code review comment: Good point. We probably have a few places where this can be applied.  I'll have a look over the next few days 

Code before review:
protected void writeTo(InputStream inputStream, OutputStream entityStream) throws IOException {
try {
byte[] buffer = new byte[8192];
int c;
while ((c = inputStream.read(buffer)) != -1) {
entityStream.write(buffer, 0, c);
}
} finally {
try {
inputStream.close();
} catch (IOException e) {
}
try {
entityStream.close();
} catch (IOException e) {
}
}
}

Line under review: int c;

Code after addressing the review:
protected void writeTo(InputStream inputStream, OutputStream entityStream) throws IOException {
try {
byte[] buffer = new byte[8192];
int c;
while ((c = inputStream.read(buffer)) != -1) {
entityStream.write(buffer, 0, c);
}
} finally {
try {
inputStream.close();
} catch (IOException e) {
}
try {
entityStream.close();
} catch (IOException e) {
}
}
}
Code review comment: Let's use `System.nanoTime` to avoid clock resets.

Code before review:
public void testScheduling() throws ExecutionException, InterruptedException {
final SchedulingRpcEndpoint endpoint = new SchedulingRpcEndpoint(akkaRpcService);
endpoint.start();
final SchedulingRpcEndpointGateway gateway =
endpoint.getSelfGateway(SchedulingRpcEndpointGateway.class);
final CompletableFuture<Void> scheduleRunnableFuture = new CompletableFuture<>();
final CompletableFuture<Void> scheduleCallableFuture = new CompletableFuture<>();
final CompletableFuture<Void> executeFuture = new CompletableFuture<>();
final long scheduleTime = System.currentTimeMillis();
gateway.schedule(scheduleRunnableFuture, scheduleCallableFuture, executeFuture);
assertThat(
scheduleRunnableFuture.thenApply(ignored -> System.currentTimeMillis()).get(),
greaterThanOrEqualTo(scheduleTime + SchedulingRpcEndpoint.DELAY_MILLIS));
assertThat(
scheduleCallableFuture.thenApply(ignored -> System.currentTimeMillis()).get(),
greaterThanOrEqualTo(scheduleTime + SchedulingRpcEndpoint.DELAY_MILLIS));
executeFuture.get();
}

Line under review: final long scheduleTime = System.currentTimeMillis();

Code after addressing the review:
public void testScheduling() throws ExecutionException, InterruptedException {
final SchedulingRpcEndpoint endpoint = new SchedulingRpcEndpoint(akkaRpcService);
endpoint.start();
final SchedulingRpcEndpointGateway gateway =
endpoint.getSelfGateway(SchedulingRpcEndpointGateway.class);
final CompletableFuture<Void> scheduleRunnableFuture = new CompletableFuture<>();
final CompletableFuture<Void> scheduleCallableFuture = new CompletableFuture<>();
final CompletableFuture<Void> executeFuture = new CompletableFuture<>();
final long scheduleTime = System.nanoTime();
gateway.schedule(scheduleRunnableFuture, scheduleCallableFuture, executeFuture);
assertThat(
scheduleRunnableFuture.thenApply(ignored -> System.nanoTime()).get(),
greaterThanOrEqualTo(
scheduleTime
+ Duration.ofMillis(SchedulingRpcEndpoint.DELAY_MILLIS).toNanos()));
assertThat(
scheduleCallableFuture.thenApply(ignored -> System.nanoTime()).get(),
greaterThanOrEqualTo(
scheduleTime
+ Duration.ofMillis(SchedulingRpcEndpoint.DELAY_MILLIS).toNanos()));
executeFuture.get();
}
Code review comment: BTW just checked, on recent JVMs the HashMap implementation is different and it looks like that this is no longer a problem.  Might be time to simplify Validator as well :)

Code before review:
public FieldsHelper(final Class<?> aClass) {
final Field[] declaredFields = aClass.getDeclaredFields();
this.fields = new HashMap<>(declaredFields.length);
for (Field field : declaredFields) {
this.fields.put(field.getName(), field);
}
}

Line under review: this.fields = new HashMap<>(declaredFields.length);

Code after addressing the review:
public FieldsHelper(final Class<?> aClass) {
final Field[] declaredFields = aClass.getDeclaredFields();
this.fields = new HashMap<>(declaredFields.length);
for (Field field : declaredFields) {
this.fields.put(field.getName(), field);
}
}
Code review comment: I'm not quite familiar with the logic here, but the QueryHeader looks like magic number style. is that better if we define some constant QueryHeader like `public final QueryHeader XXX_QUERY_HEADER=new QueryHeader(schemaName, "", "name", "name", Types.CHAR, "CHAR", 255, 0, false, false, false, false)` ? or after 3 month , it's hard to understand the logic here even by yourself.

Code before review:
private List<QueryHeader> getQueryHeader(final String schemaName) {
List<QueryHeader> result = new LinkedList<>();
result.add(new QueryHeader(schemaName, "", "name", "name", Types.CHAR, "CHAR", 255, 0, false, false, false, false));
result.add(new QueryHeader(schemaName, "", "dataSourceNames", "dataSourceNames", Types.CHAR, "CHAR", 255, 0, false, false, false, false));
result.add(new QueryHeader(schemaName, "", "discoverType", "discoverType", Types.CHAR, "CHAR", 255, 0, false, false, false, false));
result.add(new QueryHeader(schemaName, "", "discoverProps", "discoverProps", Types.CHAR, "CHAR", 255, 0, false, false, false, false));
return result;
}

Line under review: result.add(new QueryHeader(schemaName, "", "name", "name", Types.CHAR, "CHAR", 255, 0, false, false, false, false));

Code after addressing the review:
private List<QueryHeader> getQueryHeader(final String schemaName) {
List<QueryHeader> result = new LinkedList<>();
result.add(new QueryHeader(schemaName, "", "name", "name", Types.CHAR, "CHAR", 255, 0, false, false, false, false));
result.add(new QueryHeader(schemaName, "", "dataSourceNames", "dataSourceNames", Types.CHAR, "CHAR", 255, 0, false, false, false, false));
result.add(new QueryHeader(schemaName, "", "discoverType", "discoverType", Types.CHAR, "CHAR", 255, 0, false, false, false, false));
result.add(new QueryHeader(schemaName, "", "discoverProps", "discoverProps", Types.CHAR, "CHAR", 255, 0, false, false, false, false));
return result;
}
Code review comment: We also need to override the `RestOptions.BIND_PORT`, `BlobServerOptions.PORT`.

Code before review:
static Configuration loadConfiguration(Configuration dynamicParameters) {
final String configDir = System.getenv(ConfigConstants.ENV_FLINK_CONF_DIR);
Preconditions.checkNotNull(
configDir,
"Flink configuration directory (%s) in environment should not be null!",
ConfigConstants.ENV_FLINK_CONF_DIR);
final Configuration configuration =
GlobalConfiguration.loadConfiguration(configDir, dynamicParameters);
if (HighAvailabilityMode.isHighAvailabilityModeActivated(configuration)) {
if (KubernetesUtils.isHostNetwork(configuration)) {
configuration.setString(HighAvailabilityOptions.HA_JOB_MANAGER_PORT_RANGE, "0");
configuration.setInteger(JobManagerOptions.PORT, 0);
} else {
final String ipAddress = System.getenv().get(Constants.ENV_FLINK_POD_IP_ADDRESS);
Preconditions.checkState(
ipAddress != null,
"JobManager ip address environment variable %s not set",
Constants.ENV_FLINK_POD_IP_ADDRESS);
configuration.setString(JobManagerOptions.ADDRESS, ipAddress);
configuration.setString(RestOptions.ADDRESS, ipAddress);
}
}
return configuration;
}

Line under review: if (KubernetesUtils.isHostNetwork(configuration)) {

Code after addressing the review:
static Configuration loadConfiguration(Configuration dynamicParameters) {
final String configDir = System.getenv(ConfigConstants.ENV_FLINK_CONF_DIR);
Preconditions.checkNotNull(
configDir,
"Flink configuration directory (%s) in environment should not be null!",
ConfigConstants.ENV_FLINK_CONF_DIR);
final Configuration configuration =
GlobalConfiguration.loadConfiguration(configDir, dynamicParameters);
if (KubernetesUtils.isHostNetwork(configuration)) {
configuration.setString(RestOptions.BIND_PORT, "0");
configuration.setInteger(JobManagerOptions.PORT, 0);
configuration.setString(BlobServerOptions.PORT, "0");
configuration.setString(HighAvailabilityOptions.HA_JOB_MANAGER_PORT_RANGE, "0");
configuration.setString(TaskManagerOptions.RPC_PORT, "0");
}
if (HighAvailabilityMode.isHighAvailabilityModeActivated(configuration)) {
final String ipAddress = System.getenv().get(Constants.ENV_FLINK_POD_IP_ADDRESS);
Preconditions.checkState(
ipAddress != null,
"JobManager ip address environment variable %s not set",
Constants.ENV_FLINK_POD_IP_ADDRESS);
configuration.setString(JobManagerOptions.ADDRESS, ipAddress);
configuration.setString(RestOptions.ADDRESS, ipAddress);
}
return configuration;
}
Code review comment: There should also be a check to ensure there is at least one method that starts with "build".

Code before review:
public void visitToken(DetailAST token) {
switch (token.getType()) {
case TokenTypes.CLASS_DEF:
hasServiceClientBuilderAnnotationStack.push(hasServiceClientBuilderAnnotation);
final DetailAST serviceClientAnnotationBuilderToken = getServiceClientBuilderAnnotation(token);
final String className = token.findFirstToken(TokenTypes.IDENT).getText();
hasServiceClientBuilderAnnotation = serviceClientAnnotationBuilderToken != null;
if (hasServiceClientBuilderAnnotation) {
if (!className.endsWith("ClientBuilder")) {
log(token, String.format("Class annotated with @ServiceClientBuilder ''%s'' should be named <ServiceName>ClientBuilder.", className));
}
} else {
if (className.endsWith("ClientBuilder")) {
log(token, String.format("Class ''%s'' should be annotated with @ServiceClientBuilder.", className));
}
}
break;
case TokenTypes.METHOD_DEF:
if (!hasServiceClientBuilderAnnotation) {
return;
}
final String methodName = token.findFirstToken(TokenTypes.IDENT).getText();
if (methodName.startsWith("build") && !BUILD_ASYNC_CLIENT.equals(methodName) && !BUILD_CLIENT.equals(methodName)) {
log(token, String.format(
"@ServiceClientBuilder class should not have a method name, '''' starting with ''build'' " +
"other than ''buildClient'' or ''buildAsyncClient''." , methodName));
}
break;
default:
break;
}
}

Line under review: if (methodName.startsWith("build") && !BUILD_ASYNC_CLIENT.equals(methodName) && !BUILD_CLIENT.equals(methodName)) {

Code after addressing the review:
public void visitToken(DetailAST token) {
switch (token.getType()) {
case TokenTypes.CLASS_DEF:
hasServiceClientBuilderAnnotationStack.push(hasServiceClientBuilderAnnotation);
hasBuildMethodStack.push(hasBuildMethod);
final DetailAST serviceClientAnnotationBuilderToken = getServiceClientBuilderAnnotation(token);
final String className = token.findFirstToken(TokenTypes.IDENT).getText();
hasServiceClientBuilderAnnotation = serviceClientAnnotationBuilderToken != null;
if (hasServiceClientBuilderAnnotation) {
if (!className.endsWith("ClientBuilder")) {
log(token, String.format("Class annotated with @ServiceClientBuilder ''%s'' should be named <ServiceName>ClientBuilder.", className));
}
} else {
if (className.endsWith("ClientBuilder")) {
log(token, String.format("Class ''%s'' should be annotated with @ServiceClientBuilder.", className));
}
}
break;
case TokenTypes.METHOD_DEF:
if (!hasServiceClientBuilderAnnotation) {
return;
}
final String methodName = token.findFirstToken(TokenTypes.IDENT).getText();
if (!methodName.startsWith("build")) {
break;
}
hasBuildMethod = true;
if (!methodName.endsWith("Client")) {
log(token, String.format(
"@ServiceClientBuilder class should not have a method name, ''%s'' starting with ''build'' but not ending with ''Client''." , methodName));
}
break;
default:
break;
}
}
Code review comment: Yes, I think this is the very purpose of `WrappingRuntimeException`: ``` /**  * A runtime exception that is explicitly used to wrap non-runtime exceptions. ``` Or did I misunderstand something?

Code before review:
public CheckpointStreamFactory resolveCheckpointStorageLocation(long checkpointId, CheckpointStorageLocationReference reference) {
return cache.computeIfAbsent(checkpointId, id -> {
try {
return delegate.resolveCheckpointStorageLocation(checkpointId, reference);
} catch (IOException e) {
throw new WrappingRuntimeException(e);
}
});
}

Line under review: throw new WrappingRuntimeException(e);

Code after addressing the review:
public CheckpointStreamFactory resolveCheckpointStorageLocation(long checkpointId, CheckpointStorageLocationReference reference) {
return cache.computeIfAbsent(checkpointId, id -> {
try {
return delegate.resolveCheckpointStorageLocation(checkpointId, reference);
} catch (IOException e) {
throw new FlinkRuntimeException(e);
}
});
}
Code review comment: What about other ref types?

Code before review:
private static MapValue buildMapValue(Map<String, Object> section) {
MapValue map = new MapValueImpl<String, Object>();
section.forEach((key, val) -> {
if (val instanceof String || val instanceof Long || val instanceof Double || val instanceof Boolean) {
map.put(key, val);
}
});
return map;
}

Line under review: map.put(key, val);

Code after addressing the review:
private static MapValue buildMapValue(Map<String, Object> section) {
MapValue map = new MapValueImpl<String, Object>();
section.forEach((key, val) -> {
if (val instanceof String || val instanceof Long || val instanceof Double || val instanceof Boolean) {
map.put(key, val);
}
});
return map;
}
Code review comment: I think we should disable this behavior. If a user has a sink after `SqlTransform` they would probably expect the fields in the sink to match the fields in the query.

Code before review:
public void testValues_selectEmpty() throws Exception {
String sql = "select 1, '1' FROM string_table WHERE false";
PCollection<Row> rows = compilePipeline(sql, pipeline);
PAssert.that(rows)
.containsInAnyOrder(
TestUtils.RowsBuilder.of(
Schema.FieldType.INT32, "EXPR$0",
Schema.FieldType.STRING, "EXPR$1")
.getRows());
pipeline.run();
}

Line under review: String sql = "select 1, '1' FROM string_table WHERE false";

Code after addressing the review:
public void testValues_selectEmpty() throws Exception {
String sql = "select 1, '1' FROM string_table WHERE false";
PCollection<Row> rows = compilePipeline(sql, pipeline);
PAssert.that(rows)
.containsInAnyOrder(
TestUtils.RowsBuilder.of(
Schema.FieldType.INT32, "EXPR$0",
Schema.FieldType.STRING, "EXPR$1")
.getRows());
pipeline.run();
}
Code review comment: we should call to httpResponse.close() here.

Code before review:
public HttpResponse processSync(HttpPipelineCallContext context, HttpPipelineNextSyncPolicy next) {
if ("http".equals(context.getHttpRequest().getUrl().getProtocol())) {
throw LOGGER.logExceptionAsError(
new RuntimeException("token credentials require a URL using the HTTPS protocol scheme"));
}
if (context.getHttpRequest().getBody() != null) {
context.getHttpRequest().setBody(context.getHttpRequest().getBodyAsBinaryData().toReplayableBinaryData());
}
HttpPipelineNextSyncPolicy nextPolicy = next.clone();
authorizeRequestSync(context);
HttpResponse httpResponse = next.processSync();
String authHeader = httpResponse.getHeaderValue(WWW_AUTHENTICATE);
if (httpResponse.getStatusCode() == 401 && authHeader != null) {
if (authorizeRequestOnChallengeSync(context, httpResponse)) {
return nextPolicy.processSync();
} else {
return httpResponse;
}
}
return httpResponse;
}


Code after addressing the review:
public HttpResponse processSync(HttpPipelineCallContext context, HttpPipelineNextSyncPolicy next) {
if ("http".equals(context.getHttpRequest().getUrl().getProtocol())) {
throw LOGGER.logExceptionAsError(
new RuntimeException("token credentials require a URL using the HTTPS protocol scheme"));
}
if (context.getHttpRequest().getBody() != null) {
context.getHttpRequest().setBody(context.getHttpRequest().getBodyAsBinaryData().toReplayableBinaryData());
}
HttpPipelineNextSyncPolicy nextPolicy = next.clone();
authorizeRequestSync(context);
HttpResponse httpResponse = next.processSync();
String authHeader = httpResponse.getHeaderValue(WWW_AUTHENTICATE);
if (httpResponse.getStatusCode() == 401 && authHeader != null) {
if (authorizeRequestOnChallengeSync(context, httpResponse)) {
httpResponse.close();
return nextPolicy.processSync();
} else {
return httpResponse;
}
}
return httpResponse;
}
Code review comment: What do you think about testing the error message for containing some string - specified in the test? That would not depend less on the internals of the `FlinkCompletableFutureAssert`. ```suggestion         failedFuture.completeExceptionally(new IllegalStateException("abcd"));         assertThatThrownBy(() -> assertThatFuture(failedFuture).eventuallySucceeds())                 .hasMessageContaining("abcd"); ``` (ditto: `"to have failed"`)

Code before review:
void testEventuallySucceedsWithFailedFuture() {
final CompletableFuture<String> failedFuture = new CompletableFuture<>();
failedFuture.completeExceptionally(new IllegalStateException());
assertThatThrownBy(() -> assertThatFuture(failedFuture).eventuallySucceeds())
.hasMessageContaining("to have succeeded");
}

Line under review: .hasMessageContaining("to have succeeded");

Code after addressing the review:
void testEventuallySucceedsWithFailedFuture() {
final CompletableFuture<String> failedFuture = new CompletableFuture<>();
failedFuture.completeExceptionally(new IllegalStateException("Squirrel"));
assertThatThrownBy(() -> assertThatFuture(failedFuture).eventuallySucceeds())
.isInstanceOf(AssertionError.class)
.hasMessageContaining("Squirrel");
}
Code review comment: You only need to check to `j < i` or start at `i + 1`, then you wont need the `if` below...

Code before review:
public List<Node> addNodes(List<Node> nodes) {
try (Mutex lock = lockAllocation()) {
for (int i = 0; i < nodes.size(); i++) {
var node = nodes.get(i);
var message = "Cannot add " + node.hostname() + ": A node with this name already exists";
if (getNode(node.hostname()).isPresent()) throw new IllegalArgumentException(message);
for (int j = 0; j < nodes.size(); j++) {
if (i == j) continue;
var other = nodes.get(j);
if (node.equals(other)) throw new IllegalArgumentException(message);
}
}
return db.addNodes(nodes);
}
}

Line under review: for (int j = 0; j < nodes.size(); j++) {

Code after addressing the review:
public List<Node> addNodes(List<Node> nodes) {
try (Mutex lock = lockAllocation()) {
for (int i = 0; i < nodes.size(); i++) {
var node = nodes.get(i);
var message = "Cannot add " + node.hostname() + ": A node with this name already exists";
if (getNode(node.hostname()).isPresent()) throw new IllegalArgumentException(message);
for (int j = 0; j < i; j++) {
var other = nodes.get(j);
if (node.equals(other)) throw new IllegalArgumentException(message);
}
}
return db.addNodes(nodes);
}
}
Code review comment: For this test, we should just be able to instantiate just the encryption options class. We don't necessarily need to create an encrypted blob client to exercise the validation logic.

Code before review:
public void illegalRegionLength(long regionLength) {
assertThrows(IllegalArgumentException.class, () ->
new EncryptedBlobClientBuilder(EncryptionVersion.V2)
.blobEncryptionOptions(new BlobEncryptionOptions().setAuthenticatedRegionDataLength(regionLength))
.buildEncryptedBlobClient());
}

Line under review: .blobEncryptionOptions(new BlobEncryptionOptions().setAuthenticatedRegionDataLength(regionLength))

Code after addressing the review:
public void illegalRegionLength(long regionLength) {
assertThrows(IllegalArgumentException.class, () -> new BlobClientSideEncryptionOptions()
.setAuthenticatedRegionDataLengthInBytes(regionLength));
}
Code review comment: thanks for your suggestions.i'll add a test case.

Code before review:
public void registerCatalog(String catalogName, Catalog catalog) {
checkArgument(!StringUtils.isNullOrWhitespaceOnly(catalogName), "Catalog name cannot be null or empty.");
checkNotNull(catalog, "Catalog cannot be null");
if (catalogs.containsKey(catalogName)) {
throw new CatalogException(format("Catalog %s already exists.", catalogName));
}
catalog.open();
catalogs.put(catalogName, catalog);
}

Line under review: catalogs.put(catalogName, catalog);

Code after addressing the review:
public void registerCatalog(String catalogName, Catalog catalog) {
checkArgument(!StringUtils.isNullOrWhitespaceOnly(catalogName), "Catalog name cannot be null or empty.");
checkNotNull(catalog, "Catalog cannot be null");
if (catalogs.containsKey(catalogName)) {
throw new CatalogException(format("Catalog %s already exists.", catalogName));
}
catalog.open();
catalogs.put(catalogName, catalog);
}
Code review comment: This implies that we have to buffer elements up to watermark + allowed lateness.

Code before review:
public void processElement(WindowedValue<InputT> input) {
for (WindowedValue<InputT> value : input.explodeWindows()) {
BoundedWindow window = value.getWindows().iterator().next();
if (isLate(window)) {
reportDroppedElement(value, window);
} else if (requiresTimeSortedInput) {
processElementOrdered(window, value);
} else {
processElementUnordered(window, value);
}
}
}

Line under review: } else {

Code after addressing the review:
public void processElement(WindowedValue<InputT> input) {
for (WindowedValue<InputT> value : input.explodeWindows()) {
BoundedWindow window = value.getWindows().iterator().next();
if (isLate(window)) {
reportDroppedElement(value, window);
} else if (requiresTimeSortedInput) {
processElementOrdered(window, value);
} else {
processElementUnordered(window, value);
}
}
}
Code review comment: `jacksonFactory.toString` declares to throw IOException.

Code before review:
public static void assertEqualsAsJson(Object expected, Object actual) {
try {
String expectedJsonText =
expected instanceof String ? (String) expected : jacksonFactory.toString(expected);
String actualJsonText = jacksonFactory.toString(actual);
JSONAssert.assertEquals(expectedJsonText, actualJsonText, true);
} catch (JSONException ex) {
throw new IllegalArgumentException("Could not parse JSON", ex);
} catch (IOException ex) {
throw new IllegalArgumentException("Could not generate JSON text", ex);
}
}

Line under review: } catch (IOException ex) {

Code after addressing the review:
public static void assertEqualsAsJson(Object expected, Object actual) {
try {
String expectedJsonText =
expected instanceof String ? (String) expected : jacksonFactory.toString(expected);
String actualJsonText = jacksonFactory.toString(actual);
JSONAssert.assertEquals(expectedJsonText, actualJsonText, true);
} catch (JSONException ex) {
throw new IllegalArgumentException("Could not parse JSON", ex);
} catch (IOException ex) {
throw new IllegalArgumentException("Could not generate JSON text", ex);
}
}
Code review comment: Yes, I also think this is the case. I'm glad this helped a little bit. :)

Code before review:
public void testReadPublicData() throws Exception {
PCollection<PubsubMessage> messages =
pipeline.apply(
PubsubIO.readMessages()
.fromTopic("projects/pubsub-public-data/topics/taxirides-realtime"));
messages.apply(
"waitForAnyMessage", signal.signalSuccessWhen(messages.getCoder(), anyMessage -> true));
Duration timeout =
pipeline.getOptions().getRunner().getSimpleName().endsWith("DataflowRunner")
? Duration.standardMinutes(5)
: Duration.standardSeconds(30);
signal.waitForSuccess(timeout);
}

Line under review: .fromTopic("projects/pubsub-public-data/topics/taxirides-realtime"));

Code after addressing the review:
public void testReadPublicData() throws Exception {
pipeline.getOptions().as(DirectOptions.class).setBlockOnRun(false);
PCollection<String> messages =
pipeline.apply(
PubsubIO.readStrings()
.fromTopic("projects/pubsub-public-data/topics/taxirides-realtime"));
messages.apply(
"waitForAnyMessage", signal.signalSuccessWhen(messages.getCoder(), anyMessages -> true));
Supplier<Void> start = signal.waitForStart(Duration.standardMinutes(5));
pipeline.apply(signal.signalStart());
PipelineResult job = pipeline.run();
start.get();
signal.waitForSuccess(Duration.standardSeconds(30));
try {
job.cancel();
} catch (UnsupportedOperationException exc) {
}
}
Code review comment: Shall we introduce utility methods `isFlagSet` and `withFlag` to hide the bit manipulation logic?

Code before review:
private void updateDiagnostics(STNode[] children) {
for (STNode child : children) {
if (!SyntaxUtils.isSTNodePresent(child)) {
continue;
}
if ((child.flags & STNodeFlags.HAS_DIAGNOSTIC) != 0) {
this.flags |= STNodeFlags.HAS_DIAGNOSTIC;
return;
}
}
}

Line under review: if ((child.flags & STNodeFlags.HAS_DIAGNOSTIC) != 0) {

Code after addressing the review:
private void updateDiagnostics(STNode[] children) {
for (STNode child : children) {
if (!SyntaxUtils.isSTNodePresent(child)) {
continue;
}
if (STNodeFlags.isFlagSet(child.flags, STNodeFlags.HAS_DIAGNOSTIC)) {
this.flags = STNodeFlags.withFlag(this.flags, STNodeFlags.HAS_DIAGNOSTIC);
return;
}
}
}
Code review comment: I will do it, I noticed a few other small things that I will address.

Code before review:
public void testRootResource() {
RestAssured.get("/other/hello.txt").then()
.log().all()
.statusCode(200)
.body(is("hello"));
RestAssured.get("/stuff.html").then()
.log().all()
.statusCode(200)
.body(is("stuff"));
RestAssured.get("/index.html").then()
.log().all()
.statusCode(200)
.body(is("index"));
RestAssured.get("/").then()
.log().all()
.statusCode(200)
.body(is("index"));
}

Line under review: .log().all()

Code after addressing the review:
public void testRootResource() {
RestAssured.get("/other/hello.txt").then()
.log().all()
.statusCode(200)
.body(is("hello"));
RestAssured.get("/stuff.html").then()
.log().all()
.statusCode(200)
.body(is("stuff"));
RestAssured.get("/index.html").then()
.log().all()
.statusCode(200)
.body(is("index"));
RestAssured.get("/").then()
.log().all()
.statusCode(200)
.body(is("index"));
}
Code review comment: `close` instead of `stop` in the `after` method

Code before review:
public void before() {
try {
testingServer = ZooKeeperTestUtils.createZookeeperTestingServer();
} catch (Exception e) {
throw new RuntimeException("Could not start ZooKeeper testing cluster.", e);
}
configuration = new Configuration();
configuration.setString(
HighAvailabilityOptions.HA_ZOOKEEPER_QUORUM, testingServer.getConnectString());
configuration.setString(HighAvailabilityOptions.HA_MODE, "zookeeper");
curatorFrameworkWrapper =
ZooKeeperUtils.startCuratorFramework(
configuration, testingFatalErrorHandlerResource.getFatalErrorHandler());
}

Line under review: testingServer = ZooKeeperTestUtils.createZookeeperTestingServer();

Code after addressing the review:
public void before() {
try {
testingServer = ZooKeeperTestUtils.createAndStartZookeeperTestingServer();
} catch (Exception e) {
throw new RuntimeException("Could not start ZooKeeper testing cluster.", e);
}
configuration = new Configuration();
configuration.setString(
HighAvailabilityOptions.HA_ZOOKEEPER_QUORUM, testingServer.getConnectString());
configuration.setString(HighAvailabilityOptions.HA_MODE, "zookeeper");
curatorFrameworkWrapper =
ZooKeeperUtils.startCuratorFramework(
configuration, testingFatalErrorHandlerResource.getFatalErrorHandler());
}
Code review comment: Oh, that's right, I'll update.

Code before review:
public boolean tryProcessProfileAsync(Consumer<Boolean> task) {
if (executionDAG.getExecutions().isEmpty()) {
return false;
}
if (!jobSpec.isNeedReport()) {
return false;
}
boolean enableAsyncProfile = true;
if (connectContext != null && connectContext.getSessionVariable() != null) {
enableAsyncProfile = connectContext.getSessionVariable().isEnableAsyncProfile();
}
TUniqueId queryId = null;
if (connectContext != null) {
queryId = connectContext.getExecutionId();
}
if (!enableAsyncProfile || !queryProfile.addListener(task)) {
LOG.warn("Profile task is full, execute in sync mode, query id = {}", DebugUtil.printId(queryId));
collectProfileSync();
task.accept(false);
return false;
}
return true;
}

Line under review: LOG.warn("Profile task is full, execute in sync mode, query id = {}", DebugUtil.printId(queryId));

Code after addressing the review:
public boolean tryProcessProfileAsync(Consumer<Boolean> task) {
if (executionDAG.getExecutions().isEmpty()) {
return false;
}
if (!jobSpec.isNeedReport()) {
return false;
}
boolean enableAsyncProfile = true;
if (connectContext != null && connectContext.getSessionVariable() != null) {
enableAsyncProfile = connectContext.getSessionVariable().isEnableAsyncProfile();
}
TUniqueId queryId = null;
if (connectContext != null) {
queryId = connectContext.getExecutionId();
}
if (!enableAsyncProfile || !queryProfile.addListener(task)) {
if (enableAsyncProfile) {
LOG.info("Profile task is full, execute in sync mode, query id = {}", DebugUtil.printId(queryId));
}
collectProfileSync();
task.accept(false);
return false;
}
return true;
}
Code review comment: Can be replaced with ``` Set<String> notFoundNodes = new HashSet<>(hostnames); notFoundNodes.removeAll(nodes); ```

Code before review:
public List<Node> nodesFromHostnames(List<String> hostnames) {
List<Node> nodes = hostnames.stream()
.filter(h -> nodeMap.containsKey(h))
.map(h -> nodeMap.get(h))
.collect(Collectors.toList());
if (nodes.size() != hostnames.size()) {
List<String> notFoundNodes = hostnames.stream()
.filter(h -> !nodes.stream()
.map(Node::hostname).collect(Collectors.toSet()).contains(h))
.collect(Collectors.toList());
throw new IllegalArgumentException(String.format("Host(s) not found: [ %s ]",
String.join(", ", notFoundNodes)));
}
return nodes;
}

Line under review: List<String> notFoundNodes = hostnames.stream()

Code after addressing the review:
public List<Node> nodesFromHostnames(List<String> hostnames) {
List<Node> nodes = hostnames.stream()
.filter(h -> nodeMap.containsKey(h))
.map(h -> nodeMap.get(h))
.collect(Collectors.toList());
if (nodes.size() != hostnames.size()) {
Set<String> notFoundNodes = new HashSet<>(hostnames);
notFoundNodes.removeAll(nodes.stream().map(Node::hostname).collect(Collectors.toList()));
throw new IllegalArgumentException(String.format("Host(s) not found: [ %s ]",
String.join(", ", notFoundNodes)));
}
return nodes;
}