I am working on a plugin for the SeleniumXml tool that Brett demoed at
Apachecon. It sends a request to the server and parses the result, putting
it into the SeleniumXml test context.

I am using Apache's HttpClient 4.0b3 because it has some nice response
handling features. I am making two requests to the server, one to login and
one to run the request. My problem is that the login request seems to
execute okay, but when I inspect the contents of the cookies I don't see
anything that looks like a session management cookie (is it JSESSIONID ?) so
the second request does not share the session and does not think the user is
logged in, so the service fails due to authorization failure.

This is not an OFBiz problem, but I am hoping there are some OFBiz
friendlies out there that will help me move the testing environment along.
Is there something that a browser does in interacting with the server that
my HttpClient will not do unless I tell it to?
How does tomcat know to track sessions?

I have pasted in my current code. It is mostly a hack of HttpClient 4.0
examples.

package org.seleniumxml;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.scheme.SocketFactory;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.jdom.Element;


public class RemoteRequest {

    public static final String module = RemoteRequest.class.getName();

    /**
     * The default parameters.
     * Instantiated in [EMAIL PROTECTED] #setup setup}.
     */
    private static HttpParams defaultParameters = null;

    /**
     * The scheme registry.
     * Instantiated in [EMAIL PROTECTED] #setup setup}.
     */
    private static SchemeRegistry supportedSchemes;
    final private static String JsonHandleMode = "JSON_HANDLE";
    final private static String HttpHandleMode = "HTTP_HANDLE";

    private SeleniumXml parent;
    private SeleniumXml currentTest;
    private List <Element>children;
    private Map <String, Object> inMap;
    private Map <String, Object> outMap;
    private String requestUrl;
    private String host;
    private String responseHandlerMode;

    private int currentRowIndx;

    static {

        supportedSchemes = new SchemeRegistry();

        // Register the "http" protocol scheme, it is required
        // by the default operator to look up socket factories.
        SocketFactory sf = PlainSocketFactory.getSocketFactory();
        supportedSchemes.register(new Scheme("http", sf, 80));

        // prepare parameters
        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, "UTF-8");
        HttpProtocolParams.setUseExpectContinue(params, true);
        //HttpClientParams.setAuthenticating(params, true);
        defaultParameters = params;

    }
    public RemoteRequest(SeleniumXml parent, List<Element> children, String
requestUrl, String hostString, String responseHandlerMode) {
        super();
        this.parent = parent;
        this.requestUrl = requestUrl;
        this.host = hostString;
        this.children = children;
        this.responseHandlerMode =
(HttpHandleMode.equals(responseHandlerMode)) ? HttpHandleMode :
JsonHandleMode;
        initData();
    }

    private void initData() {

        String nm, name, value = null;
        for(Element elem: this.children) {
            nm = elem.getName();
            if (nm.equals("param-in") || nm.equals("param-inout")) {
                name = elem.getAttributeValue("name");
                value =
this.parent.replaceParam(elem.getAttributeValue("value"));
                this.inMap.put(name, value);
            } else if (nm.equals("param-out") || nm.equals("param-inout")) {
                name = elem.getAttributeValue("name");
                value =
this.parent.replaceParam(elem.getAttributeValue("value"));
                this.outMap.put(name, value);
            }
        }
        return;
    }

    public void runTest() {

        ClientConnectionManager ccm =
            new ThreadSafeClientConnManager(defaultParameters,
supportedSchemes);
        //  new SingleClientConnManager(getParams(), supportedSchemes);

        DefaultHttpClient client = new DefaultHttpClient(ccm,
defaultParameters);
        client.setKeepAliveStrategy(new
DefaultConnectionKeepAliveStrategy());  // Don't know what this does - a
shot in the dark

        //HttpContext clientContext = client.
        //HttpHost target = new HttpHost(this.host, 80, "http");
        HttpEntity entity = null;
        ResponseHandler <String> responseHandler = null;
        try {
            BasicHttpContext localContext = new BasicHttpContext(); // This
is what I expect to tie the requests to the same session

// because it stores the cookies
            // Create a local instance of cookie store
            CookieStore cookieStore = new BasicCookieStore();
            localContext.setAttribute(ClientContext.COOKIE_STORE,
cookieStore);
            //this.login(client, localContext);
            // I copied the 'login' code to here
            String paramString2 = "USERNAME=" + this.parent.getUserName()
                               + "&PASSWORD=" + this.parent.getPassword();
            String thisUri2 = this.host + "/eng/control/login?" +
paramString2;
            HttpGet req2 = new HttpGet ( thisUri2 );
            req2.setHeader("Connection","Keep-Alive");
            client.execute(req2, localContext);


            List<Cookie> cookies = cookieStore.getCookies();
            for (int i = 0; i < cookies.size(); i++) {
                System.out.println("Local cookie(0): " + cookies.get(i));
            }
            // The above lines print out: Local cookie(0): [version:
0][name: OFBiz.Visitor][value: 10221][domain: localhost][path: /][expiry:
Sat Nov 21 00:10:39 MST 2009]
            // I am thinking I should see something related to session
tracking here

            if (HttpHandleMode.equals(this.responseHandlerMode)) {

            } else {
                responseHandler = new JsonResponseHandler(this);
            }
            String paramString = urlEncodeArgs(this.inMap, true);
            String thisUri = this.host + this.requestUrl + "?" +
paramString;
            HttpGet req = new HttpGet ( thisUri );

            String responseBody = client.execute( req, responseHandler,
localContext);
            /*
            entity = rsp.getEntity();

            System.out.println("----------------------------------------");
            System.out.println(rsp.getStatusLine());
            Header[] headers = rsp.getAllHeaders();
            for (int i=0; i<headers.length; i++) {
                System.out.println(headers[i]);
            }
            System.out.println("----------------------------------------");

            if (entity != null) {
                System.out.println(EntityUtils.toString(rsp.getEntity()));
            }
            */
        } catch(IOException e) {
            System.out.println(e.getMessage());
        } finally {
            // If we could be sure that the stream of the entity has been
            // closed, we wouldn't need this code to release the connection.
            // However, EntityUtils.toString(...) can throw an exception.

            // if there is no entity, the connection is already released
            try {
              if (entity != null)
                entity.consumeContent(); // release connection gracefully
            } catch(IOException e) {
                System.out.println("in 'finally'  " + e.getMessage());
            }

        }
        return;
    }

Reply via email to