Thursday 31 March 2016

JSESSIONID and SoapUI

As the HTTP protocol is stateless, there has always been the question of 'How do we add state?'.

Nowadays this has been "solved" (notice the quotation marks there) by storing the state in the server, and assigning all this state to a "SessionID". The user entering the website gets a newly generated SessionID which is transmitted over and over again, so the server can associate the appropriate State with the appropriate User.

Usually the SessionID is sent along as a cookie, sometimes it is transmitted in the request as a request parameter.

In Java EE and JEE application servers, the cookie is called the "JSESSIONID". You can view an example in the headers shown below.

Retrieve Session id

In the first request a user does for a certain website, there is no cookie yet regarding the session.
PUT /resources/game/Elisa/logon?password=secret HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Fedora; Linux i686; rv:45.0) Gecko/20100101 Firefox/45.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json; charset=utf-8
X-Requested-With: XMLHttpRequest
Referer: http://localhost:8080/
Cookie: COOKIE_SUPPORT=true; GUEST_LANGUAGE_ID=en_US; LOGIN=6d61617274656e5f6c407961686f6f2e636f6d; REMEMBER_ME=true; SCREEN_NAME=416b713230756641726f6d414441412b304452616b513d3d; _ga=GA1.1.23915379.1454272946
Connection: keep-alive
Content-Length: 0
A new session is created, and a cookie is sent along to the browser of the user with the session id. It is visible in the response below with the name of JSESSIONID.
HTTP/1.1 204 No Content
Server: GlassFish Server Open Source Edition  5.0
X-Powered-By: Servlet/3.1 JSP/2.3  (GlassFish Server Open Source Edition  5.0  Java/Oracle Corporation/1.8)
Set-Cookie: JSESSIONID=29ee5541e005eacdbe4291e5e138; Path=/resources; HttpOnly
Date: Sat, 26 Mar 2016 11:11:11 GMT
From then on the cookie is sent upon each request the browser of the user sends:
GET /resources/private/Elisa/mail?offset=0&_=1459034166678 HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Fedora; Linux i686; rv:45.0) Gecko/20100101 Firefox/45.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
X-Requested-With: XMLHttpRequest
Referer: http://localhost:8080/
Cookie: JSESSIONID=536aea5126fb63309b2a7609da51; COOKIE_SUPPORT=true; GUEST_LANGUAGE_ID=en_US; LOGIN=6d61617274656e5f6c407961686f6f2e636f6d; REMEMBER_ME=true; SCREEN_NAME=416b713230756641726f6d414441412b304452616b513d3d; _ga=GA1.1.23915379.1454272946
Connection: keep-alive

HttpOnly

A session id is very vulnerable to man-in-the-middle attack. One slight way to mitigate this is by using the tag "HttpOnly", as shown above.

This means, the cookie is set by the server during a http response, and is read by the server during a http request, and everyone else is not allowed access.

This makes it hard to read the cookie for example using JavaScript/Crosssite scripting.

UML

Perhaps some UML will make things clearer.

SoapUI

Store session id

The idea here is to add a Groovy script as a Test step after the response from the server (with the Set-Cookie). The script retrieves the Session ID from the response headers and stores it in a SoapUI properties cache on testcase, testsuite or project level.
def header = testRunner.testCase.getTestStepByName("logon").httpRequest.response.responseHeaders["Set-Cookie"]
header=header.toString()
start=header.indexOf("JSESSIONID=")
end=header.indexOf("; Path=")
testCaseProperty= header.substring(start,end)
testRunner.testCase.testSuite.setPropertyValue( "JSESSIONID", testCaseProperty )
testRunner.testCase.testSuite.project.setPropertyValue( "JSESSIONID", testCaseProperty )

Use Session id

Now, the idea is to use this stored session id in subsequent http requests in other test steps and even other test cases.

You can define a new header in your subsequent http requests to send the session id along as a cookie, mimicking how a website works:

REST

I will go into REST Services, which are not stateful, in a future blog post. Basically it would mean that we need to send all information required for the REST Service, each and every time we access the REST Service. The state is effectively stored on the client side.

References

QA Strategies Best Testing practices and Automation tips - SOAPUI - Fetch session id from response header
http://qastrategies.blogspot.nl/2012/05/soapui-fetch-session-id-from-response.html
Time is running out, don't lose it. - Set Authentication WebService and Set Authentication Cookies in SoapUi
http://mariemjabloun.blogspot.nl/2014/11/set-webservice-authentication-and-set.html
SoapUI Cookie management
https://siking.wordpress.com/2013/07/25/soapui-cookie-management/
SoapUI - Working with Properties
https://www.soapui.org/functional-testing/properties/working-with-properties.html

Thursday 24 March 2016

CAFE BABE

CAFE BABE is the first four bytes in any Java compiled class file, in Hexadecimal format. It identifies the file as a Java class file.

James Gosling explained why.

    We used to go to lunch at a place called St Michael’s Alley. According to local legend, in the deep dark past, the Grateful Dead used to perform there before they made it big. It was a pretty funky place that was definitely a Grateful Dead Kinda Place. When Jerry died, they even put up a little Buddhist-esque shrine. When we used to go there, we referred to the place as Cafe Dead. Somewhere along the line, it was noticed that this was a HEX number. I was re-vamping some file format code and needed a couple of magic numbers: one for the persistent object file, and one for classes. I used CAFEDEAD for the object file format, and in grepping for 4 character hex words that fit after “CAFE” (it seemed to be a good theme) I hit on BABE and decided to use it. At that time, it didn’t seem terribly important or destined to go anywhere but the trash can of history. So CAFEBABE became the class file format, and CAFEDEAD was the persistent object format. But the persistent object facility went away, and along with it went the use of CAFEDEAD – it was eventually replaced by RMI.

References

The Magic Word in Java: CAFEBABE
https://dzone.com/articles/the-magic-word-in-java-cafebabe

Thursday 17 March 2016

Humour in Javadoc

I found this little gem that made me chuckle from Gavin King.
/**
 * A copy of the EE5 standard InvocationContext API.
 * We do this because some poor souls are still using
 * J2EE. Pray for them.
 * 
 * @author Gavin King
 *
 */

public interface InvocationContext
{
   public Object getTarget();
   public Map getContextData();
   public Method getMethod();
   public Object[] getParameters();
   public Object proceed() throws Exception;
   public void setParameters(Object[] params);
}

Thursday 10 March 2016

Lightfish

Had a small issue with installing Lightfish onto my Glassfish. I noticed this issue before, but forgot to write down the solution somewhere (that's how it goes).

[2016-03-06T13:20:51.109+0000] [glassfish 4.1] [WARNING] [poolmgr.create_resource_error] [javax.enterprise.resource.resourceadapter.com.sun.enterprise.resource.allocator] [tid: _ThreadID=224 _ThreadName=AutoDep
RAR5038:Unexpected exception while creating resource for pool DerbyPool. Exception : javax.resource.spi.ResourceAllocationException: Connection could not be allocated because: java.net.ConnectException : Error connecting to server localhost on port 1527 with message Connection refused.]]

Ahhh, found the solution again, the Derby database server is not installed/started automatically:
asadmin start-database
This's what I wanted to see:
[2016-03-06T13:34:06.500+0000] [glassfish 4.1] [INFO] [NCLS-DEPLOYMENT-02035] [javax.enterprise.system.tools.deployment.autodeploy] [tid: _ThreadID=224 _ThreadName=AutoDeployer] [timeMillis: 1457271246500] [levelValue: 800] [[
[AutoDeploy] Successfully autodeployed : /home/glassfish/glassfish4/glassfish/domains/domain1/autodeploy/lightfish.war.]]

References

[0] Adam Bien - Lightfish
http://lightfish.adam-bien.com/
[1] GitHub - Lightfish
https://github.com/AdamBien/lightfish
[2] StackOverflow - Derby Pool ping fails with java.net.ConnectException in Glassfish
http://stackoverflow.com/questions/27747479/derby-pool-ping-fails-with-java-net-connectexception-in-glassfish
Youtube - Project LightFish--Java EE Telemetry For GlassFish
https://www.youtube.com/watch?v=9nU6Oubx0tQ

Thursday 3 March 2016

Abstraction Considered Harmful

One of the more thought-provoking pieces I have read in a long time, and one I happen to fully agree with, having seen myself what too much Abstraction can lead to:

http://bravenewgeek.com/abstraction-considered-harmful/

I like the quote:
“duplication is far cheaper than the wrong abstraction”