Access mongo shell from application - java

I am looking for the approach of integrating mongo shell in my application. Wondering whether how to achieve this. There might be two cases,
I created a file which contain mongo query. Also create a list that contain all the credentials of mongodb. The goal of my application is to automatically run the mongo query from the file to mongo shell. I am stuck at how to call and run mongo shell from application.
Or, is there any way to bind mongo shell interpreter in my application? As like https://www.tutorialspoint.com/mongodb_terminal_online.php
My application is written in java .

you can run mongo shell from your java application like this, assuming your mongo binary is correctly linked. But it would be way better to use the java driver instead, as other said.
You can find more about executing mongo query from command line here :
https://docs.mongodb.com/v3.2/tutorial/write-scripts-for-the-mongo-shell/
package test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Test {
public static void main(String[] args) {
Runtime rt = Runtime.getRuntime();
try {
// the query you want to run in mongo, you can get it
// from a file using a FileReader
String query = "db.col.find();";
// the database name you need to use
String db = "database";
// run a command from terminal. this line is equivalent to
// mongo database --eval "db.col.find()"
// it calls the mongo binary and execute the javascript you
// passed in eval parameter. It should work for both unix and
// windows
Process pr = rt.exec(new String[]{"mongo", db, "--eval", query});
// read the output of the command
InputStream in = pr.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder out = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
}
// print the command and close outputstream reader
System.out.println(out.toString());
reader.close();
} catch (IOException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

You can do the things you want using the Java MongoDB driver. This is the way MongoDB is intended to be accessed using Java and that is how I would do it. While I'm sure you could find a way to access the shell from Java, it seems like a hack.
I would use the Java driver unless you have a compelling reason to do otherwise. For your specific needs look at the Eval function.
Regarding your second example - I suspect that is just a web front end that is styled to look like a terminal instance. It is probably using whatever server side language driver to execute the commands.

Related

Passing data from Java process to a python script

I call a external Python script as Java process and want to send data to this. I create a process and try to send a string. Later the python script should wait for a new input from Java, work with this data and wait again(while true loop).
Python Code (test.py):
input = input("")
print("Data: " + input)
Java Code:
Process p = Runtime.getRuntime().exec("py ./scripts/test.py");
BufferedWriter out = new BufferedWriter(new
OutputStreamWriter(p.getOutputStream()));
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
System.out.println("Output:");
String s = null;
out.write("testdata");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
The process and output of simple prints works, but not with input and BufferedWriter.
Is it possible to send data to this python input with a Java process?
I read from other solutions:
create a Python listener and send messages to this script
import the external script to Jython and pass data
Are this better solutions to handle my problem?
use Process class in java
what is process class ?
this class is used to start a .exe or any script using java
How it can help you
Create your python script to accept command line variables and send your data from java class to python script.
for Example:
System.out.println("Creating Process");
ProcessBuilder builder = new ProcessBuilder("my.py");
Process pro = builder.start();
// wait 10 seconds
System.out.println("Waiting");
Thread.sleep(10000);
// kill the process
pro.destroy();
System.out.println("Process destroyed");
Later the python script should wait for a new input from Java
If this has to happen while the python process is still a subprocess of the Java process, then you will have to use redirection of I/O using ProcessBuilder.redirect*( Redirect.INHERIT ) or ProcessBuilder.inheritIO(). Like this:
Process p = new ProcessBuilder().command( "python.exe", "./scripts/test.py" )
.inheritIO().start();
If the python process is going to be separate (which is not the case here, I think) then you will have to use some mechanism to communicate between them like client/server or shared file, etc.

Calling bash script from Java

I have this MCVE for an Java class calling a bash script:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class Test
{
static BufferedReader in;
public static void main(String[] args) throws Exception
{
String[] cmd = new String[]{"/bin/sh", "/usr/myapp/myscript.sh", "parameter1"};
Process pr = Runtime.getRuntime().exec(cmd);
in = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line = in.readLine();
while(line != null)
{
System.out.println(line);
line = in.readLine();
}
}
}
When I have the compiled .class file in the same directory as myscript.sh, it works just fine.
As soon as I move the .class file to another folder, it doesn't execute the script anymore, although I am still using the absolute path to the script.
I tested this with JDK 1.8 on a BeagleboneBlack running Angstrom if this information is good for something.
How can I run the script, although it is in a different location?
Using the getErrorStream hint by Samuel really helped.
It was clear, that some sub-scripts that were in the same folder as the original shell script were not found.
The solution was as easy as using absolute paths to sub-scripts as well since the working directory is not the one of the called script but the one of the calling application (in my case the Java App)

Can't enter password using Java ProcessBuilder to interact with a CLI

I'm trying to interact with a CLI on a server from a web browser. On the server side, I'm using a Java Servlet running on JBoss AS 7.1.1.Final. The CLI is an ovirt-engine tool (ovirt-iso-uploader). In order to use it, you have to provide the REST API password when it requests it.
Therefore, here is the following code I'm using to interact with the CLI:
private String executeCommand(String command) {
System.out.println("Executing command: " + command);
String[] commands = new String[]{"/bin/sh","-c",command};
try {
ProcessBuilder builder = new ProcessBuilder(commands);
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
System.out.println(line);
if (line.contains("Please provide the REST API password")){
writer.write( "password\n" );
writer.flush();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
However, whatever input command I'm using, I always have the same problem. (For this example I used the command ovirt-iso-uploader list to list all the ISO storage domains. You can find the documentation of the CLI here)
11:31:34,282 INFO [stdout] (http--0.0.0.0-8080-2) Executing command: ovirt-iso-uploader list
Please provide the REST API password for the admin#internal oVirt Engine user (CTRL+D to abort):
So the execution is blocked here as the CLI is waiting for the password and the Servlet can't see the line Please provide the REST API password for the admin#internal oVirt Engine user (CTRL+D to abort): as it is not send in [stdout]. However, it is working if I manually enter the password directly in the terminal.
Therefore, my question is how can I read the password request from the CLI and answer to it ?
Thank you for your time.
I would suggest that buffered reader is the wrong thing to use as it may be waiting for a newline at the end of the prompt which is not there and can not therefore return a line.
I think you will have to read the stream directly. Maybe character by character or byte by byte.
It may also not be necessary to wait for the prompt. In unix shell programming it is common to provide the standard input without reference to prompt like:
Command <!
Lineone
line two
!

Calling Python from Java (Tomcat6) as sub-process

I am trying to call a python script from a java/tomcat6 webapp. I am currently using the following code:
Process p = Runtime.getRuntime().exec("python <file.py>");
InputStream in = p.getInputStream();
InputStreamReader isr = new InputStreamReader(in);
BufferedReader b = new BufferedReader(isr);
logger.info("PYTHON OUTPUT");
String line = null;
while ( (line = b.readLine()) != null){
logger.info(line);
}
p.waitFor();
logger.info("COMPLETE PYTHON OUTPUT");
logger.info("EXIT VALUE: "+p.exitValue());
I can't really see any output in the catalinia.out file from the python script and using an adapter library like jython is not possible as the script relies on several machine learning libraries that need python's Numpy module to work.
Help?
The explanation is probably one (or more) of following:
The command is failing and writing error messages to its "stderr" fd ... which you are not looking at.
The command is failing to launch because the command name is incorrect; e.g. it can't be found on $PATH.
The command is trying to read from its stdin fd ... but you haven't provided any input (yet).
It could be a problem with command-line splitting; e.g if you are using pathnames with embedded spaces, or other things that would normally be handled by the shell.
Also, since this is python, this could be a problem with python-specific environment variables, the current directory and/or the effective user that is executing the command.
How to proceed:
Determine if the python command is actually starting. For instance. "hack" the "" to write something to a temporary file on startup.
Change to using ProcessBuilder to create the Process object. This will give you more control over the streams and how they are handled.
Find out what is going to the child processes "stderr". (ProcessBuilder allows you to redirect it to "stdout" ...)

Fetching a file from a PHP file in Google App Engine

I need to know if there is anyway that I can use file_get_html or any equivalent function in php on GAE? I know it has something called URLFetch() but I am not able to understand how I will call that from a php file.
Any help?
You cannot run PHP on Google App Engine. You can create a servlet which will read from any given URL and manipulate the data in any way you would need to, in Java (since you tagged this question with the Java tag).
From the AppEngine URL Fetch Java API Overview:
URL url = new URL("http://www.example.com/atom.xml");
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = reader.readLine()) != null) {
// ...
}
reader.close();
If you meant that you are running PHP in another application and you wish to call your AppEngine servlet from said PHP application, then you can map the servlet which performs this URL fetch to a URL within your AppEngine application, then hit that URL from your PHP application. This, however, seems like a bad design, as you're making two network calls when you could have just used done it within the PHP application in the first place.
Here's a quick and dirty wrapper function I created for URL Fetch using PHP via Quercus on Google App Engine:
function fetch_url($url){
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
$java_url = new URL($url);
$java_bufferreader = new BufferedReader(new InputStreamReader($java_url->openStream()));
while (($line = $java_bufferreader->readLine()) != null) {
$content .= $line;
}
return $content;
}
// Sample usage:
echo fetch_url('http://google.com');
Hope this helps someone who is as lost as I was.

Categories