How to read a web page using Bean shell in JMeter? - beanshell

Use Bean Shell sampler to hit simple Google search, do I need a code for this?

It is better to use HTTP Request sampler, however if for some reason you need to do it in Beanshell here is the example script:
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://google.com");
HttpResponse response = httpclient.execute(httpGet);
String responseString = EntityUtils.toString(response.getEntity());
String responseCode = String.valueOf(response.getStatusLine().getStatusCode());
String responseCode = String.valueOf(response.getStatusLine().getStatusCode());
return responseString;
See the following reference material:
HttpClient Quick Start
How to Use BeanShell: JMeter's Favorite Built-in Component

Related

How to handle a GET request for REST API request which is having a body with QAF Webservice

I am using QAF Webservice support for API automation. I have a case where a GET request has a body present. If I pass the request as either using properties file or xml file, on executing I am getting 404 not found response. If the GET request does not have a body present, it works fine in that scenario without any issues. But not with GET request having a body. Upon debugging, found that jersey client API at the end changes the request from GET to POST if a GET request has a body. Please let me know on how to handle this scenario using QAF WebService.
Thanks,
You can use apache HttpClient that will allow to have body with get request. In order to use apache HttpClient, you need to provide implementation of RestClientFactory and register using property rest.client.impl.
Here is the sample code from the qaf users group.
package qaf.example.tests;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import com.qmetry.qaf.automation.ws.rest.RestClientFactory;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientHandler;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.client.apache.ApacheHttpClient;
import com.sun.jersey.client.apache.ApacheHttpClientHandler;
import com.sun.jersey.client.apache.config.DefaultApacheHttpClientConfig;
/**
* #author chirag
*
*/
public class ApacheClientProvider extends RestClientFactory {
#Override
protected Client createClient() {
MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
connectionManager.getParams().setConnectionTimeout(5000);
connectionManager.getParams().setSoTimeout(1000);
connectionManager.getParams().setDefaultMaxConnectionsPerHost(10);
HttpClient httpClient = new HttpClient(connectionManager);
ApacheHttpClientHandler clientHandler = new ApacheHttpClientHandler(httpClient);
ClientHandler root = new ApacheHttpClient(clientHandler );
ClientConfig config = new DefaultApacheHttpClientConfig();
Client client = new Client(root, config);
return client;
}
}
In order to use it, register your class using rest.client.impl property, in above case:
rest.client.impl=qaf.example.tests.ApacheClientProvider

Token from Google Credentials Service Account NULL

I am attempting to retrieve the credentials for my Google service account with the following code:
package function
import com.amazonaws.services.lambda.runtime.Context
import com.amazonaws.services.lambda.runtime.LambdaLogger
import com.amazonaws.services.lambda.runtime.RequestHandler
import pojo.Request
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential
import com.google.api.services.sqladmin.SQLAdminScopes
import pojo.Response
class GoogleAuth implements RequestHandler<Request, Response> {
private LambdaLogger logger
#Override
Response handleRequest(Request input, Context context) {
logger = context.getLogger()
ClassLoader classLoader = getClass().getClassLoader()
File jsonCredentials = new File(classLoader.getResource("leads-cloud-function-service-account.json").getFile())
FileInputStream fis = new FileInputStream(jsonCredentials)
GoogleCredential credential = GoogleCredential.fromStream(fis).createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN))
credential.getClientAuthentication()
println("Thai test" + credential.getExpirationTimeMilliseconds())
print("This is the credential" + credential.getAccessToken())
return (new Response())
}
}
The information about the milliseconds for expiration and the AccessToken are null. Has anyone ever experienced this?
So I have resolved this myself by adding before the getToken the following command:
credential.refreshToken()
This is not properly documented in google's website but after adding it, this worked perfectly and the results are displayed with actual values.
Some other error I faced was the "com.google.common.io.ByteStreams.exhaust(Ljava/io/InputStream;)J", in order to resolve it I had to correct the dependency I was using to this one:
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.31.1</version>
</dependency>
so, keep on mind that too!

AWS S3 HTTPS API request(URL) signed with temporary security credentials to access object

How to generate the HTTPS API request(URL) signed with temporary security credentials to access AWS S3 object.I am able to access object using amazon java sdk but I would like to generate the complete url with temporary security credential like pre signed url.
package com.siriusxm.repo.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Region;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient;
import com.amazonaws.services.securitytoken.model.Credentials;
import com.amazonaws.services.securitytoken.model.GetSessionTokenRequest;
import com.amazonaws.services.securitytoken.model.GetSessionTokenResult;
import com.siriusxm.repo.DownloadServiceImpl;
public class TemporaryCredential {
private static String bucketName = "myrepo";
private static String key = "test.pdf";
public static void main(String[] args) {
System.out.println("");
AWSSecurityTokenServiceClient stsClient = new AWSSecurityTokenServiceClient(
new ProfileCredentialsProvider());
// stsClient.setRegion(regionName);sts.us-west-2.amazonaws.com
//
// Start a session.
GetSessionTokenRequest getSessionTokenRequest = new GetSessionTokenRequest();
GetSessionTokenResult sessionTokenResult = stsClient
.getSessionToken(getSessionTokenRequest);
Credentials sessionCredentials = sessionTokenResult.getCredentials();
System.out.println("Session Credentials: "
+ sessionCredentials.toString());
// Package the session credentials as a BasicSessionCredentials
// object for an S3 client object to use.
BasicSessionCredentials basicSessionCredentials = new BasicSessionCredentials(
sessionCredentials.getAccessKeyId(),
sessionCredentials.getSecretAccessKey(),
sessionCredentials.getSessionToken());
AmazonS3Client s3object = new AmazonS3Client(basicSessionCredentials);
// Test. For example, get object keys for a given bucket.
ObjectListing objects = s3object.listObjects(bucketName);
s3object.getObject( new GetObjectRequest(bucketName, key));
System.out.println("No. of Objects = "
+ objects.getObjectSummaries().size());
}
}
This code generate the dynamically access key,secret key and security token.Now i need to generate url with authorization header with signature so that i can access S3 object directly.Is there way?
From this code i want to generate url using x-amz-security-token
if you want to do this in java, you have to use AmazonS3.generatePresignedUrl
AmazonS3 s3client = new AmazonS3Client(new ProfileCredentialsProvider());
java.util.Date expiration = new java.util.Date();
long msec = expiration.getTime();
msec += 1000 * 60 * 60; // 1 hour.
expiration.setTime(msec);
GeneratePresignedUrlRequest generatePresignedUrlRequest =
new GeneratePresignedUrlRequest(bucketName, objectKey);
generatePresignedUrlRequest.setMethod(HttpMethod.GET); // Default.
generatePresignedUrlRequest.setExpiration(expiration);
URL s = s3client.generatePresignedUrl(generatePresignedUrlRequest);
if you want to do this from the console, go to you s3 bucket, click download on the object. This displays a box where you can click on "download". If you right click on this link and copy the address link, you get a pre-signed url for this object

Jetty - how to only allow requests from a specific domain

I have exposed an api provided by a jetty server to a front-end application. I want to make sure that only the front-end application (from a certain domain) has access to that api - any other requests should be unauthorised.
What's the best best way of implementing this security feature?
Update: I have set up a CrossOriginFilter - however, I can still access the api via basic GET request from my browser.
Thanks!
Use the IPAccessHandler to setup whitelists and blacklists.
Example: this will allow 127.0.0.* and 192.168.1.* to access everything.
But 192.168.1.132 cannot access /home/* content.
package jetty.demo;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.IPAccessHandler;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
public class IpAccessExample
{
public static void main(String[] args)
{
System.setProperty("org.eclipse.jetty.servlet.LEVEL","DEBUG");
System.setProperty("org.eclipse.jetty.server.handler.LEVEL","DEBUG");
Server server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(8080);
server.addConnector(connector);
// Setup IPAccessHandler
IPAccessHandler ipaccess = new IPAccessHandler();
ipaccess.addWhite("127.0.0.0-255|/*");
ipaccess.addWhite("192.168.1.1-255|/*");
ipaccess.addBlack("192.168.1.132|/home/*");
server.setHandler(ipaccess);
// Setup the basic application "context" for this application at "/"
// This is also known as the handler tree (in jetty speak)
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
// make context a subordinate of ipaccess
ipaccess.setHandler(context);
// The filesystem paths we will map
String homePath = System.getProperty("user.home");
String pwdPath = System.getProperty("user.dir");
// Fist, add special pathspec of "/home/" content mapped to the homePath
ServletHolder holderHome = new ServletHolder("static-home", DefaultServlet.class);
holderHome.setInitParameter("resourceBase",homePath);
holderHome.setInitParameter("dirAllowed","true");
holderHome.setInitParameter("pathInfoOnly","true");
context.addServlet(holderHome,"/home/*");
// Lastly, the default servlet for root content
// It is important that this is last.
ServletHolder holderPwd = new ServletHolder("default", DefaultServlet.class);
holderPwd.setInitParameter("resourceBase",pwdPath);
holderPwd.setInitParameter("dirAllowed","true");
context.addServlet(holderPwd,"/");
try
{
server.start();
server.join();
}
catch (Throwable t)
{
t.printStackTrace(System.err);
}
}
}
Or alternatively, write your own Handler to filter based on some other arbitrary rule.
Such as looking for a required request header, something that your specific front-end application provides, but a browser would not.
package jetty.demo;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.HandlerWrapper;
public class BanBrowserHandler extends HandlerWrapper
{
#Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
String xfe = request.getHeader("X-FrontEnd");
if ((xfe == null) || (!xfe.startsWith("MagicApp-")))
{
// not your front-end
response.sendError(HttpStatus.FORBIDDEN_403);
baseRequest.setHandled(true);
return;
}
getHandler().handle(target,baseRequest,request,response);
}
}
The class IPAccessHandler is deprecated. The InetAccessHandler is recommended.
org.eclipse.jetty.server.Server server = ...;
InetAccessHandler ipaccess = new InetAccessHandler();
ipaccess.include(clientIP);
ipaccess.setHandler(server.getHandler());
server.setHandler(ipaccess);

Test a web service client using JAX-WS

There is an api called "HelloWorld" on the link shown in code below. How can I call this api using the code below. The api takes no parameters.
The service already exists on the url shown. What do I need to add to the code below:
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
public class apiHelloWorld {
public static void main(String[] args) throws Exception {
URL url = new URL("http://project.url.com/service.asmx?wsdl");
}
}
Your URL suggest that you are pointing to wsdl document, not the actual service. Most likely your service is under the same URL but without ?wsdl suffic).
That being said calling SOAP web service using plain URL class requires few extra steps. But it's absolutely possible, after all this is a plain HTTP protocol.
You need a SOAP request in XML format, including SOAP Envelope. This might be the most complex part (example taken from: Sending a SOAP request to a Web Service via URLConnection):
String soapXml = //...;
java.net.URLConnection conn = new URL("http://project.url.com/service.asmx").openConnection();
conn.setRequestProperty("SOAPAction", "");
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(soapXml);
wr.flush();
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
By reading rd you can fetch the response.