99import io .scalecube .config .source .LoadedConfigProperty ;
1010import java .util .ArrayList ;
1111import java .util .Arrays ;
12+ import java .util .Collection ;
13+ import java .util .Collections ;
1214import java .util .HashMap ;
1315import java .util .List ;
1416import java .util .Map ;
15- import java .util .Objects ;
17+ import java .util .Optional ;
1618import java .util .function .Function ;
1719import java .util .function .UnaryOperator ;
1820import java .util .stream .Collectors ;
@@ -28,99 +30,99 @@ public class VaultConfigSource implements ConfigSource {
2830
2931 private static final Logger LOGGER = LoggerFactory .getLogger (VaultConfigSource .class );
3032
31- private static final String VAULT_SECRETS_PATH = "VAULT_SECRETS_PATH" ;
33+ private static final EnvironmentLoader ENVIRONMENT_LOADER = new EnvironmentLoader () ;
3234
3335 private final VaultInvoker vault ;
34- private final List <String > secretsPath ;
36+ private final List <String > secretsPaths ;
3537
36- /**
37- * Create a new {@link VaultConfigSource}.
38- * @param vault vault invoker.
39- * @param secretsPaths secret path-s.
40- */
4138 private VaultConfigSource (VaultInvoker vault , List <String > secretsPaths ) {
4239 this .vault = vault ;
43- this .secretsPath = secretsPaths ;
40+ this .secretsPaths = new ArrayList <>( secretsPaths ) ;
4441 }
4542
4643 @ Override
4744 public Map <String , ConfigProperty > loadConfig () {
4845 Map <String , ConfigProperty > result = new HashMap <>();
49- for (String path : secretsPath ) {
46+ for (String path : secretsPaths ) {
5047 try {
5148 LogicalResponse response = vault .invoke (vault -> vault .logical ().read (path ));
52- final Map <String , LoadedConfigProperty > pathProps = response .getData ().entrySet ().stream ()
53- .map (LoadedConfigProperty ::withNameAndValue )
54- .map (LoadedConfigProperty .Builder ::build )
55- .collect (Collectors .toMap (LoadedConfigProperty ::name , Function .identity ()));
49+ final Map <String , LoadedConfigProperty > pathProps =
50+ response .getData ().entrySet ().stream ()
51+ .map (LoadedConfigProperty ::withNameAndValue )
52+ .map (LoadedConfigProperty .Builder ::build )
53+ .collect (Collectors .toMap (LoadedConfigProperty ::name , Function .identity ()));
5654 result .putAll (pathProps );
5755 } catch (Exception ex ) {
58- LOGGER .warn ("unable to load config properties from {}" ,path , ex );
56+ LOGGER .warn ("Unable to load config properties from {}" , path , ex );
5957 throw new ConfigSourceNotAvailableException (ex );
6058 }
6159 }
6260 return result ;
6361 }
6462
65- /**
66- * This builder method is used internally for test purposes. please use it only for tests. Please
67- * note the following required environment variables are required.
68- *
69- * <ul>
70- * <li><code>VAULT_SECRETS_PATH</code> is the path to use (defaults to <code>secret</code>)
71- * <li><code>VAULT_TOKEN</code> is the {@link VaultConfig#token(String) token} to use
72- * <li><code>VAULT_ADDR</code> is the {@link VaultConfig#address(String) address} of the vault
73- * (API)
74- * </ul>
75- */
7663 public static Builder builder () {
7764 return new Builder ();
7865 }
7966
80- /**
81- * This builder method is used internally for test purposes. please use it only for tests
82- *
83- * @param environmentLoader an {@link EnvironmentLoader}
84- */
85- static Builder builder (EnvironmentLoader environmentLoader ) {
86- final Builder builder = new Builder ();
87- if (environmentLoader != null ) {
88- builder .environmentLoader = environmentLoader ;
89- }
90- return builder ;
91- }
92-
9367 public static final class Builder {
9468
95- private Function <VaultInvoker .Builder , VaultInvoker .Builder > vault = Function .identity ();
69+ private Function <VaultInvoker .Builder , VaultInvoker .Builder > builderFunction = b -> b ;
70+
9671 private VaultInvoker invoker ;
97- private EnvironmentLoader environmentLoader = VaultInvoker .Builder .ENVIRONMENT_LOADER ;
98- private List <String > secretsPaths = new ArrayList <>();
72+
73+ private List <String > secretsPaths =
74+ Optional .ofNullable (ENVIRONMENT_LOADER .loadVariable ("VAULT_SECRETS_PATH" ))
75+ .or (() -> Optional .ofNullable (ENVIRONMENT_LOADER .loadVariable ("VAULT_SECRETS_PATHS" )))
76+ .map (s -> s .split (":" ))
77+ .map (Arrays ::asList )
78+ .orElseGet (ArrayList ::new );
9979
10080 private Builder () {}
10181
82+ /**
83+ * @deprecated will be removed in future releases without notice, use {@link
84+ * #addSecretsPath(String...)} or {@link #secretsPaths(Collection)}.
85+ */
86+ @ Deprecated
10287 public Builder secretsPath (String secretsPath ) {
103- this .secretsPaths .add (secretsPath );
88+ this .secretsPaths .addAll (toSecretsPaths (Collections .singletonList (secretsPath )));
89+ return this ;
90+ }
91+
92+ public Builder addSecretsPath (String ... secretsPath ) {
93+ this .secretsPaths .addAll (toSecretsPaths (Arrays .asList (secretsPath )));
94+ return this ;
95+ }
96+
97+ public Builder secretsPaths (Collection <String > secretsPaths ) {
98+ this .secretsPaths = toSecretsPaths (secretsPaths );
10499 return this ;
105100 }
106101
102+ private static List <String > toSecretsPaths (Collection <String > secretsPaths ) {
103+ return secretsPaths .stream ()
104+ .flatMap (s -> Arrays .stream (s .split (":" )))
105+ .distinct ()
106+ .collect (Collectors .toList ());
107+ }
108+
107109 public Builder invoker (VaultInvoker invoker ) {
108110 this .invoker = invoker ;
109111 return this ;
110112 }
111113
112114 public Builder vault (UnaryOperator <VaultInvoker .Builder > config ) {
113- this .vault = this .vault .andThen (config );
115+ this .builderFunction = this .builderFunction .andThen (config );
114116 return this ;
115117 }
116118
117119 public Builder config (UnaryOperator <VaultConfig > vaultConfig ) {
118- this .vault = this .vault .andThen (c -> c .options (vaultConfig ));
120+ this .builderFunction = this .builderFunction .andThen (c -> c .options (vaultConfig ));
119121 return this ;
120122 }
121123
122124 public Builder tokenSupplier (VaultTokenSupplier supplier ) {
123- this .vault = this .vault .andThen (c -> c .tokenSupplier (supplier ));
125+ this .builderFunction = this .builderFunction .andThen (c -> c .tokenSupplier (supplier ));
124126 return this ;
125127 }
126128
@@ -130,17 +132,9 @@ public Builder tokenSupplier(VaultTokenSupplier supplier) {
130132 * @return instance of {@link VaultConfigSource}
131133 */
132134 public VaultConfigSource build () {
133- VaultInvoker vaultInvoker =
134- invoker != null
135- ? invoker
136- : vault .apply (new VaultInvoker .Builder (environmentLoader )).build ();
137- if (secretsPaths .isEmpty ()) {
138- String envSecretPath = Objects
139- .requireNonNull (environmentLoader .loadVariable (VAULT_SECRETS_PATH ),
140- "Missing secretsPath" );
141- secretsPaths = Arrays .asList (envSecretPath .split (":" ));
142- }
143- return new VaultConfigSource (vaultInvoker , secretsPaths );
135+ return new VaultConfigSource (
136+ invoker != null ? invoker : builderFunction .apply (new VaultInvoker .Builder ()).build (),
137+ secretsPaths );
144138 }
145139 }
146140}
0 commit comments