Tuesday, June 9, 2015

HTTP Headers useful for REST APIs

Access-Control-* headers

preflight - OPTIONS

When writing a simple CORS filter following fields can be set in response header:

response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");

CORS filter containing above code will respond to all requests with these Access-Control-* headers.

Access-Control-Allow-Origin - tell to allow all origins. 
Access-Control-Allow-Methods - HTTP methods that will be allowed
Access-Control-Allow-Headers - give header keys that must be allowed in response for CORS calls. This tells that x-requested-with is allowed as a response header when CORS call is made.


HTTP Media type headers

(http://www.newmediacampaigns.com/blog/browser-rest-http-accept-headers)
When a web browser make a request it sends information to the server about what it is looking for in headers. One of these headers is the Accept header. The Accept header tells the server what file formats, or more correctly MIME-types, the browser is looking for.
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

 Quality factors allow the user or user agent to indicate the relative degree of preference for that media-range, using the qvalue scale from 0 to 1 (section 3.9). The default value is q=1.

Order by preference value in descending order.

1: html, xhtml

0.9: xml

0.8: *

 For example if both application/xml and */* had a preference of 0.9 application/xml would still come first. Firefox chooses to make it explicit that */* is less preferred by giving it a preference of 0.8. Firefox's Accept header is sensible and well thought out. Opera's is too. Other browsers: not so much.

Twitter's REST API doesn't use the Accept header for content-negotiation, they use extensions on the URL '.json' and '.xml'.

==============

When Content-Type is null or wrong then rest service returns 

415 Unsupported Media Type - 
"message":"Content type 'null' not supported"
"message":"Content type 'application/vnd.dmi-v2+xfd' not supported"

When Content-Type is correct, but Accept header is wrong then service returns
406 Not Acceptable 

HTTP Caching headers

Works only for safe HTTP methods - GET, HEAD, OPTIONS
HTTP 304 Not modified returned if response sent from cache

Request headershould matchResponse headerE.g. value
If-Modified-Since=Last-ModifiedHTTP-date (Sat, 29 Oct 1994 19:43:31 GMT)
If-None-Match=ETag"123-abef8r3dw"

 In 200 (OK) responses to GET or HEAD, an origin server:

   o  SHOULD send an entity-tag validator unless it is not feasible to
      generate one.

   o  MAY send a weak entity-tag instead of a strong entity-tag, if
      performance considerations support the use of weak entity-tags, or
      if it is unfeasible to send a strong entity-tag.

   o  SHOULD send a Last-Modified value if it is feasible to send one.

   In other words, the preferred behavior for an origin server is to
   send both a strong entity-tag and a Last-Modified value in successful
   responses to a retrieval request.

   A client:

   o  MUST send that entity-tag in any cache validation request (using
      If-Match or If-None-Match) if an entity-tag has been provided by
      the origin server.
   o  SHOULD send the Last-Modified value in non-subrange cache
      validation requests (using If-Modified-Since) if only a
      Last-Modified value has been provided by the origin server.

   o  MAY send the Last-Modified value in subrange cache validation
      requests (using If-Unmodified-Since) if only a Last-Modified value
      has been provided by an HTTP/1.0 origin server.  The user agent
      SHOULD provide a way to disable this, in case of difficulty.

Useful Cache-Control response headers include:
  • max-age=[seconds] — specifies the maximum amount of time that a representation will be considered fresh. Similar to Expires, this directive is relative to the time of the request, rather than absolute. [seconds] is the number of seconds from the time of the request you wish the representation to be fresh for.
  • s-maxage=[seconds] — similar to max-age, except that it only applies to shared (e.g., proxy) caches.
  • public — marks authenticated responses as cacheable; normally, if HTTP authentication is required, responses are automatically private.
  • private — allows caches that are specific to one user (e.g., in a browser) to store the response; shared caches (e.g., in a proxy) may not.
  • no-cache — forces caches to submit the request to the origin server for validation before releasing a cached copy, every time. This is useful to assure that authentication is respected (in combination with public), or to maintain rigid freshness, without sacrificing all of the benefits of caching.
  • no-store — instructs caches not to keep a copy of the representation under any conditions.
  • must-revalidate — tells caches that they must obey any freshness information you give them about a representation. HTTP allows caches to serve stale representations under special conditions; by specifying this header, you’re telling the cache that you want it to strictly follow your rules.
  • proxy-revalidate — similar to must-revalidate, except that it only applies to proxy caches.
When both Cache-Control and Expires are present, Cache-Control takes precedence.


Essentially, "vary" lets the caches know which of the headers to use to figure out if they have a valid cache for a request; if a cache were a giant key-value store, adding "vary" fields appends those values to the key, thus changing which requests are considered valid matches for what exists in the cache.

What is the correct way to version my API?
The "URL" way
A commonly used way to version your API is to add a version number in the URL. For instance:/api/v1/article/1234/api/v2/article/1234GET /api/article/1234 HTTP/1.1Accept: application/vnd.api.article+xml; version=1.0To "move" to another API, one could increase the version number:The hypermedia way

References 
http://restcookbook.com/Basics/versioning/#sthash.jRlZVJ0L.dpuf

https://www.safaribooksonline.com/library/view/rest-api-design/9781449317904/ch04.html


https://devcenter.heroku.com/articles/jax-rs-http-caching

Connect to Cloudera VM installed on your MAC using MAC terminal

So recently started working on Cloudera Hadoop. And installed Cloudera VM from their website. I am using Virtual Box for running the Cloudera Hadoop VM.

Now working on VMs is slow and tedious. You can cofigure your mac to have Mac's terminal ssh to the VM.

Here are the steps:
1. Go to Virtual Box setting for the Cloudera VM and 
open virtualbox
go to File-->Preferences-->Network and click on the "Add Host-only network (Ins)
it will create automatically a "vboxnet0" network
Click to OK to save changes


2. Now on a terminal window of Cloudera Hadoop VM, write ifconfig.
This will return you information with eth0, eth1 settings.
Get the inet addr associated with eth1
3. Go to you Mac's terminal window and type
$ ssh  training@<inet addr ip from prev step>
4. This will ask you to connect to the VM. Type "yes"
and you are in. You can check by typing at prompt - hadoop fs.
If this run's then you are connected.

-connect to cloudera vm using mac
-how to connect to cloudera vm from terminal

Tuesday, February 11, 2014

Using JMeter for load testing - configuring CSV File for POST using query parameters

The Apache JMeter™ desktop application is open source software, a 100% pure Java application designed to load test functional behavior and measure performance. ( http://jmeter.apache.org/index.html )

Apache JMeter may be used to test performance both on static and dynamic resources (Files, Web dynamic languages - PHP, Java, ASP.NET, etc. -, Java Objects, Data Bases and Queries, FTP Servers and more). It can be used to simulate a heavy load on a server, group of servers, network or object to test its strength or to analyze overall performance under different load types. 

In this article I will be explaining how to load test a URL by hitting it with multiple requests configured as different query parameters in the URL. The query parameters are in a csv file. JMeter will pick the query parameters and prepare the URL and hit the server and record the results.

We will write a test plan to hit URL http://testapp.testco.com/service?param1=<var1>&param2=<var2> multiple times using multiple threads using var1 and var2 values configured in csv file and stress test it.

So lets starts configuring JMeter for our test case.

Download JMeter

You can download JMeter from http://jmeter.apache.org. And install it on you local. It is very simple. Just follow the wizard for installation.

Launch JMeter

Incase you are on Windows, Go to <jmeter home>/bin and double click on jmeter.bat. This will launch JMeter standalone console.

Create new Test Plan

Once JMeter console is open, you will see in the left navigation tree, a Test Plan.
Right click on the Test Plan go to Add -> Thread Group and click on it. This will add a Thread Group element for you. For doing anything on JMeter you need to start with adding a Thread Group element.




Once you have added the Thread Group now we need to add some more elements to generate HTTP request and add CSV config elements.

1. Add HTTP Request 

Right click on Thread Group element and Add->Sampler->HTTP Request. Click on it to add it to your thread group.

2. CSV Data Set Config

Right click on Thread Group element and Add->Config Element->CSV Data Set Config. Click on it to add it to your thread group.

3. View Results Tree

Right click on Thread Group element and Add->Listener->View Results Tree. Click on it to add it to your thread group.


Now your Thread Group navigation on left should look like this.




Once we have added all the elements that we require for testing our Test Plan now we will go and configure them.

1. Configure HTTP Request element

Now suppose you want to test a URL http://testapp.testco.com/service?param1=<var1>&param2=<var2>, where the URL can have multiple var1 & var2 values. We will configure the test plan to read the var1 and var2 values from a csv file and hit http://testapp.testco.com/service with these values using multiple threads.

  • Add you Server Name or IP without http or https.
  • In Path add service
  • In the Parameters section add param1 & param2 and values as $(param1} and ${param2}. These will be picked up at runtime from csv file.
These configurations will create a URL like http://testapp.testco.com/service?param1=<var1>&param2=<var2>





2. Configure CSV Data Set Config

Now open notepad and create a csv file new.csv with param1 and param2 values seperated by tab, like below

param1a   param2a
param1b   param2b
param1c   param2c

Using this file we will configure CSV data set config element.

Put the file name in the Filename section as c:\temp\new.csv ( where csv file is located)
Add Variable Names param1, param2
Add Delimiter \t

The section looks as follows:



Once all this is setup, you can run the Test Plan using Start ( green play button on top) or go to Run->Start.

The results will be captured in View Results Tree element that we had added.




That is all. You can test your REST web services or any configurable URL using this.
Pls leave your comments incase you need further assistance.

Tuesday, December 10, 2013

Broken Image handling in jsp/html

Instead of showing a blank image, the best thing is to hide the img element itself from html page. 
This can be done using following script:-

<script>
// Hide img tag
$("img").error(function(){ $(this).hide(); });
</script>

In case you want to show a blank image jpg, this can be achieved using following script:

<script>
// Replace missing image $('img').error(function(){ $(this).attr('src', 'missing.jpg'); });
</script>






Wednesday, December 4, 2013

Chrome's Developer Tool - Handy when debugging your web application for CSS issues.

Wanted to share the benefits of using Chrome's developer tool. I know most of you would be using it for lot of debugging and profiling. We can also use Chrome to see all our incorrectly defined CSS properties on our website. Just go to the following icon on your Chrome and select Developers Tools under Tools.


Once you open your developers tool console, it appears at the bottom of your browser.

Now you can view all your invalid CSS on a web page when you open that webpage on the browser and view "Resource" section of the developers Tool. This will list all invalid CSS properties defined on the page and you can go to your code and remove / Change them.


Monday, November 25, 2013

Struts 2 and Apache Tiles Integration

This is an extension of a series of blogs I have written on Struts 2. Feel free to go through them on this blog site to a better understanding of how to create a web application and use Struts 2.

In this blog, I will be introducing Apache Tiles integration with Struts 2.

Tiles is a templating system. It can be used to create a common look and feel for a web application. Tiles can also be used to create reusable view components.


Benefits of Tiles are:-

  • Screen definitions - Create a screen by assembling Tiles : header, footer, menu, body, etc.
  • Layouts - Define common page layouts and reuse them across your website.
  • Dynamic page building - Tiles can be gathered dynamically during page reload. It is possible to change any attribute: layout, list of Tiles in portal, list of menu items, etc.
  • Reuse of Tiles / Components - If well defined, a Tile can be reused across multiple applications.
  • Multi-channels - It is possible to load different Tiles according to a key.


Configuring Tiles:-

Configuring pom.xml

Following tiles artifacts need to be added.
I am using ${tiles.version} = 2.2.2


<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-api</artifactId>
<version>${tiles.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-compat</artifactId>
<version>${tiles.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-core</artifactId>
<version>${tiles.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>${tiles.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-servlet</artifactId>
<version>${tiles.version}</version>

</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-template</artifactId>
<version>${tiles.version}</version>

</dependency>

      <dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-tiles-plugin</artifactId>
<version>2.2.1</version>

</dependency>


Configuring web.xml to use Tiles:-

Once we have added all the Tiles dependencies in pom.xml, we need to add Tiles in our web.xml

Add following entries with you strtus2 entry. Your web.xml should look like this:-



<context-param>
   <param-name>
      org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG
   </param-name>
   <param-value>
      /WEB-INF/tiles.xml
   </param-value>
   </context-param>

   <listener>
   <listener-class>
      org.apache.struts2.tiles.StrutsTilesListener
   </listener-class>
   </listener>

  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>
      org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
    </filter-class>
  </filter>

  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>

  </filter-mapping>




Creating Tiles template and different jsps that will be included as tiles.

My tiles template would look like the image below. It will have a header jsp that contains the corporation name and logo. Body jsp that contains the dynamic content and a footer jsp that contains copyright information.
baseLayout.jsp

This is the tiles jsp that will hold the other jsps and act like a template page.

You see how I am using divs and css to create a table. It is always advisable to use div tables rather than normal html tables.


<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
  <title> Struts2 Tiles sample</title>
 <style type="text/css">
    .divInner1{

        text-align:center;
        border: .1px solid;
        float:left;

    }
div.page {
width: 11in;
height: 8.5in;
padding: .5cm auto;
margin: .1cm auto;
border: 1px #D3D3D3 solid;
border-radius: 5px;
background: white;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
}
    </style>
 </head>

 <body>
 <div class="page">
<div style="display: table; ">
<div style="display: table-row; ">
<div class='divInner1' style="width: 11in; height: 1.5in;" >
<tiles:insertAttribute name="header" />
</div>
</div>
</div>
<div style="display: table;  float:left;">
<div style="display: table-row;">
<div class='divInner1' style="width: 11in; height: 4.5in;" >
<tiles:insertAttribute name="body" />
</div>
</div>
</div>
<div style="display: table; width: 7in; height: 6.5in; float:left;">
<div style="display: table-row;">
<div class='divInner1' style="width: 11in; height: .5in;">
<tiles:insertAttribute name="footer" />
</div>   
</div>
</div>
 </body>

</html>



header.jsp

Following is the code for header.jsp marked as "header" in tiles tag in baseLayout.jsp page above.

<div class="header">

<p>This is the header</p>

</div>

<style>

div.header

{

padding:2px 3px; 

background:white;

}

p {font-size:30px;font-family:Arial;font-weight:bolder;color:blue;}

</style>

footer.jsp

Following is the html code for footer.

<div class="footer">

<p>This is the footer</p>
</div>

<style>

div.footer

{

padding:2px 3px; 

background:white;

}

p {font-size:30px;font-family:Arial;font-weight:bolder;color:blue;}

</style>


body.jsp

This is the html code for body page.

<div class="body">
<p>This is the body area</p>
</div>
<style>
div.body
{
padding:2px 3px; 
background:white;
         }
p {font-size:30px;font-family:Arial;font-weight:bolder;color:blue;}
</style>


Configuring Tiles configuration file - tiles.xml

Now a tiles.xml file has to be created and kept along with web.xml in WEB-INF. This file tells about the configuration of tiles and corresponding jsp pages.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
   "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
   "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">

<tiles-definitions>

   <definition name="baseLayout" template="/myapp/baseLayout.jsp">
      <put-attribute name="title"  value="Tiles Page"/>
      <put-attribute name="header" value="/myapp/header.jsp"/>
      <put-attribute name="body" value="/myapp/body.jsp"/>
      <put-attribute name="footer"   value="/myapp/footer.jsp"/>
   </definition>

   <definition name="success" extends="baseLayout">
   </definition>
  
</tiles-definitions>


Configuring struts.xml

Once you have created the baseLayout page, other tiles pages and configured the tiles.xml, now you will proceed to configuring the struts.xml so that everything could work.



<package name="sampleapp" namespace="/" extends="struts-default,json-default">
<result-types>
                    <result-type name="tiles"  class="org.apache.struts2.views.tiles.TilesResult" />

              </result-types>
                  ....
                  ....
                  <action name="/sampleapp/*" method="execute"  class="com.myorg.action.SampleAppAction">
<result name="success" type="tiles">success</result>
                   ....
                   ....
                   </action>
           </package>
                 


As you see in the code above, we define tiles with class TilesResult and then in our action, we direct result that are "success" to type="tiles".

This completes the sample implementation of tiles. 

Tiles framework is much more flexible and provided with much more feature, which you can try out after this sample implementation works.






Friday, November 22, 2013

Struts 2 -Repopulating a page with updated data after form submit

This post is an extension of my previous post( Creating sample Struts 2 Web Application ) that talks about creating Struts 2 web application. In this post I will talk about a much smaller and simpler trick to reload the submitted page with some updated content. I have seen on lots of forums, this question being asked that how do we show the same submitted page with new content.

 For that you need following entry as your struts.xml entry:-
<action name="loginaction" method="execute"  class="com.myorg.LoginAction">
<result name="input" >/sampleapp/Login.jsp</result>
<result name="success">/sampleapp/Login.jsp</result>
</action>


Now the entry in your Login.jsp page is, 


    <body>
              <s:form action="loginaction" method="post" > 
              <label for="name"><p>Enter your Name</p></label>
              <input type="text" size="50" name="id"/>
             <s:submit value="Submit" />
            </s:form>
      <s:if test="%{id != null}">
         <br/><p>Hello 
         <s:property value="id"/></h3>
     </s:if>

</body>


Your action class looks like this:-


public String execute() throws Exception {

if(null != id)
this.id = "Dear "+id;

        return SUCCESS;

    }


Now when you submit your page, and you have entered a name, it will be go to the action, and then repopulated on the refreshed Login page with text "Hello Dear <yourname>".