[PIE-1737] Simplify PantheonCommand `run` and `parse` methods. (#1626)

* split parse method

- handleStandaloneCommand
- addSubCommands
- registerConverters
- handleUnstableOptions
- preparePlugins
- parse

* split run method

-checkOptions
- configure
- controller
- startPlugins
- startSynchronization

* Update PantheonCommand.java

Signed-off-by: Adrian Sutton <adrian.sutton@consensys.net>
pull/2/head
Abdelhamid Bakhta 5 years ago committed by GitHub
parent 4528956d07
commit ff95eaeecc
  1. 170
      pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java

@ -568,6 +568,15 @@ public class PantheonCommand implements DefaultCommandValues, Runnable {
arity = "1") arity = "1")
private final Integer pendingTxRetentionPeriod = PendingTransactions.DEFAULT_TX_RETENTION_HOURS; private final Integer pendingTxRetentionPeriod = PendingTransactions.DEFAULT_TX_RETENTION_HOURS;
private EthNetworkConfig ethNetworkConfig;
private JsonRpcConfiguration jsonRpcConfiguration;
private GraphQLConfiguration graphQLConfiguration;
private WebSocketConfiguration webSocketConfiguration;
private MetricsConfiguration metricsConfiguration;
private Optional<PermissioningConfiguration> permissioningConfiguration;
private Collection<EnodeURL> staticNodes;
private PantheonController<?> pantheonController;
// Inner class so we can get to loggingLevel. // Inner class so we can get to loggingLevel.
public class PantheonExceptionHandler public class PantheonExceptionHandler
extends CommandLine.AbstractHandler<List<Object>, PantheonExceptionHandler> extends CommandLine.AbstractHandler<List<Object>, PantheonExceptionHandler>
@ -633,17 +642,36 @@ public class PantheonCommand implements DefaultCommandValues, Runnable {
final PantheonExceptionHandler exceptionHandler, final PantheonExceptionHandler exceptionHandler,
final InputStream in, final InputStream in,
final String... args) { final String... args) {
commandLine = new CommandLine(this).setCaseInsensitiveEnumValuesAllowed(true);
handleStandaloneCommand()
.addSubCommands(resultHandler, in)
.registerConverters()
.handleUnstableOptions()
.preparePlugins()
.parse(resultHandler, exceptionHandler, args);
}
commandLine = new CommandLine(this); @Override
public void run() {
commandLine.setCaseInsensitiveEnumValuesAllowed(true); try {
prepareLogging();
logger.info("Starting Pantheon version: {}", PantheonInfo.version());
checkOptions().configure().controller().startPlugins().startSynchronization();
} catch (final Exception e) {
throw new ParameterException(this.commandLine, e.getMessage(), e);
}
}
private PantheonCommand handleStandaloneCommand() {
standaloneCommands = new StandaloneCommand(); standaloneCommands = new StandaloneCommand();
if (isFullInstantiation()) { if (isFullInstantiation()) {
commandLine.addMixin("standaloneCommands", standaloneCommands); commandLine.addMixin("standaloneCommands", standaloneCommands);
} }
return this;
}
private PantheonCommand addSubCommands(
final AbstractParseResultHandler<List<Object>> resultHandler, final InputStream in) {
commandLine.addSubcommand( commandLine.addSubcommand(
BlocksSubCommand.COMMAND_NAME, new BlocksSubCommand(blockImporter, resultHandler.out())); BlocksSubCommand.COMMAND_NAME, new BlocksSubCommand(blockImporter, resultHandler.out()));
commandLine.addSubcommand( commandLine.addSubcommand(
@ -655,7 +683,10 @@ public class PantheonCommand implements DefaultCommandValues, Runnable {
RLPSubCommand.COMMAND_NAME, new RLPSubCommand(resultHandler.out(), in)); RLPSubCommand.COMMAND_NAME, new RLPSubCommand(resultHandler.out(), in));
commandLine.addSubcommand( commandLine.addSubcommand(
OperatorSubCommand.COMMAND_NAME, new OperatorSubCommand(resultHandler.out())); OperatorSubCommand.COMMAND_NAME, new OperatorSubCommand(resultHandler.out()));
return this;
}
private PantheonCommand registerConverters() {
commandLine.registerConverter(Address.class, Address::fromHexStringStrict); commandLine.registerConverter(Address.class, Address::fromHexStringStrict);
commandLine.registerConverter(BytesValue.class, BytesValue::fromHexString); commandLine.registerConverter(BytesValue.class, BytesValue::fromHexString);
commandLine.registerConverter(Level.class, Level::valueOf); commandLine.registerConverter(Level.class, Level::valueOf);
@ -663,13 +694,15 @@ public class PantheonCommand implements DefaultCommandValues, Runnable {
commandLine.registerConverter(UInt256.class, (arg) -> UInt256.of(new BigInteger(arg))); commandLine.registerConverter(UInt256.class, (arg) -> UInt256.of(new BigInteger(arg)));
commandLine.registerConverter(Wei.class, (arg) -> Wei.of(Long.parseUnsignedLong(arg))); commandLine.registerConverter(Wei.class, (arg) -> Wei.of(Long.parseUnsignedLong(arg)));
commandLine.registerConverter(PositiveNumber.class, PositiveNumber::fromString); commandLine.registerConverter(PositiveNumber.class, PositiveNumber::fromString);
final MetricCategoryConverter metricCategoryConverter = new MetricCategoryConverter(); final MetricCategoryConverter metricCategoryConverter = new MetricCategoryConverter();
metricCategoryConverter.addCategories(PantheonMetricCategory.class); metricCategoryConverter.addCategories(PantheonMetricCategory.class);
metricCategoryConverter.addCategories(StandardMetricCategory.class); metricCategoryConverter.addCategories(StandardMetricCategory.class);
commandLine.registerConverter(MetricCategory.class, metricCategoryConverter); commandLine.registerConverter(MetricCategory.class, metricCategoryConverter);
return this;
}
// Add performance options private PantheonCommand handleUnstableOptions() {
// Add unstable options
UnstableOptionsSubCommand.createUnstableOptions( UnstableOptionsSubCommand.createUnstableOptions(
commandLine, commandLine,
ImmutableMap.of( ImmutableMap.of(
@ -681,10 +714,19 @@ public class PantheonCommand implements DefaultCommandValues, Runnable {
ethereumWireConfigurationBuilder, ethereumWireConfigurationBuilder,
"TransactionPool", "TransactionPool",
transactionPoolConfigurationBuilder)); transactionPoolConfigurationBuilder));
return this;
}
private PantheonCommand preparePlugins() {
pantheonPluginContext.addService(PicoCLIOptions.class, new PicoCLIOptionsImpl(commandLine)); pantheonPluginContext.addService(PicoCLIOptions.class, new PicoCLIOptionsImpl(commandLine));
pantheonPluginContext.registerPlugins(pluginsDir()); pantheonPluginContext.registerPlugins(pluginsDir());
return this;
}
private PantheonCommand parse(
final AbstractParseResultHandler<List<Object>> resultHandler,
final PantheonExceptionHandler exceptionHandler,
final String... args) {
// Create a handler that will search for a config file option and use it for // Create a handler that will search for a config file option and use it for
// default values // default values
// and eventually it will run regular parsing of the remaining options. // and eventually it will run regular parsing of the remaining options.
@ -692,18 +734,44 @@ public class PantheonCommand implements DefaultCommandValues, Runnable {
new ConfigOptionSearchAndRunHandler( new ConfigOptionSearchAndRunHandler(
resultHandler, exceptionHandler, CONFIG_FILE_OPTION_NAME, environment, isDocker); resultHandler, exceptionHandler, CONFIG_FILE_OPTION_NAME, environment, isDocker);
commandLine.parseWithHandlers(configParsingHandler, exceptionHandler, args); commandLine.parseWithHandlers(configParsingHandler, exceptionHandler, args);
return this;
} }
@Override private PantheonCommand startSynchronization() {
public void run() { synchronize(
pantheonController,
p2pEnabled,
peerDiscoveryEnabled,
ethNetworkConfig,
maxPeers,
p2pHost,
p2pPort,
graphQLConfiguration,
jsonRpcConfiguration,
webSocketConfiguration,
metricsConfiguration,
permissioningConfiguration,
staticNodes);
return this;
}
private PantheonCommand startPlugins() {
pantheonPluginContext.addService(
PantheonEvents.class,
new PantheonEventsImpl((pantheonController.getProtocolManager().getBlockBroadcaster())));
pantheonPluginContext.startPlugins();
return this;
}
private void prepareLogging() {
// set log level per CLI flags // set log level per CLI flags
if (logLevel != null) { if (logLevel != null) {
System.out.println("Setting logging level to " + logLevel.name()); System.out.println("Setting logging level to " + logLevel.name());
Configurator.setAllLevels("", logLevel); Configurator.setAllLevels("", logLevel);
} }
}
logger.info("Starting Pantheon version: {}", PantheonInfo.version()); private PantheonCommand checkOptions() {
// Check that P2P options are able to work or send an error // Check that P2P options are able to work or send an error
checkOptionDependencies( checkOptionDependencies(
logger, logger,
@ -739,59 +807,32 @@ public class PantheonCommand implements DefaultCommandValues, Runnable {
"Unable to mine without a valid coinbase. Either disable mining (remove --miner-enabled)" "Unable to mine without a valid coinbase. Either disable mining (remove --miner-enabled)"
+ "or specify the beneficiary of mining (via --miner-coinbase <Address>)"); + "or specify the beneficiary of mining (via --miner-coinbase <Address>)");
} }
return this;
}
final EthNetworkConfig ethNetworkConfig = updateNetworkConfig(getNetwork()); private PantheonCommand configure() throws Exception {
try { ethNetworkConfig = updateNetworkConfig(getNetwork());
final JsonRpcConfiguration jsonRpcConfiguration = jsonRpcConfiguration(); jsonRpcConfiguration = jsonRpcConfiguration();
final GraphQLConfiguration graphQLConfiguration = graphQLConfiguration(); graphQLConfiguration = graphQLConfiguration();
final WebSocketConfiguration webSocketConfiguration = webSocketConfiguration(); webSocketConfiguration = webSocketConfiguration();
final Optional<PermissioningConfiguration> permissioningConfiguration = permissioningConfiguration = permissioningConfiguration();
permissioningConfiguration(); staticNodes = loadStaticNodes();
logger.info("Connecting to {} static nodes.", staticNodes.size());
final Collection<EnodeURL> staticNodes = loadStaticNodes(); logger.trace("Static Nodes = {}", staticNodes);
logger.info("Connecting to {} static nodes.", staticNodes.size()); final List<URI> enodeURIs =
logger.trace("Static Nodes = {}", staticNodes); ethNetworkConfig.getBootNodes().stream().map(EnodeURL::toURI).collect(Collectors.toList());
permissioningConfiguration
final List<URI> enodeURIs = .flatMap(PermissioningConfiguration::getLocalConfig)
ethNetworkConfig.getBootNodes().stream() .ifPresent(p -> ensureAllNodesAreInWhitelist(enodeURIs, p));
.map(EnodeURL::toURI)
.collect(Collectors.toList()); permissioningConfiguration
permissioningConfiguration .flatMap(PermissioningConfiguration::getLocalConfig)
.flatMap(PermissioningConfiguration::getLocalConfig) .ifPresent(
.ifPresent(p -> ensureAllNodesAreInWhitelist(enodeURIs, p)); p ->
ensureAllNodesAreInWhitelist(
permissioningConfiguration staticNodes.stream().map(EnodeURL::toURI).collect(Collectors.toList()), p));
.flatMap(PermissioningConfiguration::getLocalConfig) metricsConfiguration = metricsConfiguration();
.ifPresent( return this;
p ->
ensureAllNodesAreInWhitelist(
staticNodes.stream().map(EnodeURL::toURI).collect(Collectors.toList()), p));
final PantheonController<?> pantheonController = buildController();
final MetricsConfiguration metricsConfiguration = metricsConfiguration();
pantheonPluginContext.addService(
PantheonEvents.class,
new PantheonEventsImpl((pantheonController.getProtocolManager().getBlockBroadcaster())));
pantheonPluginContext.startPlugins();
synchronize(
pantheonController,
p2pEnabled,
peerDiscoveryEnabled,
ethNetworkConfig,
maxPeers,
p2pHost,
p2pPort,
graphQLConfiguration,
jsonRpcConfiguration,
webSocketConfiguration,
metricsConfiguration,
permissioningConfiguration,
staticNodes);
} catch (final Exception e) {
throw new ParameterException(this.commandLine, e.getMessage(), e);
}
} }
private NetworkName getNetwork() { private NetworkName getNetwork() {
@ -811,6 +852,11 @@ public class PantheonCommand implements DefaultCommandValues, Runnable {
} }
} }
private PantheonCommand controller() {
pantheonController = buildController();
return this;
}
PantheonController<?> buildController() { PantheonController<?> buildController() {
try { try {
return controllerBuilderFactory return controllerBuilderFactory

Loading…
Cancel
Save