pip/pip-280.md
In the current Pulsar codebase, the logic to parse CLI arguments for measurement units like time and bytes is scattered across various CLI classes. Each value read has its distinct parsing implementation, leading to a lack of code reuse.
This PIP is to refactor the argument parsing logic to leverage the @Parameter.converter
functionality provided by JCommander [link 3]. This will isolate the measurement-specific parsing logic and increase
code
reusability.
Cmd classes to utilize the converter functionality of JCommander. This will streamline the parsing
logic and simplify the codebase.CmdNamespaces.javaCmdTopics.java,CmdTopicPolicies.java.Consider the code snippet
from CmdNamespaces.java
for example. The existing code uses a local variable maxBlockSizeStr to temporarily store the value
of --maxBlockSize or -mbs. This is then parsed and validated in a separate section of the code.
@Parameter(
names = {"--maxBlockSize", "-mbs"},
description = "Max block size (eg: 32M, 64M), default is 64MB s3 and google-cloud-storage requires this parameter",
required = false)
private String maxBlockSizeStr;
parsing like below ....
// parsing like....
int maxBlockSizeInBytes=OffloadPoliciesImpl.DEFAULT_MAX_BLOCK_SIZE_IN_BYTES;
if(StringUtils.isNotEmpty(maxBlockSizeStr)){
long maxBlockSize=validateSizeString(maxBlockSizeStr);
if(positiveCheck("MaxBlockSize",maxBlockSize)
&&maxValueCheck("MaxBlockSize",maxBlockSize,Integer.MAX_VALUE)) {
maxBlockSizeInBytes=Long.valueOf(maxBlockSize).intValue();
}
}
@Parameter(
names = {"--maxBlockSize", "-mbs"},
description = "Max block size (eg: 32M, 64M), default is 64MB s3 and google-cloud-storage requires this parameter",
required = false, converter = MemoryUnitToByteConverter.class) // <--- parsing logic "inline" easy to follow
private long maxBlockSizeStr=DEFAULT_MAX_BLOCK_SIZE_IN_BYTES; // <---- default value in line
... and actual parsing in isolation, ready for reuse like...
class MemoryUnitToByteConverter implements IStringConverter<Long> {
private static Set<Character> sizeUnit = Sets.newHashSet('k', 'K', 'm', 'M', 'g', 'G', 't', 'T');
private final long defaultValue;
public MemoryUnitToByteConverter(long defaultValue) {
this.defaultValue = defaultValue;
}
@Override
public Long convert(String memoryLimitArgument) {
parseBytes(memoryLimitArgument);
}
long parseBytes(String memoryLimitArgument) {
if (StringUtils.isNotEmpty(memoryLimitArgument)) {
long memoryLimitArg = validateSizeString(memoryLimitArgument);
if (positiveCheckStatic("memory-limit", memoryLimitArg)) {
return memoryLimitArg;
}
}
return defaultValue;
}
...
more internal
helper methods
}