running vertx behind a proxy - java

Has anybody had a luck trying to use vertx bihind a corporate proxy? I have tried whatever possible ways that comes to my head to provide the proxy information to vertx. Nothing works so far.
set environment variable http_proxy=http://mycorporate.proxy.com:8080 - no luck
set environment variable VERTX_OPTS='-Dhttp.proxyHost=mycorporate.proxy.com -Dhttp.proxyPort=8080' - no luck
set environment variables
http.proxyHost=mycorporate.proxy.com
http.proxyPort=8080
no luck
Injecting extra echo into vertx command I can see that proxy related parameters are being passed to JVM correctly but required module still can't be downloaded ("vertx run hello.js" just stuck obviously trying to download io.vertx~lang-rhino~2.0.0-final)
Proxy itself is ok - I'm using it with no problem for maven, sbt and other different stuff requiring proxy
Same laptop being used from home can successfully run "vertx run hello.js" with downloading io.vertx~lang-rhino~2.0.0-final (for the first run)
I have just started evaluating vertx for our company needs and this is my very first choking point hindering my further attempts to make a decision. So far I have to follow next steps as workaround: 1 Run from home and get whatever required modules in sys-mods. 2 Manually upload the module(s) to sys-mods on the test server when back to the office.
Obviously this is not a normal way to run anything.

I had similar problem. I figure out that HttpClient form does not read settings from JVM_OPTS.
So solution was following:
Edit your vertx.bat(sh)
set JVM_OPTS=-Dhttp.proxyHost=xxxx -Dhttp.proxyPort=xxxx
and then in code related to httpClient try sth like this
HttpClient client = vertx.createHttpClient();
String proxyHost = System.getProperty("http.proxyHost", "none");
Integer proxyPort = Integer.valueOf(System.getProperty("http.proxyPort", "80"));
if(!"none".equalsIgnoreCase(proxyHost)){
client.setHost(proxyHost);
client.setPort(proxyPort);
}
and later in code releted to HTTP request
MultiMap map = new CaseInsensitiveMultiMap();
map.add("Host", domainName); //get domain of REQUESTED_URL
client.getNow(REQUESTED_URL, map, new new Handler<HttpClientResponse>(){...});

Building on #kamyk-pl answer. If you are using latest version of Vertx this is what you can do :
WebClientOptions webClientOptions = new WebClientOptions();
String proxyHost = System.getProperty("http.proxyHost", "none");
Integer proxyPort = Integer.valueOf(System.getProperty("http.proxyPort", "80"));
if(!"none".equalsIgnoreCase(proxyHost)){
ProxyOptions proxyOptions = new ProxyOptions();
proxyOptions.setHost(proxyHost);
proxyOptions.setPort(proxyPort);
webClientOptions.setProxyOptions(proxyOptions);
}
WebClient.create(vertx, webClientOptions)
Optionally you also want to add this if you are testing SSL connections
webClientOptions.setVerifyHost(false);
webClientOptions.setTrustAll(true);

I use vertx 3.8.0
HttpClient c = vertx.createHttpClient();
RequestOptions requestOptions = new RequestOptions();
requestOptions.setHost(ip).setPort(port).setURI("http://httpbin.org/ip");
c.request(HttpMethod.GET, requestOptions).handler(new Handler<HttpClientResponse>() {
#Override
public void handle(HttpClientResponse event) {
event.handler(new Handler<Buffer>() {
#Override
public void handle(Buffer event) {
System.out.println(event);
}
});
}
}).end();

To set the proxy, edit vertx.bat (if you are on Windows) and add
set JVM_OPTS=-Dhttp.proxyHost=xxxx -Dhttp.proxyPort=xxxx

Related

Java Azure Function with IoT Hub trigger is not starting

i am trying to trigger a java function each time my IoT Hub receives a batch of 64 messages (or whatever, the number is not important). I followed this guide to create the basic code, then i edited creating this function
public class Function {
#FunctionName("ProcessIotMessages")
public void processIotMessages(
#EventHubTrigger(name = "message",
eventHubName = "samples-workitems",
connection = "HUB-1544-DEV_events_IOTHUB") List<String> messages,
final ExecutionContext context) {...Function Logic...}
}
The connection parameter is the IoT Hub connection string in formatted as event hub compatible endpoint (e.g. Endpoint=sb://iothub-hostname-blablabla).
I package and deploy this code with maven plugins specified in the guide linked above. The deploys works fine, i can see mi function up and running with no errors from the portal, the HUB-1544-DEV_events_IOTHUB setting app is correctly created with the correct connection string.
The only strange thing i notice in the portal is in the trigger blade. As you can see, cardinality is One, while it should be set to many, since i did not specify the cardinality parameter in the function. The default one is many according to this guide. This makes me think that i not being able to pass the correct trigger syntax.
Anyway, the problem is that this function is not starting either from my local machine or the portal. Any suggestions? Thx
As #evilSnobu posted in the comments, the problem was the event hub name. Just go to Portal -> your IoT Hub -> Built-in endpoints and find all the information to configure the trigger in there.

Vertx.io GET silently fails

I'm writing a POC using vertx, looking for alternatives when we have to migrate Spring Web from 4.x to 5 to be java 9 compliant.
I've written a simple client, just a GET towards a publicly available server just to get something working but it silently fails me.
public List<String> pull() {
Vertx vertx = Vertx.vertx();
HttpClientOptions options = new HttpClientOptions().setLogActivity(true);
HttpClient hc = vertx.createHttpClient(options);
hc.getNow(80, "http://sunet.se", "/",r -> {
System.out.println("\n****** Handler called! ***\n");
});
return new ArrayList<>();
}
This will silently fail and I cannot understand why.
As far as I can tell, I do exactly as in the examples given in the docs.
In desperation I fired up wire shark and according to WS, there is no actual call (when I use the browser WS captures that). So, it seems my call is never actually done. I don't get any exceptions or anything. Setting the log level to debug gives nothing noteworthy other than
Failed to get SOMAXCONN from sysctl and file /proc/sys/net/core/somaxconn. Default: 128
And that should not fail the call.
I've also tried using vertx.io WebClient but that fails also, in the same manner.
UPDATE
I've managed to get it to work but with a caveat.
As #tsegismont states in his answer, the protocol part of the URI shouldn't be there, that was not in the examples, I just missed it myself.
I ran my example as a stand-alone and then it worked.
My original example was run as a junit test (it's an easy way to test code and I usually try to write the test code first) and when it's run as a junit test it still doesn't work. Why that is, I have no idea. I would greatly appreciate if someone could tell me how to get that to work.
The getNow variant you use expects the server host, not a URL. It should be:
hc.getNow(80, "sunet.se", "/",r -> {
System.out.println("\n****** Handler called! ***\n");
}
If you found a snippet like this in the Vert.x docs it's a bug. Would you mind to report it?
Now a few comments.
1/ The HttpClient is a low-level client.
Most users should prefer the Vert.x Web Client
Here's an example for your use case:
WebClient client = WebClient.create(vertx);
client
.get(80, "sunet.se", "/")
.send(ar -> {
if (ar.succeeded()) {
// Obtain response
HttpResponse<Buffer> response = ar.result();
System.out.println("Received response with status code" + response.statusCode());
} else {
System.out.println("Something went wrong " + ar.cause().getMessage());
}
});
2/ Create a single Vert.x and WebClient instance
Do not create a Vert.x and WebClient instance on every method call.
It wastes resources and is inefficient.

Atlassian Confluence communication/authentication between plugins

I'm (new at this) developing a macro plugin that builds on data that an existing plugin provides via its REST API. They would run on the same instance of Confluence, version 5.9.
I cannot use the Java API of the plugin, since it only provides access to a very limited amount of classes, so I decided on using Rest.
Given that the user has already authenticated with Confluence, is there any way to communicate my current user credentials from my plugins Java Rest client to the other one, preferably not using Basic Authentication?
So far, I've tried:
Shared Access Layer - this apparently used to work with the method Request#addTrustedTokenAuthentication() but is deprecated in SAL 3.0.5,
see SAL Documentation (outdated?), and SAL Version Matrix
ApplicationLink - would allow me to link to another application, but apparently it's not possible to link back to the same Confluence instance
SAL TrustedRequestFactory- comments on this atlassian answer indicate there might be a way using this, but I can't seem to figure it out (yet).
I've also tried reading up on atlassian documentation and posted a similar question on atlassian answers here. I don't mean to double post, but unfortunately, looking at other questions on that platform, few seem to get answered in a timely fashion so I thought I'd try my luck here.
Seems like this isn't a very common problem, but I thought I'd post how we eventually solved this, just in case it's needed again:
#Component
public class RestClient {
#ComponentImport
private TrustedTokenFactory tokenFactory;
// [...]
public String doRequest(HttpClient client, String url) throws Exception {
TrustedTokenAuthenticator auth =
new TrustedTokenAuthenticator(tokenFactory);
HttpMethod method = auth.makeMethod(client, url);
try {
// add request headers, etc...
int statusCode = client.executeMethod(method);
// be sure to use response data here, catch exceptions...
} finally {
method.releaseConnection();
}
}
}

Dynamic BlazeDS endpoint configuration

I search for some help creating a web Flex application using BlazeDS and Java server with dynamic BlazeDS endpoint configuration.
First, I will try to explain my current situation.
I have a Flex 3.2 application that provides GUI of the application. From the ActionScript I call Java methods using BlazeDS. To access the BlazeDS I use a Config class that provides the endpoint as shown below (it is a constructor):
public function Config(): void {
if (_serviceUrl == null) {
try {
var browser: IBrowserManager = BrowserManager.getInstance();
browser.init();
var url: String = browser.url;
var host: String = mx.utils.URLUtil.getServerName(url);
var port: uint = mx.utils.URLUtil.getPort(url);
var parts: Array = url.split('/');
if (parts[2] == '') {
url = DEFAULT_URL;
Alert.show("Unable to determine server location, using default URL: " + DEFAULT_URL, "Connection error");
}
else {
url = parts[0] + '//' + parts[2] + '/' + parts[3] + '/messagebroker/amf';
}
_serviceUrl = url;
} catch (e: Error) {
Alert.show("Exception while trying to determine server location, using default URL: " + DEFAULT_URL, "Connection exception");
_serviceUrl = DEFAULT_URL;
}
}
}
The idea of the class is to determine the endpoint from the request URL. I use a Delegate class to call the remote methods using BlazeDS like the following:
{
import com.adobe.cairngorm.business.ServiceLocator;
import mx.rpc.IResponder;
import mx.rpc.remoting.RemoteObject;
public class AbstractRemoteDelegate
{
public function AbstractRemoteDelegate(responder:IResponder,serviceName:String)
{
_responder=responder;
_locator=ServiceLocator.getInstance();
_service=_locator.getRemoteObject(serviceName);
_service.showBusyCursor=true;
_service.endpoint = Config.instance.serviceUrl;
}
private var _responder:IResponder;
private var _locator:ServiceLocator;
private var _service:RemoteObject;
protected function send(operationName:String,... args:Array) : void {
_service.getOperation(operationName).send.apply(_service.getOperation(operationName),args).addResponder(_responder);
}
}
}
This approach actually works fine. However, I got across a situation where I can't use dynamically determined URL. In such a situation, I need a hard-coded URL in the Config.as file. And this is the problem. When trying to deploy the application to another server, I always need to rebuild the application with a new URL configuration in the ActionScript class Config.
Therefore I search for a way to define a static configuration for the Flex application to connect to a BlazeDS server. And the way to change such configuration without rebuilding the application so I can give the customer his own way to reconfigure and move the Flex application.
I thought about using a configuration file, but Flex runs on the client side and there is no configuration file!
I thought about using database configuration, but I don't have any database on the client side!
To sum up, I am looking for a way, how to get BlazeDS URL from a configuration to be able to change it without rebuilding the whole app.
Thanks for any useful suggestions.
EDIT: Revised the question to be more actual. I improved the way to determine the URL dynamically from the request URL, so it works now even for proxy server. However, my curiosity persists for the configuration of flex without rebuilding.
Here is an old example Blaze DS Service of mine which does basically the same as you did. It's just the string which needs to be created correctly. If the endpoint address is wrong, catch the error accordingly.
My project may currently not build because of Flexmojos ... I'm not able to test that yet.
Since it did not read you question properly, I misunderstood you: You can put a configuration file next to the SWF and load it via URLLoader or pass it via FlashVars. That should give you the freedom to pass the endpoint dynamically.

MATLAB proxy could not be created in 180000 milliseconds

I am using the matlabcontrol-4.0.0.jar library to call Matlab from Java. This on Ubuntu 11.10, Matlab r2011b and Java version "1.6.0_23".
When trying to run this simple program:
public static void main(String[] args) throws MatlabConnectionException,
MatlabInvocationException {
//Create a proxy, which we will use to control MATLAB
MatlabProxyFactory factory = new MatlabProxyFactory(options);
MatlabProxy proxy = factory.getProxy();
//Display 'hello world' just like when using the demo
proxy.eval("disp('hello world')");
//Disconnect the proxy from MATLAB
proxy.disconnect();
}
I get, after the Matlab launch screen appears (which is good), a time out:
Exception in thread "main" matlabcontrol.MatlabConnectionException:
MATLAB proxy could not be created in 180000 milliseconds at matlabcontrol.RemoteMatlabProxyFactory.getProxy(RemoteMatlabProxyFactory.java:158)
at
matlabcontrol.MatlabProxyFactory.getProxy(MatlabProxyFactory.java:81)
at Main.main(Main.java:15)
I've looked everywhere including all the tips from provided by stackoverflow, but nothing seems to fit the problem i am encountering
*UPDATE*
I forbore to mention that I already tried the scenario described by Joshua Kaplan (thanks!) .This seems be for my case of no help, meaning that it just keeps waiting. Could someone perhaps elaborate on the communication protocol between java and the matlab proxy?
-> It could be an incompatibility issue as well, I've posted on the website delivering the resource, have received no answer so far...
*END UPDATE*
So, any of you a tip where to start looking, that would be wonderful
thanks
The getProxy() method is a blocking operation with a default timeout of 3 minutes (or 180 seconds or 180000 milliseconds). For most people's machines that is long enough, if the connection was not established in that amount of time then something has gone wrong. However, this timeout can be changed by creating an instance of a MatlabProxyFactoryOptions which is done by using a MatlabProxyFactoryOptions.Builder. The MatlabProxyFactoryOptions instance you create is passed into MatlabProxyFactory's constructor. Here's an example with a 5 minute timeout:
MatlabProxyFactoryOptions options = new MatlabProxyFactoryOptions.Builder()
.setProxyTimeout(300000L)
.build();
MatlabProxyFactory factory = new MatlabProxyFactory(options);
MatlabProxy proxy = factory.getProxy();
Alternatively you can request a proxy which is a non-blocking operation that has no timeout. Once the proxy has been created it will be passed to the provided callback. Example:
MatlabProxyFactory factory = new MatlabProxyFactory();
factory.requestProxy(new MatlabProxyFactory.RequestCallback()
{
public void proxyCreated(MatlabProxy proxy)
{
//TODO: Make use of the proxy
}
});
I got similar problem. Main issue is that in your imported .jar file "matlabcontrol-4.0.0.jar" there is default, configuration in class Configuration.java. In my case there was problem, that libraries cannot properly call matlab with all arguments. Try to add to your project not .jar file, but package matalbcontrol with all source .java files. You can download it form the same page http://code.google.com/p/matlabcontrol/downloads/list, form where you got .jar libs. Then in Configuration.java edit getMatlabLocation() lines:
else if(isWindows() || isLinux())
{
matlabLoc = "matlab";
}
replace with:
else if(isLinux())
{
matlabLoc = "/usr/local/MATLAB/R2011b/bin/matlab"; //or place where you got installed your matlab, directory bin, in my case, like in example
}
else if(isWindows())
{
matlabLoc = "matlab";
}

Categories