1919 */
2020package org .sonarsource .scanner .lib ;
2121
22+ import java .net .InetSocketAddress ;
2223import java .nio .file .Path ;
2324import java .nio .file .Paths ;
25+ import java .time .temporal .ChronoUnit ;
2426import java .util .HashMap ;
2527import java .util .Locale ;
2628import java .util .Map ;
2729import java .util .Objects ;
30+ import javax .annotation .Nonnull ;
2831import javax .annotation .Nullable ;
2932import org .apache .commons .io .FileUtils ;
33+ import org .apache .commons .lang3 .StringUtils ;
3034import org .slf4j .Logger ;
3135import org .slf4j .LoggerFactory ;
3236import org .sonarsource .scanner .lib .internal .ArchResolver ;
3640import org .sonarsource .scanner .lib .internal .Paths2 ;
3741import org .sonarsource .scanner .lib .internal .ScannerEngineLauncherFactory ;
3842import org .sonarsource .scanner .lib .internal .cache .FileCache ;
39- import org .sonarsource .scanner .lib .internal .http .ServerConnection ;
43+ import org .sonarsource .scanner .lib .internal .http .HttpConfig ;
44+ import org .sonarsource .scanner .lib .internal .http .ScannerHttpClient ;
4045import org .sonarsource .scanner .lib .internal .util .VersionUtils ;
4146
4247import static org .sonarsource .scanner .lib .ScannerProperties .SCANNER_ARCH ;
4348import static org .sonarsource .scanner .lib .ScannerProperties .SCANNER_OS ;
44- import static org .sonarsource .scanner .lib .internal .http .ServerConnection .removeTrailingSlash ;
4549
4650/**
4751 * Entry point to run a Sonar analysis programmatically.
@@ -57,14 +61,14 @@ public class ScannerEngineBootstrapper {
5761 private final IsolatedLauncherFactory launcherFactory ;
5862 private final ScannerEngineLauncherFactory scannerEngineLauncherFactory ;
5963 private final Map <String , String > bootstrapProperties = new HashMap <>();
60- private final ServerConnection serverConnection ;
64+ private final ScannerHttpClient scannerHttpClient ;
6165 private final System2 system ;
6266
6367 ScannerEngineBootstrapper (String app , String version , System2 system ,
64- ServerConnection serverConnection , IsolatedLauncherFactory launcherFactory ,
68+ ScannerHttpClient scannerHttpClient , IsolatedLauncherFactory launcherFactory ,
6569 ScannerEngineLauncherFactory scannerEngineLauncherFactory ) {
6670 this .system = system ;
67- this .serverConnection = serverConnection ;
71+ this .scannerHttpClient = scannerHttpClient ;
6872 this .launcherFactory = launcherFactory ;
6973 this .scannerEngineLauncherFactory = scannerEngineLauncherFactory ;
7074 this .setBootstrapProperty (InternalProperties .SCANNER_APP , app )
@@ -73,7 +77,7 @@ public class ScannerEngineBootstrapper {
7377
7478 public static ScannerEngineBootstrapper create (String app , String version ) {
7579 System2 system = new System2 ();
76- return new ScannerEngineBootstrapper (app , version , system , new ServerConnection (),
80+ return new ScannerEngineBootstrapper (app , version , system , new ScannerHttpClient (),
7781 new IsolatedLauncherFactory (), new ScannerEngineLauncherFactory (system ));
7882 }
7983
@@ -106,20 +110,62 @@ public ScannerEngineFacade bootstrap() {
106110 var isSimulation = properties .containsKey (InternalProperties .SCANNER_DUMP_TO_FILE );
107111 var sonarUserHome = resolveSonarUserHome (properties );
108112 var fileCache = FileCache .create (sonarUserHome );
109- serverConnection .init (properties , sonarUserHome );
113+ var httpConfig = new HttpConfig (bootstrapProperties , sonarUserHome );
114+ scannerHttpClient .init (httpConfig );
110115 String serverVersion = null ;
111116 if (!isSonarCloud ) {
112- serverVersion = getServerVersion (serverConnection , isSimulation , properties );
117+ serverVersion = getServerVersion (scannerHttpClient , isSimulation , properties );
113118 }
114119
115120 if (isSimulation ) {
116121 return new SimulationScannerEngineFacade (properties , isSonarCloud , serverVersion );
117122 } else if (isSonarCloud || VersionUtils .isAtLeastIgnoringQualifier (serverVersion , SQ_VERSION_NEW_BOOTSTRAPPING )) {
118- var launcher = scannerEngineLauncherFactory .createLauncher (serverConnection , fileCache , properties );
123+ var launcher = scannerEngineLauncherFactory .createLauncher (scannerHttpClient , fileCache , properties );
119124 return new NewScannerEngineFacade (properties , launcher , isSonarCloud , serverVersion );
120125 } else {
121- var launcher = launcherFactory .createLauncher (serverConnection , fileCache );
122- return new InProcessScannerEngineFacade (properties , launcher , false , serverVersion );
126+ var launcher = launcherFactory .createLauncher (scannerHttpClient , fileCache );
127+ var adaptedProperties = adaptDeprecatedProperties (properties , httpConfig );
128+ return new InProcessScannerEngineFacade (adaptedProperties , launcher , false , serverVersion );
129+ }
130+ }
131+
132+ /**
133+ * Older SonarQube versions used to rely on some different properties, or even {@link System} properties.
134+ * For backward compatibility, we adapt the new properties to the old format.
135+ */
136+ @ Nonnull
137+ Map <String , String > adaptDeprecatedProperties (Map <String , String > properties , HttpConfig httpConfig ) {
138+ var adaptedProperties = new HashMap <>(properties );
139+ if (!adaptedProperties .containsKey (HttpConfig .READ_TIMEOUT_SEC_PROPERTY )) {
140+ adaptedProperties .put (HttpConfig .READ_TIMEOUT_SEC_PROPERTY , "" + httpConfig .getSocketTimeout ().get (ChronoUnit .SECONDS ));
141+ }
142+ var proxy = httpConfig .getProxy ();
143+ if (proxy != null ) {
144+ setSystemPropertyIfNotAlreadySet ("http.proxyHost" , ((InetSocketAddress ) proxy .address ()).getHostString ());
145+ setSystemPropertyIfNotAlreadySet ("https.proxyHost" , ((InetSocketAddress ) proxy .address ()).getHostString ());
146+ setSystemPropertyIfNotAlreadySet ("http.proxyPort" , "" + ((InetSocketAddress ) proxy .address ()).getPort ());
147+ setSystemPropertyIfNotAlreadySet ("https.proxyPort" , "" + ((InetSocketAddress ) proxy .address ()).getPort ());
148+ }
149+ setSystemPropertyIfNotAlreadySet ("http.proxyUser" , httpConfig .getProxyUser ());
150+ setSystemPropertyIfNotAlreadySet ("http.proxyPassword" , httpConfig .getProxyPassword ());
151+
152+ var keyStore = httpConfig .getSslConfig ().getKeyStore ();
153+ if (keyStore != null ) {
154+ setSystemPropertyIfNotAlreadySet ("javax.net.ssl.keyStore" , keyStore .getPath ().toString ());
155+ setSystemPropertyIfNotAlreadySet ("javax.net.ssl.keyStorePassword" , keyStore .getKeyStorePassword ());
156+ }
157+ var trustStore = httpConfig .getSslConfig ().getTrustStore ();
158+ if (trustStore != null ) {
159+ setSystemPropertyIfNotAlreadySet ("javax.net.ssl.trustStore" , trustStore .getPath ().toString ());
160+ setSystemPropertyIfNotAlreadySet ("javax.net.ssl.trustStorePassword" , trustStore .getKeyStorePassword ());
161+ }
162+
163+ return Map .copyOf (adaptedProperties );
164+ }
165+
166+ private void setSystemPropertyIfNotAlreadySet (String key , String value ) {
167+ if (system .getProperty (key ) == null && StringUtils .isNotBlank (value )) {
168+ System .setProperty (key , value );
123169 }
124170 }
125171
@@ -134,16 +180,16 @@ private static Path resolveSonarUserHome(Map<String, String> properties) {
134180 return Paths .get (sonarUserHome );
135181 }
136182
137- private static String getServerVersion (ServerConnection serverConnection , boolean isSimulation , Map <String , String > properties ) {
183+ private static String getServerVersion (ScannerHttpClient scannerHttpClient , boolean isSimulation , Map <String , String > properties ) {
138184 if (isSimulation ) {
139185 return properties .getOrDefault (InternalProperties .SCANNER_VERSION_SIMULATION , "5.6" );
140186 }
141187
142188 try {
143- return serverConnection .callRestApi ("/analysis/version" );
189+ return scannerHttpClient .callRestApi ("/analysis/version" );
144190 } catch (Exception e ) {
145191 try {
146- return serverConnection .callWebApi ("/api/server/version" );
192+ return scannerHttpClient .callWebApi ("/api/server/version" );
147193 } catch (Exception e2 ) {
148194 var ex = new IllegalStateException ("Failed to get server version" , e2 );
149195 ex .addSuppressed (e );
@@ -154,8 +200,8 @@ private static String getServerVersion(ServerConnection serverConnection, boolea
154200
155201 private void initBootstrapDefaultValues () {
156202 setBootstrapPropertyIfNotAlreadySet (ScannerProperties .HOST_URL , getSonarCloudUrl ());
157- setBootstrapPropertyIfNotAlreadySet (ScannerProperties .API_BASE_URL , isSonarCloud ( bootstrapProperties ) ?
158- SONARCLOUD_REST_API : (removeTrailingSlash (bootstrapProperties .get (ScannerProperties .HOST_URL )) + "/api/v2" ));
203+ setBootstrapPropertyIfNotAlreadySet (ScannerProperties .API_BASE_URL ,
204+ isSonarCloud ( bootstrapProperties ) ? SONARCLOUD_REST_API : (StringUtils . removeEnd (bootstrapProperties .get (ScannerProperties .HOST_URL ), "/" ) + "/api/v2" ));
159205 if (!bootstrapProperties .containsKey (SCANNER_OS )) {
160206 setBootstrapProperty (SCANNER_OS , new OsResolver (system , new Paths2 ()).getOs ().name ().toLowerCase (Locale .ENGLISH ));
161207 }
0 commit comments