Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
7c61c8c
refactor: update JettyServer to use SteveConfiguration for configurat…
juherr Jul 27, 2025
1bae8fe
refactor: pass SteveConfiguration to SteveAppContext for improved con…
juherr Jul 27, 2025
b24a5c2
refactor: inject SteveConfiguration into apiDocs and add SteveConfigu…
juherr Jul 27, 2025
59a0cd6
refactor: pass SteveConfiguration to GithubReleaseCheckService for en…
juherr Jul 27, 2025
b31cf83
refactor: inject SteveConfiguration into WebUserService for improved …
juherr Jul 27, 2025
f668a96
refactor: update BeanConfiguration to use injected SteveConfiguration…
juherr Jul 27, 2025
40f34dd
refactor: modify Application to accept SteveConfiguration for JettySe…
juherr Jul 27, 2025
a6dfc5b
refactor: inject SteveConfiguration into OcppConfiguration and Securi…
juherr Jul 27, 2025
af349d7
refactor: inject SteveConfiguration into OcppConfiguration, ClientPro…
juherr Jul 27, 2025
27ccc3e
refactor: inject SteveConfiguration into WebSocket endpoints and Sess…
juherr Jul 27, 2025
3676afd
refactor: inject SteveConfiguration into RegistrationStatusService an…
juherr Jul 27, 2025
2fca7ae
refactor: inject SteveConfiguration into AboutSettingsController for …
juherr Jul 27, 2025
800c1e2
refactor: enhance validation configuration and inject properties for …
juherr Jul 27, 2025
8e1e632
refactor: update InternetChecker to accept user agent and enhance rel…
juherr Jul 27, 2025
f08cf59
fix: rework to fix tests
juherr Aug 22, 2025
e8056a2
fix: update after CodeRabbit and Copilot review
juherr Aug 22, 2025
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
8 changes: 6 additions & 2 deletions src/main/java/de/rwth/idsg/steve/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@
@Slf4j
public class Application {

private final JettyServer server = new JettyServer();
private final JettyServer server;

public Application(SteveConfiguration config) {
server = new JettyServer(config);
}

public static void main(String[] args) throws Exception {
// For Hibernate validator
Expand All @@ -53,7 +57,7 @@ public static void main(String[] args) throws Exception {
System.out.println("Log file: " + path.get().toAbsolutePath());
}

Application app = new Application();
Application app = new Application(sc);

try {
app.start();
Expand Down
50 changes: 27 additions & 23 deletions src/main/java/de/rwth/idsg/steve/JettyServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,15 @@
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static de.rwth.idsg.steve.SteveConfiguration.CONFIG;

/**
* @author Sevket Goekay <sevketgokay@gmail.com>
* @since 12.12.2014
*/
@Slf4j
public class JettyServer {

private final SteveConfiguration config;

private Server server;
private SteveAppContext steveAppContext;

Expand All @@ -69,6 +69,10 @@ public class JettyServer {
private static final long STOP_TIMEOUT = TimeUnit.SECONDS.toMillis(5);
private static final long IDLE_TIMEOUT = TimeUnit.MINUTES.toMillis(1);

public JettyServer(SteveConfiguration config) {
this.config = config;
}

/**
* A fully configured Jetty Server instance
*/
Expand All @@ -89,7 +93,7 @@ private void prepare() {
// HTTP Configuration
HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.setSecureScheme(HttpScheme.HTTPS.asString());
httpConfig.setSecurePort(CONFIG.getJetty().getHttpsPort());
httpConfig.setSecurePort(config.getJetty().getHttpsPort());
httpConfig.setOutputBufferSize(32768);
httpConfig.setRequestHeaderSize(8192);
httpConfig.setResponseHeaderSize(8192);
Expand All @@ -107,45 +111,45 @@ private void prepare() {
server.setStopAtShutdown(true);
server.setStopTimeout(STOP_TIMEOUT);

if (CONFIG.getJetty().isHttpEnabled()) {
if (config.getJetty().isHttpEnabled()) {
server.addConnector(httpConnector(httpConfig));
}

if (CONFIG.getJetty().isHttpsEnabled()) {
if (config.getJetty().isHttpsEnabled()) {
server.addConnector(httpsConnector(httpConfig));
}

steveAppContext = new SteveAppContext();
steveAppContext = new SteveAppContext(config);
server.setHandler(steveAppContext.getHandlers());
}

private ServerConnector httpConnector(HttpConfiguration httpConfig) {
private ServerConnector httpConnector(HttpConfiguration httpconfig) {
// === jetty-http.xml ===
ServerConnector http = new ServerConnector(server, new HttpConnectionFactory(httpConfig));
http.setHost(CONFIG.getJetty().getServerHost());
http.setPort(CONFIG.getJetty().getHttpPort());
ServerConnector http = new ServerConnector(server, new HttpConnectionFactory(httpconfig));
http.setHost(config.getJetty().getServerHost());
http.setPort(config.getJetty().getHttpPort());
http.setIdleTimeout(IDLE_TIMEOUT);
return http;
}

private ServerConnector httpsConnector(HttpConfiguration httpConfig) {
private ServerConnector httpsConnector(HttpConfiguration httpconfig) {
// === jetty-https.xml ===
// SSL Context Factory
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
sslContextFactory.setKeyStorePath(CONFIG.getJetty().getKeyStorePath());
sslContextFactory.setKeyStorePassword(CONFIG.getJetty().getKeyStorePassword());
sslContextFactory.setKeyManagerPassword(CONFIG.getJetty().getKeyStorePassword());
sslContextFactory.setKeyStorePath(config.getJetty().getKeyStorePath());
sslContextFactory.setKeyStorePassword(config.getJetty().getKeyStorePassword());
sslContextFactory.setKeyManagerPassword(config.getJetty().getKeyStorePassword());

// SSL HTTP Configuration
HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
HttpConfiguration httpsConfig = new HttpConfiguration(httpconfig);
httpsConfig.addCustomizer(new SecureRequestCustomizer());

// SSL Connector
ServerConnector https = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
new HttpConnectionFactory(httpsConfig));
https.setHost(CONFIG.getJetty().getServerHost());
https.setPort(CONFIG.getJetty().getHttpsPort());
https.setHost(config.getJetty().getServerHost());
https.setPort(config.getJetty().getHttpsPort());
https.setIdleTimeout(IDLE_TIMEOUT);
return https;
}
Expand Down Expand Up @@ -198,12 +202,12 @@ private List<String> getConnectorPathList() {
}

return Arrays.stream(server.getConnectors())
.map(JettyServer::getConnectorPath)
.map(this::getConnectorPath)
.flatMap(Collection::stream)
.collect(Collectors.toList());
}

private static List<String> getConnectorPath(Connector c) {
private List<String> getConnectorPath(Connector c) {
ServerConnector sc = (ServerConnector) c;

final String prefix;
Expand All @@ -216,12 +220,12 @@ private static List<String> getConnectorPath(Connector c) {
Set<String> ips = new HashSet<>();
String host = sc.getHost();
if (host == null || host.equals("0.0.0.0")) {
ips.addAll(getPossibleIpAddresses());
ips.addAll(getPossibleIpAddresses(config.getJetty().getServerHost()));
} else {
ips.add(host);
}

String layout = "%s://%s:%d" + CONFIG.getContextPath();
String layout = "%s://%s:%d" + config.getContextPath();

return ips.stream()
.map(k -> String.format(layout, prefix, k, sc.getPort()))
Expand All @@ -245,7 +249,7 @@ private String getElementPrefix(String str, boolean replaceHttp) {
/**
* Uses different APIs to find out the IP of this machine.
*/
private static List<String> getPossibleIpAddresses() {
private static List<String> getPossibleIpAddresses(String serverHost) {
final String host = "treibhaus.informatik.rwth-aachen.de";
final List<String> ips = new ArrayList<>();

Expand Down Expand Up @@ -292,7 +296,7 @@ private static List<String> getPossibleIpAddresses() {
if (ips.isEmpty()) {
// Well, we failed to read from system, fall back to main.properties.
// Better than nothing
ips.add(CONFIG.getJetty().getServerHost());
ips.add(serverHost);
}

return ips;
Expand Down
19 changes: 10 additions & 9 deletions src/main/java/de/rwth/idsg/steve/SteveAppContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
import java.util.EnumSet;
import java.util.HashSet;

import static de.rwth.idsg.steve.SteveConfiguration.CONFIG;
import static de.rwth.idsg.steve.config.WebSocketConfiguration.IDLE_TIMEOUT;
import static de.rwth.idsg.steve.config.WebSocketConfiguration.MAX_MSG_SIZE;

Expand All @@ -57,10 +56,12 @@
*/
public class SteveAppContext {

private final SteveConfiguration config;
private final AnnotationConfigWebApplicationContext springContext;
private final WebAppContext webAppContext;

public SteveAppContext() {
public SteveAppContext(SteveConfiguration config) {
this.config = config;
springContext = new AnnotationConfigWebApplicationContext();
springContext.scan("de.rwth.idsg.steve.config");
webAppContext = initWebApp();
Expand All @@ -83,7 +84,7 @@ public void configureWebSocket() {
}

private Handler getWebApp() {
if (!CONFIG.getJetty().isGzipEnabled()) {
if (!config.getJetty().isGzipEnabled()) {
return webAppContext;
}

Expand All @@ -94,7 +95,7 @@ private Handler getWebApp() {

private WebAppContext initWebApp() {
WebAppContext ctx = new WebAppContext();
ctx.setContextPath(CONFIG.getContextPath());
ctx.setContextPath(config.getContextPath());
ctx.setBaseResourceAsString(getWebAppURIAsString());

// if during startup an exception happens, do not swallow it, throw it
Expand All @@ -107,14 +108,14 @@ private WebAppContext initWebApp() {
ServletHolder cxf = new ServletHolder("cxf", new CXFServlet());

ctx.addEventListener(new ContextLoaderListener(springContext));
ctx.addServlet(web, CONFIG.getSpringMapping());
ctx.addServlet(cxf, CONFIG.getCxfMapping() + "/*");
ctx.addServlet(web, config.getSpringMapping());
ctx.addServlet(cxf, config.getCxfMapping() + "/*");

// add spring security
ctx.addFilter(
// The bean name is not arbitrary, but is as expected by Spring
new FilterHolder(new DelegatingFilterProxy(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)),
CONFIG.getSpringMapping() + "*",
config.getSpringMapping() + "*",
EnumSet.allOf(DispatcherType.class)
);

Expand All @@ -128,14 +129,14 @@ private Handler getRedirectHandler() {
RedirectPatternRule rule = new RedirectPatternRule();
rule.setTerminating(true);
rule.setPattern(redirect);
rule.setLocation(CONFIG.getContextPath() + "/manager/home");
rule.setLocation(config.getContextPath() + "/manager/home");
rewrite.addRule(rule);
}
return rewrite;
}

private HashSet<String> getRedirectSet() {
String path = CONFIG.getContextPath();
String path = config.getContextPath();

HashSet<String> redirectSet = new HashSet<>(3);
redirectSet.add("");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public class ApiDocsConfiguration {
}

@Bean
public OpenAPI apiDocs() {
public OpenAPI apiDocs(SteveConfiguration config) {
String title = "SteVe REST API Documentation";

String securityName = "basicAuth";
Expand All @@ -88,7 +88,7 @@ public OpenAPI apiDocs() {
.name("GPL-3.0")
.url("https://github.com/steve-community/steve/blob/master/LICENSE.txt")
)
.version(SteveConfiguration.CONFIG.getSteveVersion())
.version(config.getSteveVersion())
)
// https://stackoverflow.com/a/68185254
.servers(List.of(new Server().url("/").description("Default Server URL")))
Expand Down
44 changes: 34 additions & 10 deletions src/main/java/de/rwth/idsg/steve/config/BeanConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.Ordered;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.http.converter.HttpMessageConverter;
Expand All @@ -60,8 +61,7 @@

import javax.sql.DataSource;
import java.util.List;

import static de.rwth.idsg.steve.SteveConfiguration.CONFIG;
import java.util.Properties;

/**
* Configuration and beans of Spring Framework.
Expand All @@ -81,22 +81,26 @@ public class BeanConfiguration implements WebMvcConfigurer {
*/
@Bean
public DataSource dataSource() {
SteveConfiguration.DB dbConfig = CONFIG.getDb();
SteveConfiguration config = steveConfiguration();
SteveConfiguration.DB dbConfig = config.getDb();
return dataSource(dbConfig.getJdbcUrl(), dbConfig.getUserName(), dbConfig.getPassword(), config.getTimeZoneId());
}

public static DataSource dataSource(String dbUrl, String dbUserName, String dbPassword, String dbTimeZoneId) {
HikariConfig hc = new HikariConfig();

// set standard params
hc.setJdbcUrl(dbConfig.getJdbcUrl());
hc.setUsername(dbConfig.getUserName());
hc.setPassword(dbConfig.getPassword());
hc.setJdbcUrl(dbUrl);
hc.setUsername(dbUserName);
hc.setPassword(dbPassword);

// set non-standard params
hc.addDataSourceProperty(PropertyKey.cachePrepStmts.getKeyName(), true);
hc.addDataSourceProperty(PropertyKey.useServerPrepStmts.getKeyName(), true);
hc.addDataSourceProperty(PropertyKey.prepStmtCacheSize.getKeyName(), 250);
hc.addDataSourceProperty(PropertyKey.prepStmtCacheSqlLimit.getKeyName(), 2048);
hc.addDataSourceProperty(PropertyKey.characterEncoding.getKeyName(), "utf8");
hc.addDataSourceProperty(PropertyKey.connectionTimeZone.getKeyName(), CONFIG.getTimeZoneId());
hc.addDataSourceProperty(PropertyKey.connectionTimeZone.getKeyName(), dbTimeZoneId);
hc.addDataSourceProperty(PropertyKey.useSSL.getKeyName(), true);

// https://github.com/steve-community/steve/issues/736
Expand Down Expand Up @@ -126,7 +130,7 @@ public DSLContext dslContext(DataSource dataSource) {
// operations. We do not use or need that.
.withAttachRecords(false)
// To log or not to log the sql queries, that is the question
.withExecuteLogging(CONFIG.getDb().isSqlLogging());
.withExecuteLogging(steveConfiguration().getDb().isSqlLogging());

// Configuration for JOOQ
org.jooq.Configuration conf = new DefaultConfiguration()
Expand Down Expand Up @@ -174,8 +178,9 @@ public Validator validator() {
*/
@Bean
public ReleaseCheckService releaseCheckService() {
if (InternetChecker.isInternetAvailable()) {
return new GithubReleaseCheckService();
var config = steveConfiguration();
if (InternetChecker.isInternetAvailable(config.getSteveCompositeVersion())) {
return new GithubReleaseCheckService(config);
} else {
return new DummyReleaseCheckService();
}
Expand Down Expand Up @@ -245,4 +250,23 @@ public ObjectMapper jacksonObjectMapper(RequestMappingHandlerAdapter requestMapp
.map(conv -> ((MappingJackson2HttpMessageConverter) conv).getObjectMapper())
.orElseThrow(() -> new RuntimeException("There is no MappingJackson2HttpMessageConverter in Spring context"));
}

@Bean
public SteveConfiguration steveConfiguration() {
return SteveConfiguration.CONFIG;
}

@Bean
public PropertySourcesPlaceholderConfigurer valueConfigurer() {
var configurer = new PropertySourcesPlaceholderConfigurer();

var props = new Properties();
var chargeBoxIdValidationRegex = steveConfiguration().getOcpp().getChargeBoxIdValidationRegex();
if (chargeBoxIdValidationRegex != null) {
props.put("charge-box-id.validation.regex", chargeBoxIdValidationRegex);
}
configurer.setProperties(props);

return configurer;
}
}
Loading
Loading