I have a simply camel MINA server using the JAVA DSL, and I am running like the example documented here:
Running Camel standalone and have it keep running in JAVA
MINA 2 Component
Currently this server receives reports from a queue, updates them, and then sends them away to the next server. A very simple code:
public class MyApp_B {
private Main main;
public static void main(String... args) throws Exception {
MyApp_B loadbalancer = new MyApp_B();
loadbalancer.boot();
}
public void boot() throws Exception {
main = new Main();
main.enableHangupSupport();
main.addRouteBuilder(
new RouteBuilder(){
#Override
public void configure() throws Exception {
from("mina:tcp://localhost:9991")
.setHeader("minaServer", constant("localhost:9991"))
.beanRef("service.Reporting", "updateReport")
.to("direct:messageSender1");
from("direct:messageSender1")
.to("mina:tcp://localhost:9993")
.log("${body}");
}
}
);
System.out.println("Starting Camel MyApp_B. Use ctrl + c to terminate the JVM.\n");
main.run();
}
}
Now, I would like to know if it is possible to do two things:
Make this server send a message to a master server when it starts running. This is an "Hello" message with this server's information basically.
Tell the master server to forget him when I shut it down pressing CTRL+C or doing something else.
I have also read this:
http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/support/ServiceSupport.html#doStart%28%29
technically, by overriding the doStart and doStop methods I should get the intended behavior, however, those methods (specially the doStop method) don't work at all.
Is there a way to do this ? If yes how? If not, what are my options?
Thanks in advance, Pedro.
The code does work properly after all. The problem is my IDE, Eclipse. When using the Terminate button, Eclipse simply kills the process instead of send the CTRL+C signal to it. Furthermore it looks like Eclipse has no way of being able to send a CTRL+C signal to a process running on its console.
I have also created a discussion on Eclipse's official forums:
http://www.eclipse.org/forums/index.php/m/1176961/#msg_1176961
And may it some day help some one in a situation similar to mine.
Related
I want to terminate the Apache Mina Ssh Server on the basis of Ctrl+c that are basically SigInt I searched on the google and have looked there are SignalListener but not find any good example of it.
Please share any good example and use in ssh server.
A listener will only trigger if any Sigint or a Signal is sent, Am I right ?
To get access to signal handling you have to use sun's private classes, which makes your code not portable any mode. Anyway...
import sun.misc.Signal;
public static void main(String[] args) {
registerSignalHandler();
}
#SuppressWarnings("restriction")
private static void registerSignalHandler() {
Signal.handle(new Signal("HUP"), (Signal signal) -> {
System.out.println("Hello signal!");
});
}
my goal is to visualize vertx metrics - like for example the counts of messages, which are sent over eventbus and so on.
(please consider thath the following tools are all together on my localhost, nothing resides on separated machines)
Therefor I have used the Hawkular implementation of vertx: http://vertx.io/docs/vertx-hawkular-metrics/java/
First I installed CassandraDB with default settings:
http://www.planetcassandra.org/cassandra/
To build the Hawkular Metrics-alone Server I took an WildFly 10 and deployed the Metrics-warFile from here: https://github.com/hawkular/hawkular-metrics/releases/
When I now start the wildfly server I got under the url :http://localhost:8080/hawkular/metrics the starter screen with "Metrics Service started".
Until now all seem to be running fine....
Now I want to insert metric data - for that i programmed an short verticle with HawkularAPI:
public class Sender extends AbstractVerticle {
public static void main(String[] args) {
VertxOptions options = new VertxOptions();
VertxHawkularOptions hawkularOptions = new VertxHawkularOptions().setEnabled(true).setTenant("hawkular").setHost("localhost").setPort(8080);
options.setMetricsOptions(hawkularOptions);
Vertx.clusteredVertx(options, res -> {
Vertx vertx = res.result();
vertx.deployVerticle(new Sender());
});
}
#Override
public void start() throws Exception {
vertx.setPeriodic(1500, id -> {
vertx.eventBus().send("test", "testSend");
System.out.println("SEND!");
});
}
}
But nothing happens - have i missed something? My opinion was that I perhaps can see some charts for example by hitting :http://localhost:8080/hawkular/metrics /counter/vertx etc....instead of graphics I get following ErrorMessage:
{"errorMsg":"Tenant is not specified. Use 'Hawkular-Tenant' header."}
Hawkular Metrics does not provide charts. You need to start a graphical client like Grafana.
See http://www.hawkular.org/hawkular-clients/grafana/docs/quickstart-guide/
I encountered an issue with the FTP polling of Mule ESB standalone:
The application was running for a few days without issues, and then the FTP polling stopped without giving warning or error.
Logs were showing signs of activity for the FTP polling until it stopped. Afterward nothing, but other connectors were still active (mainly SFTP polling). I enabled DEBUG log on runtime to see if there was still activity, and the corresponding connector threads were completely silent, as if stopped or blocked.
In the end, restarting the application solved the issue temporarily, but I am trying to understand why this occured to avoid facing it again. My suspicion is that the FTP connector threads either stopped or were blocked, preventing further polls.
It may be caused by an extended FtpMessageReceiver we used to prevent file deletion after poll (overriding postProcess() function). However looking in the source code of both this component and the base FTP receiver and connector, I cannot see how it could happen.
Any idea why the poll would suddenly stop without throwing an error?
Here is the current connector configuration:
<ftp:connector name="nonDeletingFtpConnector" doc:name="FTP"
pollingFrequency="${frequency}"
validateConnections="true">
<reconnect frequency="${frequency}" count="${count}"/>
<service-overrides messageReceiver="my.comp.NonDeletingFtpMessageReceiver" />
</ftp:connector>
And the corresponding endpoint:
<ftp:inbound-endpoint host="${ftp.source.host}"
port="${ftp.source.port}"
path="${ftp.source.path}"
user="${ftp.source.login}"
responseTimeout="10000"
password="${ftp.source.password}"
connector-ref="archivingFtpConnector"
pollingFrequency="${ftp.default.polling.frequency}">
<file:filename-wildcard-filter pattern="*.zip"/>
</ftp:inbound-endpoint>
The messageReceiver code:
public class NonDeletingFtpMessageReceiver extends FtpMessageReceiver {
public NonDeletingFtpMessageReceiver(Connector connector, FlowConstruct flowConstruct, InboundEndpoint endpoint, long frequency) throws CreateException {
super(connector, flowConstruct, endpoint, frequency);
}
#Override
protected void postProcess(FTPClient client, FTPFile file, MuleMessage message) throws Exception {
//do nothing
}
}
As you can see we defined a FtpMessageReceiver to avoid the file deletion on poll (this is done further on the flow), but looking in the code I can't see how skipping the super.postProcess() call (which is responsible for deleting the file) may cause issues.
FtpMessageReceiver source code I looked in:
https://github.com/mulesoft/mule/blob/mule-3.5.0/transports/ftp/src/main/java/org/mule/transport/ftp/FtpMessageReceiver.java
Technical config:
Mule Standalone 3.5.0
Ubuntu 14.04.2 LTS
Java OpenJDK Runtime Environment (IcedTea 2.5.6) (7u79-2.5.6-0ubuntu1.14.04.1)
Any help would be appreciated. Thanks by advance !
As discussed in the comments, the bug was more linked to the Apache FTP Client and I created a specific post here.
Here is the solution found: using a custom FtpConnectionFactory to configure the client correctly with a timeout value > 0. This way the hanging is interrupted with a timeout exception being thrown.
public class SafeFtpConnectionFactory extends FtpConnectionFactory{
//define a default timeout
public static int defaultTimeout = 60000;
public static synchronized int getDefaultTimeout() {
return defaultTimeout;
}
public static synchronized void setDefaultTimeout(int defaultTimeout) {
SafeFtpConnectionFactory.defaultTimeout = defaultTimeout;
}
public SafeFtpConnectionFactory(EndpointURI uri) {
super(uri);
}
#Override
protected FTPClient createFtpClient() {
FTPClient client = super.createFtpClient();
//Define the default timeout here, which will be used by the socket by default,
//instead of the 0 timeout hanging indefinitely
client.setDefaultTimeout(getDefaultTimeout());
return client;
}
}
And then attaching it to the connector:
<ftp:connector name="archivingFtpConnector" doc:name="FTP"
pollingFrequency="${frequency}"
validateConnections="true"
connectionFactoryClass="my.comp.SafeFtpConnectionFactory">
<reconnect frequency="${reconnection.frequency}" count="${reconnection.attempt}"/>
</ftp:connector>
I'll try to update this answer if there is any notable change on the other.
This might be a very trivial question, but I'm having trouble finding an answer:
Using the Google Plugin for Eclipse, I would like to develop a plain old Java application (not a web-app), that uses AppEngine for cloud storage.
For this, I could, of course, simply create two projects, one containing the AppEngine server and one containing the Java application.
But I'm wondering whether it is possible to set up a single project in Eclipse that contains both the server and the client code (like for a GWT project). To execute it for local debugging, I would then want Eclipse to launch Tomcat to make my servlets available and then launch my Main.java from the client directory of the project as if the project was just a simple Java application. Is this what the "Launch and deploy from this directory" checkbox is for in the "Google" -> "Web Application" settings? If so, how do I use it?
I found one way to do it, but it's a bit cheesy.
First, add the following helper-class to the project:
// other imports
import com.google.appengine.tools.development.DevAppServerMain;
public class DevServer {
public static void launch(final String[] args) {
Logger logger = Logger.getLogger("");
logger.info("Launching AppEngine server...");
Thread server = new Thread() {
#Override
public void run() {
try {
DevAppServerMain.main(args); // run DevAppServer
} catch (Exception e) { e.printStackTrace(); }
}
};
server.setDaemon(true); // shut down server when rest of app completes
server.start(); // run server in separate thread
URLConnection cxn;
try {
cxn = new URL("http://localhost:8888").openConnection();
} catch (IOException e) { return; } // should never happen
boolean running = false;
while (!running) { // maybe add timeout in case server fails to load
try {
cxn.connect(); // try to connect to server
running = true;
// Maybe limit rate with a Thread.sleep(...) here
} catch (Exception e) {}
}
logger.info("Server running.");
}
}
Then, add the following line to the entry class:
public static void main(String[] args) {
DevServer.launch(args); // launch AppEngine Dev Server (blocks until ready)
// Do everything else
}
Finally, create the appropriate Run Configuration:
Simply click "Run As" -> "Web Application". To create a default Run Configuration.
In the created Run Configuration, under the "Main"-tab select your own entry class as the "Main class" instead of the default "com.google.appengine.tools.development.DevAppServerMain".
Now, if you launch this Run Configuration, it will first bring up the AppEngine server and then continue with the rest of the main(...) method in the entry class. Since the server thread is marked as a daemon thread, once the other code in main(...) completes, the application quits normally, shutting down the server as well.
Not sure if this is the most elegant solution, but it works. If someone else has a way to achieve this without the DevServer helper-class, please do post it!
Also, there might be a more elegant way to check whether the AppEngine server is running, other than pinging it with a URL connection as I did above.
Note: The AppEngine Dev Server registers its own URLStreamHandlerFactory to automatically map Http(s)URLConnections onto AppEngine's URL-fetch infrastructure. This means that you get errors complaining about missing url-fetch capabilities if you then use HttpURLConnections in your client code. Luckily, this can be fixed in two way as described here: Getting a reference to Java's default http(s) URLStreamHandler.
If you definitely want to use appengine, then you will end up creating two projects, one on appengine and another a standalone (no servlets). In this case you can take a look at appengine Remote API
I've been playing with the new Servlet 3.0 async features with Tomcat 7.0.4. I found this Chat Application, that lets clients hang on GET request to get message updates. This is working just fine when it comes to receiving the messages.
The problem arises when the client is disconnected i.e. the user closes the browser. It seems that the server does not raise IOException, even though the client has disconnected. The message thread (see the source code from link above) is happily writing to all stored AsyncContext's output streams.
Is this a Tomcat bug? or am I missing something here? If this is not a bug, then how I'm supposed to detect whether the client has closed the connection?
The code there at line 44 - 47 is taking care of it,
} catch(IOException ex) {
System.out.println(ex);
queue.remove(ac);
}
And here too at 75 - 83, using timeout thingie,
req.addAsyncListener(new AsyncListener() {
public void onComplete(AsyncEvent event) throws IOException {
queue.remove(ac);
}
public void onTimeout(AsyncEvent event) throws IOException {
queue.remove(ac);
}
});
EDIT: After getting a little more insight.
Tomcat 7.0.4 is still in beta. So, you can expect such behaviour
I tried hard but can't find the method setAsyncTimeout() in the doc, neither here, nor here. So, I think they dropped it completely in the final version due to some unknown valid reason
The example states, "why should I use the framework instead of waiting for Servlet 3.0 Async API". Which infers that its written before the final thingie
So, what I can say, after combining all these fact, that you are trying to work with the thing that is broken in a sense. That also, may be, the reason for different and weird results.