From 888aad447cde765f8f39d1b2bf81c9c6a42d8eee Mon Sep 17 00:00:00 2001 From: Clement Escoffier Date: Tue, 29 Mar 2016 16:50:29 +0200 Subject: [PATCH] Fix #1346 Execute the command specified in the manifest if set and not overriden in the command line. Signed-off-by: Clement Escoffier --- src/main/asciidoc/dataobjects.adoc | 282 +++++++++--------- .../impl/launcher/VertxCommandLauncher.java | 16 +- src/test/asciidoc/dataobjects.adoc | 30 +- .../java/io/vertx/test/core/LauncherTest.java | 50 +++- .../MANIFEST-Launcher-Default-Command.MF | 2 + .../META-INF/MANIFEST-Launcher-run.MF | 2 + 6 files changed, 223 insertions(+), 159 deletions(-) create mode 100644 src/test/resources/META-INF/MANIFEST-Launcher-Default-Command.MF create mode 100644 src/test/resources/META-INF/MANIFEST-Launcher-run.MF diff --git a/src/main/asciidoc/dataobjects.adoc b/src/main/asciidoc/dataobjects.adoc index bda71c5afca..d138d9a6a1a 100644 --- a/src/main/asciidoc/dataobjects.adoc +++ b/src/main/asciidoc/dataobjects.adoc @@ -1,10 +1,13 @@ = Cheatsheets -[[NetworkOptions]] -== NetworkOptions +[[DeliveryOptions]] +== DeliveryOptions ++++ - @author Tim Fox + Delivery options are used to configure message delivery. +

+ Delivery options allow to configure delivery timeout and message codec name, and to provide any headers + that you wish to send with the message. ++++ ''' @@ -12,32 +15,21 @@ [frame="topbot"] |=== ^|Name | Type ^| Description -|[[receiveBufferSize]]`receiveBufferSize`|`Number (int)`| -+++ -Set the TCP receive buffer size -+++ -|[[reuseAddress]]`reuseAddress`|`Boolean`| -+++ -Set the value of reuse address -+++ -|[[sendBufferSize]]`sendBufferSize`|`Number (int)`| +|[[codecName]]`codecName`|`String`| +++ -Set the TCP send buffer size +Set the codec name. +++ -|[[trafficClass]]`trafficClass`|`Number (int)`| +|[[sendTimeout]]`sendTimeout`|`Number (long)`| +++ -Set the value of traffic class +Set the send timeout. +++ |=== -[[DeliveryOptions]] -== DeliveryOptions +[[NetworkOptions]] +== NetworkOptions ++++ - Delivery options are used to configure message delivery. -

- Delivery options allow to configure delivery timeout and message codec name, and to provide any headers - that you wish to send with the message. + @author Tim Fox ++++ ''' @@ -45,13 +37,21 @@ Set the value of traffic class [frame="topbot"] |=== ^|Name | Type ^| Description -|[[codecName]]`codecName`|`String`| +|[[receiveBufferSize]]`receiveBufferSize`|`Number (int)`| +++ -Set the codec name. +Set the TCP receive buffer size +++ -|[[sendTimeout]]`sendTimeout`|`Number (long)`| +|[[reuseAddress]]`reuseAddress`|`Boolean`| +++ -Set the send timeout. +Set the value of reuse address ++++ +|[[sendBufferSize]]`sendBufferSize`|`Number (int)`| ++++ +Set the TCP send buffer size ++++ +|[[trafficClass]]`trafficClass`|`Number (int)`| ++++ +Set the value of traffic class +++ |=== @@ -626,25 +626,6 @@ Set whether Netty pooled buffers are enabled +++ |=== -[[MetricsOptions]] -== MetricsOptions - -++++ - Vert.x metrics base configuration, this class can be extended by provider implementations to configure - those specific implementations. -++++ -''' - -[cols=">25%,^25%,50%"] -[frame="topbot"] -|=== -^|Name | Type ^| Description -|[[enabled]]`enabled`|`Boolean`| -+++ -Set whether metrics will be enabled on the Vert.x instance. -+++ -|=== - [[ClientOptionsBase]] == ClientOptionsBase @@ -744,6 +725,25 @@ Set whether Netty pooled buffers are enabled +++ |=== +[[MetricsOptions]] +== MetricsOptions + +++++ + Vert.x metrics base configuration, this class can be extended by provider implementations to configure + those specific implementations. +++++ +''' + +[cols=">25%,^25%,50%"] +[frame="topbot"] +|=== +^|Name | Type ^| Description +|[[enabled]]`enabled`|`Boolean`| ++++ +Set whether metrics will be enabled on the Vert.x instance. ++++ +|=== + [[DeploymentOptions]] == DeploymentOptions @@ -1002,11 +1002,11 @@ Set the websocket subprotocols supported by the server. +++ |=== -[[EventBusOptions]] -== EventBusOptions +[[HttpClientOptions]] +== HttpClientOptions ++++ - Options to configure the event bus. + Options describing how an link will make connections. ++++ ''' @@ -1014,68 +1014,59 @@ Set the websocket subprotocols supported by the server. [frame="topbot"] |=== ^|Name | Type ^| Description -|[[acceptBacklog]]`acceptBacklog`|`Number (int)`| -+++ -Set the accept back log. -+++ -|[[clientAuth]]`clientAuth`|`link:enums.html#ClientAuth[ClientAuth]`| +|[[connectTimeout]]`connectTimeout`|`Number (int)`| +++ -Set whether client auth is required +Set the connect timeout +++ -|[[clusterPingInterval]]`clusterPingInterval`|`Number (long)`| +|[[crlPaths]]`crlPaths`|`Array of String`| +++ -Set the value of cluster ping interval, in ms. +Add a CRL path +++ -|[[clusterPingReplyInterval]]`clusterPingReplyInterval`|`Number (long)`| +|[[crlValues]]`crlValues`|`Array of Buffer`| +++ -Set the value of cluster ping reply interval, in ms. +Add a CRL value +++ -|[[clusterPublicHost]]`clusterPublicHost`|`String`| +|[[defaultHost]]`defaultHost`|`String`| +++ -Set the public facing hostname to be used for clustering. - Sometimes, e.g. when running on certain clouds, the local address the server listens on for clustering is - not the same address that other nodes connect to it at, as the OS / cloud infrastructure does some kind of - proxying. If this is the case you can specify a public hostname which is different from the hostname the - server listens at. -

- The default value is null which means use the same as the cluster hostname. +Set the default host name to be used by this client in requests if none is provided when making the request. +++ -|[[clusterPublicPort]]`clusterPublicPort`|`Number (int)`| +|[[defaultPort]]`defaultPort`|`Number (int)`| +++ -See link for an explanation. +Set the default port to be used by this client in requests if none is provided when making the request. +++ -|[[clustered]]`clustered`|`Boolean`| +|[[enabledCipherSuites]]`enabledCipherSuites`|`Array of String`| +++ -Sets whether or not the event bus is clustered. +Add an enabled cipher suite +++ -|[[connectTimeout]]`connectTimeout`|`Number (int)`| +|[[idleTimeout]]`idleTimeout`|`Number (int)`| +++ -Sets the connect timeout +Set the idle timeout, in seconds. zero means don't timeout. + This determines if a connection will timeout and be closed if no data is received within the timeout. +++ -|[[crlPaths]]`crlPaths`|`Array of String`| +|[[keepAlive]]`keepAlive`|`Boolean`| +++ -Add a CRL path +Set whether keep alive is enabled on the client +++ -|[[crlValues]]`crlValues`|`Array of Buffer`| +|[[keyStoreOptions]]`keyStoreOptions`|`link:dataobjects.html#JksOptions[JksOptions]`| +++ -Add a CRL value +Set the key/cert options in jks format, aka Java keystore. +++ -|[[enabledCipherSuites]]`enabledCipherSuites`|`Array of String`| +|[[maxChunkSize]]`maxChunkSize`|`Number (int)`| +++ -Add an enabled cipher suite +Set the maximum HTTP chunk size +++ -|[[host]]`host`|`String`| +|[[maxPoolSize]]`maxPoolSize`|`Number (int)`| +++ -Sets the host. +Set the maximum pool size for connections +++ -|[[idleTimeout]]`idleTimeout`|`Number (int)`| +|[[maxWaitQueueSize]]`maxWaitQueueSize`|`Number (int)`| +++ -Set the idle timeout, in seconds. zero means don't timeout. - This determines if a connection will timeout and be closed if no data is received within the timeout. +Set the maximum requests allowed in the wait queue, any requests beyond the max size will result in + a ConnectionPoolTooBusyException. If the value is set to a negative number then the queue will be unbounded. +++ -|[[keyStoreOptions]]`keyStoreOptions`|`link:dataobjects.html#JksOptions[JksOptions]`| +|[[maxWebsocketFrameSize]]`maxWebsocketFrameSize`|`Number (int)`| +++ -Set the key/cert options in jks format, aka Java keystore. +Set the max websocket frame size +++ |[[pemKeyCertOptions]]`pemKeyCertOptions`|`link:dataobjects.html#PemKeyCertOptions[PemKeyCertOptions]`| +++ @@ -1093,21 +1084,17 @@ Set the key/cert options in pfx format. +++ Set the trust options in pfx format +++ -|[[port]]`port`|`Number (int)`| -+++ -Sets the port. -+++ -|[[receiveBufferSize]]`receiveBufferSize`|`Number (int)`| +|[[pipelining]]`pipelining`|`Boolean`| +++ -Set the TCP receive buffer size +Set whether pipe-lining is enabled on the client +++ -|[[reconnectAttempts]]`reconnectAttempts`|`Number (int)`| +|[[protocolVersion]]`protocolVersion`|`link:enums.html#HttpVersion[HttpVersion]`| +++ -Sets the value of reconnect attempts. +Set the protocol version. +++ -|[[reconnectInterval]]`reconnectInterval`|`Number (long)`| +|[[receiveBufferSize]]`receiveBufferSize`|`Number (int)`| +++ -Set the reconnect interval. +Set the TCP receive buffer size +++ |[[reuseAddress]]`reuseAddress`|`Boolean`| +++ @@ -1139,16 +1126,24 @@ Set the value of traffic class +++ |[[trustAll]]`trustAll`|`Boolean`| +++ -Set whether all server certificates should be trusted. +Set whether all server certificates should be trusted +++ |[[trustStoreOptions]]`trustStoreOptions`|`link:dataobjects.html#JksOptions[JksOptions]`| +++ Set the trust options in jks format, aka Java trustore +++ +|[[tryUseCompression]]`tryUseCompression`|`Boolean`| ++++ +Set whether compression is enabled ++++ |[[usePooledBuffers]]`usePooledBuffers`|`Boolean`| +++ Set whether Netty pooled buffers are enabled +++ +|[[verifyHost]]`verifyHost`|`Boolean`| ++++ +Set whether hostname verification is enabled ++++ |=== [[DatagramSocketOptions]] @@ -1201,11 +1196,11 @@ Set the value of traffic class +++ |=== -[[HttpClientOptions]] -== HttpClientOptions +[[EventBusOptions]] +== EventBusOptions ++++ - Options describing how an link will make connections. + Options to configure the event bus. ++++ ''' @@ -1213,59 +1208,68 @@ Set the value of traffic class [frame="topbot"] |=== ^|Name | Type ^| Description -|[[connectTimeout]]`connectTimeout`|`Number (int)`| +|[[acceptBacklog]]`acceptBacklog`|`Number (int)`| +++ -Set the connect timeout +Set the accept back log. +++ -|[[crlPaths]]`crlPaths`|`Array of String`| +|[[clientAuth]]`clientAuth`|`link:enums.html#ClientAuth[ClientAuth]`| +++ -Add a CRL path +Set whether client auth is required +++ -|[[crlValues]]`crlValues`|`Array of Buffer`| +|[[clusterPingInterval]]`clusterPingInterval`|`Number (long)`| +++ -Add a CRL value +Set the value of cluster ping interval, in ms. +++ -|[[defaultHost]]`defaultHost`|`String`| +|[[clusterPingReplyInterval]]`clusterPingReplyInterval`|`Number (long)`| +++ -Set the default host name to be used by this client in requests if none is provided when making the request. +Set the value of cluster ping reply interval, in ms. +++ -|[[defaultPort]]`defaultPort`|`Number (int)`| +|[[clusterPublicHost]]`clusterPublicHost`|`String`| +++ -Set the default port to be used by this client in requests if none is provided when making the request. +Set the public facing hostname to be used for clustering. + Sometimes, e.g. when running on certain clouds, the local address the server listens on for clustering is + not the same address that other nodes connect to it at, as the OS / cloud infrastructure does some kind of + proxying. If this is the case you can specify a public hostname which is different from the hostname the + server listens at. +

+ The default value is null which means use the same as the cluster hostname. +++ -|[[enabledCipherSuites]]`enabledCipherSuites`|`Array of String`| +|[[clusterPublicPort]]`clusterPublicPort`|`Number (int)`| +++ -Add an enabled cipher suite +See link for an explanation. +++ -|[[idleTimeout]]`idleTimeout`|`Number (int)`| +|[[clustered]]`clustered`|`Boolean`| +++ -Set the idle timeout, in seconds. zero means don't timeout. - This determines if a connection will timeout and be closed if no data is received within the timeout. +Sets whether or not the event bus is clustered. +++ -|[[keepAlive]]`keepAlive`|`Boolean`| +|[[connectTimeout]]`connectTimeout`|`Number (int)`| +++ -Set whether keep alive is enabled on the client +Sets the connect timeout +++ -|[[keyStoreOptions]]`keyStoreOptions`|`link:dataobjects.html#JksOptions[JksOptions]`| +|[[crlPaths]]`crlPaths`|`Array of String`| +++ -Set the key/cert options in jks format, aka Java keystore. +Add a CRL path +++ -|[[maxChunkSize]]`maxChunkSize`|`Number (int)`| +|[[crlValues]]`crlValues`|`Array of Buffer`| +++ -Set the maximum HTTP chunk size +Add a CRL value +++ -|[[maxPoolSize]]`maxPoolSize`|`Number (int)`| +|[[enabledCipherSuites]]`enabledCipherSuites`|`Array of String`| +++ -Set the maximum pool size for connections +Add an enabled cipher suite +++ -|[[maxWaitQueueSize]]`maxWaitQueueSize`|`Number (int)`| +|[[host]]`host`|`String`| +++ -Set the maximum requests allowed in the wait queue, any requests beyond the max size will result in - a ConnectionPoolTooBusyException. If the value is set to a negative number then the queue will be unbounded. +Sets the host. +++ -|[[maxWebsocketFrameSize]]`maxWebsocketFrameSize`|`Number (int)`| +|[[idleTimeout]]`idleTimeout`|`Number (int)`| +++ -Set the max websocket frame size +Set the idle timeout, in seconds. zero means don't timeout. + This determines if a connection will timeout and be closed if no data is received within the timeout. ++++ +|[[keyStoreOptions]]`keyStoreOptions`|`link:dataobjects.html#JksOptions[JksOptions]`| ++++ +Set the key/cert options in jks format, aka Java keystore. +++ |[[pemKeyCertOptions]]`pemKeyCertOptions`|`link:dataobjects.html#PemKeyCertOptions[PemKeyCertOptions]`| +++ @@ -1283,18 +1287,22 @@ Set the key/cert options in pfx format. +++ Set the trust options in pfx format +++ -|[[pipelining]]`pipelining`|`Boolean`| -+++ -Set whether pipe-lining is enabled on the client -+++ -|[[protocolVersion]]`protocolVersion`|`link:enums.html#HttpVersion[HttpVersion]`| +|[[port]]`port`|`Number (int)`| +++ -Set the protocol version. +Sets the port. +++ |[[receiveBufferSize]]`receiveBufferSize`|`Number (int)`| +++ Set the TCP receive buffer size +++ +|[[reconnectAttempts]]`reconnectAttempts`|`Number (int)`| ++++ +Sets the value of reconnect attempts. ++++ +|[[reconnectInterval]]`reconnectInterval`|`Number (long)`| ++++ +Set the reconnect interval. ++++ |[[reuseAddress]]`reuseAddress`|`Boolean`| +++ Set the value of reuse address @@ -1325,24 +1333,16 @@ Set the value of traffic class +++ |[[trustAll]]`trustAll`|`Boolean`| +++ -Set whether all server certificates should be trusted +Set whether all server certificates should be trusted. +++ |[[trustStoreOptions]]`trustStoreOptions`|`link:dataobjects.html#JksOptions[JksOptions]`| +++ Set the trust options in jks format, aka Java trustore +++ -|[[tryUseCompression]]`tryUseCompression`|`Boolean`| -+++ -Set whether compression is enabled -+++ |[[usePooledBuffers]]`usePooledBuffers`|`Boolean`| +++ Set whether Netty pooled buffers are enabled +++ -|[[verifyHost]]`verifyHost`|`Boolean`| -+++ -Set whether hostname verification is enabled -+++ |=== [[PemTrustOptions]] diff --git a/src/main/java/io/vertx/core/impl/launcher/VertxCommandLauncher.java b/src/main/java/io/vertx/core/impl/launcher/VertxCommandLauncher.java index 2e4ef2b7cee..9b37a711823 100644 --- a/src/main/java/io/vertx/core/impl/launcher/VertxCommandLauncher.java +++ b/src/main/java/io/vertx/core/impl/launcher/VertxCommandLauncher.java @@ -375,6 +375,7 @@ public void dispatch(Object main, String[] args) { // By default this method retrieve the value from the 'Main-Verticle' Manifest header. However it can be overridden. String verticle = getMainVerticle(); + String command = getCommandFromManifest(); if (verticle != null) { // We have a main verticle, append it to the arg list and execute the default command (run) String[] newArgs = new String[args.length + 1]; @@ -382,9 +383,12 @@ public void dispatch(Object main, String[] args) { System.arraycopy(args, 0, newArgs, 1, args.length); execute(getDefaultCommand(), newArgs); return; + } else if (command != null) { + execute(command, args); + return; } - // Fall backs + // Fallbacks if (args.length == 0) { printGlobalUsage(); } else { @@ -401,6 +405,14 @@ public void dispatch(Object main, String[] args) { * @return the default command if specified in the {@code MANIFEST}, "run" if not found. */ protected String getDefaultCommand() { + String fromManifest = getCommandFromManifest(); + if (fromManifest == null) { + return "run"; + } + return fromManifest; + } + + protected String getCommandFromManifest() { try { Enumeration resources = RunCommand.class.getClassLoader().getResources("META-INF/MANIFEST.MF"); while (resources.hasMoreElements()) { @@ -420,7 +432,7 @@ protected String getDefaultCommand() { } catch (IOException e) { throw new IllegalStateException(e.getMessage()); } - return "run"; + return null; } /** diff --git a/src/test/asciidoc/dataobjects.adoc b/src/test/asciidoc/dataobjects.adoc index 35cc23a57f0..ac19928ffac 100644 --- a/src/test/asciidoc/dataobjects.adoc +++ b/src/test/asciidoc/dataobjects.adoc @@ -30,21 +30,6 @@ ^|Name | Type ^| Description |=== -[[ParentDataObject]] -== ParentDataObject - -++++ - @author Julien Viet -++++ -''' - -[cols=">25%,^25%,50%"] -[frame="topbot"] -|=== -^|Name | Type ^| Description -|[[parentProperty]]`parentProperty`|`String`|- -|=== - [[TestDataObject]] == TestDataObject @@ -122,6 +107,21 @@ |[[stringValues]]`stringValues`|`Array of String`|- |=== +[[ParentDataObject]] +== ParentDataObject + +++++ + @author Julien Viet +++++ +''' + +[cols=">25%,^25%,50%"] +[frame="topbot"] +|=== +^|Name | Type ^| Description +|[[parentProperty]]`parentProperty`|`String`|- +|=== + [[AggregatedDataObject]] == AggregatedDataObject diff --git a/src/test/java/io/vertx/test/core/LauncherTest.java b/src/test/java/io/vertx/test/core/LauncherTest.java index 13b7ea228ae..7cb198da487 100644 --- a/src/test/java/io/vertx/test/core/LauncherTest.java +++ b/src/test/java/io/vertx/test/core/LauncherTest.java @@ -220,6 +220,54 @@ public void testRunVerticleWithMainVerticleInManifestWithCustomCommand() throws waitUntil(() -> HelloCommand.called); } + @Test + public void testRunVerticleWithoutMainVerticleInManifestButWithCustomCommand() throws Exception { + // Copy the right manifest + File manifest = new File("target/test-classes/META-INF/MANIFEST-Launcher-Default-Command.MF"); + if (!manifest.isFile()) { + throw new IllegalStateException("Cannot find the MANIFEST-Default-Command.MF file"); + } + File target = new File("target/test-classes/META-INF/MANIFEST.MF"); + Files.copy(manifest.toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING); + + Launcher launcher = new Launcher(); + HelloCommand.called = false; + String[] args = {"--name=vert.x"}; + launcher.dispatch(args); + waitUntil(() -> HelloCommand.called); + } + + @Test + public void testRunWithOverriddenDefaultCommand() throws Exception { + // Copy the right manifest + File manifest = new File("target/test-classes/META-INF/MANIFEST-Launcher-hello.MF"); + if (!manifest.isFile()) { + throw new IllegalStateException("Cannot find the MANIFEST-Launcher-hello.MF file"); + } + File target = new File("target/test-classes/META-INF/MANIFEST.MF"); + Files.copy(manifest.toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING); + + HelloCommand.called = false; + String[] args = {"run", TestVerticle.class.getName(), "--name=vert.x"}; + Launcher.main(args); + waitUntil(() -> TestVerticle.instanceCount.get() == 1); + } + + @Test + public void testRunWithOverriddenDefaultCommandRequiringArgs() throws Exception { + // Copy the right manifest + File manifest = new File("target/test-classes/META-INF/MANIFEST-Launcher-run.MF"); + if (!manifest.isFile()) { + throw new IllegalStateException("Cannot find the MANIFEST-Launcher-run.MF file"); + } + File target = new File("target/test-classes/META-INF/MANIFEST.MF"); + Files.copy(manifest.toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING); + + String[] args = {TestVerticle.class.getName()}; + Launcher.main(args); + waitUntil(() -> TestVerticle.instanceCount.get() == 1); + } + @Test public void testRunVerticleWithExtendedMainVerticleNoArgs() throws Exception { @@ -366,7 +414,7 @@ private void testConfigureFromSystemProperties(boolean clustered) throws Excepti VertxOptions opts = launcher.getVertxOptions(); assertEquals(123, opts.getEventLoopPoolSize(), 0); - assertEquals(123767667l, opts.getMaxEventLoopExecuteTime()); + assertEquals(123767667L, opts.getMaxEventLoopExecuteTime()); assertEquals(true, opts.getMetricsOptions().isEnabled()); assertEquals("somegroup", opts.getHAGroup()); diff --git a/src/test/resources/META-INF/MANIFEST-Launcher-Default-Command.MF b/src/test/resources/META-INF/MANIFEST-Launcher-Default-Command.MF new file mode 100644 index 00000000000..08fce72cdbb --- /dev/null +++ b/src/test/resources/META-INF/MANIFEST-Launcher-Default-Command.MF @@ -0,0 +1,2 @@ +Main-Class: io.vertx.core.Launcher +Main-Command: hello diff --git a/src/test/resources/META-INF/MANIFEST-Launcher-run.MF b/src/test/resources/META-INF/MANIFEST-Launcher-run.MF new file mode 100644 index 00000000000..4a09047ba1f --- /dev/null +++ b/src/test/resources/META-INF/MANIFEST-Launcher-run.MF @@ -0,0 +1,2 @@ +Main-Class: io.vertx.core.Launcher +Main-Command: run