How to pass VertxOptions from command line (like worker threads) - vert.x

How to pass VertxOptions from command line (like worker threads)?
I'm talking about something like this:
java -jar fat.jar --workerThreads 40
or
vertx run server.js --workerThreads 40
There is no mention of that parameter in manual or API.
Is there any way to do this?
I know that there is an API:
var Vertx = require("vertx-js/vertx");
var vertx = Vertx.vertx({
"workerPoolSize" : 40
});
But when I use that API I get warning from Vertx:
You're already on a Vert.x context, are you sure you want to create a new Vertx instance?
So I thinking I am doing something wrong...

You need to put it as a system property with a vertx.options prefix.
So for the fat jar it would be:
java -jar fat.jar -Dvertx.options.workerThreads 40
As for what properties you can set, anything that has a setting in VertxOptions has a corresponding property name: the setter name without the "set" portion.
For example, in code:
options.setClusterPort(5555)
is equivalent to
-Dvertx.options.clusterPort
on the command line.
Be warned that the "vertx.options" part is case-sensitive.

Related

Camel Restlet - Context Path Ambiquity

I have Spring Boot Camel application where rest apis are exposed using camel-restlet
Sample route
#Component
public class AppRoute extends RouteBuilder{
public void configure(CamelContext context){
from("restlet:employee?restletMethods=GET").log("${body}");
}
}
The App runs perfect ( spring-boot:run ). but am unable to locate under which path the API is exposed. Log has no information.
Every API i hit returns 404. Log shows the route has been started. Under which path is it running. And how do I change it?
Note: Please dont suggest any XML based configuration. Anything that I can put under #Configuration would be perfect
I would go with the Rest DSL which is supported by the camel-restlet component like this
restConfiguration().component("restlet").port(8080);
rest("/rest")
.get("employee")
.route().log("${body}")
.endRest();
And this route will listen to the following url
http://localhost:8080/rest/employee
EDIT:
I guess you could do something like without using the Rest DSL
String host = InetAddress.getLocalHost().getHostName();
from("restlet:http://" + host + contextPath + "/employee?restletMethods=GET").log("${body}")
The port and context path are configurable with the following properties
camel.component.restlet.port=8686
server.servlet.context-path=/my-path
The context path can be injected in the routeBuilder with
#Value("${server.servlet.context-path}")
private String contextPath;
According to the documentation, the format of the URI in a restlet endpoint definition should be the following:
restlet:restletUrl[?options]
Where restletUrl should have the following format:
protocol://hostname[:port][/resourcePattern]
So in your case you could define the URI in the following way:
from("restlet:http://localhost/employee?restletMethods=GET")
This should make the endpoint available under the following URL:
http://localhost/employee
Which you can test e.g. in a web browser.
Use the first of the three configuration methods described here:
https://restlet.com/open-source/documentation/javadocs/2.0/jee/ext/org/restlet/ext/servlet/ServerServlet.html
You should be able to customize it using the Component:
https://restlet.com/open-source/documentation/javadocs/2.0/jee/api/org/restlet/Component.html?is-external=true
See in particular setServers() methods (or XML equivalent) to change the hostname and port.

Setting Hystrix timeout with environment variable

In order to change Hystrix's default request timeout (1000ms), one must set the following property :
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=2000
What is the corresponding environment variable ?
I would like to "tune" the timeout on my favorite cloud platform without touching the source code first.
I'm pretty sure this one doesn't work : HYSTRIX_COMMAND_DEFAULT_EXECUTION_ISOLATION_THREAD_TIMEOUT_IN_MILLISECONDS=2000
EDIT : Problem was found with Spring Cloud Camden / Spring Boot 1.4.
VM options and environment variables can be referenced from application configuration, which is often a more convenient way to set properties with longer names.
For example, one can define the following reference in application.yml:
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: ${service.timeout}
which will be resolved from the VM option -Dservice.timeout=10000, setting the default Hystrix command timeout to 10 seconds. It is even simpler with environment variables - thanks to relaxed binding, any of these will work (export examples are for Linux):
export service.timeout=10000
export service_timeout=10000
export SERVICE.TIMEOUT=10000
export SERVICE_TIMEOUT=10000
The common approach is to use lowercase.dot.separated for VM arguments and ALL_CAPS_WITH_UNDERSCORES for environment variables.
You could try expression with a default value:
hystrix.command.default.execution.isolation.thread.timeoutIn‌Milliseconds: ${SERVICE_TIMEOUT:2000}
In case you have SERVICE_TIMEOUTsystem variable - it will be used by an application, otherwise, a default value will be picked up.
Found more of a workaround than a solution, using SPRING_APPLICATION_JSON environment variable :
SPRING_APPLICATION_JSON='{ "hystrix" : { "command" : { "default" : { "execution" : { "isolation" : { "thread" : { "timeoutInMilliseconds" : 3000 } } } } } } }'
You can use Spring config yaml file , Please read further on following link
https://github.com/spring-cloud/spring-cloud-netflix/issues/321
VM option -Dhystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=2000 works for me. However it has a side effect, then you can not change the config value in java code since system properties are prioritized.
ConfigurationManager.getConfigInstance().setProperty(
"hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", 3000);// it doesn't work

Getting server port and contextPath programmatically - springboot

How can i get the server port and contextPath at runtime?
In application.yml, i am setting these values:
server:
port: 9300
contextPath: '/apis'
In the code, i am building a JSONAPI response to include a reference back to the REST API and therefore the need to programmatically get
{
"relationships": {
"company": {
"links": {
"related": "/api/v1/users/1/company"
}
},
"pets": {
"links": {
"related": "/api/v1/users/1/pets"
}
}
}
}
Example,
String related = port? + contextPath? + "/users" + userId + "company";
The following is taken from http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html:
Spring Boot allows you to externalize your configuration so you can
work with the same application code in different environments. You can
use properties files, YAML files, environment variables and
command-line arguments to externalize configuration. Property values
can be injected directly into your beans using the #Value
annotation, accessed via Spring’s Environment abstraction or bound to
structured objects via #ConfigurationProperties.
Spring Boot uses a very particular PropertySource order that is
designed to allow sensible overriding of values. Properties are
considered in the following order:
Devtools global settings properties on your home directory
(~/.spring-boot-devtools.properties when devtools is active).
#TestPropertySource annotations on your tests.
#SpringBootTest#properties annotation attribute on your tests.
Command line arguments.
Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an
environment variable or system property)
ServletConfig init parameters.
ServletContext init parameters.
JNDI attributes from java:comp/env.
Java System properties (System.getProperties()).
OS environment variables.
A RandomValuePropertySource that only has properties in random.*.
Profile-specific application properties outside of your packaged
jar (application-{profile}.properties and YAML variants)
Profile-specific application properties packaged inside your jar
(application-{profile}.properties and YAML variants)
Application properties outside of your packaged jar
(application.properties and YAML variants).
Application properties packaged inside your jar
(application.properties and YAML variants).
#PropertySource annotations on your #Configuration classes.
Default properties (specified using
SpringApplication.setDefaultProperties).
To provide a concrete example, suppose you develop a #Component that
uses a name property:
import org.springframework.stereotype.*
import org.springframework.beans.factory.annotation.*
#Component
public class MyBean {
#Value("${name}")
private String name;
// ...
}
On your application classpath (e.g. inside your jar) you can have an
application.properties that provides a sensible default property value
for name. When running in a new environment, an
application.properties can be provided outside of your jar that
overrides the name; and for one-off testing, you can launch with a
specific command line switch (e.g. java -jar app.jar --name="Spring").
[Tip] The SPRING_APPLICATION_JSON properties can be supplied on the
command line with an environment variable. For example in a UN*X
shell:
$ SPRING_APPLICATION_JSON='{"foo":{"bar":"spam"}}' java -jar myapp.jar
In this example you will end up with foo.bar=spam in the Spring
Environment. You can also supply the JSON as spring.application.json
in a System variable:
$ java -Dspring.application.json='{"foo":"bar"}' -jar myapp.jar
or command line argument:
$ java -jar myapp.jar --spring.application.json='{"foo":"bar"}'
or as a JNDI variable java:comp/env/spring.application.json.
Inject Spring Boot properties
You can inject the values in your code this way:
#Value("${server.port}")
private int port;
#Value("${server.contextPath}")
private String contextPath;
Hateoas
Alternatively, you could take a look at the Hateoas project, which can generate the link section for you: http://docs.spring.io/spring-hateoas/docs/current/reference/html
Use #Value annotation to inject the properties into member variables of your class. You can do this:
#Component
public class Foo
{
#Value("${server.port}")
String serverPort;
#Value("${server.contextPath}")
String contextPath;
public void doSomething()
{
String str = "serverPort: " + serverPort + "; contextPath: " + contextPath;
}
}

Felix Dependecy-Manager not creating GoGo-Command

I am trying to create a GoGo-Shell-Command using the Felix-Dependency-Manager (Version 3.2.0) without Annotations.
As far as I understand, the gogo-runtime uses the whiteboard-pattern and scans for services with Properties using the keys CommandProcessor.COMMAND_SCOPE and CommandProcessor.COMMAND_FUNCTION.
In my case, the bundle is started, the service is registered with the correct properties but my command is not listed under "help" nor does it work when I try to call it.
The following code registers the service within the BundleActivator (DependencyActivatorBase):
Properties props = new Properties();
props.put(CommandProcessor.COMMAND_SCOPE, "test");
props.put(CommandProcessor.FUNCTION_SCOPE, new String[] {"command"});
manager.add(createComponent()
.setInterface(Object.class.getName(), props)
.setImplementation(MyConsole.class)
.add(createServiceDependency()
.setService(MyService.class)));
The following bundles are listed with lb-Command when running my code.
org.apache.felix.gogo.command
org.apache.felix.gogo.runtime
org.apache.felix.gogo.shell
org.apache.felix.dependencymanager
org.apache.felix.dependencymanager.shell
mybundle.service
mybundle.api
mybundle.console
Development is done with BndTools.
Am I missing something here?
First of all, your assumption about how to register gogo commands is correct: a whiteboard pattern is used and the scope and function properties determine the commands.
You did not post the code for MyConsole. Does it actually contain a method called command? If not, that could be the problem.
Another potential problem could be that you did not actually add a Bundle-Activator line in your manifest.
If that's not it, use the dm notavail command to see if there are any unregistered components (because of missing dependencies).

How do I programatically invoke a Felix/Karaf shell command?

I want to automatically invoke the Karaf "dev:watch" command if I detect that I'm running in a dev environment. I've considered adding dev:watch * directly to etc/shell.init.script but I don't want it to run unconditionally. So, I'm considering creating a simple service that checks a Java property (something simple like -Ddevelopment=true) and invokes org.apache.karaf.shell.dev.Watch itself. I think I can ask OSGi for a Function instance with (&(osgi.command.function=watch)(osgi.command.scope=dev)) but then I need to create a mock CommandSession just to invoke it. That just seems too complicated. Is there a better approach?
Since Apache Karaf 3.0.0 most commands are backed by OSGi services.
So for example the bundle:watch command is using the service
"org.apache.karaf.bundle.core.BundleWatcher".
So just bind this service and you can call the bundle:watch functionality very conveniently.
It has been a while since the question, but I will answer.
You need to use CommandSession class, it is not trivial. This blog post could guide you. It is related with Pax Exam, but could be applied in any situation. There are more alternatives like using a remote SSH client or even better the remote JXM management console (reference).
The init script can also be used to test for a condition and run a command if that condition is satisfied, so there is no need to create a command session yourself.
The Karaf source itself reveals one answer:
In the KarafTestSupport class which is used for integration testing Karaf itself
(see https://git-wip-us.apache.org/repos/asf?p=karaf.git;a=blob;f=itests/src/test/java/org/apache/karaf/itests/KarafTestSupport.java;h=ebdea09ae8c6d926c8e4ac1fae6672f2c00a53dc;hb=HEAD)
The relevant method starts:
/**
* Executes a shell command and returns output as a String.
* Commands have a default timeout of 10 seconds.
*
* #param command The command to execute.
* #param timeout The amount of time in millis to wait for the command to execute.
* #param silent Specifies if the command should be displayed in the screen.
* #param principals The principals (e.g. RolePrincipal objects) to run the command under
* #return
*/
protected String executeCommand(final String command, final Long timeout, final Boolean silent, final Principal ... principals) {
waitForCommandService(command);
String response;
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
final PrintStream printStream = new PrintStream(byteArrayOutputStream);
final SessionFactory sessionFactory = getOsgiService(SessionFactory.class);
final Session session = sessionFactory.create(System.in, printStream, System.err);
//
//
//
// Snip