001/*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2013 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * SonarQube 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 * SonarQube 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 License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019 */
020package org.sonar.wsclient;
021
022import org.sonar.wsclient.internal.HttpRequestFactory;
023import org.sonar.wsclient.issue.ActionPlanClient;
024import org.sonar.wsclient.issue.IssueClient;
025import org.sonar.wsclient.issue.internal.DefaultActionPlanClient;
026import org.sonar.wsclient.issue.internal.DefaultIssueClient;
027import org.sonar.wsclient.permissions.PermissionClient;
028import org.sonar.wsclient.permissions.internal.DefaultPermissionClient;
029import org.sonar.wsclient.user.UserClient;
030import org.sonar.wsclient.user.internal.DefaultUserClient;
031
032import javax.annotation.Nullable;
033
034/**
035 * Entry point of the Java Client for Sonar Web Services. It does not support all web services yet.
036 * <p/>
037 * Example:
038 * <pre>
039 *   SonarClient client = SonarClient.create("http://localhost:9000");
040 *   IssueClient issueClient = client.issueClient();
041 * </pre>
042 *
043 * @since 3.6
044 */
045public class SonarClient {
046
047  public static final int DEFAULT_CONNECT_TIMEOUT_MILLISECONDS = 30000;
048  public static final int DEFAULT_READ_TIMEOUT_MILLISECONDS = 60000;
049
050  /**
051   * Visibility relaxed for unit tests
052   */
053  final HttpRequestFactory requestFactory;
054
055  private SonarClient(Builder builder) {
056    requestFactory = new HttpRequestFactory(builder.url)
057      .setLogin(builder.login)
058      .setPassword(builder.password)
059      .setProxyHost(builder.proxyHost)
060      .setProxyPort(builder.proxyPort)
061      .setProxyLogin(builder.proxyLogin)
062      .setProxyPassword(builder.proxyPassword)
063      .setConnectTimeoutInMilliseconds(builder.connectTimeoutMs)
064      .setReadTimeoutInMilliseconds(builder.readTimeoutMs);
065  }
066
067  /**
068   * New client to interact with web services related to issues
069   */
070  public IssueClient issueClient() {
071    return new DefaultIssueClient(requestFactory);
072  }
073
074  /**
075   * New client to interact with web services related to issue action plans
076   */
077  public ActionPlanClient actionPlanClient() {
078    return new DefaultActionPlanClient(requestFactory);
079  }
080
081  /**
082   * New client to interact with web services related to users
083   */
084  public UserClient userClient() {
085    return new DefaultUserClient(requestFactory);
086  }
087
088  /**
089   * New client to interact with web services related to users and groups permissions
090   */
091  public PermissionClient permissionClient() {
092    return new DefaultPermissionClient(requestFactory);
093  }
094
095  /**
096   * Create a builder of {@link SonarClient}s.
097   */
098  public static Builder builder() {
099    return new Builder();
100  }
101
102  /**
103   * Create a client with default configuration. Use {@link #builder()} to define
104   * a custom configuration (credentials, HTTP proxy, HTTP timeouts).
105   */
106  public static SonarClient create(String serverUrl) {
107    return builder().url(serverUrl).build();
108  }
109
110  public static class Builder {
111    private String login, password, url, proxyHost, proxyLogin, proxyPassword;
112    private int proxyPort = 0;
113    private int connectTimeoutMs = DEFAULT_CONNECT_TIMEOUT_MILLISECONDS, readTimeoutMs = DEFAULT_READ_TIMEOUT_MILLISECONDS;
114
115    private Builder() {
116    }
117
118    /**
119     * Mandatory HTTP server URL, eg "http://localhost:9000"
120     */
121    public Builder url(String url) {
122      this.url = url;
123      return this;
124    }
125
126    /**
127     * Optional login, for example "admin"
128     */
129    public Builder login(@Nullable String login) {
130      this.login = login;
131      return this;
132    }
133
134    /**
135     * Optional password related to {@link #login(String)}, for example "admin"
136     */
137    public Builder password(@Nullable String password) {
138      this.password = password;
139      return this;
140    }
141
142    /**
143     * Host and port of the optional HTTP proxy
144     */
145    public Builder proxy(@Nullable String proxyHost, int proxyPort) {
146      this.proxyHost = proxyHost;
147      this.proxyPort = proxyPort;
148      return this;
149    }
150
151    public Builder proxyLogin(@Nullable String proxyLogin) {
152      this.proxyLogin = proxyLogin;
153      return this;
154    }
155
156    public Builder proxyPassword(@Nullable String proxyPassword) {
157      this.proxyPassword = proxyPassword;
158      return this;
159    }
160
161    /**
162     * Sets a specified timeout value, in milliseconds, to be used when opening HTTP connection.
163     * A timeout of zero is interpreted as an infinite timeout. Default value is {@link SonarClient#DEFAULT_CONNECT_TIMEOUT_MILLISECONDS}
164     */
165    public Builder connectTimeoutMilliseconds(int i) {
166      this.connectTimeoutMs = i;
167      return this;
168    }
169
170    /**
171     * Sets the read timeout to a specified timeout, in milliseconds.
172     * A timeout of zero is interpreted as an infinite timeout. Default value is {@link SonarClient#DEFAULT_READ_TIMEOUT_MILLISECONDS}
173     */
174    public Builder readTimeoutMilliseconds(int i) {
175      this.readTimeoutMs = i;
176      return this;
177    }
178
179    /**
180     * Build a new client
181     */
182    public SonarClient build() {
183      if (url == null || "".equals(url)) {
184        throw new IllegalStateException("Server URL must be set");
185      }
186      return new SonarClient(this);
187    }
188  }
189}