1 package cn.home1.oss.boot.autoconfigure;
2
3 import static cn.home1.oss.boot.autoconfigure.AppType.MIXED;
4 import static com.google.common.base.Preconditions.checkArgument;
5 import static com.google.common.base.Preconditions.checkState;
6 import static com.google.common.collect.Sets.newLinkedHashSet;
7 import static java.util.Arrays.asList;
8 import static java.util.stream.Collectors.toList;
9 import static org.apache.commons.lang3.StringUtils.isBlank;
10 import static org.apache.commons.lang3.StringUtils.isNotBlank;
11
12 import lombok.Getter;
13 import lombok.Setter;
14
15 import org.springframework.beans.factory.InitializingBean;
16 import org.springframework.beans.factory.annotation.Autowired;
17 import org.springframework.beans.factory.annotation.Value;
18 import org.springframework.boot.context.properties.ConfigurationProperties;
19 import org.springframework.boot.context.properties.NestedConfigurationProperty;
20 import org.springframework.core.env.Environment;
21
22 import java.util.Arrays;
23 import java.util.Collection;
24 import java.util.Optional;
25 import java.util.regex.Pattern;
26
27 import cn.home1.oss.lib.common.crypto.KeyExpression;
28
29
30
31
32
33
34
35
36 @ConfigurationProperties(prefix = "app", ignoreUnknownFields = true)
37 @SuppressWarnings({"PMD.AvoidUsingHardCodedIP", "PMD.ImmutableField", "PMD.SingularField", "PMD.UnusedPrivateField"})
38 @Getter
39 public class AppProperties implements InitializingBean {
40
41 public static final Pattern PROFILE_PATTERN = Pattern.compile("[a-zA-Z0-9.]+");
42 public static final String DOT_ENV = ".env";
43 public static final String PRODUCTION = "production";
44 public static final String PRODUCTION_ENV = PRODUCTION + DOT_ENV;
45 public static final String CI = "ci";
46 public static final String CI_ENV = CI + DOT_ENV;
47 public static final String DEVELOPMENT = "development";
48 public static final String DEVELOPMENT_ENV = DEVELOPMENT + DOT_ENV;
49
50 public static final AppType DEFAULT_APP_TYPE = MIXED;
51
52 @Setter
53 private AppType type;
54
55 @NestedConfigurationProperty
56 @Setter
57 private AppLogProperties log = new AppLogProperties();
58
59
60
61
62 private String env;
63
64 @NestedConfigurationProperty
65 @Setter
66 private AppErrorProperties error = new AppErrorProperties();
67
68 @NestedConfigurationProperty
69 @Setter
70 private AppSecurityProperties security = new AppSecurityProperties();
71
72 @Setter
73 private KeyExpression adminPublicKey = new KeyExpression();
74
75
76 @Value("${random.value}")
77 private String random;
78
79 public AppProperties() {
80 this.type = DEFAULT_APP_TYPE;
81 }
82
83 static Optional<String> findEnv(final Environment environment) {
84 final Collection<String> activeProfiles = asList(environment.getActiveProfiles());
85 final Collection<String> envProfiles = newLinkedHashSet(activeProfiles).stream()
86 .filter(profile -> profile.endsWith(DOT_ENV))
87 .map(profile -> profile.substring(0, profile.length() - 4)).collect(toList());
88 checkArgument(envProfiles.size() < 2, "only 1 env is allowed, there are %s", envProfiles);
89 return Optional.ofNullable(!envProfiles.isEmpty() ? envProfiles.iterator().next() : null);
90 }
91
92 public static String getEnvironment(final Environment environment) {
93 final Optional<String> envOptional = findEnv(environment);
94 return envOptional.isPresent() ? envOptional.get() : DEVELOPMENT;
95 }
96
97 public static Boolean getProdEnvironment(final String env) {
98 return PRODUCTION.equals(env);
99 }
100
101 public Boolean getProdEnvironment() {
102 return getProdEnvironment(this.env);
103 }
104
105 @Autowired
106 public void setEnvironment(final Environment environment) {
107 final boolean allMatch = Arrays.stream(environment.getActiveProfiles())
108 .allMatch(activeProfile -> PROFILE_PATTERN.matcher(activeProfile).matches());
109 checkArgument(allMatch, "profile name must match %s", PROFILE_PATTERN.pattern());
110 this.env = getEnvironment(environment);
111 }
112
113 @Override
114 public void afterPropertiesSet() throws Exception {
115 }
116
117 public AppType getType() {
118 return this.type;
119 }
120
121 public String getEnv() {
122 return this.env;
123 }
124
125 public AppSecurityProperties getSecurity() {
126 return this.security;
127 }
128
129 public String getSecurityDefaultTestUser() {
130 checkState(!this.getProdEnvironment() || isBlank(this.security.getDefaultTestUser()),
131 "do not set app.security.defaultTestUser in env %s", PRODUCTION);
132 return this.security.getDefaultTestUser();
133 }
134
135 public Boolean getSecurityEnabled() {
136 return this.security.getEnabled();
137 }
138
139 public Boolean getSecurityUseTestUser() {
140 return isNotBlank(getSecurityDefaultTestUser());
141 }
142 }