Set parameters of GET request with groovy - groovy

I want to provide parameters for a GET request/ API call to the AYLIEN text analytics API. I can set the headers for the key and ID as authorization and the call itself works (my usage statistics of the API increase after running the code), but I don't know how to provide the text to analyze as a parameter.
def customScript(){
def connection = new
URL("https://api.aylien.com/api/v1/sentiment").openConnection() as
HttpURLConnection
connection.requestMethod = 'GET'
// set headers
connection.setRequestProperty('X-AYLIEN-TextAPI-Application-Key','//mykey')
connection.setRequestProperty('X-AYLIEN-TextAPI-Application-ID', '//myid')
// get the response code - automatically sends the request
println connection.responseCode + ": " + connection.inputStream.text
}

In a GET request, the parameters are sent as part of the URL.
For example, if you want to add the parameter id=23, you can change the code to:
def connection = new
URL("https://api.aylien.com/api/v1/sentiment?id=23").openConnection() as
HttpURLConnection

Related

Python3 how to resume at item in for loop when an exception was triggered

I'm somehow unable to came up with a solution after spending already few days on this. What I need to do:
Iterate trough a large list of hosts in a .txt file to perform a request to the devices/queries/devices/v1 API endpoint for CrowdStrike to get a so called aid (agent id).
Once I have the aid (there can be multiple aid's for a single host) I need to again iterate but this time over the aid's to the devices/entities/devices/v1 API endpoint to retrieve information such as hostname, last seen plus need to make another call, this time to the policy/combined/reveal-uninstall-token/v1 API endpoint, to get the uninstall token for each of the aid's.
The problem is that the bearer token that I'm generating initially is only valid for 30 minutes, and it needs to by provided with each subsequent request. My idea was to use the try except construct + I'm raising exceptions with Response raise for status as described in correct-way-to-try-except-using-python-requests-module. So I'm hoping that at any point I'm making a request, if it fails due to an HTTP error like 401 Client Error: Unauthorized for url: it would indicate that the token has expired and would call the login() function token = login() within except to make a call to request new a new token and assign it to the token variable and that would allow my to proceed with my for loop since the new token would be provided. The problem I now see, is that for the given host that I'm iterating over, when the token expires, it get's skipped right after the new token is generated (the loop basically continues for the next item within the list). How could I workaround this ?
PS. I know the code is far from perfect, but it's my first steps and would be really nice I someone could lead me here. Was looking and continue and break but continue seams to actually be doing exactly what I'm seeing as behavior with my code and break is not applicable for what I want to do.
for host in host_list:
try:
'''
1.Get agent id (aid) for each host (NOTE:can return multiple aid's for single host).
If the returned list is empty, that means the host is not in CS and skip the
processing of the remaining code.
'''
query_aid = requests.get(base_url+ 'devices/queries/devices/v1?limit=5000&filter=hostname:' + "'" + host + "'", headers = {"accept": "application/json", "authorization": "Bearer " + token} )
query_aid.raise_for_status()
aux = json.loads(query_aid.text)
aux2 = aux["resources"]
if len(aux2) == 0:
print(host + ' ; ' + 'not in CS')
else:
'''
for whatever count of aid's returned iterate through each and make a call to the
devices/entities/devices/v1 endpoint to pull hostname and last_seen information,
and make for each aid a call to the policy/combined/reveal-uninstall-token/v1
endpoint to pull the uninstall token for each
'''
for aid in aux2:
host_details_request = requests.get(base_url + 'devices/entities/devices/v1?ids=' + aid , headers = {"accept": "application/json", "authorization": "Bearer " + token})
host_details_request.raise_for_status()
aux = json.loads(host_details_request.text)
last_seen = re.search(r'\d{4}-\d{2}-\d{2}', aux["resources"][0]["last_seen"])
request_uninstall_token = requests.post(base_url + 'policy/combined/reveal-uninstall-token/v1', headers = {'Content-type': 'application/json', "authorization": "Bearer " + token }, json = { "audit_message": "test api ", "device_id": aid })
request_uninstall_token.raise_for_status()
aux3 = json.loads(request_uninstall_token.text)
print(aux["resources"][0]["hostname"] + 'uninstall token: ' + aux3["resources"][0]["uninstall_token"] + ';' + last_seen.group(0))
except requests.exceptions.HTTPError as err:
print(err)
token = login()
Create a function that handles your try code. Then call this function within your expect after the login call
for host in host_list:
try:
handle_host(host)
except requests.exceptions.HTTPError as err:
print(err)
token = login()
handle_host(host)

How to correctly call queryStringParameters for AWS Lambda + API Gateway?

I'm following a tutorial on setting up AWS API Gateway with a Lambda Function to create a restful API. I have the following code:
import json
def lambda_handler(event, context):
# 1. Parse query string parameters
transactionId = event['queryStringParameters']['transactionid']
transactionType = event['queryStringParameters']['type']
transactionAmounts = event['queryStringParameters']['amount']
# 2. Construct the body of the response object
transactionResponse = {}
# returning values originally passed in then add separate field at the bottom
transactionResponse['transactionid'] = transactionId
transactionResponse['type'] = transactionType
transactionResponse['amount'] = transactionAmounts
transactionResponse['message'] = 'hello from lambda land'
# 3. Construct http response object
responseObject = {}
responseObject['StatusCode'] = 200
responseObject['headers'] = {}
responseObject['headers']['Content-Type'] = 'application/json'
responseObject['body'] = json.dumps(transactionResponse)
# 4. Return the response object
return responseObject
When I link the API Gateway to this function and try to call it using query parameters I get the error:
{
"message":"Internal server error"
}
When I test the lambda function it returns the error:
{
"errorMessage": "'transactionid'",
"errorType": "KeyError",
"stackTrace": [
" File \"/var/task/lambda_function.py\", line 5, in lambda_handler\n transactionId = event['queryStringParameters']['transactionid']\n"
]
Does anybody have any idea of what's going on here/how to get it to work?
I recommend adding a couple of diagnostics, as follows:
import json
def lambda_handler(event, context):
print('event:', json.dumps(event))
print('queryStringParameters:', json.dumps(event['queryStringParameters']))
transactionId = event['queryStringParameters']['transactionid']
transactionType = event['queryStringParameters']['type']
transactionAmounts = event['queryStringParameters']['amount']
// remainder of code ...
That way you can see what is in event and event['queryStringParameters'] to be sure that it matches what you expected to see. These will be logged in CloudWatch Logs (and you can see them in the AWS Lambda console if you are testing events using the console).
In your case, it turns out that your test event included transactionId when your code expected to see transactionid (different spelling). Hence the KeyError exception.
just remove ['queryStringParameters']. the print event line shows the event i only a array not a key value pair. I happen to be following the same tutorial. I'm still on the api gateway part so i'll update once mine is completed.
Whan you test from the lambda function there is no queryStringParameters in the event but it is there when called from the api gateway, you can also test from the api gateway where queryStringParameters is required to get the values passed.
The problem is not your code. It is the Lambda function intergration setting. Please do not enable Lambda function intergration setting . You can still attach the Lambda function without it. Leave this unchecked.
It's because of the typo in responseObject['StatusCode'] = 200.
'StatusCode' should be 'statusCode'.
I got the same issue, and it was that.

Jmeter HTTP setPath - How do i set dynamic path in http sampler

I am new to jmeter and i am stuck in a condition . I am running jmeter http sample using a csv file where i am using a pre-processor script in which doing the following-
setting http.method as per request like POST , GET , PUT ,PATCH
setting http.path as "/restpath"
setting request body.json
For Path i am using a "http.path" and passed the same in http sampler like ${http.path}. All above is working fine until i have dependent HTTP request like below use case -
Step 1 - Hit HTTP Request on path "/restpath" . After successful submission , i got a serverId in response and save the same in json extractor variable "serverID".
Step 2- Now i have to hit http request on path "/rest/${serverID}" . when i am trying to pass the same from csv file then the same is not replacing with captured variable in step 1 . Whatever i passed in csv file in http.path got passed and submit.
Expectation -
In Sheet --> http.path == "/restpath/${serverID}"
In HTTP Request submission --> "/restpath/4894rh89r"
Actual -
In Sheet --> http.path == "/restpath/${serverID}"
In HTTP Request submission --> "/restpath/${serverID}"
import org.apache.jmeter.engine.util.CompoundVariable;
import org.apache.jmeter.protocol.http.util.HTTPArgument;
//test input parameters
def httpMethod = vars.get("http.method");
//change the http method as per the data sheet
sampler.setMethod(httpMethod);
//set the HTTP Path
//URL url = new URL(vars.get('http.path'));
//vars.put('http.path',url.getPath());
//set the HTTP request body
if(!vars.get("input.json").equals("")){
def dataToBePosted = new CompoundVariable(new File(vars.get("jmeter.test.home") + vars.get("input.json")).text).execute();
def arg= new HTTPArgument("", dataToBePosted, null, true);
arg.setAlwaysEncoded(false);
sampler.getArguments().addArgument(arg);
//HTTP Body is set to
log.info(dataToBePosted);
}
Tried couple of hit n trial using __V() functions but no luck :(
I think you need to change this line:
def dataToBePosted = new CompoundVariable(new File(vars.get("jmeter.test.home") + vars.get("input.json")).text).execute();
to this one:
def dataToBePosted = ((org.apache.jmeter.engine.util.CompoundVariable)([new File(vars.get("jmeter.test.home") + vars.get("input.json")).text])).execute()
Demo:
More information:
EvalFunction source
CompoundVariable JavaDoc
Apache Groovy - Why and How You Should Use It

How to pass params to a HTTP request (teststep) in a SOAP UI Test case using groovy and run it

I am writing a groovy script to execute/automate my test suite. In one test case i have a HTTPRequest where i have a request URL, parameters( username and password) and method( GET) to get a token-id and then i would pass that token id to my next step( a SOAP request)to get the data.
I am stuck at a point where i need to pass the params(username and password), request URL and method(GET) using groovy.
I have a test step created manaully under a test case, i just need to pass the params
as i search online i got to know how to pass headers,url to a SOAP request which is like below
def headers = new StringToStringMap()
testRunner = new com.eviware............WsdlTestCaseRunner(myTestCase,null);
testStepContext = new com.eviware.soapui........WsdlTestRunContext(testsetp);
headers.put("apikey", "abcd")
teststep.getTestRequest().setRequestHeaders(headers)
teststep.getHttpRequest().setEndpoint(encpointurl);
testsetp.run(testRunner ,testStepContext )
but i looking to know how to pass params to a http request(test step) and run it.
Add a Properties teststep to your testcase. Just let it keep the default "Properties" name.
Add the properties to the Properties teststep, that you need to transfer
Inside your groovy teststep, you may set the properties using something like:
def properties = testRunner.testCase.getTestStepByName("Properties");
properties.setPropertyValue("name", "value");
Add the parameters directly in your request using variables in the format ${Properties#name} and replace "name" with the actual parameter name. This can be done both in the request body and in the URL if you should wish to do so.
It can be done completely in groovy by using groovy.json.JsonBuilder Class.
def body = new StringToStringMap()
def jsonbildr = new JsonBuilder()
body.put("username","Hackme")
body.put("password","LockUout")
def root = jsonbildr body
jsonbildr = jsonbildr.toPrettyString()
log.info(jsonbildr)
testStep.setPropertyValue("Request", jsonbildr)
Output :
{
"password": "LockUout",
"username": "Hackme"
}

Can't extract data from RESTClient response

I am writing my first Groovy script, where I am calling a REST API.
I have the following call:
def client = new RESTClient( 'http://myServer:9000/api/resources/?format=json' )
That returns:
[[msr:[[data:{"level":"OK"}]], creationDate:2017-02-14T16:44:11+0000, date:2017-02-14T16:46:39+0000, id:136]]
I am trying to get the field level, like this:
def level_value = client.get( path : 'msr/data/level' )
However, when I print the value of the variable obtained:
println level_value.getData()
I get the whole JSON object instead of the field:
[[msr:[[data:{"level":"OK"}]], creationDate:2017-02-14T16:44:11+0000, date:2017-02-14T16:46:39+0000, id:136]]
So, what am I doing wrong?
Haven't looked at the docs for RESTClient but like Tim notes you seem to have a bit of a confusion around the rest client instance vs the respons object vs the json data. Something along the lines of:
def client = new RESTClient('http://myServer:9000/api/resources/?format=json')
def response = client.get(path: 'msr/data/level')
def level = response.data[0].msr[0].data.level
might get you your value. The main point here is that client is an instance of RESTClient, response is a response object representing the http response from the server, and response.data contains the parsed json payload in the response.
You would need to experiment with the expression on the last line to pull out the 'level' value.

Resources