Compare commits

..
28 Commits
Author SHA1 Message Date
kasun b08fbf3b03 Merge pull request 'added sonarqube config' (#41) from enhancement/Configure-Sonarqube-server into main
SonarQube Analysis / Build and Analyze (push) Successful in 2m1s
2026-06-27 03:23:57 +02:00
kasun 51382d0bd1 fixed sonarqube issue for grouping dependencies
SonarQube Analysis / Build and Analyze (pull_request) Successful in 2m5s
2026-06-27 03:19:27 +02:00
kasun a55270f6d5 fixed sonarqube issue with hardcoded dependency version
SonarQube Analysis / Build and Analyze (pull_request) Successful in 2m2s
2026-06-27 03:14:06 +02:00
kasun 7f6fd4259b fixed sonarqube issue with hardcoded dependency version
SonarQube Analysis / Build and Analyze (pull_request) Failing after 51s
2026-06-27 03:12:01 +02:00
kasun 46a86f15d8 fixed sonarqube issue with hardcoded dependency version
SonarQube Analysis / Build and Analyze (pull_request) Failing after 50s
2026-06-27 03:09:26 +02:00
kasun 78b6e04db6 bump test db to postgres 18.4
SonarQube Analysis / Build and Analyze (pull_request) Successful in 2m5s
2026-06-27 03:05:17 +02:00
kasun 3fed8a4ea2 revised build.yaml dropped caching
SonarQube Analysis / Build and Analyze (pull_request) Successful in 2m42s
2026-06-27 02:53:39 +02:00
kasun 5b0c2d6d02 bumb test db to postgres 18
SonarQube Analysis / Build and Analyze (pull_request) Has been cancelled
2026-06-27 01:21:51 +02:00
kasun ee2685aa07 resolve null type safety warnings from method references in stream collectors
SonarQube Analysis / Build and Analyze (pull_request) Successful in 3m50s
2026-06-27 01:15:55 +02:00
kasun 12fc7909fd added missing javadoc
SonarQube Analysis / Build and Analyze (pull_request) Successful in 3m45s
2026-06-27 01:08:49 +02:00
kasun 9bbf2fd098 format
SonarQube Analysis / Build and Analyze (pull_request) Successful in 3m44s
2026-06-27 01:07:50 +02:00
kasun 9c2cbd1608 replaced streams with for loop for serviceprovider lookup to resolves null type safety warning from Collectors.toMap
SonarQube Analysis / Build and Analyze (pull_request) Successful in 3m51s
2026-06-27 01:07:36 +02:00
kasunandClaude Sonnet 4.6 fffdd2a575 add JaCoCo coverage reporting for SonarQube
SonarQube Analysis / Build and Analyze (pull_request) Successful in 3m46s
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-06-25 22:18:07 +02:00
kasunandClaude Sonnet 4.6 8c18d7ff73 fix CI database name to satisfy vaessl_test assertion
SonarQube Analysis / Build and Analyze (pull_request) Successful in 3m40s
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-06-25 22:09:19 +02:00
kasun 4318fc13f6 added self contained postgresql db
SonarQube Analysis / Build and Analyze (pull_request) Failing after 2m52s
2026-06-25 22:01:47 +02:00
kasun a2e110d3dd fixed typo
SonarQube Analysis / Build and Analyze (pull_request) Failing after 2m24s
2026-06-25 21:50:11 +02:00
kasun adb51584e7 added missing env
SonarQube Analysis / Build and Analyze (pull_request) Failing after 2m20s
2026-06-25 21:44:18 +02:00
kasun 048120688f changed image
SonarQube Analysis / Build and Analyze (pull_request) Failing after 2m22s
2026-06-25 21:36:10 +02:00
kasun b356682175 fixed typo
SonarQube Analysis / Build and Analyze (pull_request) Failing after 13s
2026-06-25 21:33:29 +02:00
kasun bdbfece62c added env variables
SonarQube Analysis / Build and Analyze (pull_request) Failing after 2s
2026-06-25 21:32:28 +02:00
kasun 597c941994 added test failure logging
SonarQube Analysis / Build and Analyze (pull_request) Failing after 2m20s
2026-06-25 21:10:06 +02:00
kasun 8183bf61ea added network connection to self hosted postgreql db
SonarQube Analysis / Build and Analyze (pull_request) Failing after 3m15s
2026-06-25 21:03:55 +02:00
kasun 5838084b73 adjusted java version
SonarQube Analysis / Build and Analyze (pull_request) Failing after 3m41s
2026-06-25 20:46:34 +02:00
kasun 77ee6f68c6 fixed typo in build.gradle
SonarQube Analysis / Build and Analyze (pull_request) Failing after 1m42s
2026-06-25 20:43:19 +02:00
kasun 5c58fe43d9 adjusted gradlew path
SonarQube Analysis / Build and Analyze (pull_request) Failing after 1m18s
2026-06-25 20:37:13 +02:00
kasun 7652645f42 adjusted gradlew path
SonarQube Analysis / Build and Analyze (pull_request) Failing after 1m5s
2026-06-25 20:30:33 +02:00
kasun 2ea346651f adjusted gradlew path
SonarQube Analysis / Build and Analyze (pull_request) Has been cancelled
2026-06-25 20:30:08 +02:00
kasun 6b5a3b5687 added sonarqube config
SonarQube Analysis / Build and Analyze (pull_request) Failing after 2m33s
2026-06-25 20:23:22 +02:00
6 changed files with 119 additions and 14 deletions
+61
View File
@@ -0,0 +1,61 @@
name: SonarQube Analysis
on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:
jobs:
analyze:
name: Build and Analyze
runs-on: ubuntu-latest
services:
postgres:
image: postgres:18.4
env:
POSTGRES_USER: vaessl
POSTGRES_PASSWORD: vaessl
POSTGRES_DB: vaessl_test
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Checkout Code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 25
uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4.8.0
with:
java-version: "25"
distribution: "zulu" # Alternative distribution options are available.
- name: Make Gradle Executable
run: chmod +x ./gradlew
working-directory: backend
- name: Build and Analyze
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
DB_URL: jdbc:postgresql://postgres:5432/vaessl_test
DB_TEST_URL: jdbc:postgresql://postgres:5432/vaessl_test
DB_USERNAME: vaessl
DB_PASSWORD: vaessl
PG_DRIVER_CLASS_NAME: org.postgresql.Driver
OPENAI_BASE_URL: https://api.openai.com/v1
OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
ALLOWED_ORIGINS: http://localhost:3000
run: ./gradlew build sonar --info
working-directory: backend
+39 -3
View File
@@ -1,7 +1,11 @@
val wiremockVersion = "3.12.0"
plugins {
java
jacoco
id("org.springframework.boot") version "4.1.0"
id("io.spring.dependency-management") version "1.1.7"
id("org.sonarqube") version "7.3.0.8198"
}
group = "com.vaessl"
@@ -13,6 +17,15 @@ java {
}
}
sonar {
properties {
property("sonar.projectKey", "Vaessl")
property("sonar.projectName", "Vaessl")
property("sonar.coverage.jacoco.xmlReportPaths",
"${layout.buildDirectory.get()}/reports/jacoco/test/jacocoTestReport.xml")
}
}
configurations {
compileOnly {
extendsFrom(configurations.annotationProcessor.get())
@@ -25,6 +38,7 @@ repositories {
extra["springAiVersion"] = "2.0.0"
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-session-jdbc")
@@ -32,17 +46,24 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-webmvc")
implementation("org.springframework.ai:spring-ai-starter-model-openai")
compileOnly("org.projectlombok:lombok")
developmentOnly("org.springframework.boot:spring-boot-devtools")
runtimeOnly("org.postgresql:postgresql")
annotationProcessor("org.projectlombok:lombok")
testImplementation("org.springframework.boot:spring-boot-starter-data-jpa-test")
// testImplementation("org.springframework.boot:spring-boot-starter-security-test")
testImplementation("org.springframework.boot:spring-boot-starter-validation-test")
testImplementation("org.springframework.boot:spring-boot-starter-webmvc-test")
testImplementation("org.wiremock:wiremock-standalone:$wiremockVersion")
testImplementation("org.springframework.boot:spring-boot-starter-session-jdbc-test")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
testImplementation("org.wiremock:wiremock-standalone:3.12.0")
testImplementation("org.springframework.boot:spring-boot-starter-session-jdbc-test")}
}
dependencyManagement {
imports {
@@ -55,5 +76,20 @@ tasks.withType<JavaCompile> {
}
tasks.withType<Test> {
useJUnitPlatform()
useJUnitPlatform()
finalizedBy(tasks.jacocoTestReport)
testLogging {
events("failed", "standardError")
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
showExceptions = true
showCauses = true
showStackTraces = true
}
}
tasks.jacocoTestReport {
dependsOn(tasks.withType<Test>())
reports {
xml.required = true
}
}
@@ -1,9 +1,9 @@
package com.vaessl.app.connection;
import java.time.Instant;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
@@ -18,8 +18,11 @@ public class ConnectionService {
private final ConnectionRepository cRepository;
public ConnectionService(List<ConnectionProvider> providers, ConnectionRepository cRepository) {
this.providerRegistry = providers.stream()
.collect(Collectors.toMap(ConnectionProvider::getServiceType, p -> p));
Map<ServiceType, ConnectionProvider> registry = new EnumMap<>(ServiceType.class);
for (ConnectionProvider provider : providers) {
registry.put(provider.getServiceType(), provider);
}
this.providerRegistry = registry;
this.cRepository = cRepository;
}
@@ -49,7 +52,8 @@ public class ConnectionService {
return new LoginResult(saved.getId(), response.expiresAt());
}
public ConnectionStatusResponse getConnectionStatus(ServiceType serviceType, Long connectionId) {
public ConnectionStatusResponse getConnectionStatus(ServiceType serviceType,
Long connectionId) {
ConnectionEntity entity = cRepository.findById(connectionId).orElse(null);
if (entity == null)
return null;
@@ -58,7 +62,7 @@ public class ConnectionService {
Instant expiresAt = (provider != null) ? provider.getTokenExpiry(entity) : null;
boolean connected = expiresAt == null || expiresAt.isAfter(Instant.now());
return new ConnectionStatusResponse(serviceType.name(), entity.getAppUrl(), entity.getUsername(),
expiresAt, connected);
return new ConnectionStatusResponse(serviceType.name(), entity.getAppUrl(),
entity.getUsername(), expiresAt, connected);
}
}
@@ -3,7 +3,6 @@ package com.vaessl.app.exception;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ProblemDetail;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@@ -24,7 +23,7 @@ public class GlobalExceptionHandler {
public ProblemDetail handleEmptyCredentialInput(MethodArgumentNotValidException e) {
String defaultMessages = e.getBindingResult().getFieldErrors().stream()
.map(FieldError::getDefaultMessage).collect(Collectors.joining(", "));
.map(field -> field.getDefaultMessage()).collect(Collectors.joining(", "));
return ProblemDetail.forStatusAndDetail(BAD_REQUEST_EMPTY_FIELDS.getStatus(),
BAD_REQUEST_EMPTY_FIELDS.getMessage() + " [" + defaultMessages + "]");
@@ -14,6 +14,7 @@ public interface SearchProvider extends ServiceProvider {
* Executes a search query against the remote service and returns matching results.
*
* @param request the search request containing the query string, app URL, and user credentials
* @param pageable the Pageable interface
* @return a list of Page<SearchResponse> items matching the query
*/
Page<SearchResponse> getSearchResults(SearchRequest request, Pageable pageable);
@@ -1,8 +1,8 @@
package com.vaessl.app.search;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@@ -16,8 +16,12 @@ public class SearchService {
private final Map<ServiceType, SearchProvider> providerRegistry;
public SearchService(List<SearchProvider> providers) {
this.providerRegistry = Map.copyOf(providers.stream()
.collect(Collectors.toMap(SearchProvider::getServiceType, p -> p)));
Map<ServiceType, SearchProvider> registry = new EnumMap<>(ServiceType.class);
for (SearchProvider provider : providers) {
registry.put(provider.getServiceType(), provider);
}
this.providerRegistry = registry;
}
/**