dc53a233b9
重构项目结构,将分散在各模块的领域模型统一移动到manage-common模块 更新相关依赖和引用路径 调整docker-compose配置和测试标记 添加新的Playwright测试配置 优化Dockerfile构建过程
2025 lines
64 KiB
Markdown
2025 lines
64 KiB
Markdown
# Multi-Module Architecture Refactor Implementation Plan
|
||
|
||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||
|
||
**Goal:** 将 novalon-manage-api 从单体模块重构为网关 + 单体多模块架构,实现模块化、统一认证授权、独立部署和性能优化。
|
||
|
||
**Architecture:** 采用网关(manage-gateway)+ 应用层(manage-app)+ 业务模块(manage-sys、manage-audit、manage-notify、manage-file)+ 公共模块(manage-common、manage-db)的分层架构。网关统一处理JWT认证、RBAC权限和限流熔断,应用层聚合所有业务模块,通过Caffeine缓存优化性能,使用Docker容器化部署。
|
||
|
||
**Tech Stack:** Java 21, Spring Boot 3.4.1, Spring WebFlux, Spring Security, R2DBC, PostgreSQL, JWT, Caffeine, Docker, Maven
|
||
|
||
---
|
||
|
||
## Phase 1: Preparation (1-2 days)
|
||
|
||
### Task 1: Create manage-gateway module structure
|
||
|
||
**Files:**
|
||
- Create: `novalon-manage-api/manage-gateway/pom.xml`
|
||
- Create: `novalon-manage-api/manage-gateway/src/main/java/cn/novalon/manage/gateway/GatewayApplication.java`
|
||
- Create: `novalon-manage-api/manage-gateway/src/main/resources/application.yml`
|
||
- Create: `novalon-manage-api/manage-gateway/src/main/resources/application-dev.yml`
|
||
- Create: `novalon-manage-api/manage-gateway/src/main/resources/application-prod.yml`
|
||
- Create: `novalon-manage-api/manage-gateway/Dockerfile`
|
||
|
||
**Step 1: Create manage-gateway pom.xml**
|
||
|
||
```xml
|
||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||
<modelVersion>4.0.0</modelVersion>
|
||
|
||
<parent>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>novalon-manage-api</artifactId>
|
||
<version>1.0.0</version>
|
||
</parent>
|
||
|
||
<artifactId>manage-gateway</artifactId>
|
||
<packaging>jar</packaging>
|
||
|
||
<name>Manage Gateway</name>
|
||
<description>Gateway module for Novalon Manage API</description>
|
||
|
||
<dependencies>
|
||
<dependency>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>manage-common</artifactId>
|
||
<version>${project.version}</version>
|
||
</dependency>
|
||
<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.cloud</groupId>
|
||
<artifactId>spring-cloud-starter-gateway</artifactId>
|
||
<version>4.1.0</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>io.micrometer</groupId>
|
||
<artifactId>micrometer-registry-prometheus</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-test</artifactId>
|
||
<scope>test</scope>
|
||
</dependency>
|
||
</dependencies>
|
||
|
||
<build>
|
||
<plugins>
|
||
<plugin>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||
<configuration>
|
||
<mainClass>cn.novalon.manage.gateway.GatewayApplication</mainClass>
|
||
</configuration>
|
||
</plugin>
|
||
</plugins>
|
||
</build>
|
||
</project>
|
||
```
|
||
|
||
**Step 2: Create GatewayApplication.java**
|
||
|
||
```java
|
||
package cn.novalon.manage.gateway;
|
||
|
||
import org.springframework.boot.SpringApplication;
|
||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||
import org.springframework.cloud.gateway.route.RouteLocator;
|
||
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
|
||
import org.springframework.context.annotation.Bean;
|
||
|
||
@SpringBootApplication
|
||
public class GatewayApplication {
|
||
|
||
public static void main(String[] args) {
|
||
SpringApplication.run(GatewayApplication.class, args);
|
||
}
|
||
|
||
@Bean
|
||
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
|
||
return builder.routes()
|
||
.route("manage-app", r -> r
|
||
.path("/api/**")
|
||
.uri("http://manage-app:8081"))
|
||
.build();
|
||
}
|
||
}
|
||
```
|
||
|
||
**Step 3: Create application.yml**
|
||
|
||
```yaml
|
||
server:
|
||
port: 8080
|
||
|
||
spring:
|
||
application:
|
||
name: manage-gateway
|
||
cloud:
|
||
gateway:
|
||
routes:
|
||
- id: manage-app
|
||
uri: http://manage-app:8081
|
||
predicates:
|
||
- Path=/api/**
|
||
default-filters:
|
||
- name: Retry
|
||
args:
|
||
retries: 3
|
||
statuses: BAD_GATEWAY,SERVICE_UNAVAILABLE
|
||
methods: GET,POST
|
||
backoff:
|
||
firstBackoff: 10ms
|
||
maxBackoff: 50ms
|
||
factor: 2
|
||
basedOnPreviousValue: false
|
||
|
||
management:
|
||
endpoints:
|
||
web:
|
||
exposure:
|
||
include: health,info,metrics
|
||
base-path: /actuator
|
||
endpoint:
|
||
health:
|
||
show-details: always
|
||
metrics:
|
||
tags:
|
||
application: ${spring.application.name}
|
||
|
||
logging:
|
||
level:
|
||
cn.novalon.manage: DEBUG
|
||
org.springframework.cloud.gateway: DEBUG
|
||
```
|
||
|
||
**Step 4: Create Dockerfile**
|
||
|
||
```dockerfile
|
||
FROM openjdk:21-jdk-slim
|
||
|
||
WORKDIR /app
|
||
|
||
COPY manage-gateway/target/manage-gateway-1.0.0.jar app.jar
|
||
|
||
EXPOSE 8080
|
||
|
||
ENTRYPOINT ["java", "-jar", "app.jar"]
|
||
```
|
||
|
||
**Step 5: Compile and verify**
|
||
|
||
Run: `cd novalon-manage-api && mvn clean compile -pl manage-gateway -am`
|
||
|
||
Expected: BUILD SUCCESS
|
||
|
||
**Step 6: Commit**
|
||
|
||
```bash
|
||
git add novalon-manage-api/manage-gateway/
|
||
git commit -m "feat: create manage-gateway module structure"
|
||
```
|
||
|
||
---
|
||
|
||
### Task 2: Create manage-app module structure
|
||
|
||
**Files:**
|
||
- Create: `novalon-manage-api/manage-app/pom.xml`
|
||
- Create: `novalon-manage-api/manage-app/src/main/java/cn/novalon/manage/app/ManageApplication.java`
|
||
- Create: `novalon-manage-api/manage-app/src/main/resources/application.yml`
|
||
- Create: `novalon-manage-api/manage-app/src/main/resources/application-dev.yml`
|
||
- Create: `novalon-manage-api/manage-app/src/main/resources/application-prod.yml`
|
||
- Create: `novalon-manage-api/manage-app/Dockerfile`
|
||
|
||
**Step 1: Create manage-app pom.xml**
|
||
|
||
```xml
|
||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||
<modelVersion>4.0.0</modelVersion>
|
||
|
||
<parent>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>novalon-manage-api</artifactId>
|
||
<version>1.0.0</version>
|
||
</parent>
|
||
|
||
<artifactId>manage-app</artifactId>
|
||
<packaging>jar</packaging>
|
||
|
||
<name>Manage App</name>
|
||
<description>Application module for Novalon Manage API</description>
|
||
|
||
<dependencies>
|
||
<dependency>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>manage-sys</artifactId>
|
||
<version>${project.version}</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>manage-audit</artifactId>
|
||
<version>${project.version}</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>manage-notify</artifactId>
|
||
<version>${project.version}</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>manage-file</artifactId>
|
||
<version>${project.version}</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>manage-db</artifactId>
|
||
<version>${project.version}</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>manage-common</artifactId>
|
||
<version>${project.version}</version>
|
||
</dependency>
|
||
<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>io.micrometer</groupId>
|
||
<artifactId>micrometer-registry-prometheus</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.postgresql</groupId>
|
||
<artifactId>r2dbc-postgresql</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.postgresql</groupId>
|
||
<artifactId>postgresql</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.flywaydb</groupId>
|
||
<artifactId>flyway-core</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.flywaydb</groupId>
|
||
<artifactId>flyway-database-postgresql</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-test</artifactId>
|
||
<scope>test</scope>
|
||
</dependency>
|
||
</dependencies>
|
||
|
||
<build>
|
||
<plugins>
|
||
<plugin>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||
<configuration>
|
||
<mainClass>cn.novalon.manage.app.ManageApplication</mainClass>
|
||
</configuration>
|
||
</plugin>
|
||
</plugins>
|
||
</build>
|
||
</project>
|
||
```
|
||
|
||
**Step 2: Create ManageApplication.java**
|
||
|
||
```java
|
||
package cn.novalon.manage.app;
|
||
|
||
import org.springframework.boot.SpringApplication;
|
||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
|
||
import org.springframework.context.annotation.ComponentScan;
|
||
|
||
@SpringBootApplication
|
||
@ConfigurationPropertiesScan(basePackages = "cn.novalon.manage")
|
||
@ComponentScan(basePackages = "cn.novalon.manage")
|
||
public class ManageApplication {
|
||
|
||
public static void main(String[] args) {
|
||
SpringApplication.run(ManageApplication.class, args);
|
||
}
|
||
}
|
||
```
|
||
|
||
**Step 3: Create application.yml**
|
||
|
||
```yaml
|
||
server:
|
||
port: 8081
|
||
|
||
spring:
|
||
application:
|
||
name: manage-app
|
||
r2dbc:
|
||
url: r2dbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5432}/${DB_NAME:novalon_manage}
|
||
username: ${DB_USERNAME:postgres}
|
||
password: ${DB_PASSWORD:postgres}
|
||
pool:
|
||
initial-size: 10
|
||
max-size: 50
|
||
max-idle-time: 30m
|
||
max-life-time: 1h
|
||
acquire-timeout: 5s
|
||
flyway:
|
||
enabled: true
|
||
locations: classpath:db/migration
|
||
|
||
management:
|
||
endpoints:
|
||
web:
|
||
exposure:
|
||
include: health,info,metrics,env,loggers
|
||
base-path: /actuator
|
||
endpoint:
|
||
health:
|
||
show-details: always
|
||
metrics:
|
||
tags:
|
||
application: ${spring.application.name}
|
||
environment: ${spring.profiles.active}
|
||
|
||
logging:
|
||
level:
|
||
cn.novalon.manage: DEBUG
|
||
org.springframework.r2dbc: DEBUG
|
||
```
|
||
|
||
**Step 4: Create Dockerfile**
|
||
|
||
```dockerfile
|
||
FROM openjdk:21-jdk-slim
|
||
|
||
WORKDIR /app
|
||
|
||
COPY manage-app/target/manage-app-1.0.0.jar app.jar
|
||
|
||
EXPOSE 8081
|
||
|
||
ENTRYPOINT ["java", "-jar", "app.jar"]
|
||
```
|
||
|
||
**Step 5: Compile and verify**
|
||
|
||
Run: `cd novalon-manage-api && mvn clean compile -pl manage-app -am`
|
||
|
||
Expected: BUILD SUCCESS
|
||
|
||
**Step 6: Commit**
|
||
|
||
```bash
|
||
git add novalon-manage-api/manage-app/
|
||
git commit -m "feat: create manage-app module structure"
|
||
```
|
||
|
||
---
|
||
|
||
### Task 3: Create manage-common module structure
|
||
|
||
**Files:**
|
||
- Create: `novalon-manage-api/manage-common/pom.xml`
|
||
- Create: `novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/`
|
||
- Create: `novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/util/`
|
||
- Create: `novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/config/`
|
||
- Create: `novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/filter/`
|
||
- Create: `novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/exception/`
|
||
|
||
**Step 1: Create manage-common pom.xml**
|
||
|
||
```xml
|
||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||
<modelVersion>4.0.0</modelVersion>
|
||
|
||
<parent>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>novalon-manage-api</artifactId>
|
||
<version>1.0.0</version>
|
||
</parent>
|
||
|
||
<artifactId>manage-common</artifactId>
|
||
<packaging>jar</packaging>
|
||
|
||
<name>Manage Common</name>
|
||
<description>Common module for Novalon Manage API</description>
|
||
|
||
<dependencies>
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-webflux</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-cache</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>com.github.ben-manes.caffeine</groupId>
|
||
<artifactId>caffeine</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.apache.commons</groupId>
|
||
<artifactId>commons-lang3</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>io.jsonwebtoken</groupId>
|
||
<artifactId>jjwt-api</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>io.jsonwebtoken</groupId>
|
||
<artifactId>jjwt-impl</artifactId>
|
||
<scope>runtime</scope>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>io.jsonwebtoken</groupId>
|
||
<artifactId>jjwt-jackson</artifactId>
|
||
<scope>runtime</scope>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-test</artifactId>
|
||
<scope>test</scope>
|
||
</dependency>
|
||
</dependencies>
|
||
|
||
<build>
|
||
<plugins>
|
||
<plugin>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||
<configuration>
|
||
<skip>true</skip>
|
||
</configuration>
|
||
</plugin>
|
||
</plugins>
|
||
</build>
|
||
</project>
|
||
```
|
||
|
||
**Step 2: Create package structure**
|
||
|
||
Run: `mkdir -p novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/{util,config,filter,exception,dto}`
|
||
|
||
Expected: Directories created successfully
|
||
|
||
**Step 3: Create common exception classes**
|
||
|
||
Create: `novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/exception/BusinessException.java`
|
||
|
||
```java
|
||
package cn.novalon.manage.common.exception;
|
||
|
||
public class BusinessException extends RuntimeException {
|
||
|
||
private final String code;
|
||
private final String message;
|
||
|
||
public BusinessException(String code, String message) {
|
||
super(message);
|
||
this.code = code;
|
||
this.message = message;
|
||
}
|
||
|
||
public String getCode() {
|
||
return code;
|
||
}
|
||
|
||
@Override
|
||
public String getMessage() {
|
||
return message;
|
||
}
|
||
}
|
||
```
|
||
|
||
**Step 4: Compile and verify**
|
||
|
||
Run: `cd novalon-manage-api && mvn clean compile -pl manage-common -am`
|
||
|
||
Expected: BUILD SUCCESS
|
||
|
||
**Step 5: Commit**
|
||
|
||
```bash
|
||
git add novalon-manage-api/manage-common/
|
||
git commit -m "feat: create manage-common module structure"
|
||
```
|
||
|
||
---
|
||
|
||
### Task 4: Create manage-db module structure
|
||
|
||
**Files:**
|
||
- Create: `novalon-manage-api/manage-db/pom.xml`
|
||
- Create: `novalon-manage-api/manage-db/src/main/java/cn/novalon/manage/db/`
|
||
- Create: `novalon-manage-api/manage-db/src/main/java/cn/novalon/manage/db/entity/`
|
||
- Create: `novalon-manage-api/manage-db/src/main/java/cn/novalon/manage/db/repository/`
|
||
- Create: `novalon-manage-api/manage-db/src/main/resources/db/migration/`
|
||
|
||
**Step 1: Create manage-db pom.xml**
|
||
|
||
```xml
|
||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||
<modelVersion>4.0.0</modelVersion>
|
||
|
||
<parent>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>novalon-manage-api</artifactId>
|
||
<version>1.0.0</version>
|
||
</parent>
|
||
|
||
<artifactId>manage-db</artifactId>
|
||
<packaging>jar</packaging>
|
||
|
||
<name>Manage DB</name>
|
||
<description>Database module for Novalon Manage API</description>
|
||
|
||
<dependencies>
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.postgresql</groupId>
|
||
<artifactId>r2dbc-postgresql</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.postgresql</groupId>
|
||
<artifactId>postgresql</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.flywaydb</groupId>
|
||
<artifactId>flyway-core</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.flywaydb</groupId>
|
||
<artifactId>flyway-database-postgresql</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.mapstruct</groupId>
|
||
<artifactId>mapstruct</artifactId>
|
||
<version>1.5.5.Final</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.mapstruct</groupId>
|
||
<artifactId>mapstruct-processor</artifactId>
|
||
<version>1.5.5.Final</version>
|
||
<scope>provided</scope>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-test</artifactId>
|
||
<scope>test</scope>
|
||
</dependency>
|
||
</dependencies>
|
||
|
||
<build>
|
||
<plugins>
|
||
<plugin>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||
<configuration>
|
||
<skip>true</skip>
|
||
</configuration>
|
||
</plugin>
|
||
</plugins>
|
||
</build>
|
||
</project>
|
||
```
|
||
|
||
**Step 2: Copy migration scripts**
|
||
|
||
Run: `cp -r novalon-manage-api/manage-sys/src/main/resources/db/migration/* novalon-manage-api/manage-db/src/main/resources/db/migration/`
|
||
|
||
Expected: Migration scripts copied successfully
|
||
|
||
**Step 3: Compile and verify**
|
||
|
||
Run: `cd novalon-manage-api && mvn clean compile -pl manage-db -am`
|
||
|
||
Expected: BUILD SUCCESS
|
||
|
||
**Step 4: Commit**
|
||
|
||
```bash
|
||
git add novalon-manage-api/manage-db/
|
||
git commit -m "feat: create manage-db module structure"
|
||
```
|
||
|
||
---
|
||
|
||
### Task 5: Create manage-audit module structure
|
||
|
||
**Files:**
|
||
- Create: `novalon-manage-api/manage-audit/pom.xml`
|
||
- Create: `novalon-manage-api/manage-audit/src/main/java/cn/novalon/manage/audit/`
|
||
- Create: `novalon-manage-api/manage-audit/src/main/java/cn/novalon/manage/audit/handler/`
|
||
- Create: `novalon-manage-api/manage-audit/src/main/java/cn/novalon/manage/audit/service/`
|
||
- Create: `novalon-manage-api/manage-audit/src/main/java/cn/novalon/manage/audit/dto/`
|
||
|
||
**Step 1: Create manage-audit pom.xml**
|
||
|
||
```xml
|
||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||
<modelVersion>4.0.0</modelVersion>
|
||
|
||
<parent>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>novalon-manage-api</artifactId>
|
||
<version>1.0.0</version>
|
||
</parent>
|
||
|
||
<artifactId>manage-audit</artifactId>
|
||
<packaging>jar</packaging>
|
||
|
||
<name>Manage Audit</name>
|
||
<description>Audit module for Novalon Manage API</description>
|
||
|
||
<dependencies>
|
||
<dependency>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>manage-db</artifactId>
|
||
<version>${project.version}</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>manage-common</artifactId>
|
||
<version>${project.version}</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-test</artifactId>
|
||
<scope>test</scope>
|
||
</dependency>
|
||
</dependencies>
|
||
|
||
<build>
|
||
<plugins>
|
||
<plugin>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||
<configuration>
|
||
<skip>true</skip>
|
||
</configuration>
|
||
</plugin>
|
||
</plugins>
|
||
</build>
|
||
</project>
|
||
```
|
||
|
||
**Step 2: Compile and verify**
|
||
|
||
Run: `cd novalon-manage-api && mvn clean compile -pl manage-audit -am`
|
||
|
||
Expected: BUILD SUCCESS
|
||
|
||
**Step 3: Commit**
|
||
|
||
```bash
|
||
git add novalon-manage-api/manage-audit/
|
||
git commit -m "feat: create manage-audit module structure"
|
||
```
|
||
|
||
---
|
||
|
||
### Task 6: Create manage-notify module structure
|
||
|
||
**Files:**
|
||
- Create: `novalon-manage-api/manage-notify/pom.xml`
|
||
- Create: `novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/`
|
||
- Create: `novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/handler/`
|
||
- Create: `novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/service/`
|
||
- Create: `novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/config/`
|
||
|
||
**Step 1: Create manage-notify pom.xml**
|
||
|
||
```xml
|
||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||
<modelVersion>4.0.0</modelVersion>
|
||
|
||
<parent>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>novalon-manage-api</artifactId>
|
||
<version>1.0.0</version>
|
||
</parent>
|
||
|
||
<artifactId>manage-notify</artifactId>
|
||
<packaging>jar</packaging>
|
||
|
||
<name>Manage Notify</name>
|
||
<description>Notify module for Novalon Manage API</description>
|
||
|
||
<dependencies>
|
||
<dependency>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>manage-db</artifactId>
|
||
<version>${project.version}</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>manage-common</artifactId>
|
||
<version>${project.version}</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-test</artifactId>
|
||
<scope>test</scope>
|
||
</dependency>
|
||
</dependencies>
|
||
|
||
<build>
|
||
<plugins>
|
||
<plugin>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||
<configuration>
|
||
<skip>true</skip>
|
||
</configuration>
|
||
</plugin>
|
||
</plugins>
|
||
</build>
|
||
</project>
|
||
```
|
||
|
||
**Step 2: Compile and verify**
|
||
|
||
Run: `cd novalon-manage-api && mvn clean compile -pl manage-notify -am`
|
||
|
||
Expected: BUILD SUCCESS
|
||
|
||
**Step 3: Commit**
|
||
|
||
```bash
|
||
git add novalon-manage-api/manage-notify/
|
||
git commit -m "feat: create manage-notify module structure"
|
||
```
|
||
|
||
---
|
||
|
||
### Task 7: Create manage-file module structure
|
||
|
||
**Files:**
|
||
- Create: `novalon-manage-api/manage-file/pom.xml`
|
||
- Create: `novalon-manage-api/manage-file/src/main/java/cn/novalon/manage/file/`
|
||
- Create: `novalon-manage-api/manage-file/src/main/java/cn/novalon/manage/file/handler/`
|
||
- Create: `novalon-manage-api/manage-file/src/main/java/cn/novalon/manage/file/service/`
|
||
- Create: `novalon-manage-api/manage-file/src/main/java/cn/novalon/manage/file/config/`
|
||
|
||
**Step 1: Create manage-file pom.xml**
|
||
|
||
```xml
|
||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||
<modelVersion>4.0.0</modelVersion>
|
||
|
||
<parent>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>novalon-manage-api</artifactId>
|
||
<version>1.0.0</version>
|
||
</parent>
|
||
|
||
<artifactId>manage-file</artifactId>
|
||
<packaging>jar</packaging>
|
||
|
||
<name>Manage File</name>
|
||
<description>File module for Novalon Manage API</description>
|
||
|
||
<dependencies>
|
||
<dependency>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>manage-db</artifactId>
|
||
<version>${project.version}</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>manage-common</artifactId>
|
||
<version>${project.version}</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-test</artifactId>
|
||
<scope>test</scope>
|
||
</dependency>
|
||
</dependencies>
|
||
|
||
<build>
|
||
<plugins>
|
||
<plugin>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||
<configuration>
|
||
<skip>true</skip>
|
||
</configuration>
|
||
</plugin>
|
||
</plugins>
|
||
</build>
|
||
</project>
|
||
```
|
||
|
||
**Step 2: Compile and verify**
|
||
|
||
Run: `cd novalon-manage-api && mvn clean compile -pl manage-file -am`
|
||
|
||
Expected: BUILD SUCCESS
|
||
|
||
**Step 3: Commit**
|
||
|
||
```bash
|
||
git add novalon-manage-api/manage-file/
|
||
git commit -m "feat: create manage-file module structure"
|
||
```
|
||
|
||
---
|
||
|
||
### Task 8: Update parent pom.xml with new modules
|
||
|
||
**Files:**
|
||
- Modify: `novalon-manage-api/pom.xml`
|
||
|
||
**Step 1: Update modules section**
|
||
|
||
Read: `novalon-manage-api/pom.xml`
|
||
|
||
Find: `<modules>` section and replace with:
|
||
|
||
```xml
|
||
<modules>
|
||
<module>manage-gateway</module>
|
||
<module>manage-app</module>
|
||
<module>manage-sys</module>
|
||
<module>manage-audit</module>
|
||
<module>manage-notify</module>
|
||
<module>manage-file</module>
|
||
<module>manage-common</module>
|
||
<module>manage-db</module>
|
||
</modules>
|
||
```
|
||
|
||
**Step 2: Verify build**
|
||
|
||
Run: `cd novalon-manage-api && mvn clean compile`
|
||
|
||
Expected: BUILD SUCCESS
|
||
|
||
**Step 3: Commit**
|
||
|
||
```bash
|
||
git add novalon-manage-api/pom.xml
|
||
git commit -m "feat: update parent pom.xml with new modules"
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 2: Module Extraction (3-5 days)
|
||
|
||
### Task 9: Extract common utilities to manage-common
|
||
|
||
**Files:**
|
||
- Modify: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/utils/SnowflakeId.java`
|
||
- Create: `novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/util/SnowflakeId.java`
|
||
- Modify: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/JwtProperties.java`
|
||
- Create: `novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/config/JwtProperties.java`
|
||
|
||
**Step 1: Move SnowflakeId to manage-common**
|
||
|
||
Read: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/utils/SnowflakeId.java`
|
||
|
||
Copy content to: `novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/util/SnowflakeId.java`
|
||
|
||
Update package declaration: `package cn.novalon.manage.common.util;`
|
||
|
||
**Step 2: Move JwtProperties to manage-common**
|
||
|
||
Read: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/JwtProperties.java`
|
||
|
||
Copy content to: `novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/config/JwtProperties.java`
|
||
|
||
Update package declaration: `package cn.novalon.manage.common.config;`
|
||
|
||
**Step 3: Update manage-sys imports**
|
||
|
||
Find all files in manage-sys that import SnowflakeId or JwtProperties and update imports:
|
||
|
||
```bash
|
||
cd novalon-manage-api/manage-sys
|
||
find src -name "*.java" -exec grep -l "SnowflakeId\|JwtProperties" {} \;
|
||
```
|
||
|
||
Update imports from:
|
||
- `import cn.novalon.manage.sys.utils.SnowflakeId;` to `import cn.novalon.manage.common.util.SnowflakeId;`
|
||
- `import cn.novalon.manage.sys.config.JwtProperties;` to `import cn.novalon.manage.common.config.JwtProperties;`
|
||
|
||
**Step 4: Remove old files from manage-sys**
|
||
|
||
Run: `rm novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/utils/SnowflakeId.java`
|
||
|
||
Run: `rm novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/JwtProperties.java`
|
||
|
||
**Step 5: Compile and verify**
|
||
|
||
Run: `cd novalon-manage-api && mvn clean compile`
|
||
|
||
Expected: BUILD SUCCESS
|
||
|
||
**Step 6: Commit**
|
||
|
||
```bash
|
||
git add novalon-manage-api/manage-common/ novalon-manage-api/manage-sys/
|
||
git commit -m "refactor: extract common utilities to manage-common"
|
||
```
|
||
|
||
---
|
||
|
||
### Task 10: Extract database entities to manage-db
|
||
|
||
**Files:**
|
||
- Move: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/*` to `novalon-manage-api/manage-db/src/main/java/cn/novalon/manage/db/entity/`
|
||
- Move: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/repository/*` to `novalon-manage-api/manage-db/src/main/java/cn/novalon/manage/db/repository/`
|
||
|
||
**Step 1: Move entity classes**
|
||
|
||
Run: `mkdir -p novalon-manage-api/manage-db/src/main/java/cn/novalon/manage/db/entity`
|
||
|
||
Run: `mv novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/entity/* novalon-manage-api/manage-db/src/main/java/cn/novalon/manage/db/entity/`
|
||
|
||
**Step 2: Update entity package declarations**
|
||
|
||
For each entity file in manage-db/entity, update package declaration:
|
||
|
||
From: `package cn.novalon.manage.sys.infrastructure.db.entity;`
|
||
To: `package cn.novalon.manage.db.entity;`
|
||
|
||
**Step 3: Move repository interfaces**
|
||
|
||
Run: `mkdir -p novalon-manage-api/manage-db/src/main/java/cn/novalon/manage/db/repository`
|
||
|
||
Run: `mv novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/infrastructure/db/repository/* novalon-manage-api/manage-db/src/main/java/cn/novalon/manage/db/repository/`
|
||
|
||
**Step 4: Update repository package declarations**
|
||
|
||
For each repository file in manage-db/repository, update package declaration:
|
||
|
||
From: `package cn.novalon.manage.sys.infrastructure.db.repository;`
|
||
To: `package cn.novalon.manage.db.repository;`
|
||
|
||
**Step 5: Update imports in manage-sys**
|
||
|
||
Find all files in manage-sys that import entities or repositories and update imports:
|
||
|
||
```bash
|
||
cd novalon-manage-api/manage-sys
|
||
find src -name "*.java" -exec grep -l "cn.novalon.manage.sys.infrastructure.db" {} \;
|
||
```
|
||
|
||
Update imports from:
|
||
- `import cn.novalon.manage.sys.infrastructure.db.entity.*;` to `import cn.novalon.manage.db.entity.*;`
|
||
- `import cn.novalon.manage.sys.infrastructure.db.repository.*;` to `import cn.novalon.manage.db.repository.*;`
|
||
|
||
**Step 6: Compile and verify**
|
||
|
||
Run: `cd novalon-manage-api && mvn clean compile`
|
||
|
||
Expected: BUILD SUCCESS
|
||
|
||
**Step 7: Commit**
|
||
|
||
```bash
|
||
git add novalon-manage-api/manage-db/ novalon-manage-api/manage-sys/
|
||
git commit -m "refactor: extract database entities to manage-db"
|
||
```
|
||
|
||
---
|
||
|
||
### Task 11: Refactor manage-sys module
|
||
|
||
**Files:**
|
||
- Modify: `novalon-manage-api/manage-sys/pom.xml`
|
||
- Modify: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/ManageSysApplication.java`
|
||
|
||
**Step 1: Update manage-sys pom.xml dependencies**
|
||
|
||
Read: `novalon-manage-api/manage-sys/pom.xml`
|
||
|
||
Replace dependencies section with:
|
||
|
||
```xml
|
||
<dependencies>
|
||
<dependency>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>manage-db</artifactId>
|
||
<version>${project.version}</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>cn.novalon.manage</groupId>
|
||
<artifactId>manage-common</artifactId>
|
||
<version>${project.version}</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-validation</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.springdoc</groupId>
|
||
<artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-test</artifactId>
|
||
<scope>test</scope>
|
||
</dependency>
|
||
</dependencies>
|
||
```
|
||
|
||
**Step 2: Update ManageSysApplication.java**
|
||
|
||
Read: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/ManageSysApplication.java`
|
||
|
||
Update package scan to include new packages:
|
||
|
||
```java
|
||
package cn.novalon.manage.sys;
|
||
|
||
import org.springframework.boot.SpringApplication;
|
||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
|
||
import org.springframework.context.annotation.ComponentScan;
|
||
|
||
@SpringBootApplication
|
||
@ConfigurationPropertiesScan(basePackages = "cn.novalon.manage")
|
||
@ComponentScan(basePackages = "cn.novalon.manage")
|
||
public class ManageSysApplication {
|
||
|
||
public static void main(String[] args) {
|
||
SpringApplication.run(ManageSysApplication.class, args);
|
||
}
|
||
}
|
||
```
|
||
|
||
**Step 3: Compile and verify**
|
||
|
||
Run: `cd novalon-manage-api && mvn clean compile -pl manage-sys -am`
|
||
|
||
Expected: BUILD SUCCESS
|
||
|
||
**Step 4: Commit**
|
||
|
||
```bash
|
||
git add novalon-manage-api/manage-sys/
|
||
git commit -m "refactor: update manage-sys module dependencies"
|
||
```
|
||
|
||
---
|
||
|
||
### Task 12: Migrate audit functionality to manage-audit
|
||
|
||
**Files:**
|
||
- Move: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/log/SysLogHandler.java` to `novalon-manage-api/manage-audit/src/main/java/cn/novalon/manage/audit/handler/`
|
||
- Move: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/OperationLogService.java` to `novalon-manage-api/manage-audit/src/main/java/cn/novalon/manage/audit/service/impl/`
|
||
- Move: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysLoginLogService.java` to `novalon-manage-api/manage-audit/src/main/java/cn/novalon/manage/audit/service/impl/`
|
||
- Move: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysExceptionLogService.java` to `novalon-manage-api/manage-audit/src/main/java/cn/novalon/manage/audit/service/impl/`
|
||
|
||
**Step 1: Move audit handlers**
|
||
|
||
Run: `mkdir -p novalon-manage-api/manage-audit/src/main/java/cn/novalon/manage/audit/handler`
|
||
|
||
Run: `mv novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/log/SysLogHandler.java novalon-manage-api/manage-audit/src/main/java/cn/novalon/manage/audit/handler/`
|
||
|
||
**Step 2: Move audit services**
|
||
|
||
Run: `mkdir -p novalon-manage-api/manage-audit/src/main/java/cn/novalon/manage/audit/service/impl`
|
||
|
||
Run: `mv novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/OperationLogService.java novalon-manage-api/manage-audit/src/main/java/cn/novalon/manage/audit/service/impl/`
|
||
|
||
Run: `mv novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysLoginLogService.java novalon-manage-api/manage-audit/src/main/java/cn/novalon/manage/audit/service/impl/`
|
||
|
||
Run: `mv novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysExceptionLogService.java novalon-manage-api/manage-audit/src/main/java/cn/novalon/manage/audit/service/impl/`
|
||
|
||
**Step 3: Update package declarations**
|
||
|
||
For each moved file, update package declaration:
|
||
|
||
From: `package cn.novalon.manage.sys.handler.log;` to `package cn.novalon.manage.audit.handler;`
|
||
From: `package cn.novalon.manage.sys.core.service.impl;` to `package cn.novalon.manage.audit.service.impl;`
|
||
|
||
**Step 4: Compile and verify**
|
||
|
||
Run: `cd novalon-manage-api && mvn clean compile -pl manage-audit -am`
|
||
|
||
Expected: BUILD SUCCESS
|
||
|
||
**Step 5: Commit**
|
||
|
||
```bash
|
||
git add novalon-manage-api/manage-audit/ novalon-manage-api/manage-sys/
|
||
git commit -m "refactor: migrate audit functionality to manage-audit"
|
||
```
|
||
|
||
---
|
||
|
||
### Task 13: Migrate notify functionality to manage-notify
|
||
|
||
**Files:**
|
||
- Move: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/notice/SysNoticeHandler.java` to `novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/handler/`
|
||
- Move: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/message/SysUserMessageHandler.java` to `novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/handler/`
|
||
- Move: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysNoticeService.java` to `novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/service/impl/`
|
||
- Move: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysUserMessageService.java` to `novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/service/impl/`
|
||
- Move: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/WebSocketServiceImpl.java` to `novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/service/impl/`
|
||
- Move: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/WebSocketConfig.java` to `novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/config/`
|
||
|
||
**Step 1: Move notify handlers**
|
||
|
||
Run: `mkdir -p novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/handler`
|
||
|
||
Run: `mv novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/notice/SysNoticeHandler.java novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/handler/`
|
||
|
||
Run: `mv novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/message/SysUserMessageHandler.java novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/handler/`
|
||
|
||
**Step 2: Move notify services**
|
||
|
||
Run: `mkdir -p novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/service/impl`
|
||
|
||
Run: `mv novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysNoticeService.java novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/service/impl/`
|
||
|
||
Run: `mv novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysUserMessageService.java novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/service/impl/`
|
||
|
||
Run: `mv novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/WebSocketServiceImpl.java novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/service/impl/`
|
||
|
||
**Step 3: Move notify config**
|
||
|
||
Run: `mkdir -p novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/config`
|
||
|
||
Run: `mv novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/WebSocketConfig.java novalon-manage-api/manage-notify/src/main/java/cn/novalon/manage/notify/config/`
|
||
|
||
**Step 4: Update package declarations**
|
||
|
||
For each moved file, update package declaration:
|
||
|
||
From: `package cn.novalon.manage.sys.handler.notice;` to `package cn.novalon.manage.notify.handler;`
|
||
From: `package cn.novalon.manage.sys.handler.message;` to `package cn.novalon.manage.notify.handler;`
|
||
From: `package cn.novalon.manage.sys.core.service.impl;` to `package cn.novalon.manage.notify.service.impl;`
|
||
From: `package cn.novalon.manage.sys.config;` to `package cn.novalon.manage.notify.config;`
|
||
|
||
**Step 5: Compile and verify**
|
||
|
||
Run: `cd novalon-manage-api && mvn clean compile -pl manage-notify -am`
|
||
|
||
Expected: BUILD SUCCESS
|
||
|
||
**Step 6: Commit**
|
||
|
||
```bash
|
||
git add novalon-manage-api/manage-notify/ novalon-manage-api/manage-sys/
|
||
git commit -m "refactor: migrate notify functionality to manage-notify"
|
||
```
|
||
|
||
---
|
||
|
||
### Task 14: Migrate file functionality to manage-file
|
||
|
||
**Files:**
|
||
- Move: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/file/SysFileHandler.java` to `novalon-manage-api/manage-file/src/main/java/cn/novalon/manage/file/handler/`
|
||
- Move: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysFileService.java` to `novalon-manage-api/manage-file/src/main/java/cn/novalon/manage/file/service/impl/`
|
||
- Move: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/MultipartConfig.java` to `novalon-manage-api/manage-file/src/main/java/cn/novalon/manage/file/config/`
|
||
|
||
**Step 1: Move file handler**
|
||
|
||
Run: `mkdir -p novalon-manage-api/manage-file/src/main/java/cn/novalon/manage/file/handler`
|
||
|
||
Run: `mv novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/file/SysFileHandler.java novalon-manage-api/manage-file/src/main/java/cn/novalon/manage/file/handler/`
|
||
|
||
**Step 2: Move file service**
|
||
|
||
Run: `mkdir -p novalon-manage-api/manage-file/src/main/java/cn/novalon/manage/file/service/impl`
|
||
|
||
Run: `mv novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysFileService.java novalon-manage-api/manage-file/src/main/java/cn/novalon/manage/file/service/impl/`
|
||
|
||
**Step 3: Move file config**
|
||
|
||
Run: `mkdir -p novalon-manage-api/manage-file/src/main/java/cn/novalon/manage/file/config`
|
||
|
||
Run: `mv novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/config/MultipartConfig.java novalon-manage-api/manage-file/src/main/java/cn/novalon/manage/file/config/`
|
||
|
||
**Step 4: Update package declarations**
|
||
|
||
For each moved file, update package declaration:
|
||
|
||
From: `package cn.novalon.manage.sys.handler.file;` to `package cn.novalon.manage.file.handler;`
|
||
From: `package cn.novalon.manage.sys.core.service.impl;` to `package cn.novalon.manage.file.service.impl;`
|
||
From: `package cn.novalon.manage.sys.config;` to `package cn.novalon.manage.file.config;`
|
||
|
||
**Step 5: Compile and verify**
|
||
|
||
Run: `cd novalon-manage-api && mvn clean compile -pl manage-file -am`
|
||
|
||
Expected: BUILD SUCCESS
|
||
|
||
**Step 6: Commit**
|
||
|
||
```bash
|
||
git add novalon-manage-api/manage-file/ novalon-manage-api/manage-sys/
|
||
git commit -m "refactor: migrate file functionality to manage-file"
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 3: Gateway and Application Layer (2-3 days)
|
||
|
||
### Task 15: Implement JWT authentication filter in manage-gateway
|
||
|
||
**Files:**
|
||
- Create: `novalon-manage-api/manage-gateway/src/main/java/cn/novalon/manage/gateway/filter/JwtAuthenticationFilter.java`
|
||
- Create: `novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/util/JwtTokenProvider.java`
|
||
- Create: `novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/dto/JwtUser.java`
|
||
|
||
**Step 1: Create JwtUser DTO**
|
||
|
||
Create: `novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/dto/JwtUser.java`
|
||
|
||
```java
|
||
package cn.novalon.manage.common.dto;
|
||
|
||
import lombok.AllArgsConstructor;
|
||
import lombok.Data;
|
||
import lombok.NoArgsConstructor;
|
||
|
||
import java.util.List;
|
||
|
||
@Data
|
||
@NoArgsConstructor
|
||
@AllArgsConstructor
|
||
public class JwtUser {
|
||
private String userId;
|
||
private String username;
|
||
private List<String> roles;
|
||
private List<String> permissions;
|
||
}
|
||
```
|
||
|
||
**Step 2: Create JwtTokenProvider**
|
||
|
||
Create: `novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/util/JwtTokenProvider.java`
|
||
|
||
```java
|
||
package cn.novalon.manage.common.util;
|
||
|
||
import cn.novalon.manage.common.config.JwtProperties;
|
||
import cn.novalon.manage.common.dto.JwtUser;
|
||
import io.jsonwebtoken.Claims;
|
||
import io.jsonwebtoken.Jwts;
|
||
import io.jsonwebtoken.security.Keys;
|
||
import org.springframework.stereotype.Component;
|
||
|
||
import javax.crypto.SecretKey;
|
||
import java.util.Date;
|
||
import java.util.List;
|
||
|
||
@Component
|
||
public class JwtTokenProvider {
|
||
|
||
private final JwtProperties jwtProperties;
|
||
private final SecretKey key;
|
||
|
||
public JwtTokenProvider(JwtProperties jwtProperties) {
|
||
this.jwtProperties = jwtProperties;
|
||
this.key = Keys.hmacShaKeyFor(jwtProperties.getSecret().getBytes());
|
||
}
|
||
|
||
public String generateToken(JwtUser user) {
|
||
Date now = new Date();
|
||
Date expiryDate = new Date(now.getTime() + jwtProperties.getExpiration() * 1000);
|
||
|
||
return Jwts.builder()
|
||
.subject(user.getUserId())
|
||
.claim("username", user.getUsername())
|
||
.claim("roles", user.getRoles())
|
||
.claim("permissions", user.getPermissions())
|
||
.issuedAt(now)
|
||
.expiration(expiryDate)
|
||
.signWith(key)
|
||
.compact();
|
||
}
|
||
|
||
public JwtUser parseToken(String token) {
|
||
Claims claims = Jwts.parserBuilder()
|
||
.setSigningKey(key)
|
||
.build()
|
||
.parseClaimsJws(token)
|
||
.getBody();
|
||
|
||
JwtUser user = new JwtUser();
|
||
user.setUserId(claims.getSubject());
|
||
user.setUsername(claims.get("username", String.class));
|
||
user.setRoles(claims.get("roles", List.class));
|
||
user.setPermissions(claims.get("permissions", List.class));
|
||
|
||
return user;
|
||
}
|
||
|
||
public boolean validateToken(String token) {
|
||
try {
|
||
Jwts.parserBuilder()
|
||
.setSigningKey(key)
|
||
.build()
|
||
.parseClaimsJws(token);
|
||
return true;
|
||
} catch (Exception e) {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**Step 3: Create JwtAuthenticationFilter**
|
||
|
||
Create: `novalon-manage-api/manage-gateway/src/main/java/cn/novalon/manage/gateway/filter/JwtAuthenticationFilter.java`
|
||
|
||
```java
|
||
package cn.novalon.manage.gateway.filter;
|
||
|
||
import cn.novalon.manage.common.dto.JwtUser;
|
||
import cn.novalon.manage.common.util.JwtTokenProvider;
|
||
import org.springframework.cloud.gateway.filter.GatewayFilter;
|
||
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
|
||
import org.springframework.http.HttpHeaders;
|
||
import org.springframework.http.HttpStatus;
|
||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||
import org.springframework.stereotype.Component;
|
||
import org.springframework.web.server.ServerWebExchange;
|
||
import reactor.core.publisher.Mono;
|
||
|
||
@Component
|
||
public class JwtAuthenticationFilter extends AbstractGatewayFilterFactory<JwtAuthenticationFilter.Config> {
|
||
|
||
private final JwtTokenProvider jwtTokenProvider;
|
||
|
||
public JwtAuthenticationFilter(JwtTokenProvider jwtTokenProvider) {
|
||
super(Config.class);
|
||
this.jwtTokenProvider = jwtTokenProvider;
|
||
}
|
||
|
||
@Override
|
||
public GatewayFilter apply(Config config) {
|
||
return (exchange, chain) -> {
|
||
ServerHttpRequest request = exchange.getRequest();
|
||
String path = request.getPath().value();
|
||
|
||
if (isPublicPath(path)) {
|
||
return chain.filter(exchange);
|
||
}
|
||
|
||
String token = extractToken(request);
|
||
|
||
if (token == null || !jwtTokenProvider.validateToken(token)) {
|
||
return unauthorized(exchange.getResponse());
|
||
}
|
||
|
||
JwtUser user = jwtTokenProvider.parseToken(token);
|
||
addHeaders(exchange, user);
|
||
|
||
return chain.filter(exchange);
|
||
};
|
||
}
|
||
|
||
private boolean isPublicPath(String path) {
|
||
return path.startsWith("/api/auth/login") || path.startsWith("/api/auth/register");
|
||
}
|
||
|
||
private String extractToken(ServerHttpRequest request) {
|
||
String bearerToken = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
|
||
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
|
||
return bearerToken.substring(7);
|
||
}
|
||
return null;
|
||
}
|
||
|
||
private void addHeaders(ServerWebExchange exchange, JwtUser user) {
|
||
ServerHttpRequest mutatedRequest = exchange.getRequest().mutate()
|
||
.header("X-User-Id", user.getUserId())
|
||
.header("X-User-Username", user.getUsername())
|
||
.header("X-User-Roles", String.join(",", user.getRoles()))
|
||
.header("X-User-Permissions", String.join(",", user.getPermissions()))
|
||
.build();
|
||
|
||
exchange.mutate().request(mutatedRequest).build();
|
||
}
|
||
|
||
private Mono<Void> unauthorized(ServerHttpResponse response) {
|
||
response.setStatusCode(HttpStatus.UNAUTHORIZED);
|
||
return response.setComplete();
|
||
}
|
||
|
||
public static class Config {
|
||
}
|
||
}
|
||
```
|
||
|
||
**Step 4: Compile and verify**
|
||
|
||
Run: `cd novalon-manage-api && mvn clean compile -pl manage-gateway,manage-common -am`
|
||
|
||
Expected: BUILD SUCCESS
|
||
|
||
**Step 5: Commit**
|
||
|
||
```bash
|
||
git add novalon-manage-api/manage-gateway/ novalon-manage-api/manage-common/
|
||
git commit -m "feat: implement JWT authentication filter in manage-gateway"
|
||
```
|
||
|
||
---
|
||
|
||
### Task 16: Implement RBAC authorization filter in manage-gateway
|
||
|
||
**Files:**
|
||
- Create: `novalon-manage-api/manage-gateway/src/main/java/cn/novalon/manage/gateway/filter/RbacAuthorizationFilter.java`
|
||
- Create: `novalon-manage-api/manage-gateway/src/main/java/cn/novalon/manage/gateway/config/PermissionConfig.java`
|
||
|
||
**Step 1: Create PermissionConfig**
|
||
|
||
Create: `novalon-manage-api/manage-gateway/src/main/java/cn/novalon/manage/gateway/config/PermissionConfig.java`
|
||
|
||
```java
|
||
package cn.novalon.manage.gateway.config;
|
||
|
||
import org.springframework.context.annotation.Configuration;
|
||
|
||
import java.util.HashMap;
|
||
import java.util.Map;
|
||
|
||
@Configuration
|
||
public class PermissionConfig {
|
||
|
||
public static final Map<String, String> PATH_PERMISSIONS = new HashMap<>();
|
||
|
||
static {
|
||
PATH_PERMISSIONS.put("/api/sys/users", "user:read");
|
||
PATH_PERMISSIONS.put("/api/sys/users/**", "user:write");
|
||
PATH_PERMISSIONS.put("/api/sys/roles", "role:read");
|
||
PATH_PERMISSIONS.put("/api/sys/roles/**", "role:write");
|
||
PATH_PERMISSIONS.put("/api/sys/menus", "menu:read");
|
||
PATH_PERMISSIONS.put("/api/sys/menus/**", "menu:write");
|
||
PATH_PERMISSIONS.put("/api/sys/config", "config:read");
|
||
PATH_PERMISSIONS.put("/api/sys/config/**", "config:write");
|
||
PATH_PERMISSIONS.put("/api/audit/logs", "audit:read");
|
||
PATH_PERMISSIONS.put("/api/notify/notices", "notice:read");
|
||
PATH_PERMISSIONS.put("/api/notify/notices/**", "notice:write");
|
||
PATH_PERMISSIONS.put("/api/file/files", "file:read");
|
||
PATH_PERMISSIONS.put("/api/file/files/**", "file:write");
|
||
}
|
||
|
||
public static String getRequiredPermission(String path, String method) {
|
||
String permissionKey = path;
|
||
if (!PATH_PERMISSIONS.containsKey(path)) {
|
||
permissionKey = path.substring(0, path.lastIndexOf('/'));
|
||
}
|
||
return PATH_PERMISSIONS.get(permissionKey);
|
||
}
|
||
}
|
||
```
|
||
|
||
**Step 2: Create RbacAuthorizationFilter**
|
||
|
||
Create: `novalon-manage-api/manage-gateway/src/main/java/cn/novalon/manage/gateway/filter/RbacAuthorizationFilter.java`
|
||
|
||
```java
|
||
package cn.novalon.manage.gateway.filter;
|
||
|
||
import cn.novalon.manage.gateway.config.PermissionConfig;
|
||
import org.springframework.cloud.gateway.filter.GatewayFilter;
|
||
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
|
||
import org.springframework.http.HttpStatus;
|
||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||
import org.springframework.stereotype.Component;
|
||
import org.springframework.web.server.ServerWebExchange;
|
||
import reactor.core.publisher.Mono;
|
||
|
||
import java.util.Arrays;
|
||
import java.util.List;
|
||
|
||
@Component
|
||
public class RbacAuthorizationFilter extends AbstractGatewayFilterFactory<RbacAuthorizationFilter.Config> {
|
||
|
||
@Override
|
||
public GatewayFilter apply(Config config) {
|
||
return (exchange, chain) -> {
|
||
ServerHttpRequest request = exchange.getRequest();
|
||
String path = request.getPath().value();
|
||
String method = request.getMethod().name();
|
||
|
||
if (isPublicPath(path)) {
|
||
return chain.filter(exchange);
|
||
}
|
||
|
||
List<String> permissions = request.getHeaders().get("X-User-Permissions");
|
||
List<String> roles = request.getHeaders().get("X-User-Roles");
|
||
|
||
if (permissions == null || roles == null) {
|
||
return forbidden(exchange.getResponse());
|
||
}
|
||
|
||
String requiredPermission = PermissionConfig.getRequiredPermission(path, method);
|
||
|
||
if (requiredPermission != null && !hasPermission(permissions, requiredPermission)) {
|
||
return forbidden(exchange.getResponse());
|
||
}
|
||
|
||
return chain.filter(exchange);
|
||
};
|
||
}
|
||
|
||
private boolean isPublicPath(String path) {
|
||
return path.startsWith("/api/auth/login") || path.startsWith("/api/auth/register");
|
||
}
|
||
|
||
private boolean hasPermission(List<String> permissions, String requiredPermission) {
|
||
return permissions.contains(requiredPermission) || permissions.contains("*:*");
|
||
}
|
||
|
||
private Mono<Void> forbidden(ServerHttpResponse response) {
|
||
response.setStatusCode(HttpStatus.FORBIDDEN);
|
||
return response.setComplete();
|
||
}
|
||
|
||
public static class Config {
|
||
}
|
||
}
|
||
```
|
||
|
||
**Step 3: Update GatewayApplication to register filters**
|
||
|
||
Read: `novalon-manage-api/manage-gateway/src/main/java/cn/novalon/manage/gateway/GatewayApplication.java`
|
||
|
||
Update to include filters:
|
||
|
||
```java
|
||
package cn.novalon.manage.gateway;
|
||
|
||
import cn.novalon.manage.gateway.filter.JwtAuthenticationFilter;
|
||
import cn.novalon.manage.gateway.filter.RbacAuthorizationFilter;
|
||
import org.springframework.boot.SpringApplication;
|
||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||
import org.springframework.cloud.gateway.route.RouteLocator;
|
||
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
|
||
import org.springframework.context.annotation.Bean;
|
||
|
||
@SpringBootApplication
|
||
public class GatewayApplication {
|
||
|
||
public static void main(String[] args) {
|
||
SpringApplication.run(GatewayApplication.class, args);
|
||
}
|
||
|
||
@Bean
|
||
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
|
||
return builder.routes()
|
||
.route("manage-app", r -> r
|
||
.path("/api/**")
|
||
.filters(f -> f
|
||
.filter(new JwtAuthenticationFilter.Config())
|
||
.filter(new RbacAuthorizationFilter.Config()))
|
||
.uri("http://manage-app:8081"))
|
||
.build();
|
||
}
|
||
}
|
||
```
|
||
|
||
**Step 4: Compile and verify**
|
||
|
||
Run: `cd novalon-manage-api && mvn clean compile -pl manage-gateway -am`
|
||
|
||
Expected: BUILD SUCCESS
|
||
|
||
**Step 5: Commit**
|
||
|
||
```bash
|
||
git add novalon-manage-api/manage-gateway/
|
||
git commit -m "feat: implement RBAC authorization filter in manage-gateway"
|
||
```
|
||
|
||
---
|
||
|
||
### Task 17: Configure Caffeine cache in manage-common
|
||
|
||
**Files:**
|
||
- Create: `novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/config/CacheConfig.java`
|
||
- Create: `novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/service/TokenBlacklistService.java`
|
||
|
||
**Step 1: Create CacheConfig**
|
||
|
||
Create: `novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/config/CacheConfig.java`
|
||
|
||
```java
|
||
package cn.novalon.manage.common.config;
|
||
|
||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||
import org.springframework.cache.CacheManager;
|
||
import org.springframework.cache.annotation.EnableCaching;
|
||
import org.springframework.cache.caffeine.CaffeineCacheManager;
|
||
import org.springframework.context.annotation.Bean;
|
||
import org.springframework.context.annotation.Configuration;
|
||
|
||
import java.util.concurrent.TimeUnit;
|
||
|
||
@Configuration
|
||
@EnableCaching
|
||
public class CacheConfig {
|
||
|
||
@Bean
|
||
public CacheManager cacheManager() {
|
||
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
|
||
cacheManager.setCaffeine(caffeineCacheBuilder());
|
||
return cacheManager;
|
||
}
|
||
|
||
@Bean
|
||
public com.github.benmanes.caffeine.cache.Cache<Object, Object> caffeineCache() {
|
||
return Caffeine.newBuilder()
|
||
.maximumSize(10000)
|
||
.expireAfterWrite(10, TimeUnit.MINUTES)
|
||
.build();
|
||
}
|
||
|
||
private Caffeine<Object, Object> caffeineCacheBuilder() {
|
||
return Caffeine.newBuilder()
|
||
.maximumSize(10000)
|
||
.expireAfterWrite(10, TimeUnit.MINUTES);
|
||
}
|
||
}
|
||
```
|
||
|
||
**Step 2: Create TokenBlacklistService**
|
||
|
||
Create: `novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/service/TokenBlacklistService.java`
|
||
|
||
```java
|
||
package cn.novalon.manage.common.service;
|
||
|
||
import com.github.benmanes.caffeine.cache.Cache;
|
||
import org.springframework.stereotype.Service;
|
||
|
||
import java.util.concurrent.TimeUnit;
|
||
|
||
@Service
|
||
public class TokenBlacklistService {
|
||
|
||
private final Cache<String, Boolean> tokenBlacklistCache;
|
||
|
||
public TokenBlacklistService() {
|
||
this.tokenBlacklistCache = com.github.benmanes.caffeine.cache.Caffeine.newBuilder()
|
||
.maximumSize(10000)
|
||
.expireAfterWrite(2, TimeUnit.HOURS)
|
||
.build();
|
||
}
|
||
|
||
public void addToBlacklist(String tokenId) {
|
||
tokenBlacklistCache.put(tokenId, true);
|
||
}
|
||
|
||
public boolean isBlacklisted(String tokenId) {
|
||
return tokenBlacklistCache.getIfPresent(tokenId) != null;
|
||
}
|
||
}
|
||
```
|
||
|
||
**Step 3: Compile and verify**
|
||
|
||
Run: `cd novalon-manage-api && mvn clean compile -pl manage-common -am`
|
||
|
||
Expected: BUILD SUCCESS
|
||
|
||
**Step 4: Commit**
|
||
|
||
```bash
|
||
git add novalon-manage-api/manage-common/
|
||
git commit -m "feat: configure Caffeine cache in manage-common"
|
||
```
|
||
|
||
---
|
||
|
||
### Task 18: Create Docker Compose configuration
|
||
|
||
**Files:**
|
||
- Create: `novalon-manage-system/docker-compose.yml`
|
||
- Create: `novalon-manage-system/.env.example`
|
||
|
||
**Step 1: Create docker-compose.yml**
|
||
|
||
Create: `novalon-manage-system/docker-compose.yml`
|
||
|
||
```yaml
|
||
version: '3.8'
|
||
|
||
services:
|
||
postgres:
|
||
image: postgres:15-alpine
|
||
container_name: novalon-postgres
|
||
environment:
|
||
POSTGRES_DB: novalon_manage
|
||
POSTGRES_USER: ${DB_USERNAME:-postgres}
|
||
POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
|
||
ports:
|
||
- "5432:5432"
|
||
volumes:
|
||
- postgres_data:/var/lib/postgresql/data
|
||
- ./docs/sql:/docker-entrypoint-initdb.d
|
||
networks:
|
||
- novalon-network
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 5
|
||
|
||
manage-gateway:
|
||
build:
|
||
context: ./novalon-manage-api
|
||
dockerfile: manage-gateway/Dockerfile
|
||
container_name: novalon-gateway
|
||
ports:
|
||
- "8080:8080"
|
||
environment:
|
||
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-prod}
|
||
JWT_SECRET: ${JWT_SECRET}
|
||
JWT_EXPIRATION: ${JWT_EXPIRATION:-7200}
|
||
APP_SERVICE_URL: http://manage-app:8081
|
||
depends_on:
|
||
manage-app:
|
||
condition: service_healthy
|
||
networks:
|
||
- novalon-network
|
||
healthcheck:
|
||
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
|
||
manage-app:
|
||
build:
|
||
context: ./novalon-manage-api
|
||
dockerfile: manage-app/Dockerfile
|
||
container_name: novalon-app
|
||
ports:
|
||
- "8081:8081"
|
||
environment:
|
||
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-prod}
|
||
DB_HOST: postgres
|
||
DB_PORT: 5432
|
||
DB_NAME: novalon_manage
|
||
DB_USERNAME: ${DB_USERNAME:-postgres}
|
||
DB_PASSWORD: ${DB_PASSWORD:-postgres}
|
||
JWT_SECRET: ${JWT_SECRET}
|
||
depends_on:
|
||
postgres:
|
||
condition: service_healthy
|
||
networks:
|
||
- novalon-network
|
||
healthcheck:
|
||
test: ["CMD", "curl", "-f", "http://localhost:8081/actuator/health"]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
|
||
volumes:
|
||
postgres_data:
|
||
|
||
networks:
|
||
novalon-network:
|
||
driver: bridge
|
||
```
|
||
|
||
**Step 2: Create .env.example**
|
||
|
||
Create: `novalon-manage-system/.env.example`
|
||
|
||
```bash
|
||
# Database Configuration
|
||
DB_USERNAME=postgres
|
||
DB_PASSWORD=your_secure_password
|
||
|
||
# JWT Configuration
|
||
JWT_SECRET=your_jwt_secret_key_minimum_256_bits
|
||
JWT_EXPIRATION=7200
|
||
|
||
# Spring Profile
|
||
SPRING_PROFILES_ACTIVE=prod
|
||
```
|
||
|
||
**Step 3: Commit**
|
||
|
||
```bash
|
||
git add novalon-manage-system/docker-compose.yml novalon-manage-system/.env.example
|
||
git commit -m "feat: add Docker Compose configuration"
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 4: Testing and Optimization (2-3 days)
|
||
|
||
### Task 19: Write unit tests for manage-common
|
||
|
||
**Files:**
|
||
- Create: `novalon-manage-api/manage-common/src/test/java/cn/novalon/manage/common/util/JwtTokenProviderTest.java`
|
||
- Create: `novalon-manage-api/manage-common/src/test/java/cn/novalon/manage/common/service/TokenBlacklistServiceTest.java`
|
||
|
||
**Step 1: Write JwtTokenProviderTest**
|
||
|
||
Create: `novalon-manage-api/manage-common/src/test/java/cn/novalon/manage/common/util/JwtTokenProviderTest.java`
|
||
|
||
```java
|
||
package cn.novalon.manage.common.util;
|
||
|
||
import cn.novalon.manage.common.config.JwtProperties;
|
||
import cn.novalon.manage.common.dto.JwtUser;
|
||
import org.junit.jupiter.api.BeforeEach;
|
||
import org.junit.jupiter.api.Test;
|
||
|
||
import java.util.Arrays;
|
||
import java.util.List;
|
||
|
||
import static org.junit.jupiter.api.Assertions.*;
|
||
|
||
class JwtTokenProviderTest {
|
||
|
||
private JwtTokenProvider jwtTokenProvider;
|
||
private JwtProperties jwtProperties;
|
||
|
||
@BeforeEach
|
||
void setUp() {
|
||
jwtProperties = new JwtProperties();
|
||
jwtProperties.setSecret("test-secret-key-for-testing-purposes-only");
|
||
jwtProperties.setExpiration(7200);
|
||
jwtTokenProvider = new JwtTokenProvider(jwtProperties);
|
||
}
|
||
|
||
@Test
|
||
void testGenerateToken() {
|
||
JwtUser user = new JwtUser();
|
||
user.setUserId("user123");
|
||
user.setUsername("testuser");
|
||
user.setRoles(Arrays.asList("ADMIN"));
|
||
user.setPermissions(Arrays.asList("user:read", "user:write"));
|
||
|
||
String token = jwtTokenProvider.generateToken(user);
|
||
|
||
assertNotNull(token);
|
||
assertFalse(token.isEmpty());
|
||
}
|
||
|
||
@Test
|
||
void testParseToken() {
|
||
JwtUser originalUser = new JwtUser();
|
||
originalUser.setUserId("user123");
|
||
originalUser.setUsername("testuser");
|
||
originalUser.setRoles(Arrays.asList("ADMIN"));
|
||
originalUser.setPermissions(Arrays.asList("user:read", "user:write"));
|
||
|
||
String token = jwtTokenProvider.generateToken(originalUser);
|
||
JwtUser parsedUser = jwtTokenProvider.parseToken(token);
|
||
|
||
assertEquals(originalUser.getUserId(), parsedUser.getUserId());
|
||
assertEquals(originalUser.getUsername(), parsedUser.getUsername());
|
||
assertEquals(originalUser.getRoles(), parsedUser.getRoles());
|
||
assertEquals(originalUser.getPermissions(), parsedUser.getPermissions());
|
||
}
|
||
|
||
@Test
|
||
void testValidateToken() {
|
||
JwtUser user = new JwtUser();
|
||
user.setUserId("user123");
|
||
user.setUsername("testuser");
|
||
user.setRoles(Arrays.asList("ADMIN"));
|
||
user.setPermissions(Arrays.asList("user:read"));
|
||
|
||
String validToken = jwtTokenProvider.generateToken(user);
|
||
assertTrue(jwtTokenProvider.validateToken(validToken));
|
||
|
||
String invalidToken = "invalid.token.here";
|
||
assertFalse(jwtTokenProvider.validateToken(invalidToken));
|
||
}
|
||
}
|
||
```
|
||
|
||
**Step 2: Write TokenBlacklistServiceTest**
|
||
|
||
Create: `novalon-manage-api/manage-common/src/test/java/cn/novalon/manage/common/service/TokenBlacklistServiceTest.java`
|
||
|
||
```java
|
||
package cn.novalon.manage.common.service;
|
||
|
||
import org.junit.jupiter.api.BeforeEach;
|
||
import org.junit.jupiter.api.Test;
|
||
|
||
import static org.junit.jupiter.api.Assertions.*;
|
||
|
||
class TokenBlacklistServiceTest {
|
||
|
||
private TokenBlacklistService tokenBlacklistService;
|
||
|
||
@BeforeEach
|
||
void setUp() {
|
||
tokenBlacklistService = new TokenBlacklistService();
|
||
}
|
||
|
||
@Test
|
||
void testAddToBlacklist() {
|
||
String tokenId = "token123";
|
||
tokenBlacklistService.addToBlacklist(tokenId);
|
||
|
||
assertTrue(tokenBlacklistService.isBlacklisted(tokenId));
|
||
}
|
||
|
||
@Test
|
||
void testIsBlacklisted() {
|
||
String tokenId = "token456";
|
||
assertFalse(tokenBlacklistService.isBlacklisted(tokenId));
|
||
|
||
tokenBlacklistService.addToBlacklist(tokenId);
|
||
assertTrue(tokenBlacklistService.isBlacklisted(tokenId));
|
||
}
|
||
|
||
@Test
|
||
void testMultipleTokens() {
|
||
String token1 = "token1";
|
||
String token2 = "token2";
|
||
String token3 = "token3";
|
||
|
||
tokenBlacklistService.addToBlacklist(token1);
|
||
tokenBlacklistService.addToBlacklist(token2);
|
||
tokenBlacklistService.addToBlacklist(token3);
|
||
|
||
assertTrue(tokenBlacklistService.isBlacklisted(token1));
|
||
assertTrue(tokenBlacklistService.isBlacklisted(token2));
|
||
assertTrue(tokenBlacklistService.isBlacklisted(token3));
|
||
}
|
||
}
|
||
```
|
||
|
||
**Step 3: Run tests**
|
||
|
||
Run: `cd novalon-manage-api && mvn test -pl manage-common`
|
||
|
||
Expected: All tests pass
|
||
|
||
**Step 4: Commit**
|
||
|
||
```bash
|