Performance tuning done
This commit is contained in:
9
.vscode/launch.json
vendored
9
.vscode/launch.json
vendored
@@ -3,20 +3,19 @@
|
|||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"type": "java",
|
"type": "java",
|
||||||
"name": "Matrix - Tomcat 10 (JDK 21)",
|
"name": "Cygnus On-Prem - Tomcat 10 (JDK 21)",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"mainClass": "matrix.nimble.EmbeddedTomcatServer",
|
"mainClass": "matrix.nimble.EmbeddedTomcatServer",
|
||||||
"projectName": "matrix",
|
"cwd": "${workspaceFolder}/cygnus-onprem-app",
|
||||||
"cwd": "${workspaceFolder}",
|
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
"preLaunchTask": "matrix: dev compile",
|
"preLaunchTask": "cygnus: dev compile",
|
||||||
"classPaths": [
|
"classPaths": [
|
||||||
"$Test"
|
"$Test"
|
||||||
],
|
],
|
||||||
"env": {
|
"env": {
|
||||||
"JAVA_HOME": "/Users/maddy/Library/Java/JavaVirtualMachines/ms-21.0.8/Contents/Home"
|
"JAVA_HOME": "/Users/maddy/Library/Java/JavaVirtualMachines/ms-21.0.8/Contents/Home"
|
||||||
},
|
},
|
||||||
"vmArgs": "-Dserver.port=8080 -Djava.awt.headless=true -Dmatrix.webapp=${workspaceFolder}/build/WebContent -Dmatrix.classes=${workspaceFolder}/target/classes",
|
"vmArgs": "-Dserver.port=8080 -Djava.awt.headless=true -Dmatrix.webapp=${workspaceFolder}/cygnus-onprem-app/build/WebContent -Dmatrix.classes=${workspaceFolder}/cygnus-onprem-app/target/classes",
|
||||||
"shortenCommandLine": "argfile"
|
"shortenCommandLine": "argfile"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
2
.vscode/tasks.json
vendored
2
.vscode/tasks.json
vendored
@@ -2,7 +2,7 @@
|
|||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"tasks": [
|
"tasks": [
|
||||||
{
|
{
|
||||||
"label": "matrix: dev compile",
|
"label": "cygnus: dev compile",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "mvn",
|
"command": "mvn",
|
||||||
"args": [
|
"args": [
|
||||||
|
|||||||
84
cygnus-cloud-service/pom.xml
Normal file
84
cygnus-cloud-service/pom.xml
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.cygnus</groupId>
|
||||||
|
<artifactId>cygnus-parent</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>cygnus-cloud-service</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Cygnus Cloud Service</name>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-dependencies</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.vertx</groupId>
|
||||||
|
<artifactId>vertx-pg-client</artifactId>
|
||||||
|
<version>${vertx.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-webflux-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.cygnus.cloud;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@ConfigurationPropertiesScan
|
||||||
|
public class CygnusCloudServiceApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(CygnusCloudServiceApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
9
cygnus-cloud-service/src/main/java/com/cygnus/cloud/cache/CacheProperties.java
vendored
Normal file
9
cygnus-cloud-service/src/main/java/com/cygnus/cloud/cache/CacheProperties.java
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package com.cygnus.cloud.cache;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
@ConfigurationProperties("cygnus.cache")
|
||||||
|
public record CacheProperties(String keyPrefix, Duration defaultTtl) {
|
||||||
|
}
|
||||||
44
cygnus-cloud-service/src/main/java/com/cygnus/cloud/cache/ReactiveCacheService.java
vendored
Normal file
44
cygnus-cloud-service/src/main/java/com/cygnus/cloud/cache/ReactiveCacheService.java
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package com.cygnus.cloud.cache;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
import org.springframework.data.redis.core.ReactiveStringRedisTemplate;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ReactiveCacheService {
|
||||||
|
|
||||||
|
private final ReactiveStringRedisTemplate redis;
|
||||||
|
private final CacheProperties properties;
|
||||||
|
|
||||||
|
public ReactiveCacheService(ReactiveStringRedisTemplate redis, CacheProperties properties) {
|
||||||
|
this.redis = redis;
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mono<String> get(String namespace, String key) {
|
||||||
|
return redis.opsForValue().get(cacheKey(namespace, key));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mono<Boolean> put(String namespace, String key, String value) {
|
||||||
|
return put(namespace, key, value, properties.defaultTtl());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mono<Boolean> put(String namespace, String key, String value, Duration ttl) {
|
||||||
|
return redis.opsForValue().set(cacheKey(namespace, key), value, ttl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mono<Boolean> putIfAbsent(String namespace, String key, String value, Duration ttl) {
|
||||||
|
return redis.opsForValue().setIfAbsent(cacheKey(namespace, key), value, ttl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mono<Boolean> evict(String namespace, String key) {
|
||||||
|
return redis.delete(cacheKey(namespace, key)).map(deleted -> deleted > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String cacheKey(String namespace, String key) {
|
||||||
|
return properties.keyPrefix() + ':' + namespace + ':' + key;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.cygnus.cloud.database;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
@ConfigurationProperties("cygnus.database")
|
||||||
|
public record DatabaseProperties(
|
||||||
|
String host,
|
||||||
|
int port,
|
||||||
|
String database,
|
||||||
|
String username,
|
||||||
|
String password,
|
||||||
|
boolean ssl,
|
||||||
|
Duration connectTimeout,
|
||||||
|
int poolSize,
|
||||||
|
int poolWaitQueueSize) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package com.cygnus.cloud.database;
|
||||||
|
|
||||||
|
import io.vertx.sqlclient.Pool;
|
||||||
|
import io.vertx.sqlclient.Row;
|
||||||
|
import io.vertx.sqlclient.RowSet;
|
||||||
|
import io.vertx.sqlclient.Tuple;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reactor boundary around the Vert.x PostgreSQL pool. Feature repositories
|
||||||
|
* should use parameterized SQL and pass values through {@link Tuple}.
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class ReactiveDatabaseClient {
|
||||||
|
|
||||||
|
private final Pool pool;
|
||||||
|
|
||||||
|
public ReactiveDatabaseClient(Pool pool) {
|
||||||
|
this.pool = pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mono<RowSet<Row>> query(String sql) {
|
||||||
|
return Mono.fromCompletionStage(() -> pool.query(sql).execute().toCompletionStage());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mono<RowSet<Row>> preparedQuery(String sql, Tuple parameters) {
|
||||||
|
return Mono.fromCompletionStage(
|
||||||
|
() -> pool.preparedQuery(sql).execute(parameters).toCompletionStage());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.cygnus.cloud.database;
|
||||||
|
|
||||||
|
import io.vertx.core.Vertx;
|
||||||
|
import io.vertx.pgclient.PgConnectOptions;
|
||||||
|
import io.vertx.pgclient.PgBuilder;
|
||||||
|
import io.vertx.sqlclient.Pool;
|
||||||
|
import io.vertx.sqlclient.PoolOptions;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class VertxDatabaseConfiguration {
|
||||||
|
|
||||||
|
@Bean(destroyMethod = "close")
|
||||||
|
Vertx vertx() {
|
||||||
|
return Vertx.vertx();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(destroyMethod = "close")
|
||||||
|
Pool postgresPool(Vertx vertx, DatabaseProperties properties) {
|
||||||
|
PgConnectOptions connection = new PgConnectOptions()
|
||||||
|
.setHost(properties.host())
|
||||||
|
.setPort(properties.port())
|
||||||
|
.setDatabase(properties.database())
|
||||||
|
.setUser(properties.username())
|
||||||
|
.setPassword(properties.password())
|
||||||
|
.setSslMode(properties.ssl()
|
||||||
|
? io.vertx.pgclient.SslMode.REQUIRE
|
||||||
|
: io.vertx.pgclient.SslMode.DISABLE);
|
||||||
|
|
||||||
|
PoolOptions pool = new PoolOptions()
|
||||||
|
.setMaxSize(properties.poolSize())
|
||||||
|
.setMaxWaitQueueSize(properties.poolWaitQueueSize())
|
||||||
|
.setConnectionTimeout(Math.toIntExact(properties.connectTimeout().toMillis()))
|
||||||
|
.setConnectionTimeoutUnit(TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
|
return PgBuilder.pool()
|
||||||
|
.using(vertx)
|
||||||
|
.connectingTo(connection)
|
||||||
|
.with(pool)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.cygnus.cloud.security;
|
||||||
|
|
||||||
|
import org.springframework.security.oauth2.core.OAuth2Error;
|
||||||
|
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
|
||||||
|
import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult;
|
||||||
|
import org.springframework.security.oauth2.jwt.Jwt;
|
||||||
|
|
||||||
|
final class AudienceValidator implements OAuth2TokenValidator<Jwt> {
|
||||||
|
|
||||||
|
private static final OAuth2Error INVALID_AUDIENCE =
|
||||||
|
new OAuth2Error("invalid_token", "Required token audience is missing", null);
|
||||||
|
|
||||||
|
private final String audience;
|
||||||
|
|
||||||
|
AudienceValidator(String audience) {
|
||||||
|
this.audience = audience;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OAuth2TokenValidatorResult validate(Jwt jwt) {
|
||||||
|
return jwt.getAudience().contains(audience)
|
||||||
|
? OAuth2TokenValidatorResult.success()
|
||||||
|
: OAuth2TokenValidatorResult.failure(INVALID_AUDIENCE);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.cygnus.cloud.security;
|
||||||
|
|
||||||
|
import static org.springframework.security.config.Customizer.withDefaults;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.config.web.server.ServerHttpSecurity;
|
||||||
|
import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator;
|
||||||
|
import org.springframework.security.oauth2.jwt.Jwt;
|
||||||
|
import org.springframework.security.oauth2.jwt.JwtValidators;
|
||||||
|
import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder;
|
||||||
|
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
|
||||||
|
import org.springframework.security.web.server.SecurityWebFilterChain;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class CloudSecurityConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
SecurityWebFilterChain cloudSecurityFilterChain(
|
||||||
|
ServerHttpSecurity http,
|
||||||
|
CommunicationSecurityProperties properties) {
|
||||||
|
http.csrf(ServerHttpSecurity.CsrfSpec::disable);
|
||||||
|
|
||||||
|
if (!properties.enabled()) {
|
||||||
|
return http.authorizeExchange(exchange -> exchange.anyExchange().permitAll()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
return http
|
||||||
|
.authorizeExchange(exchange -> exchange
|
||||||
|
.pathMatchers("/actuator/health", "/actuator/info").permitAll()
|
||||||
|
.anyExchange().authenticated())
|
||||||
|
.oauth2ResourceServer(resourceServer -> resourceServer.jwt(withDefaults()))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty(name = "cygnus.security.enabled", havingValue = "true")
|
||||||
|
ReactiveJwtDecoder reactiveJwtDecoder(CommunicationSecurityProperties properties) {
|
||||||
|
NimbusReactiveJwtDecoder decoder = NimbusReactiveJwtDecoder
|
||||||
|
.withIssuerLocation(properties.issuerUri())
|
||||||
|
.build();
|
||||||
|
decoder.setJwtValidator(new DelegatingOAuth2TokenValidator<Jwt>(
|
||||||
|
JwtValidators.createDefaultWithIssuer(properties.issuerUri()),
|
||||||
|
new AudienceValidator(properties.audience())));
|
||||||
|
return decoder;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.cygnus.cloud.security;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
@ConfigurationProperties("cygnus.security")
|
||||||
|
public record CommunicationSecurityProperties(
|
||||||
|
boolean enabled,
|
||||||
|
String issuerUri,
|
||||||
|
String audience,
|
||||||
|
Duration assertionTtl,
|
||||||
|
Duration accessTokenTtl) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.cygnus.cloud.security;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
import com.cygnus.cloud.cache.ReactiveCacheService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class JwtReplayProtectionService {
|
||||||
|
|
||||||
|
private static final String NAMESPACE = "jwt-jti";
|
||||||
|
|
||||||
|
private final ReactiveCacheService cache;
|
||||||
|
|
||||||
|
public JwtReplayProtectionService(ReactiveCacheService cache) {
|
||||||
|
this.cache = cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mono<Boolean> claim(String jwtId, Duration remainingLifetime) {
|
||||||
|
return cache.putIfAbsent(NAMESPACE, jwtId, "used", remainingLifetime);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.cygnus.cloud.system;
|
||||||
|
|
||||||
|
import java.time.Clock;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class SystemConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
Clock systemClock() {
|
||||||
|
return Clock.systemUTC();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.cygnus.cloud.system;
|
||||||
|
|
||||||
|
import java.time.Clock;
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/system")
|
||||||
|
public class SystemInfoController {
|
||||||
|
|
||||||
|
private final Clock clock;
|
||||||
|
|
||||||
|
public SystemInfoController(Clock clock) {
|
||||||
|
this.clock = clock;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/info")
|
||||||
|
public Mono<SystemInfoResponse> info() {
|
||||||
|
return Mono.just(new SystemInfoResponse(
|
||||||
|
"cygnus-cloud-service",
|
||||||
|
"1.0.0-SNAPSHOT",
|
||||||
|
Instant.now(clock)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package com.cygnus.cloud.system;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
public record SystemInfoResponse(String service, String version, Instant timestamp) {
|
||||||
|
}
|
||||||
55
cygnus-cloud-service/src/main/resources/application.yml
Normal file
55
cygnus-cloud-service/src/main/resources/application.yml
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: cygnus-cloud-service
|
||||||
|
data:
|
||||||
|
redis:
|
||||||
|
host: ${REDIS_HOST:192.168.0.111}
|
||||||
|
port: ${REDIS_PORT:7901}
|
||||||
|
password: ${REDIS_PASSWORD:M@triXR3d1s@6202}
|
||||||
|
connect-timeout: ${REDIS_CONNECT_TIMEOUT:3s}
|
||||||
|
timeout: ${REDIS_COMMAND_TIMEOUT:3s}
|
||||||
|
lettuce:
|
||||||
|
pool:
|
||||||
|
max-active: ${REDIS_MAX_ACTIVE:20}
|
||||||
|
max-idle: ${REDIS_MAX_IDLE:10}
|
||||||
|
min-idle: ${REDIS_MIN_IDLE:1}
|
||||||
|
max-wait: ${REDIS_MAX_WAIT:2s}
|
||||||
|
|
||||||
|
cygnus:
|
||||||
|
database:
|
||||||
|
host: ${DB_HOST:192.168.0.111}
|
||||||
|
port: ${DB_PORT:5432}
|
||||||
|
database: ${DB_NAME:matrix}
|
||||||
|
username: ${DB_USER:postgres}
|
||||||
|
password: ${DB_PASSWORD:M@triXPostgr3s@6202}
|
||||||
|
ssl: ${DB_SSL:false}
|
||||||
|
connect-timeout: ${DB_CONNECT_TIMEOUT:3s}
|
||||||
|
pool-size: ${DB_POOL_SIZE:20}
|
||||||
|
pool-wait-queue-size: ${DB_POOL_WAIT_QUEUE_SIZE:100}
|
||||||
|
security:
|
||||||
|
enabled: ${CYGNUS_SECURITY_ENABLED:false}
|
||||||
|
issuer-uri: ${CYGNUS_JWT_ISSUER_URI:http://localhost:8090}
|
||||||
|
audience: ${CYGNUS_JWT_AUDIENCE:cygnus-cloud-api}
|
||||||
|
assertion-ttl: ${CYGNUS_ASSERTION_TTL:5m}
|
||||||
|
access-token-ttl: ${CYGNUS_ACCESS_TOKEN_TTL:20m}
|
||||||
|
cache:
|
||||||
|
key-prefix: ${CYGNUS_CACHE_PREFIX:cygnus}
|
||||||
|
default-ttl: ${CYGNUS_CACHE_TTL:10m}
|
||||||
|
|
||||||
|
server:
|
||||||
|
port: ${CYGNUS_CLOUD_PORT:8090}
|
||||||
|
shutdown: graceful
|
||||||
|
|
||||||
|
management:
|
||||||
|
endpoints:
|
||||||
|
web:
|
||||||
|
exposure:
|
||||||
|
include: health,info
|
||||||
|
endpoint:
|
||||||
|
health:
|
||||||
|
show-details: never
|
||||||
|
|
||||||
|
info:
|
||||||
|
app:
|
||||||
|
name: ${spring.application.name}
|
||||||
|
version: 1.0.0-SNAPSHOT
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package com.cygnus.cloud;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import com.cygnus.cloud.cache.ReactiveCacheService;
|
||||||
|
import com.cygnus.cloud.database.DatabaseProperties;
|
||||||
|
import com.cygnus.cloud.database.ReactiveDatabaseClient;
|
||||||
|
import com.cygnus.cloud.security.CommunicationSecurityProperties;
|
||||||
|
import io.vertx.sqlclient.Pool;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest(
|
||||||
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
|
properties = "cygnus.security.enabled=false")
|
||||||
|
class InfrastructureConfigurationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Pool postgresPool;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ReactiveDatabaseClient databaseClient;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ReactiveCacheService cacheService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DatabaseProperties databaseProperties;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CommunicationSecurityProperties securityProperties;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void communicationInfrastructureStartsWithoutOpeningExternalConnections() {
|
||||||
|
assertThat(postgresPool).isNotNull();
|
||||||
|
assertThat(databaseClient).isNotNull();
|
||||||
|
assertThat(cacheService).isNotNull();
|
||||||
|
assertThat(databaseProperties.database()).isEqualTo("cygnus");
|
||||||
|
assertThat(securityProperties.audience()).isEqualTo("cygnus-cloud-api");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package com.cygnus.cloud.system;
|
||||||
|
|
||||||
|
import java.time.Clock;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.context.annotation.Primary;
|
||||||
|
import org.springframework.boot.test.context.TestConfiguration;
|
||||||
|
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||||
|
|
||||||
|
@WebFluxTest(SystemInfoController.class)
|
||||||
|
@Import(SystemInfoControllerTest.FixedClockConfiguration.class)
|
||||||
|
class SystemInfoControllerTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WebTestClient webTestClient;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void exposesVersionedServiceInformation() {
|
||||||
|
webTestClient.get()
|
||||||
|
.uri("/api/v1/system/info")
|
||||||
|
.exchange()
|
||||||
|
.expectStatus().isOk()
|
||||||
|
.expectHeader().contentTypeCompatibleWith("application/json")
|
||||||
|
.expectBody()
|
||||||
|
.jsonPath("$.service").isEqualTo("cygnus-cloud-service")
|
||||||
|
.jsonPath("$.version").isEqualTo("1.0.0-SNAPSHOT")
|
||||||
|
.jsonPath("$.timestamp").isEqualTo("2026-07-22T12:00:00Z");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestConfiguration
|
||||||
|
static class FixedClockConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Primary
|
||||||
|
Clock fixedClock() {
|
||||||
|
return Clock.fixed(Instant.parse("2026-07-22T12:00:00Z"), ZoneOffset.UTC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
55
cygnus-cloud-service/target/classes/application.yml
Normal file
55
cygnus-cloud-service/target/classes/application.yml
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: cygnus-cloud-service
|
||||||
|
data:
|
||||||
|
redis:
|
||||||
|
host: ${REDIS_HOST:192.168.0.111}
|
||||||
|
port: ${REDIS_PORT:7901}
|
||||||
|
password: ${REDIS_PASSWORD:M@triXR3d1s@6202}
|
||||||
|
connect-timeout: ${REDIS_CONNECT_TIMEOUT:3s}
|
||||||
|
timeout: ${REDIS_COMMAND_TIMEOUT:3s}
|
||||||
|
lettuce:
|
||||||
|
pool:
|
||||||
|
max-active: ${REDIS_MAX_ACTIVE:20}
|
||||||
|
max-idle: ${REDIS_MAX_IDLE:10}
|
||||||
|
min-idle: ${REDIS_MIN_IDLE:1}
|
||||||
|
max-wait: ${REDIS_MAX_WAIT:2s}
|
||||||
|
|
||||||
|
cygnus:
|
||||||
|
database:
|
||||||
|
host: ${DB_HOST:192.168.0.111}
|
||||||
|
port: ${DB_PORT:5432}
|
||||||
|
database: ${DB_NAME:matrix}
|
||||||
|
username: ${DB_USER:postgres}
|
||||||
|
password: ${DB_PASSWORD:M@triXPostgr3s@6202}
|
||||||
|
ssl: ${DB_SSL:false}
|
||||||
|
connect-timeout: ${DB_CONNECT_TIMEOUT:3s}
|
||||||
|
pool-size: ${DB_POOL_SIZE:20}
|
||||||
|
pool-wait-queue-size: ${DB_POOL_WAIT_QUEUE_SIZE:100}
|
||||||
|
security:
|
||||||
|
enabled: ${CYGNUS_SECURITY_ENABLED:false}
|
||||||
|
issuer-uri: ${CYGNUS_JWT_ISSUER_URI:http://localhost:8090}
|
||||||
|
audience: ${CYGNUS_JWT_AUDIENCE:cygnus-cloud-api}
|
||||||
|
assertion-ttl: ${CYGNUS_ASSERTION_TTL:5m}
|
||||||
|
access-token-ttl: ${CYGNUS_ACCESS_TOKEN_TTL:20m}
|
||||||
|
cache:
|
||||||
|
key-prefix: ${CYGNUS_CACHE_PREFIX:cygnus}
|
||||||
|
default-ttl: ${CYGNUS_CACHE_TTL:10m}
|
||||||
|
|
||||||
|
server:
|
||||||
|
port: ${CYGNUS_CLOUD_PORT:8090}
|
||||||
|
shutdown: graceful
|
||||||
|
|
||||||
|
management:
|
||||||
|
endpoints:
|
||||||
|
web:
|
||||||
|
exposure:
|
||||||
|
include: health,info
|
||||||
|
endpoint:
|
||||||
|
health:
|
||||||
|
show-details: never
|
||||||
|
|
||||||
|
info:
|
||||||
|
app:
|
||||||
|
name: ${spring.application.name}
|
||||||
|
version: 1.0.0-SNAPSHOT
|
||||||
Binary file not shown.
BIN
cygnus-cloud-service/target/classes/com/cygnus/cloud/cache/CacheProperties.class
vendored
Normal file
BIN
cygnus-cloud-service/target/classes/com/cygnus/cloud/cache/CacheProperties.class
vendored
Normal file
Binary file not shown.
BIN
cygnus-cloud-service/target/classes/com/cygnus/cloud/cache/ReactiveCacheService.class
vendored
Normal file
BIN
cygnus-cloud-service/target/classes/com/cygnus/cloud/cache/ReactiveCacheService.class
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,3 @@
|
|||||||
|
artifactId=cygnus-cloud-service
|
||||||
|
groupId=com.cygnus
|
||||||
|
version=1.0.0-SNAPSHOT
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
com/cygnus/cloud/security/CommunicationSecurityProperties.class
|
||||||
|
com/cygnus/cloud/security/JwtReplayProtectionService.class
|
||||||
|
com/cygnus/cloud/system/SystemConfiguration.class
|
||||||
|
com/cygnus/cloud/cache/CacheProperties.class
|
||||||
|
com/cygnus/cloud/security/CloudSecurityConfiguration.class
|
||||||
|
com/cygnus/cloud/database/VertxDatabaseConfiguration.class
|
||||||
|
com/cygnus/cloud/database/ReactiveDatabaseClient.class
|
||||||
|
com/cygnus/cloud/security/AudienceValidator.class
|
||||||
|
com/cygnus/cloud/system/SystemInfoController.class
|
||||||
|
com/cygnus/cloud/CygnusCloudServiceApplication.class
|
||||||
|
com/cygnus/cloud/cache/ReactiveCacheService.class
|
||||||
|
com/cygnus/cloud/database/DatabaseProperties.class
|
||||||
|
com/cygnus/cloud/system/SystemInfoResponse.class
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
/Users/maddy/Projects/matrix/cygnus-cloud-service/src/main/java/com/cygnus/cloud/CygnusCloudServiceApplication.java
|
||||||
|
/Users/maddy/Projects/matrix/cygnus-cloud-service/src/main/java/com/cygnus/cloud/cache/CacheProperties.java
|
||||||
|
/Users/maddy/Projects/matrix/cygnus-cloud-service/src/main/java/com/cygnus/cloud/cache/ReactiveCacheService.java
|
||||||
|
/Users/maddy/Projects/matrix/cygnus-cloud-service/src/main/java/com/cygnus/cloud/database/DatabaseProperties.java
|
||||||
|
/Users/maddy/Projects/matrix/cygnus-cloud-service/src/main/java/com/cygnus/cloud/database/ReactiveDatabaseClient.java
|
||||||
|
/Users/maddy/Projects/matrix/cygnus-cloud-service/src/main/java/com/cygnus/cloud/database/VertxDatabaseConfiguration.java
|
||||||
|
/Users/maddy/Projects/matrix/cygnus-cloud-service/src/main/java/com/cygnus/cloud/security/AudienceValidator.java
|
||||||
|
/Users/maddy/Projects/matrix/cygnus-cloud-service/src/main/java/com/cygnus/cloud/security/CloudSecurityConfiguration.java
|
||||||
|
/Users/maddy/Projects/matrix/cygnus-cloud-service/src/main/java/com/cygnus/cloud/security/CommunicationSecurityProperties.java
|
||||||
|
/Users/maddy/Projects/matrix/cygnus-cloud-service/src/main/java/com/cygnus/cloud/security/JwtReplayProtectionService.java
|
||||||
|
/Users/maddy/Projects/matrix/cygnus-cloud-service/src/main/java/com/cygnus/cloud/system/SystemConfiguration.java
|
||||||
|
/Users/maddy/Projects/matrix/cygnus-cloud-service/src/main/java/com/cygnus/cloud/system/SystemInfoController.java
|
||||||
|
/Users/maddy/Projects/matrix/cygnus-cloud-service/src/main/java/com/cygnus/cloud/system/SystemInfoResponse.java
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
com/cygnus/cloud/system/SystemInfoControllerTest$FixedClockConfiguration.class
|
||||||
|
com/cygnus/cloud/system/SystemInfoControllerTest.class
|
||||||
|
com/cygnus/cloud/InfrastructureConfigurationTest.class
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
/Users/maddy/Projects/matrix/cygnus-cloud-service/src/test/java/com/cygnus/cloud/InfrastructureConfigurationTest.java
|
||||||
|
/Users/maddy/Projects/matrix/cygnus-cloud-service/src/test/java/com/cygnus/cloud/system/SystemInfoControllerTest.java
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Test set: com.cygnus.cloud.InfrastructureConfigurationTest
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.673 s -- in com.cygnus.cloud.InfrastructureConfigurationTest
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Test set: com.cygnus.cloud.system.SystemInfoControllerTest
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.908 s -- in com.cygnus.cloud.system.SystemInfoControllerTest
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 103 KiB |
Binary file not shown.
@@ -0,0 +1,84 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
<configSections>
|
||||||
|
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
|
||||||
|
<section name="ReportsBackup.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
||||||
|
</sectionGroup>
|
||||||
|
</configSections>
|
||||||
|
<userSettings>
|
||||||
|
<ReportsBackup.Properties.Settings>
|
||||||
|
<setting name="bankreportsfdt" serializeAs="String">
|
||||||
|
<value>2017-11-30</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="bankreportstdt" serializeAs="String">
|
||||||
|
<value>2017-11-30</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="bankreports" serializeAs="String">
|
||||||
|
<value>X:\reports\output\bankreports\1\1</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="casedoc" serializeAs="String">
|
||||||
|
<value>X:\reports\output\casedoc</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="vendormails" serializeAs="String">
|
||||||
|
<value>X:\reports\output\fcu\vendormails</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="dedupe" serializeAs="String">
|
||||||
|
<value>X:\reports\output\dedupe\1\1</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="doc_reports" serializeAs="String">
|
||||||
|
<value>X:\reports\matrixonline\bankreports</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="doc_trackers" serializeAs="String">
|
||||||
|
<value>X:\reports\matrixonline\trackers</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="tbankreports" serializeAs="String">
|
||||||
|
<value>Y:\reports\output\bankreports\1\1</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="tcasedoc" serializeAs="String">
|
||||||
|
<value>Y:\reports\output\casedoc</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="tvendormails" serializeAs="String">
|
||||||
|
<value>Y:\reports\output\fcu\vendormails</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="tdedupe" serializeAs="String">
|
||||||
|
<value>Y:\reports\output\dedupe\1\1</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="tdoc_reports" serializeAs="String">
|
||||||
|
<value>Y:\reports\matrixonline\bankreports</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="tdoc_trackers" serializeAs="String">
|
||||||
|
<value>Y:\reports\matrixonline\trackers</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="casedocfdt" serializeAs="String">
|
||||||
|
<value>2014-04-01</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="casedoctdt" serializeAs="String">
|
||||||
|
<value>2014-04-01</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="vendormailsfdt" serializeAs="String">
|
||||||
|
<value>2014-04-01</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="vendormailstdt" serializeAs="String">
|
||||||
|
<value>2014-04-01</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="dedupefdt" serializeAs="String">
|
||||||
|
<value>2014-04-01</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="dedupetdt" serializeAs="String">
|
||||||
|
<value>2014-04-01</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="doc_reportsfdt" serializeAs="String">
|
||||||
|
<value>2014-04-01</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="doc_reportstdt" serializeAs="String">
|
||||||
|
<value>2014-04-01</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="doc_trackersfdt" serializeAs="String">
|
||||||
|
<value>2014-04-01</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="doc_trackerstdt" serializeAs="String">
|
||||||
|
<value>2014-04-01</value>
|
||||||
|
</setting>
|
||||||
|
</ReportsBackup.Properties.Settings>
|
||||||
|
</userSettings>
|
||||||
|
</configuration>
|
||||||
259550
cygnus-onprem-app/build/WebContent/ReportsBackup/log.txt
Normal file
259550
cygnus-onprem-app/build/WebContent/ReportsBackup/log.txt
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user