Connect to kubernetes container and curl inside of it in Java - java

I'm trying to connect to one of my containers inside my cluster and execute multiple curl commands programmatically in Java.
To solve this I've written the following code:
String[] executeResetServerCachesBatFileCommand = {"cmd.exe", "/C", "start", "resetServerCaches.bat"};
ProcessBuilder cacheResetBuilder = new ProcessBuilder(executeResetServerCachesBatFileCommand);
cacheResetBuilder.directory(new File("C:/Program Files/PuTTY/"));
Process cacheReset = cacheResetBuilder.start();
The goal is to run a .bat file which contains multiple commands line by line.
The commands inside the .bat file are as follows:
kubectl exec --stdin --tty <podname> --namespace=<namespace> -- /bin/bash (connect to container)
curl -X DELETE -H "Authorization: Basic <auth> <url>
curl -X DELETE -H "Authorization: Basic <auth> <url>
curl -X DELETE -H "Authorization: Basic <auth> <url>
Don't wonder, I haven't written down the original values.
The bat file gets executed, so that is working. The problem is that after the first command in the .bat file (connect to container, which works) the rest of the commands are not executed or skipped.
I've put commands just as ipconfig or dir on the first line and then connect to the container to debug the problem. I found out that ipconfig and dir get executed just as the connecting part. So the problem is that the kubectl exec command take some seconds to finish and the rest is somehow skipped or bugged out.
I also tried working with "&" and "&&" to wait for the first command but that didn't work either.
I've went to many stackoverflow topics and googled but I couldn't make it.
Maybe someone can help me.
Best regards,
Julian

Related

Execute a .jar file using shell script

I want to execute a jar file of DOMO CLI from a shell script. The jar file itself has some functions which I want to call after I call the main jar file. The problem which I am facing is that after it executes the jar file, I am not able to pass the additional commands to execute inside that jar through a shell script. It just stops after calling jar and doesn't take further commands. Can anyone please help? Below is the code I am calling from a shell script.
java -jar XX.jar
The commands are as below which follow the above jar. So once we enter into the above jar we have to execute the below commands one after the other. I am not sure how to achieve this through a shell script.
connect -s X.domo.com -t Ysssss
upload-dataset -a -i dhdhdhdh -f /prehdfs/dev/comres/herm/data/yyyy.csv
Did you try using pipes and inputs.
When you execute above it runs it under a child shell.
You may try below format if not tried already
$ (echo "connect -s X.domo.com -t Ysssss" && cat) | java -jar XX.jar
If you can reference a file in your use case, you could put your commands in a file.
File: list_my_datasets.domo
connect -t ... -s ...
list-dataset
quit
then run the command:
java -jar domoUtil.jar -script list_my_datasets.domo > datasets
I wanted the data from it so I piped to a file (where I had to grep what I wanted), but you would omit that I believe, unless it has some output you'd want to check. I haven't tested with the upload command, but I would hope any commands substituted or added to the example work similarly.
Domo docs on scripting

Running pmcmd from java

I am trying to run pmcmd and pass arguments from java. This is my code :
String cmd="C:\\Informatica\\9.6.1\\clients\\PowerCenterClient\\CommandLineUtilities\\PC\\server\\bin\\pmcmd.exe";
final Process cmdProcess;
cmdProcess = Runtime.getRuntime().exec(new String[]{cmd,"connect -sv IS_NAME -d DOMAIN_NAME -u USER -p PWD"});
cmdProcess.getOutputStream().close();
The problem is I am not able to get the desired output. I get the following error:
ERROR: Unknown command [connect]
When I try the same command on the command line, it works.
pmcmd>connect -sv IS_NAME -d DOMAIN_NAME -u USER -p PWD
The output:
Connected to Integration Service:[IS_NAME].
Can anyone tell what mistake I am doing?
(adding my comment as an answer, after it worked according to the OP)
Your command line example suggests that the connect -sv ... is issued within the pmcmd process, and not provided as an argument.
So you should probably send that to the process' STDIN (accessed by cmdProcess.getOutputStream()) instead of passing as argument to the call.
pmcmd works in two modes, command line and interactive. connect command works in interactive mode only.
When invoking from java, you are using command line mode, and do not need to connect first. You can directly invoke the command you intend to run (ex. startWorkflow) and provide the connection parameters with that command like below:
pmcmd startworkflow -sv MyIntService -d MyDomain -u seller3 -p jackson ‑f SalesEast wf_SalesAvg
More details here.
I had to issue a command within the pmcmd process. So I modified my code and it works :
String cmd="C:\\Informatica\\9.6.1\\clients\\PowerCenterClient\\CommandLineUtilities\\PC\\server\\bin\\pmcmd.exe";
final Process cmdProcess;
cmdProcess = Runtime.getRuntime().exec(new String[]{cmd,""});
OutputStream out = cmdProcess.getOutputStream();
out.write("connect -sv IS_NAME -d DOMAIN_NAME -u USER -p PWD".getBytes());
out.close;

DigitalOcean: How to run Docker command on newly created Droplet via Java API

I'm trying to create a new Droplet and then kick off a Docker command via a UserData bash script. I set the user data via the Java API when creating the droplet and observe that the test files and logs I made are created.
newDroplet.setUserData("#!/bin/bash\n" +
"touch /test.txt;"+
"docker login --username=myname--password=mypass > /loginlog;"+
"docker pull mybuild > /pulllog;"+
"docker run --log-opt max-size=1g --net host --name myserver -t -i mybuild > /runlog;");
loginlog and pulllog both show successful outcomes. However nothing exists in the file runlog.
I can ssh into the droplet and then run the exact same docker command and it runs as expected. Why can't it be run from a userdata script? Why is no output generated?
The problem ended up being the -t flag in the docker run command. Apparently this doesn't work because it isn't a terminal or something like that. Remove the flag and it runs fine.

Docker running nginx plus jar

I'm trying to run a docker container that contains both a java jar server and nginx in front of it to perform subdomain->port forwarding, and I don't seem to be setting it up correctly.
This is my Dockerfile:
FROM java:8
MAINTAINER somefool
RUN apt-get update
RUN apt-get -y install nginx
COPY theBigOwlServer.jar /data/server.jar
RUN rm -v /etc/nginx/nginx.conf
ADD nginx.conf /etc/nginx/
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
EXPOSE 80 8080
CMD java -jar /data/server.jar
CMD service nginx start #<--- line AAA
The java jar listens on ports 8080 and 8090. When I run this container with -p 80:80 -p 8080:8080, the jar just doesn't seem to start. I don't see any console output from it, and I can't reach it from outside the container with curl localhost:8080. I can reach nginx on port 80, but requests that should be forwarding to the jar are coming back with an empty reply.
However, if I comment out line AAA, then the jar starts fine. It generates console output and curl localhost:8080 reaches it. How can I run nginx and the jar together?
Docker containers are designed for single-process sandboxing, so only take one CMD argument. In this case it's just picking up the last one in the file. If you need to run multiple prorcesses in a container (and sometimes it makes sense to do so) then use something like Supervisor to run your commands for you (so your CMD would run Supervisor). Then you get goodies like process watchdogs and such thrown in too.
You could do something like:
ENTRYPOINT sh -c 'service nginx start && java -jar /data/server.jar'
I tried this out and it worked for me.

Curl syntax simulation in Java

I have a curl syntax in .sh file. I need to run the curl sytnax or curl command in Java replicating the same syntax, but I am facing problem in replicating the same.
$AUTH_OPTION="--basic -u testuser:testpwd"
$HTTP_METHOD=POST
$FILE_OPTION="-d #$INPUT_FILE"
$CONTENT_TYPE="application/xml"
$ACCEPT_TYPE="application/xml"
echo curl -o response.txt -w %{http_code} -k -v $AUTH_OPTION -X $HTTP_METHOD $FILE_OPTION -H \"Content-Type: $CONTENT_TYPE\" -H \"Accept: $ACCEPT_TYPE\"
I have the corresponding Java code as:
StringBuffer curlCmd=new StringBuffer();
curlCmd.append("curl -o response.txt");
curlCmd.append(WHITE_SPACE);
curlCmd.append("-w %{http_code}");
curlCmd.append("-k -v -u testuser:testpwd");
curlCmd.append(WHITE_SPACE);
curlCmd.append("-X POST");
curlCmd.append(WHITE_SPACE);
curlCmd.append("-d #/test/xyz/xml" );
curlCmd.append(WHITE_SPACE);
curlCmd.append("-H"+"Content-type: application/xml");
curlCmd.append(WHITE_SPACE);
curlCmd.append("-H"+" Accept: application/xml");
curlCmd.append(WHITE_SPACE);
This does not seems to work: its not simulating the same behaviour of .sh curl syntax. Can any one help me to sort out this issue?
output
curl -o response.txt -w %{http_code} -k -v -u testuser:testpwd -X POST -d #/path/xyz.xml -H "Content-Type: application/xml" -H "Accept: application/xml"
the problem is xml is not getting accessed properly
I think there are a few possible problems, but one that catches my eye is that you are missing quotes around Content-Type: $CONTENT_TYPE and Accept: $ACCEPT_TYPE, for example:
"-H \"Content-type: application/xml\""
A second error is you have written -d #/test/xyz/xml but it should be:
-d #/test/xyz.xml
If it still doesn't work, can you post the output of both the sh script and your StringBuffer so we can more easily see where the differences are?
If you're using environment variables then you need to make sure that:
they are exported
you execute curl via a shell (e.g. /bin/bash)
The exporting means that the variables are exposed to child processes. The shell execution will expand these prior to calling your executable.
So your invocation will look like:
sh curl ....
It would help to see how you're invoking Process.exec(). One common gotcha is that you need to consume the stdout/stderr of the process concurrently, otherwise your sh/curl process may block waiting for your parent process to consume the output. See here for more details.
You should probably replace %{http_code} with something else on line 4 of the Java code. Environment variables will not be interpolated by Java.
Also, take a look at the Runtime#exec method. This lets you execute commands without having to worry about escaping quotes and such.
It's probably a good idea to make sure that your command runs without problems (such as the server not accepting the posted content) before trying to debug the invocation from java. It's far easier to deal with one problem at a time.

Categories