Communication between two Machines using java - java

I have Gui Application written which running on windows,and i want to connect to remote unix machine and perform actions there such like API's ,go over the log file in the machines and send back to the application the last log file or others API that i want to perform on the remote machine.
In the remote machine i don;t have application server i just have Java which installed there.
I want to use Java in order to perform remote API over the remote machine;
what is the advice ,can i use web services ,can any one please advise.
Thanks in advance.

If Java can perform the actions you're talking about, I would use Sockets to communicate with the UNIX-Machine (over TCP/IP).
Your Windows-PC would be the client sending commands to the Unix-PC.

Web services would be a bit heavy handed option, esp if you opt for the SOAP ones. If you don't have a problem with the client and server always being Java, RMI seems to be the simplest solution to this problem since it's communication between two different JVM's using the normal method calling mechanism (with some additional interfaces and rules to be followed to please the RMI specification).

The Spring Framework ships with a number of remoting options that are all very easy to setup. You can use their classes for simpler configuration of something standard like RMI or JMS, or use a lightweight web services protocol such as Spring's HTTP invoker or Hessian.

For analyzing log files of remote machines you can always use Apache Commons sftp programmatically to FTP a copy of the remote log file to your PC.
If you configure the log files to be rotatable or to rotate each time they reach a specific size, you can avoid reloading the same information over and over.

You can use Ganymed SSH-2 for Java to ssh to the remote host from Client Java App and run the commands. No need to run any additional components on remote server. You can do password based authentication or key based authentication to login to remote host. We had successfully used it to administer (start/stop/grep log files, etc.) applications running on remote UNIX hosts. You can capture output of the remote command using the StreamGobbler class provided in the package. You can pass multiple commands separated by semi-colon in one remote call.
Basic Example included in the package:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
public class Basic
{
public static void main(String[] args)
{
String hostname = "127.0.0.1";
String username = "joe";
String password = "joespass";
try
{
/* Create a connection instance */
Connection conn = new Connection(hostname);
/* Now connect */
conn.connect();
/* Authenticate.
* If you get an IOException saying something like
* "Authentication method password not supported by the server at this stage."
* then please check the FAQ.
*/
boolean isAuthenticated = conn.authenticateWithPassword(username, password);
if (isAuthenticated == false)
throw new IOException("Authentication failed.");
/* Create a session */
Session sess = conn.openSession();
sess.execCommand("uname -a && date && uptime && who");
System.out.println("Here is some information about the remote host:");
/*
* This basic example does not handle stderr, which is sometimes dangerous
* (please read the FAQ).
*/
InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
while (true)
{
String line = br.readLine();
if (line == null)
break;
System.out.println(line);
}
/* Show exit status, if available (otherwise "null") */
System.out.println("ExitCode: " + sess.getExitStatus());
/* Close this session */
sess.close();
/* Close the connection */
conn.close();
}
catch (IOException e)
{
e.printStackTrace(System.err);
System.exit(2);
}
}
}

Related

How do I connect to a remote Cassandra instance running in Docker to retrieve data using Java?

I'm trying to connect to a remote machine which has docker installed. I want to exec into the docker container and connect to database and then fetch a table data using java.
Following are my commands that i'm trying to execute.
docker exec it containerID - to login to docker container
cqlsh -u username -p password -- to connect to cassandra DB
use keyspace; ---to connect to cassandra keyspace
desc tables; --- to view the tables that are available in keyspace.
Following is the Java code that I'm trying. Can someone let me know if this approach is correct or what should i do to make this code work. I'm completely new to java code.
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
public class ExecuteanyCommands {
public static void main(String[] args) throws JSchException, InterruptedException, IOException {
//JSch
JSch jsch = new JSch();
Session session = jsch.getSession("cambi", "10.10.96.20", 22);
session.setPassword("axone");
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
Channel channel = session.openChannel("exec");
InputStream in = channel.getInputStream();
((ChannelExec) channel).setCommand("docker exec -it containerID; cqlsh -u username -p password; use keyspace; desc tables;");
channel.connect();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while((line = reader.readLine()) != null) {
System.out.println(line);
}
channel.disconnect();
session.disconnect();
}
}
If you want to connect to a container from a remote machine over SSH, then the way to do it is to define an SSH tunnel, external to your Java program.
In addition, the idea of interacting with Cassandra by running cqlsh on the host is very unusual.
It's better to use the official Cassandra Java driver for that purpose.
To summarize:
Create an SSH tunnel between the client and the docker host
Write a Java program that uses the Java Driver to query Cassandra
I echo Jonathan Jacobson's point that your method isn't the correct. Running cqlsh which itself is an app/client to retrieve data from your Cassandra tables is incorrect.
You need to instead use one of the available Cassandra drivers to connect to your cluster. In your case, it would be the Java driver for Apache Cassandra.
On the Astra DB docs site, there's a fully working Java code example for connecting to a cluster. Here's a stripped down version that you can use:
import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.cql.ResultSet;
import com.datastax.oss.driver.api.core.cql.Row;
public class ConnectDatabase {
public static void main(String[] args) {
try (CqlSession session = CqlSession.builder()
.withAuthCredentials("your_username","your_password")
.build()) {
// select the release_version from the system.local table
ResultSet rs = session.execute("SELECT release_version FROM system.local");
Row row = rs.one();
// print the results to the console
if (row != null) {
System.out.println(row.getString("release_version"));
} else {
System.out.println("An error occurred.");
}
}
System.exit(0);
}
}
You'll need to get a copy of the example pom.xml file to compile the app. You can get more information about the Java driver here.
Note that you will need to expose the ports in Docker so that Cassandra is accessible from outside the container. For example, map the CQL port with -p 9042:9042.
If you're new to Cassandra, I recommend having a look at datastax.com/dev which has lots of free hands-on interactive learning resources. In particular, the Cassandra Fundamentals learning series lets you learn the basic concepts quickly.
For what it's worth, you can also use the Stargate.io data platform. It allows you to connect to a Cassandra cluster using APIs you're already familiar with. It is fully open-source so it's free to use. Here are links to the Stargate tutorials on datastax.com/dev: REST API, Document API, GraphQL API, and more recently gRPC API.
Finally, we also run live workshops for free to teach developers how to build apps for Cassandra. We provide all the materials including all the source code for fully working apps plus coding environments on the cloud so there's nothing for you to install. There are 2-3 workshops every week and details are at datastax.com/workshops. Cheers!

How to programmatically connect internet via datacard with AT commands?

I have a datacard ZTE MF190. I want to use AT commands to register in 2G or 3G and access internet via datacard. Found this article about how to make data call:
AT+cgatt=1
AT+CGDCONT=1,”IP”,”epc.tmobile.com” //I used my operator PDP context
AT+CGACT=1,1
But ping from OS terminal shows 100% package loss.
I've tried on Ubuntu 14 and Windows 7.
How can I connect internet with AT commands using datacard on Ubuntu?
UPDATE
I gave bounty to #tripleee's answer because it's more full than first one and answered all my questions. But I'm not satisfied with answers, so I'll answer my own question in a week.
In my answer I'll show how to handle this process with Java. So, please do not move this question to other Stack Exchange websites.
Creating a connection between the card and your provider is not sufficient. You need some mechanism for creating a network interface out of this connection, and set up your network stack to route packets over this interface.
Traditionally, the pppd daemon has been a popular choice for this task. You would create a "chat script" with the commands for establishing a data call (these days, pppd might come packaged with a suitable canned script) and the daemon would handle the entire process of placing the call, authenticating, setting up a network interface over the circuit, and configuring the system to route packets over it, as well as configuring DNS etc to use it for resolver queries, etc.
I tried to sniff USB port but on this case dashboard can not connect because of busy port
It is certainly possible. See this question
Found this article about how to make data call
What that article is about is how to set up the call, not how to make it.
After you made correct setup, connect to internet with this command:
ATD*99***1#
UPDATE1: After a bit of research I believe that article was written only to promote their software and has no practical use. In reality dialing is made with pppd or wvdial
UPDATE2: We discussed ways to solve the problem in a chat room (in Russian). It turned out cnetworkmanager will be the way to go
As far as I know wvdial uses ppp daemon to connect to the internet using modem. wvdial is preinstalled on desktop version of Ubuntu.
wvdial uses a config file located /etc/wvdial.conf. Let's edit this file. Type in your terminal
sudo nano /etc/wvdial.conf
and you will see something like this
[Dialer Defaults]
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2
Stupid Mode = yes
ISDN = 0
Modem Type = Analog Modem
New PPPD = yes
Phone = *99#
Modem = /dev/ttyUSB2
Username = ''
Password = ''
Baud = 9600
Dial Timeout = 30
Dial Attempts = 3
Explanation of all keys you can find in wvdial.conf(5) - Linux man page. If you need to change your provider dial number, username, password or any other information about connection and device you can change file content and save it.
There are 3 serial ports for ZTE MF190. Normally it's ttyUSB0, ttyUSB1 and ttyUSB2. And in my case ttyUSB2 is for internet connection. It would not work on other ports. So you need to find the right serial port for your modem.
There is an automatic configurator which edits wvdial.conf file, sets serial port baud rate etc. Since it is not always configure correctly I would not recommend to use it:
sudo wvdialconf /etc/wvdial.conf
It would be better if you configure wvdial manually.
Now, when your device connected and wvdial configured to work with device, you can execute this line from terminal:
wvdial
You will see a lot of lines. But if you see those lines - you have succeeded.
local IP address XX.XX.XX.XX
remote IP address XX.XX.XX.XX
primary DNS address XX.XX.XX.XX
secondary DNS address XX.XX.XX.XX
Now, how we can use it in programming? I'll provide some code to work with it on Java. You can use this code to dial.
public int dialer() {
// status for debug. If status == 4 then you connected successfully
int status;
// create process of wvdial
ProcessBuilder builder = new ProcessBuilder("wvdial");
try {
// start wvdial
final Process process = builder.start();
// wvdial listener thread
final Thread ioThread = new Thread() {
#Override
public void run() {
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getErrorStream()));
// wvdial output line
String line;
while ((line = reader.readLine()) != null) {
// if "local IP address" line detected set status 1
if (line.contains("local IP address")) {
status = 1;
}
if (line.contains("remote IP address")) {
status = 2;
}
if (line.contains("primary DNS address")) {
status = 3;
}
if (line.contains("secondary DNS address")) {
status = 4;
}
}
reader.close();
} catch (final Exception e) {
}
}
};
// start listener
ioThread.start();
// wait 6 secs and return status. Some kind of timeout
Thread.sleep(6000);
} catch (Exception e) {
}
return status;
}
And here is a disconnector method. All you need is to kill wvdial process and thread will be destroyed:
public boolean disconnect() {
ProcessBuilder builder = new ProcessBuilder("pkill", "wvdial");
try {
builder.start();
return true;
} catch (IOException e) {
return false;
}
}

Using external server restlet framework

I am using the Restlet Framework, but now I want to change to a proper server instead of using localhost.
I have already added my php files (they access the java files using the rest_server URL) to the server's folder and my java files as well, but I am not sure how to change the code so it identifies where the new location of the files is.
Here is the code from IdentiscopeServer (constructor empty):
public static void main(String[] args) throws Exception {
//setsup our security manager
if (System.getSecurityManager() == null){
System.setSecurityManager(new SecurityManager());
}
identiscopeServerApp = new IdentiscopeServerApplication();
IdentiscopeServer server = new IdentiscopeServer();
server.getServers().add(Protocol.HTTP,8888);
server.getDefaultHost().attach("", identiscopeServerApp);
server.start();
}
I guess that the correct line to change is the one with "Protocol.HTTP, 8888". If the address of my new server is http://devweb2013.co.uk/research/Identiscope, how exactly do I set this up? Is there anything else necessary for it to work apart from just moving the files to a folder in the server?
The IdensticopeServerApplication is the following:
public class IdentiscopeServerApplication extends Application {
public IdentiscopeServerApplication() {
}
public Restlet createInboundRoot() {
Router router = new Router(getContext());
//attaches the /tweet path to the TweetRest class
router.attach("/collectionPublic", CollectionPublicREST.class);
router.attach("/collectionPrivate", CollectionPrivateREST.class);
router.attach("/analysis", AnalysisREST.class);
return router;
}
}
Thank you in advance, it is my first time using this Framework.
If I understand you correctly, you just want to run your main() method as the server, correct? In this case, the code for main() needs to be in a location that -- when running -- can provide the service at http://devweb2013.co.uk/research/Identiscope. Since you haven't stated what kind of server you are putting the code, I can't say where the best place to put the code would be. I assume you have superuser privileges on your deployment server, since the URL you provided implies port 80 will be serving your Identiscope web service (port 80 is a privileged port on most OS's). So as an answer, I can only provide general information.
On your deployment server, port 80 must be free (i.e. nothing else should be acting as a web server on port 80 on that machine) and the IdentiscopeApplication must be running on port 80. To do that, you need only change the line:
server.getServers().add(Protocol.HTTP,8888);
to:
server.getServers().add(Protocol.HTTP, 80);
then run the application as a user that is allowed to start servers on port 80 (preferably NOT the superuser). If you haven't already, you will need to get Java running on your deployment server and make sure all Restlet libraries are in the classpath where you plan to run your application.
If I understand what you are trying to do, then this should do the trick.

developing android application with server using web service

I am developing client/server apps (the client is an Android application which sends data to the server). I am developing the server using Java. I already connected the sever application "using NetBeans" using SQL Navigator 5.5. I want to use Json as a middle ware, but I don't know how! What is the most suitable, XML or Json? Do i need to use HTTP? If so, how (as I want to be able to secure the application)?
The other thing that the server should respond to is the Android application by sending "longitude and latitude", for which Android should "geocode" and display on the form of map "location." Also, I need to understand more about the concept of web service that should work on the application.
This is the server code:
(The values that the server should get from the client are "long and lat")
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package pkg;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;
#WebService(serviceName = "lbsws")
public class lbsws {
/** This is a sample web service operation */
#WebMethod(operationName = "hello")
public String hello(#WebParam(name = "name") String longg) {
String result=null;
try
{
Connection con = dbConnection.getdbConnection("system","lbs","orcll", "localhost");
Statement st = con.createStatement();
String lat ="10";
String query="select longg,lat,abs(("+longg+"-longg))/abs(("+lat+"-lat)) as function1 from lbs where abs(("+longg+"-longg))/abs(("+lat+"-lat)) = ("+
"select min(abs(("+longg+"-longg))/abs(("+lat+"-lat))) from lbs)";
ResultSet rs = st.executeQuery(query);
while(rs.next())
{
result = rs.getFloat("longg")+","+ rs.getFloat("lat")+"-"+ rs.getFloat("function1");
}
}
catch(Exception e)
{
System.out.println(e.toString());
}
return result;
}
}
A few things:
1) JSON Thumbs up for the transport layer. Don't give it a second thought.
2) Consuming JSON Web Services. Use HttpClient in Java based systems. Just to get the response back
than you can convert JSON to objects as needed. But calling web service is via HttpClient
3) Creating JSON Services. Well you could use Jersey. There are a few choices. I would recommend developing in Tomcat server. Its faster and not so much up/down as with Java EE servers. There are some other good choices beside Jersey.
But mainly write the simplest thing first and get it working from end-to-end. Thats what you want to do.
Just produce a service that returns the Sytem time and send that back via JSON consume it on the client and display. Then re-evaluate Jersey vs. whatever. But get something running end to end.
So step one is write a JSON Web Service and just test it in the browser. Don't worry about client side right now. Just get the service running and invoke it using the browser. BTW, there are reason to go with RESTful JSON web service. Its a good way to structure your web services.
Never attack two problems at the same time. Forget about connecting to a database until you have got the service up and running with just data that is stubbed out.

WebSockets, GlassFish, Grizzly -- can't connect

I am trying to get started with WebSockets, and trying to write a simple application to send messages back and forth via a websoket.
However, it looks like the socket that I am trying to create never gets connected. Why can that be?
Below is the code of my WebSockets class. When .onConnect() is called, it logs:
I am socket, I was connected. Am i connected? - false
Update: in JavaScript, where I create the socket in question, the readyState is 1, which means "socket open, communication is possble".
import a.b.Misc; //writes logs.
import com.sun.grizzly.websockets.BaseServerWebSocket;
import com.sun.grizzly.websockets.DataFrame;
import com.sun.grizzly.websockets.WebSocketListener;
public class ChatWebSocket_v2 extends BaseServerWebSocket {
private String user;
public ChatWebSocket_v2(WebSocketListener... listeners) {
super(listeners);
}
public String getUser() {
if (user == null) {
Misc.print("User is null in ChatWebSocket");
throw new NullPointerException("+=The user is null in chat web socket");
}
return user;
}
public void setUser(String user) {
Misc.print("Just set user: " + user);
this.user = user;
}
#Override
public void onMessage(String message) {
Misc.print(message +"\n");
}
#Override
public void onMessage(byte[] message) {
Misc.print(new String(message) +" << Bytes\n");
}
#Override
public void onConnect() {
Misc.print("I am socket, i was connected. Am i connected? - " + this.isConnected());
}
#Override
public void onClose(DataFrame df) {
Misc.print("I am socket, i was closed");
}
}
If you're just trying to make a connection somewhere, you might want to try this instead. There is a live working demo and you can download the javascript code and play with it yourself. Note that the javascript code only works if you have it installed on a server (due to browser security because it's 'fancy'.) There is also a step by step browser-based client tutorial in the works that I will post as soon as it's ready. Most proxy servers haven't been upgraded to handle websockets so they will screw up connection request and most people won't be able to connect to websocket servers from work. Firefox 7 (release) or Google Chrome 14 or later support the latest version of the websocket protocol that the demo server runs.
If you want to try to get the grizzly demo working, you might have some debugging to do and maybe I'll help with that. Note that in comments below the article, other people said they couldn't get it working either and I haven't found any follow up. At this point it seems no better than the echo app above even if we do get it running and is possibly overly complicated and underly documented if you're just trying to get started. But if you want to try to get it running, you should 'git' the latest version of the code here, which was at least committed recently and may be fixed.
Then make sure that app.url in the application javascript file is set to your installation directory. His is hard-coded as:
url: 'ws://localhost:8080/grizzly-websockets-chat/chat',
If you're using Firefox 7, the javascript needs to be modified to use the Moz prefix, for example:
if (typeof MozWebSocket != "undefined") { // window.MozWebSocket or "MozWebSocket" in window
ok
} else if (window.WebSocket) { // he uses if ("WebSocket" in window)
ok
} else {
do your print "browser doesn't support websockets"
}
.... then if the browser supports websockets
websocket = new WebSocket(app.url); or
websocket = new MozWebSocket(app.url);
// depending on which it is.
The HLL websocket server demo code has this all sorted out.
(another) UPDATE: As I work through grizzly myself, I found on the Quick Start in the glassfish admin console, there's a hello sample that's pretty easy to set up and run. You'll find instructions there. The sample directory also contains a war file named: websocket-mozilla; so I guess its supposed to use websockets. Someone who's familiar with jsp should review the source code. All I can see is that it's using an http session. No mention of a websocket at all. It's a lot like the hello sample.

Categories

Resources