Unable to execute CURL command through java Runtime.getRuntime().exec() - java

I am executing a curl command using java.
curl -i --user "OAMADMIN_tenant_358922247351079_svc_358922247369079_APPID:Iuj.2swilg5fhv" -H "Content-Type: application/json" -H "Accept: application/json" -H 'X-USER-IDENTITY-DOMAIN-NAME: tenant_358922247351079' -H "X-RESOURCE-IDENTITY-DOMAIN-NAME: tenant_358922247351079" --request GET "https://slc04yre-1.dev.oraclecorp.com:4443/oam/services/rest/11.1.2.0.0/oauth/admin/Clients?name=myMCS_svc_358922247369079_MCS_Client_OAUTHCLIENT"
I want to get the output of this curl command in my code,but my stdoutput is coming out to be empty.
private static String executeCommand(String command) {
StringBuffer output = new StringBuffer();
Process p;
try {
p = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(
p.getInputStream()));
//p.waitFor();
String line = "";
while ((line = reader.readLine()) != null) {
System.out.println("line="+line);
output.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
return output.toString();
}
Tried executing the curl command manually, its working fine.
Then I printed the standard error, and I can see:
[testng] error line=
[testng] error line=curl: (6) Couldn't resolve host 'application'
[testng] error line=
[testng] error line=curl: (6) Couldn't resolve host 'application'
[testng] error line=
[testng] error line=curl: (6) Couldn't resolve host 'tenant_359516638431079''
[testng] error line=
[testng] error line=curl: (6) Couldn't resolve host 'tenant_359516638431079"'
[testng] error line=
[testng] error line=curl: (1) Unsupported protocol: "https
When curl command is executed manually, its working fine then why not through Runtime.getRuntime() ?
Kindly suggest!! Any help will be appreciated.

It seems like the data shell/console is interpreting/changing characters. For example the following line:
-H "Content-Type: application/json"
... seems to be getting interpreted as three different arguments:
-H Content-Type: and application and /json by the shell/console.
Try breaking the command string down into an array of components using the format:
exec(String[] cmdarray)
That way it will be clear to the shell/console which arguments are grouped together.
Here is a test in groovy that proves the point:
def Object executeCommand(command) {
def proc = Runtime.getRuntime().exec(command);
def sout = new StringBuffer()
def serr = new StringBuffer()
proc.consumeProcessOutput(sout, serr)
proc.waitFor()
return [ 'sout':sout.toString(), 'serr':serr.toString() ]
}
response = executeCommand('''curl --silent --show-error -H "Accept: application/json" --request GET "https://education.cloudant.com/"''')
assert response['sout'] == ''
assert response['serr'].startsWith( 'curl: (6) Could not resolve host: application' )
response = executeCommand(['curl', '--silent', '--show-error', '-H', 'Accept: application/json', '--request', 'GET', 'https://education.cloudant.com/'] as String[] )
assert response['sout'].startsWith('{"couchdb":"Welcome","version":"1.0.2","cloudant_build":"2367"}')
assert response['serr'] == ''

Related

Pass Blank space in Json value in curl command string in Java

I am sending a POST request using curl command string in Java. I am passing json in the command string which has spaces in the values. I am getting an error when compiler encounters space in json. I need to retain spaces and pass the values in the string curl command. Please help. i would be great if someone can re-write my string[] command to help me understand my mistake. Here is my code.
String[] command = { "curl", "-X", "POST", "http://my.url.com/add", "-H", "accept: application/json", "-H", "AuthorizationToken: 123", "-H", "Content-Type: application/json", "-d", "{\"FieldLabels\":\"Name,Status,Employee number\",\"FieldValues\":\"test7,Planned,Raj Kumar(123)\",\"Type\":\"BT\"}" };
ProcessBuilder process = new ProcessBuilder(command);
Process p;
try
{
p = process.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
StringBuilder builder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
builder.append(line);
builder.append(System.getProperty("line.separator"));
}
String result = builder.toString();
System.out.print(result);
}
catch (Exception e)
{
e.printStackTrace();
}
Error:
{
"message" : {
"statusCode" : "500",
"Status" : "Internal Server Error",
"requestedURI" : "/api/EFormService/createEFormItemData",
"error" : "Expected a ':' after a key at character 25 of {FieldLabels:Name,Status,Employee"
}
}
Try to place the json request in a file and use the below format in the curl request
--data "#<path/to/file>"
'#' represent the request data is in a file in the path follows.
for your example:
data:
{"FieldLabels":"Name,Status,Employee
number","FieldValues":"test7,Planned,Raj Kumar(123)","Type":"BT"}
this data need to be saved into a file eg: /tmp/reqData
then below is your command
{ "curl", "-X", "POST", "http://my.url.com/add", "-H", "accept: application/json", "-H", "AuthorizationToken: 123", "-H", "Content-Type: application/json", "-d", "#/tmp/reqData" };
i have created JSON object, opened a connection with httpurlconnection, set header parameters and pass jason object in body. it worked. Thanks Sarath.

How to run a curl command from java? [duplicate]

This question already has an answer here:
Using curl command in java
(1 answer)
Closed 4 years ago.
I am trying to make a POST request from Java using curl. It also has some payload. I am getting status code 400. What am I missing?
Following is the curl I use in terminal..
curl --cookie "token=xyzxyzxyzxyz" --header "Content-Type:application/json" --data
{"branchName":"name","branchId":"bid","sourceBranch":"sb","alias":"pppp","mainPackageFullPath":"main.full.path"}'
-k http://app.aws.application/api/random/create
You can do it like this
String branchName="name";
String branchId="bid";
String sourceBranch="sb"
String alias="ppp"
String[] command = {"curl" "-k" "-i" "-X" POST "-H" "Content-Type: multipart/form-data" --cookie "rsession=your rsession" "Content-Type:application/json" --data{branchName+":"+branchId":"+sourceBranch":",+alias}};
ProcessBuilder process = new ProcessBuilder(command);
Process p;
try
{
p = process.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
StringBuilder builder = new StringBuilder();
String line = null;
while ( (line = reader.readLine()) != null) {
builder.append(line);
builder.append(System.getProperty("line.separator"));
}
String result = builder.toString();
System.out.print(result);
}
catch (IOException e)
{ System.out.print("error");
e.printStackTrace();
}

Execute Curl from Java

I am trying to execute the following curl command from Java, but the answer I get is incorrect, since it always returns the status 401.
curl -k -v -u "admin2:0xdRv63RKq2MtA326BNGQAI6yA1QNGO09enamGxI" -d "{"username":"test","token_code":"246212"}" -H "Content-Type: application/json" https://192.168.101.59/api/v1/auth/
I am sending correctly the user "admin2" with his password for the authentication. I think the problem is the use of character (") in my code.
String[] command = {"curl", "-k", "-v", "-u","admin2:0xdRv63RKq2MtA326BNGQAI6yA1QNGO09enamGxI",
"-d", "{\"username\":\"test\",\"token_code\":\"246212\"}","-H", "Content-Type: application/json", "https://192.168.101.59/api/v1/auth/"};
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
String curlResult = "";
String line = "";
try {
Process process = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(process.getInputStream()));
while (true) {
line = r.readLine();
if (line == null) {
break;
}
curlResult = curlResult + line;
}
} catch (Exception e) {
e.printStackTrace();
}
In 'command', try removing the single quotes from
"'admin2:0xdRv63RKq2MtA326BNGQAI6yA1QNGO09enamGxI'"
so that it becomes
"admin2:0xdRv63RKq2MtA326BNGQAI6yA1QNGO09enamGxI"
and see if that helps. It might be considering them as part of the actual username and password.
I think the issue is the Json in this case and I think you are right then that the double quotes are the issue. Try putting the Json in a file and use curl to send the file contents as the body of your message.
String[] command = {"curl", "-k", "-v", "-u","admin2:0xdRv63RKq2MtA326BNGQAI6yA1QNGO09enamGxI",
"-d", "#/path/to/filename.json", "-H", "Content-Type: application/json", "https://192.168.101.59/api/v1/auth/"};

How to get processbuilder command before execution

I want to know the command that will be executed before it happens.
String cmd[] = {"curl",
"-X",
"POST",
"https://api.renam.cl/medicion/insert?access-token={Yoq3UGQqDKP4D1L3Y6xIYp-Lb6fyvavpF3Lm-8cD}",
"-H",
"content-type: application/json",
"-d",
json.toString()};
ProcessBuilder pb = new ProcessBuilder(cmd);
Log.debug("COMANDO.TOSTRING " + pb.command().toString());
Process p = pb.start();
Log.debug(p.getOutputStream().toString());
p.waitFor();
BufferedReader reader
= new BufferedReader(new InputStreamReader(p.getInputStream()));
String readline;
while ((readline = reader.readLine()) != null) {
Log.debug(readline);
}
With the readline I have the server answer output but I don't know hot to get the curl command I have exectuted with the processbuilder.
EDIT 1:
I just need to send this command by using the linux console:
curl -X POST 'https://api.com/data/insert?access-token=Yoq3UGQqDKP4D1L3Y6xIYp-Lb6fyvavpF3Lm-8cD' -H 'content-type: application/json' -d '{ "pm25":2, "timestamp":1495077872, "dispositivo_mac": "12:34:56:78:90:12" }'
Basically I need to print the cmd array processed by the ProcessBuilder object to see it before the star method execution.
I had success with this code:
ProcessBuilder pb = new ProcessBuilder(command);
logger.debug(String.join(" ",pb.command().toArray(new String[0])));
Here is code for printing the runnable command:
private String getRunnableCommand(ProcessBuilder processBuilder)
{
List<String> commandsList = processBuilder.command();
StringBuilder runnableCommandBuilder = new StringBuilder();
int commandIndex = 0;
for (String command : commandsList)
{
if (command.contains(" "))
{
runnableCommandBuilder.append("\"");
}
runnableCommandBuilder.append(command);
if (command.contains(" "))
{
runnableCommandBuilder.append("\"");
}
if (commandIndex != commandsList.size() - 1)
{
runnableCommandBuilder.append(" ");
}
commandIndex++;
}
return runnableCommandBuilder.toString();
}
It will surround arguments containing spaces properly with quotation marks.

Java runtime exec psql logging

I can run the following via bash and it will work:
psql -h <host> -p <port> -d <dbname> -U <username> -w -v username="'user'" -v rid=2 -c '\ir ../../../resources/sql/myFile.sql'
When I try to run the command in Java using the following, it doesn't do anything but it doesn't throw an error either. Is there a way I can log what the exec in Java is doing so I can see why it isn't working?
try {
String line;
log.error("Working Directory = " +
System.getProperty("user.dir"));
Process p = Runtime.getRuntime().exec("psql -h <host> -p <port> -d <dbname> -U <username> -w -v username=\"'user'\" -v " +
"rid=2 -c '\\ir sql/myFile.sql'");
log.error("HERE");
BufferedReader input =new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
log.error(line);
}
input.close();
log.error("here2");
} catch (Exception e) {
log.error("Error occurred" + e.toString());
}
HERE and here2 print out to the console, but nothing in Error occurred.
The process exit value is 1.
In case other people run into this as well. I was able to get more information about errors by using the following:
InputStream stderr = p.getErrorStream();
InputStreamReader isr = new InputStreamReader(stderr);
BufferedReader br = new BufferedReader(isr);
System.out.println("<ERROR>");
while ( (line = br.readLine()) != null)
System.out.println(line);
System.out.println("</ERROR>");
int exitVal = p.waitFor();
System.out.println("Process exitValue: " + exitVal);
I found this in this article: http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html

Categories

Resources