url: /setup/upgrade-notes/ | url: /setup/upgrade-notes/ | ||||
--- | --- | ||||
## Release 7.8 Upgrade Notes | |||||
**Scanner version compatibility** | |||||
Only the following scanner versions are compatible with SonarQube 7.8: | |||||
* SonarQube Scanner CLI 2.9+ | |||||
* SonarQube Scanner Maven 3.3.0.603+ | |||||
* SonarQube Scanner Gradle 2.3+ | |||||
## Release 7.7 Upgrade Notes | ## Release 7.7 Upgrade Notes | ||||
**Deprecated parameters dropped** | **Deprecated parameters dropped** | ||||
`sonar.language`, and `sonar.profile`, both deprecated since 4.5, are dropped in this version as is `sonar.analysis.mode`, which as been deprecated since 6.6. These now-unrecognized parameters will simply be ignored, rather than failing analysis. | `sonar.language`, and `sonar.profile`, both deprecated since 4.5, are dropped in this version as is `sonar.analysis.mode`, which as been deprecated since 6.6. These now-unrecognized parameters will simply be ignored, rather than failing analysis. |
private static final String EMPTY = ""; | private static final String EMPTY = ""; | ||||
private static final List<Redirect> REDIRECTS = ImmutableList.of( | private static final List<Redirect> REDIRECTS = ImmutableList.of( | ||||
newSimpleRedirect("/api", "/api/webservices/list"), | |||||
new BatchRedirect(), | |||||
new BatchBootstrapRedirect(), | |||||
new ProfilesExportRedirect()); | |||||
newSimpleRedirect("/api", "/api/webservices/list")); | |||||
@Override | @Override | ||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { | ||||
String apply(HttpServletRequest request); | String apply(HttpServletRequest request); | ||||
} | } | ||||
/** | |||||
* Old scanners were using /batch/file.jar url (see SCANNERAPI-167) | |||||
*/ | |||||
private static class BatchRedirect implements Redirect { | |||||
private static final String BATCH_WS = "/batch"; | |||||
@Override | |||||
public boolean test(String path) { | |||||
return path.startsWith(BATCH_WS + "/") && path.endsWith(".jar"); | |||||
} | |||||
@Override | |||||
public String apply(HttpServletRequest request) { | |||||
String path = extractPath(request); | |||||
return format("%s%s/file?name=%s", request.getContextPath(), BATCH_WS, path.replace(BATCH_WS + "/", EMPTY)); | |||||
} | |||||
} | |||||
/** | |||||
* Old scanners were using /batch_bootstrap url (see SCANNERAPI-167) | |||||
*/ | |||||
private static class BatchBootstrapRedirect implements Redirect { | |||||
@Override | |||||
public boolean test(String path) { | |||||
return "/batch_bootstrap/index".equals(path); | |||||
} | |||||
@Override | |||||
public String apply(HttpServletRequest request) { | |||||
return format("%s%s/index", request.getContextPath(), "/batch"); | |||||
} | |||||
} | |||||
/** | |||||
* Old scanners were using /profiles/export url (see SVS-130) | |||||
*/ | |||||
private static class ProfilesExportRedirect implements Redirect { | |||||
private static final String PROFILES_EXPORT = "/profiles/export"; | |||||
private static final String API_QUALITY_PROFILE_EXPORT = "/api/qualityprofiles/export"; | |||||
@Override | |||||
public boolean test(String path) { | |||||
return PROFILES_EXPORT.equals(path); | |||||
} | |||||
@Override | |||||
public String apply(HttpServletRequest request) { | |||||
return format("%s%s?%s", request.getContextPath(), API_QUALITY_PROFILE_EXPORT, request.getQueryString()); | |||||
} | |||||
} | |||||
private static String extractPath(HttpServletRequest request) { | private static String extractPath(HttpServletRequest request) { | ||||
return sanitizePath(request.getRequestURI().replaceFirst(request.getContextPath(), EMPTY)); | return sanitizePath(request.getRequestURI().replaceFirst(request.getContextPath(), EMPTY)); | ||||
} | } |
public class RedirectFilterTest { | public class RedirectFilterTest { | ||||
HttpServletRequest request = mock(HttpServletRequest.class); | |||||
HttpServletResponse response = mock(HttpServletResponse.class); | |||||
FilterChain chain = mock(FilterChain.class); | |||||
private HttpServletRequest request = mock(HttpServletRequest.class); | |||||
private HttpServletResponse response = mock(HttpServletResponse.class); | |||||
private FilterChain chain = mock(FilterChain.class); | |||||
RedirectFilter underTest = new RedirectFilter(); | |||||
private RedirectFilter underTest = new RedirectFilter(); | |||||
@Before | @Before | ||||
public void setUp() throws Exception { | public void setUp() throws Exception { | ||||
verifyRedirection("/api/", null, "/sonarqube/api/webservices/list"); | verifyRedirection("/api/", null, "/sonarqube/api/webservices/list"); | ||||
} | } | ||||
@Test | |||||
public void send_redirect_when_url_contains_batch_with_jar() throws Exception { | |||||
verifyRedirection("/batch/file.jar", null, "/sonarqube/batch/file?name=file.jar"); | |||||
} | |||||
@Test | |||||
public void send_redirect_when_url_contains_batch_bootstrap() throws Exception { | |||||
verifyRedirection("/batch_bootstrap/index", null, "/sonarqube/batch/index"); | |||||
verifyRedirection("/batch_bootstrap/index/", null, "/sonarqube/batch/index"); | |||||
} | |||||
@Test | |||||
public void send_redirect_when_url_contains_profiles_export() throws Exception { | |||||
verifyRedirection("/profiles/export", "format=pmd", "/sonarqube/api/qualityprofiles/export?format=pmd"); | |||||
verifyRedirection("/profiles/export/", "format=pmd", "/sonarqube/api/qualityprofiles/export?format=pmd"); | |||||
} | |||||
@Test | @Test | ||||
public void does_not_redirect_and_execute_remaining_filter_on_unknown_path() throws Exception { | public void does_not_redirect_and_execute_remaining_filter_on_unknown_path() throws Exception { | ||||
verifyNoRedirection("/api/issues/search", null); | verifyNoRedirection("/api/issues/search", null); |