001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2009 SonarSource SA 004 * mailto:contact AT sonarsource DOT com 005 * 006 * Sonar is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * Sonar is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with Sonar; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 019 */ 020 package org.sonar.wsclient.connectors; 021 022 import org.apache.commons.httpclient.*; 023 import org.apache.commons.httpclient.auth.AuthScope; 024 import org.apache.commons.httpclient.methods.DeleteMethod; 025 import org.apache.commons.httpclient.methods.GetMethod; 026 import org.apache.commons.httpclient.methods.PostMethod; 027 import org.apache.commons.httpclient.params.HttpConnectionManagerParams; 028 import org.apache.commons.httpclient.util.URIUtil; 029 import org.sonar.wsclient.Host; 030 import org.sonar.wsclient.services.CreateQuery; 031 import org.sonar.wsclient.services.DeleteQuery; 032 import org.sonar.wsclient.services.Query; 033 034 import java.io.BufferedReader; 035 import java.io.IOException; 036 import java.io.InputStream; 037 import java.io.InputStreamReader; 038 039 /** 040 * @since 2.1 041 */ 042 public class HttpClient3Connector extends Connector { 043 044 private static final int MAX_TOTAL_CONNECTIONS = 40; 045 private static final int MAX_HOST_CONNECTIONS = 4; 046 047 private final Host server; 048 private HttpClient httpClient; 049 050 public HttpClient3Connector(final Host server) { 051 this.server = server; 052 createClient(); 053 } 054 055 public HttpClient3Connector(Host server, HttpClient httpClient) { 056 this.httpClient = httpClient; 057 this.server = server; 058 } 059 060 private void createClient() { 061 final HttpConnectionManagerParams params = new HttpConnectionManagerParams(); 062 params.setConnectionTimeout(TIMEOUT_MS); 063 params.setSoTimeout(TIMEOUT_MS); 064 params.setDefaultMaxConnectionsPerHost(MAX_HOST_CONNECTIONS); 065 params.setMaxTotalConnections(MAX_TOTAL_CONNECTIONS); 066 final MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); 067 connectionManager.setParams(params); 068 this.httpClient = new HttpClient(connectionManager); 069 configureCredentials(); 070 } 071 072 private void configureCredentials() { 073 if (server.getUsername() != null) { 074 httpClient.getParams().setAuthenticationPreemptive(true); 075 Credentials defaultcreds = new UsernamePasswordCredentials(server.getUsername(), server.getPassword()); 076 httpClient.getState().setCredentials(AuthScope.ANY, defaultcreds); 077 } 078 } 079 080 public String execute(Query query) { 081 return executeRequest(newGetRequest(query)); 082 } 083 084 public String execute(CreateQuery query) { 085 return executeRequest(newPostRequest(query)); 086 } 087 088 public String execute(DeleteQuery query) { 089 return executeRequest(newDeleteRequest(query)); 090 } 091 092 private String executeRequest(HttpMethodBase method) { 093 String json = null; 094 try { 095 httpClient.executeMethod(method); 096 if (method.getStatusCode() == HttpStatus.SC_OK) { 097 json = getResponseBodyAsString(method); 098 099 } else if (method.getStatusCode() != HttpStatus.SC_NOT_FOUND) { 100 throw new ConnectionException("HTTP error: " + method.getStatusCode() + ", msg: " + method.getStatusText() + ", query: " + method); 101 } 102 103 } catch (HttpException e) { 104 throw new ConnectionException("Query: " + method, e); 105 106 } catch (IOException e) { 107 throw new ConnectionException("Query: " + method, e); 108 109 } finally { 110 if (method != null) { 111 method.releaseConnection(); 112 } 113 } 114 return json; 115 } 116 117 private HttpMethodBase newGetRequest(Query query) { 118 try { 119 String url = server.getHost() + URIUtil.encodeQuery(query.getUrl()); 120 HttpMethodBase method = new GetMethod(url); 121 method.setRequestHeader("Accept", "application/json"); 122 return method; 123 124 } catch (URIException e) { 125 throw new ConnectionException("Query: " + query, e); 126 } 127 } 128 129 private HttpMethodBase newPostRequest(CreateQuery query) { 130 try { 131 String url = server.getHost() + URIUtil.encodeQuery(query.getUrl()); 132 HttpMethodBase method = new PostMethod(url); 133 method.setRequestHeader("Accept", "application/json"); 134 return method; 135 136 } catch (URIException e) { 137 throw new ConnectionException("Query: " + query, e); 138 } 139 } 140 141 private HttpMethodBase newDeleteRequest(DeleteQuery query) { 142 try { 143 String url = server.getHost() + URIUtil.encodeQuery(query.getUrl()); 144 HttpMethodBase method = new DeleteMethod(url); 145 method.setRequestHeader("Accept", "application/json"); 146 return method; 147 148 } catch (URIException e) { 149 throw new ConnectionException("Query: " + query, e); 150 } 151 } 152 153 private String getResponseBodyAsString(HttpMethod method) { 154 BufferedReader reader = null; 155 try { 156 final InputStream inputStream = method.getResponseBodyAsStream(); 157 reader = new BufferedReader(new InputStreamReader(inputStream)); 158 final StringBuilder sb = new StringBuilder(); 159 String line; 160 161 while ((line = reader.readLine()) != null) { 162 sb.append(line).append("\n"); 163 } 164 return sb.toString(); 165 166 } catch (IOException e) { 167 throw new ConnectionException("Can not read response", e); 168 169 } finally { 170 if (reader != null) { 171 try { 172 reader.close(); 173 174 } catch (Exception e) { 175 // TODO 176 } 177 } 178 } 179 } 180 }