ext {
protobufVersion = '3.21.12'
+ springVersion = '5.3.23'
}
sonar {
dependency('org.mockito:mockito-core:5.0.0') {
exclude 'org.hamcrest:hamcrest-core'
}
+ dependency "org.springframework:spring-test:${springVersion}"
dependency 'org.mybatis:mybatis:3.5.11'
dependencySet(group: 'org.slf4j', version: '2.0.6') {
entry 'jcl-over-slf4j'
dependency 'org.simpleframework:simple:5.1.6'
dependency 'org.sonarsource.orchestrator:sonar-orchestrator:3.40.0.183'
dependency 'org.sonarsource.update-center:sonar-update-center-common:1.29.0.1000'
- dependency('org.springframework:spring-context:5.3.23') {
+ dependency("org.springframework:spring-context:${springVersion}") {
exclude 'commons-logging:commons-logging'
}
+ dependency ("org.springframework:spring-webmvc:${springVersion}") {
+ exclude 'commons-logging:commons-logging'
+ }
+ dependency 'org.springdoc:springdoc-openapi-ui:1.6.14'
dependency 'org.subethamail:subethasmtp:3.1.7'
dependency 'org.yaml:snakeyaml:1.33'
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
-
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context.xsd
- http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
-
- <context:annotation-config/>
- <context:component-scan base-package="org.sonar.server.v2"/>
- <mvc:annotation-driven />
-</beans>
dependencies {
// please keep the list grouped by configuration and ordered by name
- api 'org.springframework:spring-webmvc:5.3.23'
+ api 'org.springdoc:springdoc-openapi-ui'
+ api 'org.springframework:spring-webmvc'
api project(':server:sonar-db-dao')
// We are not suppose to have a v1 dependency. The ideal would be to have another common module between webapi and webapi-v2 but that needs a lot of refactoring.
api project(':server:sonar-webserver-webapi')
+
testImplementation 'org.mockito:mockito-core'
- testImplementation 'org.springframework:spring-test:5.3.23'
+ testImplementation 'org.springframework:spring-test'
testImplementation testFixtures(project(':server:sonar-server-common'))
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.v2;
-
-import java.util.List;
-import java.util.stream.Collectors;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.Loggers;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationListener;
-import org.springframework.context.event.ContextRefreshedEvent;
-import org.springframework.stereotype.Component;
-import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping;
-import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
-
-@Component
-public class LogComponent implements ApplicationListener<ContextRefreshedEvent> {
-
- private static final Logger LOGGER = Loggers.get(LogComponent.class);
- @Override
- public void onApplicationEvent(ContextRefreshedEvent event) {
- ApplicationContext applicationContext = event.getApplicationContext();
- List<Integer> isUseless = applicationContext.getBeansOfType(RequestMappingHandlerMapping.class).values().stream()
- .map(AbstractHandlerMethodMapping::getHandlerMethods)
- .map(d->{
- d.forEach((e, c)-> LOGGER.info("Registered endpoint: "+e.getName()+" "+e.getDirectPaths()+" "+e));
- return 1;
- })
- .collect(Collectors.toList());
- }
-}
package org.sonar.server.v2.common;
import java.util.Optional;
+import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.ServerException;
+import org.sonar.server.exceptions.UnauthorizedException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class RestResponseEntityExceptionHandler {
+ @ExceptionHandler(IllegalStateException.class)
+ @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
+ protected ResponseEntity<Object> handleIllegalStateException(IllegalStateException illegalStateException) {
+ return new ResponseEntity<>(illegalStateException.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+
+ @ExceptionHandler(ForbiddenException.class)
+ @ResponseStatus(HttpStatus.FORBIDDEN)
+ protected ResponseEntity<Object> handleForbiddenException(ForbiddenException forbiddenException) {
+ return handleServerException(forbiddenException);
+ }
+
+ @ExceptionHandler(UnauthorizedException.class)
+ @ResponseStatus(HttpStatus.UNAUTHORIZED)
+ protected ResponseEntity<Object> handleUnauthorizedException(UnauthorizedException unauthorizedException) {
+ return handleServerException(unauthorizedException);
+ }
+
+
@ExceptionHandler(ServerException.class)
protected ResponseEntity<Object> handleServerException(ServerException serverException) {
return new ResponseEntity<>(serverException.getMessage(), Optional.ofNullable(HttpStatus.resolve(serverException.httpCode())).orElse(HttpStatus.INTERNAL_SERVER_ERROR));
}
-
}
*/
package org.sonar.server.v2.config;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.info.Info;
import org.sonar.server.v2.common.RestResponseEntityExceptionHandler;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
@EnableWebMvc
+@ComponentScan(basePackages = {"org.springdoc"})
+@PropertySource("classpath:springdoc.properties")
public class CommonWebConfig {
@Bean
return new RestResponseEntityExceptionHandler();
}
+ @Bean
+ public OpenAPI customOpenAPI() {
+ return new OpenAPI()
+ .info(
+ new Info()
+ .title("SonarQube Web API")
+ .version("0.0.1 alpha")
+ .description("Documentation of SonarQube Web API")
+ );
+ }
+
}
--- /dev/null
+springdoc.api-docs.path=/api-docs
api 'io.prometheus:simpleclient_common'
api 'io.prometheus:simpleclient_servlet'
- api 'org.springframework:spring-webmvc:5.3.23'
- api 'org.springframework:spring-web:5.3.23'
- api 'org.springframework:spring-context:5.3.23'
- api 'org.springframework:spring-core:5.3.23'
- testImplementation 'org.springframework:spring-test:5.3.23'
-
api project(':server:sonar-ce-common')
api project(':server:sonar-ce-task')
api project(':server:sonar-db-dao')
import org.sonar.api.utils.log.Profiler;
import org.sonar.core.platform.ExtensionContainer;
import org.sonar.core.platform.SpringComponentContainer;
-import org.sonar.server.platform.web.ApiV2Servlet;
import org.sonar.server.app.ProcessCommandWrapper;
import org.sonar.server.platform.db.migration.version.DatabaseVersion;
import org.sonar.server.platform.platformlevel.PlatformLevel;
import org.sonar.server.platform.platformlevel.PlatformLevel4;
import org.sonar.server.platform.platformlevel.PlatformLevelSafeMode;
import org.sonar.server.platform.platformlevel.PlatformLevelStartup;
-import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
+import org.sonar.server.platform.web.ApiV2Servlet;
import static org.sonar.process.ProcessId.WEB_SERVER;
private PlatformLevel level3 = null;
private PlatformLevel level4 = null;
private PlatformLevel currentLevel = null;
- private AnnotationConfigWebApplicationContext springMvcContext = null;
private boolean dbConnected = false;
private boolean started = false;
private final List<Object> level4AddedComponents = new ArrayList<>();
private final Profiler profiler = Profiler.createIfTrace(Loggers.get(PlatformImpl.class));
- private ApiV2Servlet servlet;
+ private ApiV2Servlet servlet = null;
public static PlatformImpl getInstance() {
return INSTANCE;
shadowJar {
archiveBaseName = 'sonar-application'
archiveClassifier = null
- mergeServiceFiles('META-INF/spring.*')
+ mergeServiceFiles()
manifest {
attributes('Main-Class': 'org.sonar.application.App')
}
// Check the size of the archive
zip.doLast {
def minLength = 320000000
- def maxLength = 345000000
+ def maxLength = 355000000
def length = archiveFile.get().asFile.length()
if (length < minLength)