Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
build/
build/
.env
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ gradle-app.setting
# Mac files
.DS_Store

# Generated Gradle classes
core/bin/

# dev enviroment files
/.dev-env/

Expand Down
20 changes: 17 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,23 @@ COPY --chown=gradle:gradle settings.gradle .
RUN gradle build --no-daemon -x test


FROM eclipse-temurin:21-jre-alpine-3.21 AS runtime
# create user
RUN adduser -H -D sbox
FROM eclipse-temurin:21-jre-jammy AS runtime
# Install vulnerability scanners
USER root
RUN apt-get update && apt-get install -y curl wget ca-certificates
# Install Grype
ARG GRYPE_VERSION=0.104.0
RUN curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin v${GRYPE_VERSION}
# Install Trivy
ARG TRIVY_VERSION=0.67.2
RUN curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin v${TRIVY_VERSION}
# Install OSV Scanner - using install script
RUN curl -L https://github.com/google/osv-scanner/releases/latest/download/osv-scanner_linux_amd64 -o /usr/local/bin/osv-scanner && chmod +x /usr/local/bin/osv-scanner || echo "OSV Scanner installation failed, continuing without it"
# Cleanup
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# create user (Debian/Ubuntu syntax)
RUN useradd -m -s /bin/bash sbox
USER sbox
# copy jar
WORKDIR /app
Expand Down
16 changes: 16 additions & 0 deletions api/bin/main/application.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# TODO: Figure out how to use environment variables when running detached API
# Configure JDBC MySQL instance source
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/${MYSQL_DATABASE:sbox}?autoReconnect=true
spring.datasource.username=${MYSQL_USER}
spring.datasource.password=${MYSQL_PASSWORD}
# Configure Hibernate
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.hibernate.ddl-auto=update
# configure MultipartFile upload size
spring.servlet.multipart.max-file-size=2048MB
spring.servlet.multipart.max-request-size=2048MB
# configure OSI endpoint
osi.api.url=http://${OSI_HOST:localhost}:${OSI_PORT:5000}
# configure vulnerability scanning
vulnerability.scan.enabled=${VULN_SCAN_ENABLED:true}
vulnerability.scan.tools=${VULN_SCAN_TOOLS:grype,trivy}
1 change: 1 addition & 0 deletions api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ dependencies {
implementation 'org.apache.httpcomponents:httpclient:4.5.14'
implementation 'com.mikemybytes:junit5-formatted-source:1.0.1'
implementation 'com.mysql:mysql-connector-j:9.3.0'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.2'
implementation 'org.cyclonedx:cyclonedx-core-java:10.2.1'
implementation 'org.springframework:spring-web:6.2.9'
implementation 'org.springframework.boot:spring-boot-autoconfigure:3.5.4'
Expand Down
64 changes: 64 additions & 0 deletions api/src/main/java/org/svip/api/config/AsyncConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* Copyright 2021 Rochester Institute of Technology (RIT). Developed with
* government support under contract 70RCSA22C00000008 awarded by the United
* States Department of Homeland Security for Cybersecurity and Infrastructure Security Agency.
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* <p>
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* <p>
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package org.svip.api.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
* File: AsyncConfig.java
* Configuration for asynchronous task execution, specifically for parallel vulnerability scanning
*
* @author Ibrahim Matar
*/
@Configuration
@EnableAsync
public class AsyncConfig {

/**
* Executor service for parallel vulnerability scanning
* Uses virtual threads (Java 21+) if available, otherwise fixed thread pool
*
* @return Executor for vulnerability scanning tasks
*/
@Bean(name = "vulnerabilityScanExecutor")
public Executor vulnerabilityScanExecutor() {
// Use virtual threads if available (Java 21+), otherwise use fixed thread pool
try {
// Try to use virtual threads (more efficient for I/O-bound tasks like scanning)
return Executors.newVirtualThreadPerTaskExecutor();
} catch (UnsupportedOperationException e) {
// Fall back to fixed thread pool for Java 17/19
return Executors.newFixedThreadPool(4);
}
}
}



52 changes: 52 additions & 0 deletions api/src/main/java/org/svip/api/config/JacksonConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* Copyright 2021 Rochester Institute of Technology (RIT). Developed with
* government support under contract 70RCSA22C00000008 awarded by the United
* States Department of Homeland Security for Cybersecurity and Infrastructure Security Agency.
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* <p>
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* <p>
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package org.svip.api.config;

import com.fasterxml.jackson.core.StreamReadConstraints;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* Configures Jackson to handle Java 8+ time types and large SBOM payloads.
*/
@Configuration
public class JacksonConfig {

@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
return builder -> {
builder.modulesToInstall(new JavaTimeModule());
builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
builder.postConfigurer(objectMapper -> objectMapper.getFactory().setStreamReadConstraints(
StreamReadConstraints.builder()
.maxStringLength(500_000_000) // 500MB limit for JSON strings
.build()
));
};
}
}
Loading