001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     * 
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.performance.http;
019    
020    import java.util.logging.Logger;
021    
022    import org.apache.commons.httpclient.HttpClient;
023    import org.apache.commons.httpclient.HttpException;
024    import org.apache.commons.httpclient.HttpMethod;
025    import org.apache.commons.httpclient.HttpStatus;
026    import org.apache.commons.httpclient.methods.GetMethod;
027    import org.apache.commons.httpclient.methods.PostMethod;
028    
029    import org.apache.commons.performance.ClientThread;
030    import org.apache.commons.performance.Statistics;
031    
032    /**
033     * Client thread that executes http requests in a loop against a configured
034     * url, with the number of requests, time between requests and 
035     * query strings governed by constructor parameters. See 
036     * {@link ClientThread ClientThread javadoc} for a description
037     * of how times between requests are computed.
038     *
039     */
040    public class HttpClientThread extends ClientThread {
041    
042        private HttpClient httpClient = new HttpClient();
043        private HttpMethod httpMethod = null;
044        private String successKey = null;
045        
046        public HttpClientThread(long iterations, long minDelay, long maxDelay,
047                double sigma, String delayType, long rampPeriod,
048                long peakPeriod, long troughPeriod, String cycleType,
049                String rampType, Logger logger,
050                Statistics stats, String url, String method,
051                int socketTimeout, String successKey)  {
052            
053            super(iterations, minDelay, maxDelay, sigma, delayType, rampPeriod,
054                    peakPeriod, troughPeriod, cycleType, rampType, logger,
055                    stats);
056            
057            httpClient.getParams().setSoTimeout(socketTimeout);
058            if (method.trim().toUpperCase().equals("POST")) {
059                httpMethod = new PostMethod(url);
060            } else {
061                httpMethod = new GetMethod(url);
062            }
063            this.successKey = successKey;
064        }
065    
066        /** Nothing to do here at this point */
067        public void setUp() throws Exception {}
068        
069        /**
070         * Execute the http method against the target url.
071         * Throws HttpException if something other than 200 status is returned
072         * or if there is a successKey configured and the response does not contain
073         * the specified key.
074         */
075        public void execute() throws Exception {
076            int statusCode = httpClient.executeMethod(httpMethod);
077            if (statusCode != HttpStatus.SC_OK) {
078                throw new HttpException("Request failed with status code: "
079                        + statusCode);
080            }
081            // Should use stream here - for now assume body is small
082            String responseBody = httpMethod.getResponseBodyAsString();
083            if (successKey != null && responseBody.indexOf(successKey) < 0 ) {
084                throw new HttpException("Response did not include success key: "
085                        + successKey);
086            }
087        }
088        
089        /** Release http connection */
090        public void cleanUp() throws Exception {
091             httpMethod.releaseConnection();
092        }
093    
094    }