docs: add IDEA shadow deployment and rollback guide
This commit is contained in:
@@ -178,3 +178,15 @@ xss:
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
|
||||
# 影子算法默认关闭;现场测试仅通过 IDEA 环境变量显式开启
|
||||
fortucky:
|
||||
shadow:
|
||||
enabled: ${FORTUCKY_SHADOW_ENABLED:false}
|
||||
warehouse-id: ${FORTUCKY_SHADOW_WAREHOUSE_ID:}
|
||||
timeout-seconds: ${FORTUCKY_SHADOW_TIMEOUT_SECONDS:3}
|
||||
algorithm:
|
||||
mode: ${FORTUCKY_ALGORITHM_MODE:SHADOW}
|
||||
warehouse-id: ${FORTUCKY_ALGORITHM_WAREHOUSE_ID:01}
|
||||
database-writes-enabled: ${FORTUCKY_ALGORITHM_DATABASE_WRITES_ENABLED:true}
|
||||
legacy-fallback-on-technical-error: ${FORTUCKY_ALGORITHM_LEGACY_FALLBACK_ON_TECHNICAL_ERROR:false}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.ruoyi.algorithm.shadow;
|
||||
|
||||
import com.ruoyi.algorithm.integration.AlgorithmProperties;
|
||||
import com.ruoyi.algorithm.integration.SchedulingMode;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.context.properties.bind.Bindable;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.boot.env.YamlPropertySourceLoader;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class ShadowConfigurationTest {
|
||||
|
||||
@Test
|
||||
void applicationDefaultsKeepShadowDisabledAndReadyForExplicitShadowEnablement() throws IOException {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
Binder binder = applicationBinder(environment);
|
||||
|
||||
ShadowObservationProperties shadow = binder
|
||||
.bind("fortucky.shadow", Bindable.of(ShadowObservationProperties.class))
|
||||
.orElseThrow(() -> new IllegalStateException("fortucky.shadow configuration is missing"));
|
||||
AlgorithmProperties algorithm = binder
|
||||
.bind("fortucky.algorithm", Bindable.of(AlgorithmProperties.class))
|
||||
.orElseThrow(() -> new IllegalStateException("fortucky.algorithm configuration is missing"));
|
||||
|
||||
assertThat(shadow.isEnabled()).isFalse();
|
||||
assertThat(shadow.getWarehouseId()).isEmpty();
|
||||
assertThat(shadow.getTimeoutSeconds()).isEqualTo(3);
|
||||
assertThat(algorithm.getMode()).isEqualTo(SchedulingMode.SHADOW);
|
||||
assertThat(algorithm.isDatabaseWritesEnabled()).isTrue();
|
||||
assertThat(algorithm.getWarehouseId()).isEqualTo("01");
|
||||
}
|
||||
|
||||
@Test
|
||||
void standardLegacyFallbackEnvironmentVariableOverridesTheSafeDefault() throws IOException {
|
||||
MockEnvironment environment = new MockEnvironment()
|
||||
.withProperty("FORTUCKY_ALGORITHM_LEGACY_FALLBACK_ON_TECHNICAL_ERROR", "true");
|
||||
|
||||
AlgorithmProperties algorithm = applicationBinder(environment)
|
||||
.bind("fortucky.algorithm", Bindable.of(AlgorithmProperties.class))
|
||||
.orElseThrow(() -> new IllegalStateException("fortucky.algorithm configuration is missing"));
|
||||
|
||||
assertThat(algorithm.isLegacyFallbackOnTechnicalError()).isTrue();
|
||||
}
|
||||
|
||||
private Binder applicationBinder(MockEnvironment environment) throws IOException {
|
||||
MutablePropertySources propertySources = environment.getPropertySources();
|
||||
List<PropertySource<?>> yaml = new YamlPropertySourceLoader()
|
||||
.load("application", new ClassPathResource("application.yml"));
|
||||
yaml.forEach(propertySources::addLast);
|
||||
return Binder.get(environment);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user