001/*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2008-2012 SonarSource
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 */
020package org.sonar.api.utils;
021
022import org.apache.commons.configuration.Configuration;
023import org.apache.commons.io.IOUtils;
024import org.apache.commons.lang.StringUtils;
025import org.sonar.api.BatchComponent;
026
027import java.io.IOException;
028import java.io.InputStream;
029import java.io.InputStreamReader;
030import java.io.Reader;
031import java.net.HttpURLConnection;
032import java.net.URL;
033
034/**
035 * @since 1.10
036 * @deprecated use org.sonar.api.plaform.Server instead
037 */
038@Deprecated
039public class ServerHttpClient implements BatchComponent {
040
041  protected static final String SERVER_API_PATH = "/api/server";
042  private static final String KEY_PATH = SERVER_API_PATH + "/key";
043  private static final String VERSION_PATH = SERVER_API_PATH + "/version";
044  protected static final String MAVEN_PATH = "/deploy/maven";
045  private static final int CONNECT_TIMEOUT_MILLISECONDS = 30000;
046  private static final int READ_TIMEOUT_MILLISECONDS = 60000;
047
048  private String url;
049  private Integer connectTimeoutMiliseconds = CONNECT_TIMEOUT_MILLISECONDS;
050  private Integer readTimeoutMiliseconds = READ_TIMEOUT_MILLISECONDS;
051
052  public ServerHttpClient(String remoteServerUrl) {
053    this(remoteServerUrl, null, null);
054  }
055
056  public ServerHttpClient(String remoteServerUrl, Integer connectTimeoutMiliseconds, Integer readTimeoutMiliseconds) {
057    this.url = StringUtils.chomp(remoteServerUrl, "/");
058    if (connectTimeoutMiliseconds != null) {
059      this.connectTimeoutMiliseconds = connectTimeoutMiliseconds;
060    }
061    if (readTimeoutMiliseconds != null) {
062      this.readTimeoutMiliseconds = readTimeoutMiliseconds;
063    }
064
065  }
066
067  public ServerHttpClient(Configuration configuration) {
068    this(configuration.getString("sonar.host.url", "http://localhost:9000"),
069        configuration.getInteger("sonar.host.connectTimeoutMs", CONNECT_TIMEOUT_MILLISECONDS),
070        configuration.getInteger("sonar.host.readTimeoutMs", READ_TIMEOUT_MILLISECONDS));
071
072  }
073
074  /**
075   * Throws a runtime ServerConnectionException if it fails to connect Sonar server
076   */
077  public void checkUp() {
078    String exceptionLabel = "Sonar server at " + url +
079        " is unreacheable. Either start it or setup the sonar.host.url setting if the URL is incorrect";
080    if (getId() == null) {
081      throw new ServerConnectionException(exceptionLabel);
082    }
083  }
084
085  public String getId() {
086    return executeAction(KEY_PATH);
087  }
088
089  public String getVersion() {
090    return executeAction(VERSION_PATH);
091  }
092
093  public String getMavenRepositoryUrl() {
094    return this.url + MAVEN_PATH;
095  }
096
097  protected String executeAction(String action) {
098    String result = getRemoteContent(url + action);
099    if (StringUtils.isBlank(result)) {
100      throw new ServerApiEmptyContentException("Empty " + action + " returned from server");
101    }
102    return result;
103  }
104
105  protected String getRemoteContent(String url) {
106    HttpURLConnection conn = null;
107    Reader reader = null;
108    try {
109      conn = getConnection(url, "GET");
110      reader = new InputStreamReader((InputStream) conn.getContent());
111
112      int statusCode = conn.getResponseCode();
113      if (statusCode != HttpURLConnection.HTTP_OK) {
114        throw new ServerConnectionException("Status returned by url : '" + url + "' is invalid : " + statusCode);
115      }
116
117      return IOUtils.toString(reader);
118    } catch (IOException e) {
119      throw new ServerConnectionException("url=" + url, e);
120
121    } finally {
122      IOUtils.closeQuietly(reader);
123      if (conn != null) {
124        conn.disconnect();
125      }
126    }
127  }
128
129  public String getUrl() {
130    return url;
131  }
132
133  private HttpURLConnection getConnection(String url, String method) throws IOException {
134    URL page = new URL(url);
135    HttpURLConnection conn = (HttpURLConnection) page.openConnection();
136    conn.setConnectTimeout(connectTimeoutMiliseconds);
137    conn.setReadTimeout(readTimeoutMiliseconds);
138
139    conn.setRequestMethod(method);
140    conn.connect();
141    return conn;
142  }
143
144  public static class ServerApiEmptyContentException extends SonarException {
145
146    public ServerApiEmptyContentException(String s) {
147      super(s);
148    }
149  }
150
151  public static class ServerConnectionException extends SonarException {
152
153    public ServerConnectionException(String msg) {
154      super(msg);
155    }
156
157    public ServerConnectionException(String msg, Throwable throwable) {
158      super(msg, throwable);
159    }
160
161  }
162}