9
9
import io .scalecube .config .source .LoadedConfigProperty ;
10
10
import java .util .ArrayList ;
11
11
import java .util .Arrays ;
12
+ import java .util .Collection ;
13
+ import java .util .Collections ;
12
14
import java .util .HashMap ;
13
15
import java .util .List ;
14
16
import java .util .Map ;
15
- import java .util .Objects ;
17
+ import java .util .Optional ;
16
18
import java .util .function .Function ;
17
19
import java .util .function .UnaryOperator ;
18
20
import java .util .stream .Collectors ;
@@ -28,99 +30,99 @@ public class VaultConfigSource implements ConfigSource {
28
30
29
31
private static final Logger LOGGER = LoggerFactory .getLogger (VaultConfigSource .class );
30
32
31
- private static final String VAULT_SECRETS_PATH = "VAULT_SECRETS_PATH" ;
33
+ private static final EnvironmentLoader ENVIRONMENT_LOADER = new EnvironmentLoader () ;
32
34
33
35
private final VaultInvoker vault ;
34
- private final List <String > secretsPath ;
36
+ private final List <String > secretsPaths ;
35
37
36
- /**
37
- * Create a new {@link VaultConfigSource}.
38
- * @param vault vault invoker.
39
- * @param secretsPaths secret path-s.
40
- */
41
38
private VaultConfigSource (VaultInvoker vault , List <String > secretsPaths ) {
42
39
this .vault = vault ;
43
- this .secretsPath = secretsPaths ;
40
+ this .secretsPaths = new ArrayList <>( secretsPaths ) ;
44
41
}
45
42
46
43
@ Override
47
44
public Map <String , ConfigProperty > loadConfig () {
48
45
Map <String , ConfigProperty > result = new HashMap <>();
49
- for (String path : secretsPath ) {
46
+ for (String path : secretsPaths ) {
50
47
try {
51
48
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 ()));
56
54
result .putAll (pathProps );
57
55
} 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 );
59
57
throw new ConfigSourceNotAvailableException (ex );
60
58
}
61
59
}
62
60
return result ;
63
61
}
64
62
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
- */
76
63
public static Builder builder () {
77
64
return new Builder ();
78
65
}
79
66
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
-
93
67
public static final class Builder {
94
68
95
- private Function <VaultInvoker .Builder , VaultInvoker .Builder > vault = Function .identity ();
69
+ private Function <VaultInvoker .Builder , VaultInvoker .Builder > builderFunction = b -> b ;
70
+
96
71
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 );
99
79
100
80
private Builder () {}
101
81
82
+ /**
83
+ * @deprecated will be removed in future releases without notice, use {@link
84
+ * #addSecretsPath(String...)} or {@link #secretsPaths(Collection)}.
85
+ */
86
+ @ Deprecated
102
87
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 );
104
99
return this ;
105
100
}
106
101
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
+
107
109
public Builder invoker (VaultInvoker invoker ) {
108
110
this .invoker = invoker ;
109
111
return this ;
110
112
}
111
113
112
114
public Builder vault (UnaryOperator <VaultInvoker .Builder > config ) {
113
- this .vault = this .vault .andThen (config );
115
+ this .builderFunction = this .builderFunction .andThen (config );
114
116
return this ;
115
117
}
116
118
117
119
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 ));
119
121
return this ;
120
122
}
121
123
122
124
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 ));
124
126
return this ;
125
127
}
126
128
@@ -130,17 +132,9 @@ public Builder tokenSupplier(VaultTokenSupplier supplier) {
130
132
* @return instance of {@link VaultConfigSource}
131
133
*/
132
134
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 );
144
138
}
145
139
}
146
140
}
0 commit comments