You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@jmeter.apache.org by Markus Obermann <ma...@yahoo.de.INVALID> on 2019/12/02 16:11:32 UTC

Problems Execute Linux Commands using JSR223 PrePrcessor with Groovy Engine and pipe-symbol

Hi, 

i need to do some wired stuff where i have to call linux commands from jmeter - to be clear its openssl i need to run.Bevore the openssl command is executed i have to "echo" something to my system console and want that this is piped to openssl.So the command i want to execute is this (and it's working perfect on bash)
echo -en "https://my-url.com:8888" | openssl smime -sing -signer cert.crt -inkey cert.key -outform der -binary -md sha384 -out blah.p7

I have a HTTP Sampler and there is a JSR223 PreProcessor as a child with this tiny code://First i get the URL from my Sampler
import org.apache.jmeter.protocol.http.sampler.HTTPSampler;String path = sampler.getURL();
This works and will print out the URL from the Sampler.Then i do this:
log.info("echo -en $path | openssl smime -sing -signer cert.crt -inkey cert.key -outform der -binary -md sha384 -out blah.p7".execute().text)
In my Jmeter console i do see the "log.info" output which looks perfect. BUT it seems that nothing happen. I do not see the -out blah.p7 fileCould it be that jmeter cant handle the pipe-symbol?

If i do some changes to my command and do not echo my command but paste the url as -in directly to my openssl command then its working.Thus i can do this:log.info("openssl smime -in https//my-url.com:8888 -sing -signer cert.crt -inkey cert.key -outform der -binary -md sha384 -out blah.p7".execute().text)

But as im using different urls i cant make it static - i need to determine the url from sampler and paste it to my openssl command.
For sure i will find a way which will work - but maybe someone have an idea about the "pipe-symbol" - or what i'm doing wrong?
Br

Re: Problems Execute Linux Commands using JSR223 PrePrcessor with Groovy Engine and pipe-symbol

Posted by Markus Obermann <ma...@yahoo.de.INVALID>.
 Hello,
sorry for my very late reply and many thanks for your help - it really helped me a lot so i wanna share with you what i have done now and how it is working.
First some background what i needed to do:1) i have an https server where i need to connect using mutual tls which works perfect with the keystore (i only have 1 cert in the keystore)2) i do HTTPS POST request to my API running on this server where i send (text and/or xml) data. The server send me data back which then i store (using jmeters save-response-to-file)3) The tricky part is that i must sign (using S/MIME (p7 signature) the data i wanna send AND my URL using my priv. key and cert. AND THEN i need to do a base64 encoding of this signed file and paste the base64 result string as an specific HTTP-Header and sent this with my request.
Well doing this with openssl using bash works quite well - but doing this with jmeter would be either using bouncy-castle and do s/mime - or i just call my openssl commands from jmeter using groovy :)
So my solution looks like this (it's not yet fully optimized but it works quite good and stable)I use a JSR223 PreProcessor with groovy engine with this code (i also have some user-defined-variables defined thus do not wonder about the vars.get():

<start of code>

1: import org.apache.jmeter.protocol.http.sampler.HTTPSampler;
2: String path = sampler.getPath(); // this was very tricky as i do NOT have to use getURL(); but only the "Path"
3: String datapath = vars.get("datapath");4: String cert = vars.get("cert");5: String key = vars.get("key");6: String tempsave = vars.get("tempsave");

7: p="echo -en $path".execute() | "openssl smime -sign -signer $cert -inkey $key -outform der -binary -md sha384 -out $savetemp/url.p7".execute() | "openssl smime -in $datapath/data.xml -sign -signer $cert -inkey $key -outform der -binary -md sha384 -out $savetemp/file.p7".execute()8: p.text
9: f="base64 -w 0 $savetemp/file.p7".execute().text10: u="base64 -w 0 $savetemp/url.p7".execute().text
11: vars.put("filebase64", f);12: vars.put("urlbase64", u);
<end of code>
Well this works and will do the stuff i need. It was a little bit tricky about the getPath() stuff at line 2.As ive told before i need to sign the URL. Thus i thought this must be everything from beginning with https to end of the line without \r\n and without the method (POST) and without the protocol version which is HTTP/1.1So first what i did in line 2: was a "sampler.getURL()" and print it out on console. It gaves me exact what i first thought is correct namely the URL staring with https://. I also looked on the view results tree what jmeter doing with the POST and it looked quite good. 
But my server said that the URL signature is wrong. Thus i've calculated the URL sign - and send withhin the request - but it was wrong.
Then i've noticed what jmeter was really sending namely "POST /path". This means jmeter has not sent the URL starting with "https://ip:port/path" but only POST /path.Maybe this is because im using an http-request-default-config element?
Well if jmeter sends the /path then i have changed in line 2: from "sampler.getURL()" to "sampler.getPath()" and then it worked.Mostly thats it - the rest was just making some static stuff more generic.
BrMarkus

    Am Mittwoch, 4. Dezember 2019, 19:16:13 MEZ hat Felix Schumacher <fe...@internetallee.de> Folgendes geschrieben:  
 
 
Am 04.12.19 um 11:33 schrieb glinius@live.com:
> As you correctly mentioned, "it's working perfect on bash". 
>
> Groovy knows nothing about the pipe symbol so you need to execute  bash -c
> command <https://www.gnu.org/software/bash/manual/bash.html>  and pass your
> whole command as the parameter, something like:
>
>
>> "/bin/bash -c \"echo -en \\\"https://my-url.com:8888\\\" | openssl smime
>> -sing -signer cert.crt -inkey cert.key -outform der -binary -md sha384
>> -out blah.p7\"".execute().text


Alternatively you could use groovy's magic to write the url to the stdin
of the openssl process by using something like

p = "openssl smime ...".execute()
p.withWriter { writer -> writer.println("https://...") }
p.text

I find it more readable.  It is probably faster, too, as it doesn't need
to instantiate a shell.

On a side node, groovy's Process instances can be used together with a
pipe symbol inside groovy like the following

p = "date".execute() | "tr a-z A-Z".execute()
p.text

> Groovy neither knows your *$path* environment variable, if the environment
> variable exists and is available to JVM you can read its value using 
> System.getEnv()
> <https://docs.oracle.com/javase/tutorial/essential/environment/env.html>  
> function
>
> It might be easier to go for  OS Process Sampler
> <https://jmeter.apache.org/usermanual/component_reference.html#OS_Process_Sampler> 
> , check out  How to Run External Commands and Programs Locally and Remotely
> from JMeter
> <https://www.blazemeter.com/blog/how-run-external-commands-and-programs-locally-and-remotely-jmeter/>  
> article for details. 
>
> And from the performance perspective instead of calling external
> applications you should rather consider creating the CSR request using i..e 
> BouncyCastle API <https://www.bouncycastle.org/>  

+1


Felix



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@jmeter.apache.org
For additional commands, e-mail: user-help@jmeter.apache.org

  

Re: Problems Execute Linux Commands using JSR223 PrePrcessor with Groovy Engine and pipe-symbol

Posted by Felix Schumacher <fe...@internetallee.de>.
Am 04.12.19 um 11:33 schrieb glinius@live.com:
> As you correctly mentioned, "it's working perfect on bash". 
>
> Groovy knows nothing about the pipe symbol so you need to execute  bash -c
> command <https://www.gnu.org/software/bash/manual/bash.html>   and pass your
> whole command as the parameter, something like:
>
>
>> "/bin/bash -c \"echo -en \\\"https://my-url.com:8888\\\" | openssl smime
>> -sing -signer cert.crt -inkey cert.key -outform der -binary -md sha384
>> -out blah.p7\"".execute().text


Alternatively you could use groovy's magic to write the url to the stdin
of the openssl process by using something like

p = "openssl smime ...".execute()
p.withWriter { writer -> writer.println("https://...") }
p.text

I find it more readable.  It is probably faster, too, as it doesn't need
to instantiate a shell.

On a side node, groovy's Process instances can be used together with a
pipe symbol inside groovy like the following

p = "date".execute() | "tr a-z A-Z".execute()
p.text

> Groovy neither knows your *$path* environment variable, if the environment
> variable exists and is available to JVM you can read its value using 
> System.getEnv()
> <https://docs.oracle.com/javase/tutorial/essential/environment/env.html>  
> function
>
> It might be easier to go for  OS Process Sampler
> <https://jmeter.apache.org/usermanual/component_reference.html#OS_Process_Sampler> 
> , check out  How to Run External Commands and Programs Locally and Remotely
> from JMeter
> <https://www.blazemeter.com/blog/how-run-external-commands-and-programs-locally-and-remotely-jmeter/>  
> article for details. 
>
> And from the performance perspective instead of calling external
> applications you should rather consider creating the CSR request using i..e 
> BouncyCastle API <https://www.bouncycastle.org/>  

+1


Felix



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@jmeter.apache.org
For additional commands, e-mail: user-help@jmeter.apache.org


Re: Problems Execute Linux Commands using JSR223 PrePrcessor with Groovy Engine and pipe-symbol

Posted by "glinius@live.com" <gl...@live.com>.
As you correctly mentioned, "it's working perfect on bash". 

Groovy knows nothing about the pipe symbol so you need to execute  bash -c
command <https://www.gnu.org/software/bash/manual/bash.html>   and pass your
whole command as the parameter, something like:


> "/bin/bash -c \"echo -en \\\"https://my-url.com:8888\\\" | openssl smime
> -sing -signer cert.crt -inkey cert.key -outform der -binary -md sha384
> -out blah.p7\"".execute().text

Groovy neither knows your *$path* environment variable, if the environment
variable exists and is available to JVM you can read its value using 
System.getEnv()
<https://docs.oracle.com/javase/tutorial/essential/environment/env.html>  
function

It might be easier to go for  OS Process Sampler
<https://jmeter.apache.org/usermanual/component_reference.html#OS_Process_Sampler> 
, check out  How to Run External Commands and Programs Locally and Remotely
from JMeter
<https://www.blazemeter.com/blog/how-run-external-commands-and-programs-locally-and-remotely-jmeter/>  
article for details. 

And from the performance perspective instead of calling external
applications you should rather consider creating the CSR request using i..e 
BouncyCastle API <https://www.bouncycastle.org/>  
 



--
Sent from: http://www.jmeter-archive.org/JMeter-User-f512775.html

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@jmeter.apache.org
For additional commands, e-mail: user-help@jmeter.apache.org


Re: Problems Execute Linux Commands using JSR223 PrePrcessor with Groovy Engine and pipe-symbol

Posted by Deepak Shetty <sh...@gmail.com>.
Hi
you should be able to do something like (not tested) - also be careful with
your paths - I believe they will be relative to JMeter's bin directory so
you might want to try with absolute paths first(for your .key and .crt
files)
String path = sampler.getURL();
String s = "openssl smime -in " + path + " -sing -signer cert.crt -inkey
cert.key -outform der -binary -md sha384 -out blah.p7";
s.execute();

regards
deepak

On Mon, Dec 2, 2019 at 8:11 AM Markus Obermann
<ma...@yahoo.de.invalid> wrote:

> Hi,
>
> i need to do some wired stuff where i have to call linux commands from
> jmeter - to be clear its openssl i need to run.Bevore the openssl command
> is executed i have to "echo" something to my system console and want that
> this is piped to openssl.So the command i want to execute is this (and it's
> working perfect on bash)
> echo -en "https://my-url.com:8888" | openssl smime -sing -signer cert.crt
> -inkey cert.key -outform der -binary -md sha384 -out blah.p7
>
> I have a HTTP Sampler and there is a JSR223 PreProcessor as a child with
> this tiny code://First i get the URL from my Sampler
> import org.apache.jmeter.protocol.http.sampler.HTTPSampler;String path =
> sampler.getURL();
> This works and will print out the URL from the Sampler.Then i do this:
> log.info("echo -en $path | openssl smime -sing -signer cert.crt -inkey
> cert.key -outform der -binary -md sha384 -out blah.p7".execute().text)
> In my Jmeter console i do see the "log.info" output which looks perfect.
> BUT it seems that nothing happen. I do not see the -out blah.p7 fileCould
> it be that jmeter cant handle the pipe-symbol?
>
> If i do some changes to my command and do not echo my command but paste
> the url as -in directly to my openssl command then its working.Thus i can
> do this:log.info("openssl smime -in https//my-url.com:8888 -sing -signer
> cert.crt -inkey cert.key -outform der -binary -md sha384 -out
> blah.p7".execute().text)
>
> But as im using different urls i cant make it static - i need to determine
> the url from sampler and paste it to my openssl command.
> For sure i will find a way which will work - but maybe someone have an
> idea about the "pipe-symbol" - or what i'm doing wrong?
> Br
>