se.vgregion.pubsub.loadtesting.LoadtestingServlet.java Source code

Java tutorial

Introduction

Here is the source code for se.vgregion.pubsub.loadtesting.LoadtestingServlet.java

Source

/**
 * Copyright 2010 Vstra Gtalandsregionen
 *
 *   This library is free software; you can redistribute it and/or modify
 *   it under the terms of version 2.1 of the GNU Lesser General Public
 *   License as published by the Free Software Foundation.
 *
 *   This library is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this library; if not, write to the
 *   Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 *   Boston, MA 02111-1307  USA
 *
 */

package se.vgregion.pubsub.loadtesting;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;

@SuppressWarnings("serial")
public class LoadtestingServlet extends HttpServlet {

    private Map<UUID, CountDownLatch> publications = new ConcurrentHashMap<UUID, CountDownLatch>();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // ping publish
        // wait for notification
        // response
        // error if timeout

        if (req.getPathInfo().equals("/feed")) {
            // serve ATOM feed
            resp.getWriter().write(atom(getFragment(req)));
        } else {
            // publish

            UUID id = UUID.randomUUID();
            String publicationUrl = "http://" + req.getServerName() + ":" + req.getServerPort()
                    + req.getContextPath() + "/feed#" + id;

            String hubUrl = System.getProperty("hub.url");
            if (hubUrl == null) {
                throw new RuntimeException("System properti hub.url missing");
            }

            try {
                CountDownLatch latch = new CountDownLatch(1);
                publications.put(id, latch);

                HttpPost publication = new HttpPost(hubUrl);
                List<NameValuePair> parameters = new ArrayList<NameValuePair>();
                parameters.add(new BasicNameValuePair("hub.mode", "publish"));
                parameters.add(new BasicNameValuePair("hub.url", publicationUrl));

                publication.setEntity(new UrlEncodedFormEntity(parameters));

                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpResponse publicationResponse = httpClient.execute(publication);

                if (publicationResponse.getStatusLine().getStatusCode() == 204) {
                    try {
                        if (latch.await(20000, TimeUnit.MILLISECONDS)) {
                            // all happy, return
                            return;
                        } else {
                            // timeout
                            resp.sendError(591);
                        }
                    } catch (InterruptedException e) {
                        // interrupted
                        resp.sendError(592);
                    }
                } else {
                    // publication failed
                    resp.sendError(publicationResponse.getStatusLine().getStatusCode(),
                            publicationResponse.getStatusLine().getReasonPhrase());
                }
            } finally {
                // try to prevent memory leaks
                publications.remove(id);
            }
        }
    }

    private String getFragment(HttpServletRequest request) {
        // !!! Jetty dependent
        String s = request.toString();
        int hash = s.indexOf("#");
        int end = s.indexOf("]", hash);
        if (hash > -1) {
            return s.substring(hash + 1, end);
        } else {
            throw new RuntimeException("Can not parse fragment, this code is Jetty specific for now");
        }
    }

    private String atom(String id) {
        return "<feed xmlns='http://www.w3.org/2005/Atom'>" + "<title>foobar</title>" + "<id>urn:f1</id>"
                + "<entry>" + "<title>t1</title>" + "<id>uuid:" + id + "</id>" + "<updated>" + print(new DateTime())
                + "</updated>" + "</entry></feed>";
    }

    public static String print(DateTime value) {
        DateTimeFormatter fmt = ISODateTimeFormat.dateTime().withZone(DateTimeZone.UTC);
        return fmt.print(value);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // find the ID in the feed content
        BufferedReader reader = req.getReader();
        String line = reader.readLine();
        while (line != null) {
            int start = line.indexOf("uuid:");
            if (start > -1) {
                int end = line.indexOf("<", start);
                String id = line.substring(start + 5, end);
                UUID uuid = UUID.fromString(id);

                // found id, now try to count down latch
                CountDownLatch latch = publications.get(uuid);
                if (latch != null) {
                    latch.countDown();

                    publications.remove(id);
                    return;
                } else {
                    throw new RuntimeException("Could not find latch");
                }
            }
            line = reader.readLine();
        }
    }

}