feat: 发号器测试

main
13009 2024-07-26 20:19:01 +08:00
parent e3be3de77b
commit b6e4e4dd31
12 changed files with 248 additions and 46 deletions

View File

@ -15,11 +15,7 @@ public class DefaultSequencer implements Sequencer {
@Override
public String next() {
return String.format("%s%s%s", getCurrentDate(), getRandomStr(), getNumber());
}
private String getCurrentDate() {
return DateTimes.of("yyyyMMdd");
return String.format("%s%s%s", DateTimes.of("yyyyMMdd"), getRandomStr(), number.getAndIncrement());
}
private String getRandomStr() {
@ -30,8 +26,4 @@ public class DefaultSequencer implements Sequencer {
return sb.toString();
}
private Integer getNumber() {
return number.getAndIncrement();
}
}

View File

@ -11,6 +11,9 @@ import com.czcb.scfs.api.core.http.Proxy;
* @since 2.0.0
*/
public abstract class AbstractAutoConfiguration {
public static final String PREFIX = "scfs.api-gateway.cipher";
public static final String CIPHER_TYPE = "type";
protected abstract ScfsApiGatewayProperties getProperties();
protected HttpProfile getHttpProfile() {

View File

@ -1,8 +1,10 @@
package com.czcb.scfs.spring.boot.starter;
import com.czcb.scfs.api.core.cipher.Sequencer;
import com.czcb.scfs.api.core.cipher.StoreType;
import com.czcb.scfs.api.core.util.PemFile;
import com.czcb.scfs.api.rsa.RsaProfile;
import lombok.Getter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@ -16,22 +18,25 @@ import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.czcb.scfs.spring.boot.starter.AbstractAutoConfiguration.CIPHER_TYPE;
import static com.czcb.scfs.spring.boot.starter.AbstractAutoConfiguration.PREFIX;
/**
* @since 2.0.0
*/
@Getter
@Configuration
@ConditionalOnClass(RsaProfile.class)
@ConditionalOnProperty(value = "scfs.api-gateway.cipher.type", havingValue = "rsa")
@ConditionalOnProperty(prefix = PREFIX, value = CIPHER_TYPE, havingValue = RsaConfiguration.HAVING_VALUE)
public class RsaConfiguration extends AbstractAutoConfiguration {
public static final String HAVING_VALUE = "rsa";
private final ScfsApiGatewayProperties properties;
private final Sequencer sequencer;
public RsaConfiguration(ScfsApiGatewayProperties properties) {
public RsaConfiguration(ScfsApiGatewayProperties properties, Sequencer sequencer) {
this.properties = properties;
}
@Override
public ScfsApiGatewayProperties getProperties() {
return properties;
this.sequencer = sequencer;
}
private List<X509Certificate> getCertificates() {
@ -63,6 +68,7 @@ public class RsaConfiguration extends AbstractAutoConfiguration {
.httpProfile(getHttpProfile())
.privateKey(getPrivateKey())
.addCertificates(getCertificates())
.sequencer(getSequencer())
.build();
}
}

View File

@ -2,8 +2,6 @@ package com.czcb.scfs.spring.boot.starter;
import com.czcb.scfs.api.core.ApiClient;
import com.czcb.scfs.api.core.Profile;
import com.czcb.scfs.api.core.cipher.DefaultSequencer;
import com.czcb.scfs.api.core.cipher.Sequencer;
import com.czcb.scfs.api.core.http.ApiClientBuilder;
import com.czcb.scfs.api.service.echo.EchoService;
import com.czcb.scfs.api.service.v2.account.AccountService;
@ -25,7 +23,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import javax.annotation.Resource;
@ -35,7 +32,6 @@ import javax.annotation.Resource;
@Configuration
@ComponentScan("com.czcb.scfs.spring.boot.starter")
@EnableConfigurationProperties({ScfsApiGatewayProperties.class})
@Import({SmConfiguration.class, RsaConfiguration.class})
public class ScfsAutoConfiguration {
@Resource
private Profile profile;
@ -56,15 +52,6 @@ public class ScfsAutoConfiguration {
return new EchoService(apiClient);
}
/**
*
*/
@Bean
@ConditionalOnMissingBean
public Sequencer sequencer() {
return new DefaultSequencer();
}
/**
*
*/

View File

@ -0,0 +1,23 @@
package com.czcb.scfs.spring.boot.starter;
import com.czcb.scfs.api.core.cipher.DefaultSequencer;
import com.czcb.scfs.api.core.cipher.Sequencer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author wangwei
* @since 2024/7/26
*/
@Configuration
public class SequencerAutoConfiguration {
/**
*
*/
@Bean
@ConditionalOnMissingBean
public Sequencer sequencer() {
return new DefaultSequencer();
}
}

View File

@ -1,9 +1,11 @@
package com.czcb.scfs.spring.boot.starter;
import com.czcb.scfs.api.core.cipher.Sequencer;
import com.czcb.scfs.api.core.cipher.StoreType;
import com.czcb.scfs.api.core.util.PemFile;
import com.czcb.scfs.api.sm.SmProfile;
import com.tencent.kona.KonaProvider;
import lombok.Getter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@ -17,22 +19,26 @@ import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.czcb.scfs.spring.boot.starter.AbstractAutoConfiguration.CIPHER_TYPE;
import static com.czcb.scfs.spring.boot.starter.AbstractAutoConfiguration.PREFIX;
import static com.czcb.scfs.spring.boot.starter.SmConfiguration.HAVING_VALUE;
/**
* @since 2.0.0
*/
@Getter
@Configuration
@ConditionalOnClass(SmProfile.class)
@ConditionalOnProperty(value = "scfs.api-gateway.cipher.type", havingValue = "sm", matchIfMissing = true)
@ConditionalOnProperty(prefix = PREFIX, value = CIPHER_TYPE, havingValue = HAVING_VALUE, matchIfMissing = true)
public class SmConfiguration extends AbstractAutoConfiguration {
public static final String HAVING_VALUE = "sm";
private final ScfsApiGatewayProperties properties;
private final Sequencer sequencer;
public SmConfiguration(ScfsApiGatewayProperties properties) {
public SmConfiguration(ScfsApiGatewayProperties properties, Sequencer sequencer) {
this.properties = properties;
}
@Override
public ScfsApiGatewayProperties getProperties() {
return properties;
this.sequencer = sequencer;
}
private List<X509Certificate> getCertificates() {
@ -65,6 +71,7 @@ public class SmConfiguration extends AbstractAutoConfiguration {
.privateKey(getPrivateKey())
.certificateSerial(getChannelCertificateSerial())
.addCertificates(getCertificates())
.sequencer(getSequencer())
.build();
}
}

View File

@ -0,0 +1,12 @@
package com.czcb.scfs.spring.boot.starter;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
class AbstractAutoConfigurationTest {
@Test
void test() {
Assertions.assertEquals("scfs.api-gateway.cipher", AbstractAutoConfiguration.PREFIX);
Assertions.assertEquals("type", AbstractAutoConfiguration.CIPHER_TYPE);
}
}

View File

@ -1,14 +1,21 @@
package com.czcb.scfs.spring.boot.starter;
import com.czcb.scfs.api.core.cipher.DefaultSequencer;
import com.czcb.scfs.api.core.cipher.StoreType;
import com.czcb.scfs.api.core.http.LogLevel;
import com.czcb.scfs.api.rsa.RsaProfile;
import org.assertj.core.util.Lists;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
@ -16,6 +23,46 @@ class RsaConfigurationTest {
private RsaConfiguration rsaConfiguration;
@Test
void testHavingValue() {
Assertions.assertEquals("rsa", RsaConfiguration.HAVING_VALUE);
}
@Test
void testAnnotation() {
Annotation[] annotations = RsaConfiguration.class.getAnnotations();
Assertions.assertTrue(Arrays.stream(annotations).anyMatch(annotation -> annotation.annotationType().isAssignableFrom(Configuration.class)));
Assertions.assertTrue(Arrays.stream(annotations).anyMatch(annotation -> annotation.annotationType().isAssignableFrom(ConditionalOnClass.class)));
Assertions.assertTrue(Arrays.stream(annotations).anyMatch(annotation -> annotation.annotationType().isAssignableFrom(ConditionalOnProperty.class)));
Assertions.assertEquals(3, annotations.length);
}
@Test
void testConditionalOnClass() {
Annotation[] annotations = RsaConfiguration.class.getAnnotations();
Optional<Annotation> optional = Arrays.stream(annotations)
.filter(annotation -> annotation.annotationType().isAssignableFrom(ConditionalOnClass.class))
.findFirst();
Assertions.assertTrue(optional.isPresent());
Assertions.assertArrayEquals(new Class[]{RsaProfile.class}, ((ConditionalOnClass) optional.get()).value());
}
@Test
void testConditionalOnProperty() {
Annotation[] annotations = RsaConfiguration.class.getAnnotations();
Optional<Annotation> optional = Arrays.stream(annotations)
.filter(annotation -> annotation.annotationType().isAssignableFrom(ConditionalOnProperty.class))
.findFirst();
Assertions.assertTrue(optional.isPresent());
Assertions.assertFalse(((ConditionalOnProperty) optional.get()).matchIfMissing());
Assertions.assertArrayEquals(new String[]{"type"}, ((ConditionalOnProperty) optional.get()).value());
Assertions.assertEquals("scfs.api-gateway.cipher", ((ConditionalOnProperty) optional.get()).prefix());
Assertions.assertEquals("rsa", ((ConditionalOnProperty) optional.get()).havingValue());
}
private ScfsApiGatewayProperties properties() {
ScfsApiGatewayProperties properties = new ScfsApiGatewayProperties();
@ -63,14 +110,14 @@ class RsaConfigurationTest {
@Test
void getProperties() {
rsaConfiguration = new RsaConfiguration(properties());
rsaConfiguration = new RsaConfiguration(properties(), new DefaultSequencer());
ScfsApiGatewayProperties properties = rsaConfiguration.getProperties();
Assertions.assertNotNull(properties);
}
@Test
void smProfile() {
rsaConfiguration = new RsaConfiguration(properties());
rsaConfiguration = new RsaConfiguration(properties(), new DefaultSequencer());
RsaProfile profile = rsaConfiguration.rsaProfile();
Assertions.assertNotNull(profile);
assertThatJson("{\"appNo\":\"111111\",\"channelNo\":\"000000\",\"channelGroupMode\":false}").isEqualTo(profile.getChannel());

View File

@ -1,6 +1,7 @@
package com.czcb.scfs.spring.boot.starter;
import com.czcb.scfs.api.core.ApiClient;
import com.czcb.scfs.api.core.cipher.DefaultSequencer;
import com.czcb.scfs.api.core.cipher.StoreType;
import com.czcb.scfs.api.core.http.LogLevel;
import com.czcb.scfs.api.core.http.client.ApacheHttpclient;
@ -10,14 +11,50 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@ExtendWith(MockitoExtension.class)
class ScfsAutoConfigurationTest {
private final ScfsAutoConfiguration configuration = new ScfsAutoConfiguration();
@Test
void testAnnotation() {
Annotation[] annotations = ScfsAutoConfiguration.class.getAnnotations();
Assertions.assertTrue(Arrays.stream(annotations).anyMatch(annotation -> annotation.annotationType().isAssignableFrom(Configuration.class)));
Assertions.assertTrue(Arrays.stream(annotations).anyMatch(annotation -> annotation.annotationType().isAssignableFrom(ComponentScan.class)));
Assertions.assertTrue(Arrays.stream(annotations).anyMatch(annotation -> annotation.annotationType().isAssignableFrom(EnableConfigurationProperties.class)));
Assertions.assertEquals(3, annotations.length);
}
@Test
void testComponentScan() {
Annotation[] annotations = ScfsAutoConfiguration.class.getAnnotations();
Optional<Annotation> optional = Arrays.stream(annotations)
.filter(annotation -> annotation.annotationType().isAssignableFrom(ComponentScan.class))
.findFirst();
Assertions.assertTrue(optional.isPresent());
Assertions.assertArrayEquals(new String[]{"com.czcb.scfs.spring.boot.starter"}, ((ComponentScan) optional.get()).value());
}
@Test
void testEnableConfigurationProperties() {
Annotation[] annotations = ScfsAutoConfiguration.class.getAnnotations();
Optional<Annotation> optional = Arrays.stream(annotations)
.filter(annotation -> annotation.annotationType().isAssignableFrom(EnableConfigurationProperties.class))
.findFirst();
Assertions.assertTrue(optional.isPresent());
Assertions.assertArrayEquals(new Class[]{ScfsApiGatewayProperties.class}, ((EnableConfigurationProperties) optional.get()).value());
}
private ScfsApiGatewayProperties properties() {
ScfsApiGatewayProperties properties = new ScfsApiGatewayProperties();
@ -63,7 +100,7 @@ class ScfsAutoConfigurationTest {
}
protected ApiClient apiClient() {
SmConfiguration smConfiguration = new SmConfiguration(properties());
SmConfiguration smConfiguration = new SmConfiguration(properties(), new DefaultSequencer());
return new ApacheHttpclient(HttpClients.custom().build(), smConfiguration.smProfile());
}
@ -72,11 +109,6 @@ class ScfsAutoConfigurationTest {
Assertions.assertNotNull(configuration.echoService(apiClient()));
}
@Test
void sequencer() {
Assertions.assertNotNull(configuration.sequencer());
}
@Test
void accountService() {
Assertions.assertNotNull(configuration.accountService(apiClient()));

View File

@ -0,0 +1,12 @@
package com.czcb.scfs.spring.boot.starter;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
class SequencerAutoConfigurationTest {
@Test
void sequencer() {
SequencerAutoConfiguration configuration = new SequencerAutoConfiguration();
Assertions.assertNotNull(configuration.sequencer());
}
}

View File

@ -1,5 +1,6 @@
package com.czcb.scfs.spring.boot.starter;
import com.czcb.scfs.api.core.cipher.DefaultSequencer;
import com.czcb.scfs.api.core.cipher.StoreType;
import com.czcb.scfs.api.core.http.LogLevel;
import com.czcb.scfs.api.sm.SmProfile;
@ -8,9 +9,15 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
@ -19,6 +26,45 @@ class SmConfigurationTest {
private SmConfiguration smConfiguration;
@Test
void testHavingValue() {
Assertions.assertEquals("sm", SmConfiguration.HAVING_VALUE);
}
@Test
void testAnnotation() {
Annotation[] annotations = SmConfiguration.class.getAnnotations();
Assertions.assertTrue(Arrays.stream(annotations).anyMatch(annotation -> annotation.annotationType().isAssignableFrom(Configuration.class)));
Assertions.assertTrue(Arrays.stream(annotations).anyMatch(annotation -> annotation.annotationType().isAssignableFrom(ConditionalOnClass.class)));
Assertions.assertTrue(Arrays.stream(annotations).anyMatch(annotation -> annotation.annotationType().isAssignableFrom(ConditionalOnProperty.class)));
Assertions.assertEquals(3, annotations.length);
}
@Test
void testConditionalOnClass() {
Annotation[] annotations = SmConfiguration.class.getAnnotations();
Optional<Annotation> optional = Arrays.stream(annotations)
.filter(annotation -> annotation.annotationType().isAssignableFrom(ConditionalOnClass.class))
.findFirst();
Assertions.assertTrue(optional.isPresent());
Assertions.assertArrayEquals(new Class[]{SmProfile.class}, ((ConditionalOnClass) optional.get()).value());
}
@Test
void testConditionalOnProperty() {
Annotation[] annotations = SmConfiguration.class.getAnnotations();
Optional<Annotation> optional = Arrays.stream(annotations)
.filter(annotation -> annotation.annotationType().isAssignableFrom(ConditionalOnProperty.class))
.findFirst();
Assertions.assertTrue(optional.isPresent());
Assertions.assertTrue(((ConditionalOnProperty) optional.get()).matchIfMissing());
Assertions.assertArrayEquals(new String[]{"type"}, ((ConditionalOnProperty) optional.get()).value());
Assertions.assertEquals("scfs.api-gateway.cipher", ((ConditionalOnProperty) optional.get()).prefix());
Assertions.assertEquals("sm", ((ConditionalOnProperty) optional.get()).havingValue());
}
private ScfsApiGatewayProperties properties(boolean channelGroupMode) {
ScfsApiGatewayProperties properties = new ScfsApiGatewayProperties();
@ -70,14 +116,14 @@ class SmConfigurationTest {
@Test
void getProperties() {
smConfiguration = new SmConfiguration(properties(false));
smConfiguration = new SmConfiguration(properties(false), new DefaultSequencer());
ScfsApiGatewayProperties properties = smConfiguration.getProperties();
Assertions.assertNotNull(properties);
}
@Test
void smProfile() {
smConfiguration = new SmConfiguration(properties(true));
smConfiguration = new SmConfiguration(properties(true), new DefaultSequencer());
SmProfile smProfile = smConfiguration.smProfile();
Assertions.assertNotNull(smProfile);
assertThatJson("{\"appNo\":\"111111\",\"channelNo\":\"000000\",\"channelGroupMode\":true}").isEqualTo(smProfile.getChannel());

View File

@ -0,0 +1,35 @@
package com.czcb.scfs.api.test;
import com.czcb.scfs.api.core.cipher.Sequencer;
import com.czcb.scfs.api.service.echo.EchoService;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
import javax.annotation.Resource;
/**
*
*
* @author wangwei
* @since 2024/7/26
*/
@SpringBootTest
@Import(CustomSequencerTest.CustomSequencer.class)
class CustomSequencerTest {
@Resource
private EchoService echoService;
@Test
void test() {
Assertions.assertThrows(UnsupportedOperationException.class, () -> echoService.echo());
}
public static class CustomSequencer implements Sequencer {
@Override
public String next() {
throw new UnsupportedOperationException();
}
}
}