muttakin2301/ccr_train_1000 huggingface dataset:
Code review comment: Should all the getPrivs() methods of UserPriveTable/TablePriveTable/DbPrivTable/ResourcePrivTable use getReadOnlyIteratorByUser to get the the entiryLIst? 

Code before review:
public void getPrivs(UserIdentity currentUser, String db, PrivBitSet savedPrivs) {
List<PrivEntry> userPrivEntryList = map.get(currentUser);
if (userPrivEntryList == null) {
return;
}
DbPrivEntry matchedEntry = null;
for (PrivEntry entry : userPrivEntryList) {
DbPrivEntry dbPrivEntry = (DbPrivEntry) entry;
if (!dbPrivEntry.isAnyDb() && !dbPrivEntry.getDbPattern().match(db)) {
continue;
}
matchedEntry = dbPrivEntry;
break;
}
if (matchedEntry == null) {
return;
}
savedPrivs.or(matchedEntry.getPrivSet());
}

Line under review: List<PrivEntry> userPrivEntryList = map.get(currentUser);

Code after addressing the review:
public void getPrivs(UserIdentity currentUser, String db, PrivBitSet savedPrivs) {
List<PrivEntry> userPrivEntryList = map.get(currentUser);
if (userPrivEntryList == null) {
return;
}
DbPrivEntry matchedEntry = null;
for (PrivEntry entry : userPrivEntryList) {
DbPrivEntry dbPrivEntry = (DbPrivEntry) entry;
if (!dbPrivEntry.isAnyDb() && !dbPrivEntry.getDbPattern().match(db)) {
continue;
}
matchedEntry = dbPrivEntry;
break;
}
if (matchedEntry == null) {
return;
}
savedPrivs.or(matchedEntry.getPrivSet());
}
Code review comment: I think `IllegalArgumentException` is fine but since it a static method I'm not sure if( we should use a logger or not. I don't think we want to have static loggers. Any thoughts @srngar?

Code before review:
public static KeyVaultRoleScope fromUrl(String url) {
try {
return fromString(new URL(url).getPath(), KeyVaultRoleScope.class);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}

Line under review: throw new RuntimeException(e);

Code after addressing the review:
public static KeyVaultRoleScope fromUrl(String url) {
try {
return fromString(new URL(url).getPath(), KeyVaultRoleScope.class);
} catch (MalformedURLException e) {
throw new IllegalArgumentException(e);
}
}
Code review comment: I was thinking the service would always send US formatted datetimes, but i'm not sure

Code before review:
private static Long parseDateToEpochSeconds(String dateTime) {
ClientLogger logger = new ClientLogger(MSIToken.class);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/yyyy H:mm:ss XXX", Locale.US);
DateTimeFormatter dtf_windows = DateTimeFormatter.ofPattern("M/d/yyyy K:mm:ss a XXX", Locale.US);
try {
return Long.parseLong(dateTime);
} catch (NumberFormatException e) {
logger.error(e.getMessage());
}
try {
return Instant.from(dtf.parse(dateTime)).getEpochSecond();
} catch (DateTimeParseException e) {
logger.error(e.getMessage());
}
try {
return Instant.from(dtf_windows.parse(dateTime)).getEpochSecond();
} catch (DateTimeParseException e) {
logger.error(e.getMessage());
}
throw logger.logExceptionAsError(new IllegalArgumentException("Unable to parse date time " + dateTime));
}

Line under review: DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/yyyy H:mm:ss XXX", Locale.US);

Code after addressing the review:
private static Long parseDateToEpochSeconds(String dateTime) {
ClientLogger logger = new ClientLogger(MSIToken.class);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/yyyy H:mm:ss XXX");
DateTimeFormatter dtfWindows = DateTimeFormatter.ofPattern("M/d/yyyy K:mm:ss a XXX");
try {
return Long.parseLong(dateTime);
} catch (NumberFormatException e) {
logger.error(e.getMessage());
}
try {
return Instant.from(dtf.parse(dateTime)).getEpochSecond();
} catch (DateTimeParseException e) {
logger.error(e.getMessage());
}
try {
return Instant.from(dtfWindows.parse(dateTime)).getEpochSecond();
} catch (DateTimeParseException e) {
logger.error(e.getMessage());
}
throw logger.logExceptionAsError(new IllegalArgumentException("Unable to parse date time " + dateTime));
}
Code review comment: Test/sample code.  As `data` is of type [`object`](https://github.com/Azure/azure-rest-api-specs/blob/master/specification/resourcegraph/resource-manager/Microsoft.ResourceGraph/stable/2019-04-01/resourcegraph.json#L292-L295), it is not easy to use the result in Java.

Code before review:
public void testResourceGraph() {
QueryRequest queryRequest = new QueryRequest();
queryRequest.withSubscriptions(Arrays.asList(subscription));
queryRequest.withQuery("Resources | project name, type | order by name asc | limit 5");
QueryResponse queryResponse = resourceGraphManager.resourceProviders().resources(queryRequest);
Assert.assertTrue(queryResponse.count() > 0);
Assert.assertNotNull(queryResponse.data());
Assert.assertTrue(queryResponse.data() instanceof Map);
Map<String, Object> dataAsDict = (Map<String, Object>) queryResponse.data();
Assert.assertTrue(dataAsDict.containsKey("columns"));
Assert.assertTrue(dataAsDict.containsKey("rows"));
List<String> columns = (List<String>) dataAsDict.get("columns");
List<String> rows = (List<String>) dataAsDict.get("columns");
Assert.assertEquals(2, columns.size());
Assert.assertTrue(rows.size() > 0);
}

Line under review: }

Code after addressing the review:
public void testResourceGraph() {
QueryRequest queryRequest = new QueryRequest();
queryRequest.withSubscriptions(Arrays.asList(subscription));
queryRequest.withQuery("Resources | project name, type | order by name asc | limit 5");
queryRequest.withOptions(new QueryRequestOptions().withResultFormat(ResultFormat.TABLE));
QueryResponse queryResponse = resourceGraphManager.resourceProviders().resources(queryRequest);
Assert.assertTrue(queryResponse.count() > 0);
Assert.assertNotNull(queryResponse.data());
Assert.assertTrue(queryResponse.data() instanceof Map);
Map<String, Object> dataAsDict = (Map<String, Object>) queryResponse.data();
Assert.assertTrue(dataAsDict.containsKey("columns"));
Assert.assertTrue(dataAsDict.containsKey("rows"));
List<String> columns = (List<String>) dataAsDict.get("columns");
List<String> rows = (List<String>) dataAsDict.get("columns");
Assert.assertEquals(2, columns.size());
Assert.assertTrue(rows.size() > 0);
queryRequest.withOptions(new QueryRequestOptions().withResultFormat(ResultFormat.OBJECT_ARRAY));
queryResponse = resourceGraphManager.resourceProviders().resources(queryRequest);
Assert.assertTrue(queryResponse.count() > 0);
Assert.assertTrue(queryResponse.data() instanceof List);
List<Object> dataAsList = (List<Object>) queryResponse.data();
Map<String, String> itemAsDict = (Map<String, String>) dataAsList.iterator().next();
Assert.assertTrue(itemAsDict.containsKey("name"));
Assert.assertTrue(itemAsDict.containsKey("type"));
}
Code review comment: I just wanted to make sure we deserialize properly but checking the value itself should tell us if there's changes on the service-side of things. It should be `0` by default from what I've seen.

Code before review:
public void createKey(HttpClient httpClient, KeyServiceVersion serviceVersion) {
createKeyAsyncClient(httpClient, serviceVersion);
createKeyRunner((keyToCreate) ->
StepVerifier.create(keyAsyncClient.createKey(keyToCreate))
.assertNext(createdKey -> {
assertKeyEquals(keyToCreate, createdKey);
assertNotNull(createdKey.getProperties().getHsmPlatform());
})
.verifyComplete());
}

Line under review: assertNotNull(createdKey.getProperties().getHsmPlatform());

Code after addressing the review:
public void createKey(HttpClient httpClient, KeyServiceVersion serviceVersion) {
createKeyAsyncClient(httpClient, serviceVersion);
createKeyRunner((keyToCreate) ->
StepVerifier.create(keyAsyncClient.createKey(keyToCreate))
.assertNext(createdKey -> {
assertKeyEquals(keyToCreate, createdKey);
assertEquals("0", createdKey.getProperties().getHsmPlatform());
})
.verifyComplete());
}
Code review comment: Not a stupid question at all 😃   While it is unknown how often an `arrayOffset` and/or `position` to be set in a passed `ByteBuffer` using them ensures we're only accessing what is still considered readable by the `ByteBuffer`.   For example, I create a `ByteBuffer` with a 4096 byte array, and I know the array has special metadata in the first 128 bytes. So, I'll create a wrapping `ByteBuffer` offset by 128 bytes, so its effective reading range are the bytes [128, 4096). At this point the `toString` logic highlighted will be based on that range, `new String(byte[], 128, 4096-128, UTF_8)` (pardon any off-by-one errors as I'm free-handing this). But, let's say next that I know the range [128, 1024) is either junk data or something unrelated to the string, I'll make the new position 1024-128 as there is an offset of 128. Now, the `toString` becomes `new String(byte[], 128+896, 4096, UTF_8)`.  For the second question, this is more difficult on whether the `ByteBuffer`'s position should be mutated, in this case I'd say no as `toString` is more a representation and may result in broken runtime behavior if `transactionId` is fully consumed by it. Also, when debugging, many IDEs will call `toString` when inspecting the object in the debug window, likely breaking debugging.

Code before review:
public String toString() {
if (transactionId.hasArray()) {
return new String(transactionId.array(), transactionId.arrayOffset() + transactionId.position(),
transactionId.remaining(), StandardCharsets.UTF_8);
} else {
return new String(FluxUtil.byteBufferToArray(transactionId.duplicate()), StandardCharsets.UTF_8);
}
}

Line under review: transactionId.remaining(), StandardCharsets.UTF_8);

Code after addressing the review:
public String toString() {
if (transactionId.hasArray()) {
return new String(transactionId.array(), transactionId.arrayOffset() + transactionId.position(),
transactionId.remaining(), StandardCharsets.UTF_8);
} else {
return new String(FluxUtil.byteBufferToArray(transactionId.duplicate()), StandardCharsets.UTF_8);
}
}
Code review comment: Yes - there is a race. Multiple threads might call setxxxAccessor concurrently - only one thread wil "win" (enter the else statement) - this "winner" will have set the accessor and also the the xxxClassLoaded flag. So threads calling into getxxxAccessor will only not call into the xxx.initialize (with calls setxxxAcccessor) after we are sure the accessor has been set. So, yes - there is a race - and yes - it is thread-safe now.

Code before review:
public static void setCosmosClientBuilderAccessor(final CosmosClientBuilderAccessor newAccessor) {
if (!accessor.compareAndSet(null, newAccessor)) {
logger.debug("CosmosClientBuilderAccessor already initialized!");
} else {
logger.info("Setting CosmosClientBuilderAccessor...");
cosmosClientBuilderClassLoaded.set(true);
}
}

Line under review: cosmosClientBuilderClassLoaded.set(true);

Code after addressing the review:
public static void setCosmosClientBuilderAccessor(final CosmosClientBuilderAccessor newAccessor) {
if (!accessor.compareAndSet(null, newAccessor)) {
logger.debug("CosmosClientBuilderAccessor already initialized!");
} else {
logger.info("Setting CosmosClientBuilderAccessor...");
cosmosClientBuilderClassLoaded.set(true);
}
}
Code review comment: If try-with-resources is used and `/dev/null` feeds the input as well as output, then the `finally` block is not needed anymore.

Code before review:
private static String getLinuxID(String option) {
Process process = null;
BufferedReader reader = null;
try {
StringBuilder responseBuilder = new StringBuilder();
String line;
ProcessBuilder idPB = new ProcessBuilder().command("id", option);
idPB.redirectError(new File("/dev/null"));
try {
process = idPB.start();
process.getOutputStream().close();
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = reader.readLine()) != null) {
responseBuilder.append(line);
}
return responseBuilder.toString();
} finally {
if (process != null) {
process.getInputStream().close();
process.getErrorStream().close();
}
if (reader != null) {
reader.close();
}
}
} catch (Exception e) {
return null;
}
}

Line under review: process.getInputStream().close();

Code after addressing the review:
private static String getLinuxID(String option) {
Process process;
try {
StringBuilder responseBuilder = new StringBuilder();
String line;
ProcessBuilder idPB = new ProcessBuilder().command("id", option);
idPB.redirectError(new File("/dev/null"));
idPB.redirectOutput(new File("/dev/null"));
process = idPB.start();
try (InputStream inputStream = process.getInputStream()) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
while ((line = reader.readLine()) != null) {
responseBuilder.append(line);
}
safeWaitFor(process);
return responseBuilder.toString();
}
} catch (Throwable t) {
safeWaitFor(process);
throw t;
}
} catch (IOException e) {
return null;
}
}
Code review comment: Good catch. This has no use since we checked whether it's lower case. 

Code before review:
public CloudEvent addExtensionAttribute(String name, Object value) {
if (Objects.isNull(name)) {
throw LOGGER.logExceptionAsError(new IllegalArgumentException("'name' cannot be null."));
}
if (Objects.isNull(value)) {
throw LOGGER.logExceptionAsError(new IllegalArgumentException("'value' cannot be null."));
}
if (!validateAttributeName(name)) {
throw LOGGER.logExceptionAsError(new IllegalArgumentException(
"'name' must have only small-case alphanumeric characters and not be one of the CloudEvent reserved "
+ "attribute names"));
}
if (this.extensionAttributes == null) {
this.extensionAttributes = new HashMap<>();
}
this.extensionAttributes.put(name.toLowerCase(Locale.ENGLISH), value);
return this;
}

Line under review: this.extensionAttributes.put(name.toLowerCase(Locale.ENGLISH), value);

Code after addressing the review:
public CloudEvent addExtensionAttribute(String name, Object value) {
Objects.requireNonNull(name, "'name' cannot be null.");
Objects.requireNonNull(value, "'value' cannot be null.");
if (!validateAttributeName(name)) {
throw LOGGER.logExceptionAsError(new IllegalArgumentException(
"Extension attribute 'name' must have only lower-case alphanumeric characters and not be one of the "
+ "CloudEvent reserved attribute names: " + String.join(",", RESERVED_ATTRIBUTE_NAMES)));
}
if (this.extensionAttributes == null) {
this.extensionAttributes = new HashMap<>();
}
this.extensionAttributes.put(name, value);
return this;
}
Code review comment: This generated expr is only used for filtering files.The Expr sent to BE is another set of logic. Mainly because this reduction based on struct type has not been fully tested, and the existing DeltaLake implementation does not support it, so keep this logic unchanged for now  

Code before review:
private static DeltaDataType getColumnType(String qualifiedName, DeltaLakeContext context) {
StructType structType = context.getSchema();
StructField field = structType.get(qualifiedName);
if (field != null) {
DeltaDataType type = DeltaDataType.instanceFrom(field.getDataType().getClass());
if (type == DeltaDataType.TIMESTAMP && context.isPartitionColumn(qualifiedName)) {
return DeltaDataType.TIMESTAMP_NTZ;
} else {
return type;
}
} else {
return DeltaDataType.OTHER;
}
}


Code after addressing the review:
private static DeltaDataType getColumnType(String qualifiedName, DeltaLakeContext context) {
StructType structType = context.getSchema();
StructField field = structType.get(qualifiedName);
if (field != null) {
DeltaDataType type = DeltaDataType.instanceFrom(field.getDataType().getClass());
if (type == DeltaDataType.TIMESTAMP && context.isPartitionColumn(qualifiedName)) {
return DeltaDataType.TIMESTAMP_NTZ;
} else {
return type;
}
} else {
return DeltaDataType.OTHER;
}
}
Code review comment: I will remove the wrapper and let the CI run...

Code before review:
public Consumer<Route> start() {
List<Handler<RoutingContext>> handlers = new ArrayList<>();
if (hotDeploymentResourcePaths != null && !hotDeploymentResourcePaths.isEmpty()) {
for (Path resourcePath : hotDeploymentResourcePaths) {
String root = resourcePath.toAbsolutePath().toString();
ThreadLocalHandler staticHandler = new ThreadLocalHandler(new Supplier<Handler<RoutingContext>>() {
@Override
public Handler<RoutingContext> get() {
StaticHandler staticHandler = StaticHandler.create();
staticHandler.setCachingEnabled(false);
staticHandler.setAllowRootFileSystemAccess(true);
staticHandler.setWebRoot(root);
staticHandler.setDefaultContentEncoding("UTF-8");
return staticHandler;
}
});
handlers.add(event -> {
try {
staticHandler.handle(event);
} catch (Exception e) {
event.next();
}
});
}
}
if (!knownPaths.isEmpty()) {
ThreadLocalHandler staticHandler = new ThreadLocalHandler(new Supplier<Handler<RoutingContext>>() {
@Override
public Handler<RoutingContext> get() {
return StaticHandler.create(META_INF_RESOURCES)
.setDefaultContentEncoding("UTF-8");
}
});
handlers.add(ctx -> {
String rel = ctx.mountPoint() == null ? ctx.normalisedPath()
: ctx.normalisedPath().substring(ctx.mountPoint().length());
if (knownPaths.contains(rel)) {
staticHandler.handle(ctx);
} else {
ctx.next();
}
});
}
return new Consumer<Route>() {
@Override
public void accept(Route route) {
for (Handler<RoutingContext> i : handlers) {
route.handler(i);
}
}
};
}

Line under review: ThreadLocalHandler staticHandler = new ThreadLocalHandler(new Supplier<Handler<RoutingContext>>() {

Code after addressing the review:
public Consumer<Route> start() {
List<Handler<RoutingContext>> handlers = new ArrayList<>();
if (hotDeploymentResourcePaths != null && !hotDeploymentResourcePaths.isEmpty()) {
for (Path resourcePath : hotDeploymentResourcePaths) {
String root = resourcePath.toAbsolutePath().toString();
StaticHandler staticHandler = StaticHandler.create();
staticHandler.setCachingEnabled(false);
staticHandler.setAllowRootFileSystemAccess(true);
staticHandler.setWebRoot(root);
staticHandler.setDefaultContentEncoding("UTF-8");
handlers.add(event -> {
try {
staticHandler.handle(event);
} catch (Exception e) {
event.next();
}
});
}
}
if (!knownPaths.isEmpty()) {
StaticHandler staticHandler = StaticHandler.create(META_INF_RESOURCES).setDefaultContentEncoding("UTF-8");
handlers.add(ctx -> {
String rel = ctx.mountPoint() == null ? ctx.normalisedPath()
: ctx.normalisedPath().substring(ctx.mountPoint().length());
if (knownPaths.contains(rel)) {
staticHandler.handle(ctx);
} else {
ctx.next();
}
});
}
return new Consumer<Route>() {
@Override
public void accept(Route route) {
for (Handler<RoutingContext> i : handlers) {
route.handler(i);
}
}
};
}
Code review comment: We need to keep this since it has been used to keep track of function call depths.

Code before review:
public static void autoClose(BString[] channelIds) {
Strand currentStrand = Scheduler.getStrand();
Strand channelHoldingStrand = Objects.requireNonNullElse(currentStrand.parent, currentStrand);
for (BString channelId : channelIds) {
String channelName = getMatchingChannelName(channelId.getValue(), currentStrand);
WorkerDataChannel workerDataChannel = channelHoldingStrand.wdChannels.getWorkerDataChannel(channelName);
workerDataChannel.autoClose();
}
}

Line under review: for (BString channelId : channelIds) {

Code after addressing the review:
public static void autoClose(BString[] channelIds) {
Strand currentStrand = Scheduler.getStrand();
Strand channelHoldingStrand = Objects.requireNonNullElse(currentStrand.parent, currentStrand);
for (BString channelId : channelIds) {
String channelName = getMatchingChannelName(channelId.getValue(), currentStrand);
WorkerDataChannel workerDataChannel = channelHoldingStrand.wdChannels.getWorkerDataChannel(channelName);
workerDataChannel.autoClose();
}
}
Code review comment: Any reason to choose `System.nanoTime()` vs `System.currentTimeMillis()`?

Code before review:
private void executeBatch() throws SQLException, IOException, InterruptedException {
if (records.isEmpty()) {
return;
}
Long startTimeNs = System.nanoTime();
if (connection == null) {
connection = dataSource.getConnection();
connection.setAutoCommit(false);
preparedStatement = connection.prepareStatement(spec.getStatement().get());
}
Sleeper sleeper = Sleeper.DEFAULT;
BackOff backoff = retryBackOff.backoff();
while (true) {
try (PreparedStatement preparedStatement =
connection.prepareStatement(spec.getStatement().get())) {
try {
for (T record : records) {
processRecord(record, preparedStatement);
}
preparedStatement.executeBatch();
connection.commit();
RECORDS_PER_BATCH.update(records.size());
MS_PER_BATCH.update((System.nanoTime() - startTimeNs) / 1000);
break;
} catch (SQLException exception) {
if (!spec.getRetryStrategy().apply(exception)) {
throw exception;
}
LOG.warn("Deadlock detected, retrying", exception);
preparedStatement.clearBatch();
connection.rollback();
if (!BackOffUtils.next(sleeper, backoff)) {
throw exception;
}
}
}
}
records.clear();
}

Line under review: Long startTimeNs = System.nanoTime();

Code after addressing the review:
private void executeBatch() throws SQLException, IOException, InterruptedException {
if (records.isEmpty()) {
return;
}
Long startTimeNs = System.nanoTime();
if (connection == null) {
connection = dataSource.getConnection();
connection.setAutoCommit(false);
preparedStatement = connection.prepareStatement(spec.getStatement().get());
}
Sleeper sleeper = Sleeper.DEFAULT;
BackOff backoff = retryBackOff.backoff();
while (true) {
try (PreparedStatement preparedStatement =
connection.prepareStatement(spec.getStatement().get())) {
try {
for (T record : records) {
processRecord(record, preparedStatement);
}
preparedStatement.executeBatch();
connection.commit();
RECORDS_PER_BATCH.update(records.size());
MS_PER_BATCH.update(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTimeNs));
break;
} catch (SQLException exception) {
if (!spec.getRetryStrategy().apply(exception)) {
throw exception;
}
LOG.warn("Deadlock detected, retrying", exception);
preparedStatement.clearBatch();
connection.rollback();
if (!BackOffUtils.next(sleeper, backoff)) {
throw exception;
}
}
}
}
records.clear();
}
Code review comment: ```suggestion             boolean methodCallOnVarRef = expr != null; ``` Why do we need this(`expr.getKind() == NodeKind.SIMPLE_VARIABLE_REF`) check. Here kind of `expr` is always `SIMPLE_VARIABLE_REF`. right?

Code before review:
private boolean isGlobalVarsInitialized(Location pos, BLangInvocation invocation) {
if (env.isModuleInit) {
boolean isFirstUninitializedField = true;
StringBuilder uninitializedFields = new StringBuilder();
BLangExpression expr = invocation.expr;
boolean methodCallOnVarRef = expr != null && expr.getKind() == NodeKind.SIMPLE_VARIABLE_REF;
for (BSymbol symbol : this.uninitializedVars.keySet()) {
if (symbol.owner.getKind() != SymbolKind.PACKAGE || symbol == invocation.symbol ||
(methodCallOnVarRef && ((BLangSimpleVarRef) expr).symbol == symbol)) {
continue;
}
if (isFirstUninitializedField) {
uninitializedFields = new StringBuilder(symbol.getName().value);
isFirstUninitializedField = false;
} else {
uninitializedFields.append(", ").append(symbol.getName().value);
}
}
if (uninitializedFields.length() != 0) {
this.dlog.error(pos, DiagnosticErrorCode.INVALID_FUNCTION_CALL_WITH_UNINITIALIZED_VARIABLES,
uninitializedFields.toString());
return false;
}
}
return true;
}

Line under review: boolean methodCallOnVarRef = expr != null && expr.getKind() == NodeKind.SIMPLE_VARIABLE_REF;

Code after addressing the review:
private boolean isGlobalVarsInitialized(Location pos, BLangInvocation invocation) {
if (env.isModuleInit) {
boolean isFirstUninitializedField = true;
StringBuilder uninitializedFields = new StringBuilder();
BLangExpression expr = invocation.expr;
boolean methodCallOnVarRef = expr != null && expr.getKind() == NodeKind.SIMPLE_VARIABLE_REF;
for (BSymbol symbol : this.uninitializedVars.keySet()) {
if (symbol.owner.getKind() != SymbolKind.PACKAGE || symbol == invocation.symbol ||
(methodCallOnVarRef && ((BLangSimpleVarRef) expr).symbol == symbol)) {
continue;
}
if (isFirstUninitializedField) {
uninitializedFields = new StringBuilder(symbol.getName().value);
isFirstUninitializedField = false;
} else {
uninitializedFields.append(", ").append(symbol.getName().value);
}
}
if (uninitializedFields.length() != 0) {
this.dlog.error(pos, DiagnosticErrorCode.INVALID_FUNCTION_CALL_WITH_UNINITIALIZED_VARIABLES,
uninitializedFields.toString());
return false;
}
}
return true;
}
Code review comment: That's nice!  We can use that actually by checking if `result` is `Multi` and doing this special handling in such a case.

Code before review:
private void handleStreaming(ResteasyReactiveRequestContext requestContext, Publisher<?> result, boolean json) {
result.subscribe(new StreamingMultiSubscriber(requestContext, json));
}

Line under review: result.subscribe(new StreamingMultiSubscriber(requestContext, json));

Code after addressing the review:
private void handleStreaming(ResteasyReactiveRequestContext requestContext, Publisher<?> result, boolean json) {
result.subscribe(new StreamingMultiSubscriber(requestContext, json));
}
Code review comment: The deactivate implementation in the config server client only have retries over the three servers, as it needs to hit the correct one. There is no other retrying logic there, for that path. 

Code before review:
private Optional<RunStatus> deactivateReal(RunId id, DualLogger logger) {
try {
return retrying(10, () -> {
logger.log("Deactivating deployment of " + id.application() + " in " + id.type().zone(controller.system()) + " ...");
controller.applications().deactivate(id.application(), id.type().zone(controller.system()));
return running;
});
}
catch (RuntimeException e) {
logger.log(WARNING, "Failed deleting application " + id.application(), e);
return Optional.of(error);
}
}

Line under review: return retrying(10, () -> {

Code after addressing the review:
private Optional<RunStatus> deactivateReal(RunId id, DualLogger logger) {
try {
return retrying(10, () -> {
logger.log("Deactivating deployment of " + id.application() + " in " + id.type().zone(controller.system()) + " ...");
controller.applications().deactivate(id.application(), id.type().zone(controller.system()));
return running;
});
}
catch (RuntimeException e) {
logger.log(WARNING, "Failed deleting application " + id.application(), e);
return Optional.of(error);
}
}
Code review comment: Step one, in order to be compatible, fe generate dsl can not affect exist logic, what do you think?

Code before review:
public String toJson() {
StringWriter writer = new StringWriter();
try {
JsonGenerator gen = mapper.getFactory().createGenerator(writer);
this.toJson(gen);
gen.flush();
gen.close();
} catch (IOException e) {
LOG.warn("QueryBuilder toJson error");
return null;
}
return writer.toString();
}

Line under review: LOG.warn("QueryBuilder toJson error");

Code after addressing the review:
public String toJson() {
StringWriter writer = new StringWriter();
try {
JsonGenerator gen = mapper.getFactory().createGenerator(writer);
this.toJson(gen);
gen.flush();
gen.close();
} catch (IOException e) {
LOG.warn("QueryBuilder toJson error", e);
return null;
}
return writer.toString();
}
Code review comment: ```suggestion         // An object containing the details of the recently updated key rotation policy will be returned by the update method. ```

Code before review:
public static void main(String[] args) {
KeyClient keyClient = new KeyClientBuilder()
.vaultUrl("https:
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();
KeyVaultKey originalKey = keyClient.createRsaKey(new CreateRsaKeyOptions("MyRsaKey").setKeySize(2048));
System.out.printf("Key created with name %s and type %s%n", originalKey.getName(), originalKey.getKeyType());
KeyVaultKey manuallyRotatedKey = keyClient.rotateKey("MyRsaKey");
System.out.printf("Rotated key with name %s%n", manuallyRotatedKey.getName());
List<KeyRotationLifetimeAction> keyRotationLifetimeActionList = new ArrayList<>();
KeyRotationLifetimeAction rotateLifetimeAction = new KeyRotationLifetimeAction(KeyRotationPolicyAction.ROTATE)
.setTimeAfterCreate("P90D");
keyRotationLifetimeActionList.add(rotateLifetimeAction);
KeyRotationPolicyProperties keyRotationPolicyProperties = new KeyRotationPolicyProperties()
.setLifetimeActions(keyRotationLifetimeActionList)
.setExpiryTime("P6M");
KeyRotationPolicy keyRotationPolicy =
keyClient.updateKeyRotationPolicy("MyRsaKey", keyRotationPolicyProperties);
System.out.printf("Updated key rotation policy with id: %s%n", keyRotationPolicy.getId());
}


Code after addressing the review:
public static void main(String[] args) {
KeyClient keyClient = new KeyClientBuilder()
.vaultUrl("https:
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();
String keyName = "MyKey";
KeyVaultKey originalKey = keyClient.createRsaKey(new CreateRsaKeyOptions(keyName).setKeySize(2048));
System.out.printf("Key created with name %s and type %s%n", originalKey.getName(), originalKey.getKeyType());
List<KeyRotationLifetimeAction> keyRotationLifetimeActionList = new ArrayList<>();
KeyRotationLifetimeAction rotateLifetimeAction = new KeyRotationLifetimeAction(KeyRotationPolicyAction.ROTATE)
.setTimeAfterCreate("P90D");
keyRotationLifetimeActionList.add(rotateLifetimeAction);
KeyRotationPolicyProperties keyRotationPolicyProperties = new KeyRotationPolicyProperties()
.setLifetimeActions(keyRotationLifetimeActionList)
.setExpiryTime("P6M");
KeyRotationPolicy keyRotationPolicy =
keyClient.updateKeyRotationPolicy(keyName, keyRotationPolicyProperties);
System.out.printf("Updated key rotation policy with id: %s%n", keyRotationPolicy.getId());
KeyVaultKey manuallyRotatedKey = keyClient.rotateKey(keyName);
System.out.printf("Rotated key with name %s%n", manuallyRotatedKey.getName());
}
Code review comment: Shall we remove metric publishing from here and publish error scenario in response callback notify success method

Code before review:
private void dispatchWithDataBinding(ObjectValue msgObj, BType intendedType, byte[] data) {
try {
Object typeBoundData = bindDataToIntendedType(data, intendedType);
CountDownLatch countDownLatch = new CountDownLatch(1);
executeResource(msgObj, countDownLatch, typeBoundData);
countDownLatch.await();
} catch (NumberFormatException e) {
ErrorValue dataBindError = Utils
.createNatsError("The received message is unsupported by the resource signature");
ErrorHandler.dispatchError(serviceObject, msgObj, dataBindError, runtime, connectedUrl);
NatsMetricsUtil.reportConsumerError(connectedUrl, msgObj.getStringValue(Constants.SUBJECT),
NatsObservabilityConstants.ERROR_TYPE_MSG_RECEIVED);
} catch (ErrorValue e) {
ErrorHandler.dispatchError(serviceObject, msgObj, e, runtime, connectedUrl);
NatsMetricsUtil.reportConsumerError(connectedUrl, msgObj.getStringValue(Constants.SUBJECT),
NatsObservabilityConstants.ERROR_TYPE_MSG_RECEIVED);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
NatsMetricsUtil.reportConsumerError(connectedUrl, msgObj.getStringValue(Constants.SUBJECT),
NatsObservabilityConstants.ERROR_TYPE_MSG_RECEIVED);
throw Utils.createNatsError(Constants.THREAD_INTERRUPTED_ERROR);
}
}

Line under review: NatsObservabilityConstants.ERROR_TYPE_MSG_RECEIVED);

Code after addressing the review:
private void dispatchWithDataBinding(ObjectValue msgObj, BType intendedType, byte[] data) {
try {
Object typeBoundData = bindDataToIntendedType(data, intendedType);
CountDownLatch countDownLatch = new CountDownLatch(1);
executeResource(msgObj, countDownLatch, typeBoundData);
countDownLatch.await();
} catch (NumberFormatException e) {
ErrorValue dataBindError = Utils
.createNatsError("The received message is unsupported by the resource signature");
ErrorHandler.dispatchError(serviceObject, msgObj, dataBindError, runtime, connectedUrl);
} catch (ErrorValue e) {
ErrorHandler.dispatchError(serviceObject, msgObj, e, runtime, connectedUrl);
} catch (InterruptedException e) {
NatsMetricsUtil.reportConsumerError(connectedUrl, msgObj.getStringValue(Constants.SUBJECT),
NatsObservabilityConstants.ERROR_TYPE_MSG_RECEIVED);
Thread.currentThread().interrupt();
throw Utils.createNatsError(Constants.THREAD_INTERRUPTED_ERROR);
}
}
Code review comment: I'm wondering whether we should use `CompletableFuture` here, instead. That way, we could collect any `RuntimeException` (which would be otherwise swallowed by the concurrent execution). WDYT? :thinking: 

Code before review:
void testCancelExecutionInteractiveMode() throws Exception {
final MockExecutor mockExecutor = new MockExecutor(new SqlParserHelper(), true);
Path historyFilePath = historyTempFile();
InputStream inputStream = new ByteArrayInputStream("SELECT 1;\nHELP;\n ".getBytes());
OutputStream outputStream = new ByteArrayOutputStream(248);
CountDownLatch closedLatch = new CountDownLatch(1);
try (Terminal terminal = TerminalUtils.createDumbTerminal(inputStream, outputStream);
CliClient client =
new CliClient(() -> terminal, mockExecutor, historyFilePath, null)) {
Thread thread =
new Thread(
() -> {
try {
client.executeInInteractiveMode();
} catch (Exception ignore) {
} finally {
closedLatch.countDown();
}
});
thread.start();
while (!mockExecutor.isAwait) {
Thread.sleep(10);
}
terminal.raise(Terminal.Signal.INT);
CommonTestUtils.waitUntilCondition(
() -> outputStream.toString().contains(CliStrings.MESSAGE_HELP));
closedLatch.await(30, TimeUnit.SECONDS);
}
}

Line under review: } finally {

Code after addressing the review:
void testCancelExecutionInteractiveMode() throws Exception {
final MockExecutor mockExecutor = new MockExecutor(new SqlParserHelper(), true);
Path historyFilePath = historyTempFile();
InputStream inputStream = new ByteArrayInputStream("SELECT 1;\nHELP;\n ".getBytes());
OutputStream outputStream = new ByteArrayOutputStream(248);
try (Terminal terminal = TerminalUtils.createDumbTerminal(inputStream, outputStream);
CliClient client =
new CliClient(() -> terminal, mockExecutor, historyFilePath, null)) {
CheckedThread thread =
new CheckedThread() {
@Override
public void go() {
client.executeInInteractiveMode();
}
};
thread.start();
while (!mockExecutor.isAwait) {
Thread.sleep(10);
}
terminal.raise(Terminal.Signal.INT);
CommonTestUtils.waitUntilCondition(
() -> outputStream.toString().contains(CliStrings.MESSAGE_HELP));
thread.sync();
}
}
Code review comment: Can we make this initilization as a default approach, rather than in an else block

Code before review:
public void visit(BLangTypeDefinition astTypeDefinition) {
Visibility visibility = getVisibility(astTypeDefinition.symbol);
List<BIRFunction> attachedFuncs;
int typeTag = astTypeDefinition.symbol.type.tag;
if (typeTag == TypeTags.OBJECT || typeTag == TypeTags.RECORD) {
attachedFuncs = new ArrayList<>();
} else {
attachedFuncs = null;
}
BIRTypeDefinition typeDef = new BIRTypeDefinition(astTypeDefinition.pos,
astTypeDefinition.symbol.name,
visibility,
astTypeDefinition.typeNode.type,
attachedFuncs);
typeDefs.put(astTypeDefinition.symbol, typeDef);
this.env.enclPkg.typeDefs.add(typeDef);
typeDef.index = this.env.enclPkg.typeDefs.size() - 1;
}

Line under review: attachedFuncs = null;

Code after addressing the review:
public void visit(BLangTypeDefinition astTypeDefinition) {
Visibility visibility = getVisibility(astTypeDefinition.symbol);
List<BIRFunction> attachedFuncs;
int typeTag = astTypeDefinition.symbol.type.tag;
if (typeTag == TypeTags.OBJECT || typeTag == TypeTags.RECORD) {
attachedFuncs = new ArrayList<>();
} else {
attachedFuncs = null;
}
BIRTypeDefinition typeDef = new BIRTypeDefinition(astTypeDefinition.pos,
astTypeDefinition.symbol.name,
visibility,
astTypeDefinition.typeNode.type,
attachedFuncs);
typeDefs.put(astTypeDefinition.symbol, typeDef);
this.env.enclPkg.typeDefs.add(typeDef);
typeDef.index = this.env.enclPkg.typeDefs.size() - 1;
}
Code review comment: the type nullable  may not be correct if the input is null , why the return type is DataTypes.MULTISET(argumentDataTypes.get(0)).notNull(), which is not null 

Code before review:
public Optional<DataType> inferType(CallContext callContext) {
List<DataType> argumentDataTypes = callContext.getArgumentDataTypes();
if (argumentDataTypes.size() != 1) {
return Optional.empty();
}
return Optional.of(DataTypes.MULTISET(argumentDataTypes.get(0)).notNull());
}

Line under review: }

Code after addressing the review:
public Optional<DataType> inferType(CallContext callContext) {
List<DataType> argumentDataTypes = callContext.getArgumentDataTypes();
if (argumentDataTypes.size() != 1) {
return Optional.empty();
}
return Optional.of(DataTypes.MULTISET(argumentDataTypes.get(0)).notNull());
}
Code review comment: As far as I have understood, this whole method is actually not doing anything for `coordinatorClient`. Shouldn't we just add a shortcut? ```     if (coordinatorClient == null) {         return Collections.emptyList();     } ``` Then we could simplify `notifyCheckpointComplete` and just have some `checkState(coordinatorClient != null)` when it actually comes to committing. 

Code before review:
public List<PulsarPartitionSplit> snapshotState(long checkpointId) {
LOG.debug("Trigger the new transaction for downstream readers.");
List<PulsarPartitionSplit> splits =
((PulsarUnorderedFetcherManager<OUT>) splitFetcherManager)
.snapshotState(checkpointId);
if (splits.isEmpty() && transactionsOfFinishedSplits.isEmpty()) {
transactionsToCommit.put(checkpointId, Collections.emptyList());
} else {
List<TxnID> txnIDs =
transactionsToCommit.computeIfAbsent(checkpointId, id -> new ArrayList<>());
for (PulsarPartitionSplit split : splits) {
TxnID uncommittedTransactionId = split.getUncommittedTransactionId();
if (uncommittedTransactionId != null) {
txnIDs.add(uncommittedTransactionId);
}
}
}
return splits;
}

Line under review: .snapshotState(checkpointId);

Code after addressing the review:
public List<PulsarPartitionSplit> snapshotState(long checkpointId) {
LOG.debug("Trigger the new transaction for downstream readers.");
List<PulsarPartitionSplit> splits =
((PulsarUnorderedFetcherManager<OUT>) splitFetcherManager)
.snapshotState(checkpointId);
if (coordinatorClient != null) {
List<TxnID> txnIDs =
transactionsToCommit.computeIfAbsent(checkpointId, id -> new ArrayList<>());
for (PulsarPartitionSplit split : splits) {
TxnID uncommittedTransactionId = split.getUncommittedTransactionId();
if (uncommittedTransactionId != null) {
txnIDs.add(uncommittedTransactionId);
}
}
}
return splits;
}
Code review comment: What about the distributor!? :)

Code before review:
private StorageNode buildSingleNode(DeployState deployState, ContentCluster parent) {
int distributionKey = 0;
StorageNode sNode = new StorageNode(deployState.getProperties(), parent.getStorageCluster(), 1.0, distributionKey , false);
sNode.setHostResource(parent.hostSystem().getHost(Container.SINGLENODE_CONTAINER_SERVICESPEC));
sNode.initService(deployLogger);
PersistenceEngine provider = parent.getPersistence().create(deployState, sNode, storageGroup, null);
new Distributor(deployState.getProperties(), parent.getDistributorNodes(), distributionKey, null, provider);
return sNode;
}

Line under review: sNode.initService(deployLogger);

Code after addressing the review:
private StorageNode buildSingleNode(DeployState deployState, ContentCluster parent) {
int distributionKey = 0;
StorageNode searchNode = new StorageNode(deployState.getProperties(), parent.getStorageCluster(), 1.0, distributionKey , false);
searchNode.setHostResource(parent.hostSystem().getHost(Container.SINGLENODE_CONTAINER_SERVICESPEC));
PersistenceEngine provider = parent.getPersistence().create(deployState, searchNode, storageGroup, null);
searchNode.initService(deployLogger);
Distributor distributor = new Distributor(deployState.getProperties(), parent.getDistributorNodes(), distributionKey, null, provider);
distributor.setHostResource(searchNode.getHostResource());
distributor.initService(deployLogger);
return searchNode;
}
Code review comment: Shall we pass the logger from outside instead of expose it as `public/(default)`?

Code before review:
private void cleanup() throws Exception {
StreamTask.LOG.debug(
"Cleanup AsyncCheckpointRunnable for checkpoint {} of {}.",
checkpointMetaData.getCheckpointId(),
taskName);
Exception exception = null;
for (OperatorSnapshotFutures operatorSnapshotResult : operatorSnapshotsInProgress.values()) {
if (operatorSnapshotResult != null) {
try {
operatorSnapshotResult.cancel();
} catch (Exception cancelException) {
exception = ExceptionUtils.firstOrSuppressed(cancelException, exception);
}
}
}
if (null != exception) {
throw exception;
}
}

Line under review: StreamTask.LOG.debug(

Code after addressing the review:
private void cleanup() throws Exception {
LOG.debug(
"Cleanup AsyncCheckpointRunnable for checkpoint {} of {}.",
checkpointMetaData.getCheckpointId(),
taskName);
Exception exception = null;
for (OperatorSnapshotFutures operatorSnapshotResult : operatorSnapshotsInProgress.values()) {
if (operatorSnapshotResult != null) {
try {
operatorSnapshotResult.cancel();
} catch (Exception cancelException) {
exception = ExceptionUtils.firstOrSuppressed(cancelException, exception);
}
}
}
if (null != exception) {
throw exception;
}
}
Code review comment: Now we need to check for null here too.

Code before review:
private void ensureClusterTableIsUpdated() {
try {
if (0 == engine.get().getStatus(newContext().getCairoSecurityContext(), new Path(), clusterTable.name)) {
}
} catch (Exception e) {
clusterTable.repair(e);
}
}

Line under review: if (0 == engine.get().getStatus(newContext().getCairoSecurityContext(), new Path(), clusterTable.name)) {

Code after addressing the review:
private void ensureClusterTableIsUpdated() {
try {
if (0 == engine().getStatus(newContext().getCairoSecurityContext(), new Path(), clusterTable.name)) {
}
} catch (Exception e) {
clusterTable.repair(e);
}
}
Code review comment: Yes, `Mono.just` would work but `Mono.fromCallable` further defers the creation of `AccessToken`, so if the reactive stream is never subscribed the `AccessToken` is never instantiated.

Code before review:
public Mono<AccessToken> getToken(TokenRequestContext request) {
return Mono.fromCallable(() -> new AccessToken(encodedCredential, OffsetDateTime.MAX));
}

Line under review: return Mono.fromCallable(() -> new AccessToken(encodedCredential, OffsetDateTime.MAX));

Code after addressing the review:
public Mono<AccessToken> getToken(TokenRequestContext request) {
return Mono.fromCallable(() -> new AccessToken(encodedCredential, OffsetDateTime.MAX));
}
Code review comment: Both surrogate pairs have their sign bits at 1 so they can't be mistaken for the ascii we're replacing, so we're good.

Code before review:
private String doEscape(CharSequence value, int index, StringBuilder builder) {
int length = value.length();
while (++index < length) {
char c = value.charAt(index);
String replacement = replacements.get(c);
if (replacement != null) {
builder.append(replacement);
} else {
builder.append(c);
}
}
return builder.toString();
}

Line under review: char c = value.charAt(index);

Code after addressing the review:
private String doEscape(CharSequence value, int index, StringBuilder builder) {
int length = value.length();
while (++index < length) {
char c = value.charAt(index);
String replacement = replacements.get(c);
if (replacement != null) {
builder.append(replacement);
} else {
builder.append(c);
}
}
return builder.toString();
}
Code review comment: In the more general context, "this" in the presence of lambdas is tricky and could lead to bugs. I've probably had such case here as well before settling to the final code.

Code before review:
public Mono<Void> processChanges(ChangeFeedObserverContext context, List<CosmosItemProperties> docs) {
AutoCheckpointer self = this;
return self.observer.processChanges(context, docs)
.then(self.afterProcessChanges(context));
}

Line under review: AutoCheckpointer self = this;

Code after addressing the review:
public Mono<Void> processChanges(ChangeFeedObserverContext context, List<CosmosItemProperties> docs) {
return this.observer.processChanges(context, docs)
.then(this.afterProcessChanges(context));
}
Code review comment: I didn't add a unit test as after the other fixes in master (#14052) this change is not strictly necessary (though I think it's still less error-prone to not update SQN unnecessarily).

Code before review:
public void onBuffer(Buffer buffer, int sequenceNumber, int backlog) throws IOException {
boolean recycleBuffer = true;
try {
if (expectedSequenceNumber != sequenceNumber) {
onError(new BufferReorderingException(expectedSequenceNumber, sequenceNumber));
return;
}
final boolean wasEmpty;
boolean firstPriorityEvent = false;
synchronized (receivedBuffers) {
if (isReleased.get()) {
return;
}
wasEmpty = receivedBuffers.isEmpty();
SequenceBuffer sequenceBuffer = new SequenceBuffer(buffer, sequenceNumber);
DataType dataType = buffer.getDataType();
if (dataType.hasPriority()) {
firstPriorityEvent = addPriorityBuffer(sequenceBuffer);
}
else {
receivedBuffers.add(sequenceBuffer);
if (dataType.requiresAnnouncement()) {
firstPriorityEvent = addPriorityBuffer(announce(sequenceBuffer));
}
}
channelStatePersister.checkForBarrier(sequenceBuffer.buffer).ifPresent(id -> {
lastBarrierSequenceNumber = sequenceBuffer.sequenceNumber;
lastBarrierId = id;
});
channelStatePersister.maybePersist(buffer);
++expectedSequenceNumber;
}
recycleBuffer = false;
if (firstPriorityEvent) {
notifyPriorityEvent(sequenceNumber);
}
if (wasEmpty) {
notifyChannelNonEmpty();
}
if (backlog >= 0) {
onSenderBacklog(backlog);
}
} finally {
if (recycleBuffer) {
buffer.recycleBuffer();
}
}
}

Line under review: recycleBuffer = false;

Code after addressing the review:
public void onBuffer(Buffer buffer, int sequenceNumber, int backlog) throws IOException {
boolean recycleBuffer = true;
try {
if (expectedSequenceNumber != sequenceNumber) {
onError(new BufferReorderingException(expectedSequenceNumber, sequenceNumber));
return;
}
final boolean wasEmpty;
boolean firstPriorityEvent = false;
synchronized (receivedBuffers) {
if (isReleased.get()) {
return;
}
wasEmpty = receivedBuffers.isEmpty();
SequenceBuffer sequenceBuffer = new SequenceBuffer(buffer, sequenceNumber);
DataType dataType = buffer.getDataType();
if (dataType.hasPriority()) {
firstPriorityEvent = addPriorityBuffer(sequenceBuffer);
}
else {
receivedBuffers.add(sequenceBuffer);
if (dataType.requiresAnnouncement()) {
firstPriorityEvent = addPriorityBuffer(announce(sequenceBuffer));
}
}
channelStatePersister
.checkForBarrier(sequenceBuffer.buffer)
.filter(id -> id > lastBarrierId)
.ifPresent(id -> {
lastBarrierId = id;
lastBarrierSequenceNumber = sequenceBuffer.sequenceNumber;
});
channelStatePersister.maybePersist(buffer);
++expectedSequenceNumber;
}
recycleBuffer = false;
if (firstPriorityEvent) {
notifyPriorityEvent(sequenceNumber);
}
if (wasEmpty) {
notifyChannelNonEmpty();
}
if (backlog >= 0) {
onSenderBacklog(backlog);
}
} finally {
if (recycleBuffer) {
buffer.recycleBuffer();
}
}
}
Code review comment: Do we want to keep the `catch` and log the testing error?

Code before review:
public void intercept(IMethodInvocation invocation) throws Throwable {
String testName = TestNameProvider.getTestName(invocation.getIteration());
System.out.printf("%s is starting", testName);
long startTimestamp = System.currentTimeMillis();
try {
invocation.proceed();
} finally {
long duration = System.currentTimeMillis() - startTimestamp;
System.out.printf("%s finished and took %d ms", testName, duration);
}
}

Line under review: } finally {

Code after addressing the review:
public void intercept(IMethodInvocation invocation) throws Throwable {
String testName = TestNameProvider.getTestName(invocation.getIteration());
System.out.printf("%s is starting%n", testName);
LOGGER.info("{} is starting", testName);
long startTimestamp = System.currentTimeMillis();
try {
invocation.proceed();
} finally {
long duration = System.currentTimeMillis() - startTimestamp;
System.out.printf("%s finished and took %d ms%n", testName, duration);
LOGGER.info("{} finished and took {} ms", testName, duration);
}
}
Code review comment: The base class' ChangeFeedStartFromInternal.populatePropertyBag is a no-op as is its baseclass JsonSerializable's populatePropertyBag method.

Code before review:
public void populatePropertyBag() {
super.populatePropertyBag();
synchronized(this) {
setProperty(
this,
Constants.Properties.CHANGE_FEED_START_FROM_TYPE,
ChangeFeedStartFromTypes.NOW);
}
}

Line under review: super.populatePropertyBag();

Code after addressing the review:
public void populatePropertyBag() {
super.populatePropertyBag();
synchronized(this) {
setProperty(
this,
Constants.Properties.CHANGE_FEED_START_FROM_TYPE,
ChangeFeedStartFromTypes.NOW);
}
}