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