11package io .scalecube .config .vault ;
22
33import com .bettercloud .vault .EnvironmentLoader ;
4- import com .bettercloud .vault .Vault ;
54import com .bettercloud .vault .VaultConfig ;
6- import com .bettercloud .vault .VaultException ;
75import com .bettercloud .vault .response .LogicalResponse ;
86import io .scalecube .config .ConfigProperty ;
97import io .scalecube .config .ConfigSourceNotAvailableException ;
108import io .scalecube .config .source .ConfigSource ;
119import io .scalecube .config .source .LoadedConfigProperty ;
12- import io .scalecube .config .utils .ThrowableUtil ;
13- import java .time .Duration ;
1410import java .util .Map ;
1511import java .util .Objects ;
16- import java .util .concurrent .Executors ;
17- import java .util .concurrent .ThreadFactory ;
18- import java .util .concurrent .TimeUnit ;
1912import java .util .function .Function ;
2013import java .util .function .UnaryOperator ;
2114import java .util .stream .Collectors ;
@@ -31,95 +24,33 @@ public class VaultConfigSource implements ConfigSource {
3124
3225 private static final Logger LOGGER = LoggerFactory .getLogger (VaultConfigSource .class );
3326
34- private static final ThreadFactory THREAD_FACTORY =
35- r -> {
36- Thread thread = new Thread (r );
37- thread .setDaemon (true );
38- thread .setName (VaultConfigSource .class .getSimpleName ().toLowerCase () + "-token-renewer" );
39- return thread ;
40- };
41-
4227 private static final String VAULT_SECRETS_PATH = "VAULT_SECRETS_PATH" ;
43- private static final String VAULT_RENEW_PERIOD = "VAULT_RENEW_PERIOD" ;
4428
45- private final Vault vault ;
29+ private final VaultInvoker vault ;
4630 private final String secretsPath ;
4731
4832 /**
49- * Create a new {@link VaultConfigSource} with the given {@link Builder} .
33+ * Create a new {@link VaultConfigSource}.
5034 *
51- * @param builder configuration to create vault access with.
35+ * @param vault vault invoker.
36+ * @param secretsPath secret path.
5237 */
53- private VaultConfigSource (Builder builder ) throws VaultException {
54- EnvironmentLoader environmentLoader =
55- builder .environmentLoader != null ? builder .environmentLoader : new EnvironmentLoader ();
56-
57- secretsPath =
58- Objects .requireNonNull (
59- builder .secretsPath != null
60- ? builder .secretsPath
61- : environmentLoader .loadVariable (VAULT_SECRETS_PATH ),
62- "Missing secretsPath" );
63-
64- VaultConfig vaultConfig =
65- builder .config .apply (new VaultConfig ()).environmentLoader (environmentLoader ).build ();
66- String token = builder .tokenSupplier .getToken (environmentLoader , vaultConfig );
67- vault = new Vault (vaultConfig .token (token ));
68-
69- Duration renewEvery =
70- builder .renewEvery != null
71- ? builder .renewEvery
72- : duration (environmentLoader .loadVariable (VAULT_RENEW_PERIOD ));
73-
74- if (renewEvery != null ) {
75- scheduleVaultTokenRenew (renewEvery );
76- }
77- }
78-
79- private void scheduleVaultTokenRenew (Duration renewEvery ) {
80- long initialDelay = renewEvery .toMillis ();
81- long period = renewEvery .toMillis ();
82- Executors .newSingleThreadScheduledExecutor (THREAD_FACTORY )
83- .scheduleAtFixedRate (
84- () -> {
85- try {
86- this .vault .auth ().renewSelf ();
87- LOGGER .info ("renew token success" );
88- } catch (VaultException vaultException ) {
89- LOGGER .error ("failed to renew token" , vaultException );
90- }
91- },
92- initialDelay ,
93- period ,
94- TimeUnit .MILLISECONDS );
95- }
96-
97- private void checkVaultStatus () throws VaultException {
98- if (vault .seal ().sealStatus ().getSealed ()) {
99- throw new VaultException ("Vault is sealed" );
100- }
101- Boolean initialized = vault .debug ().health ().getInitialized ();
102- if (!initialized ) {
103- throw new VaultException ("Vault not yet initialized" );
104- }
105- }
106-
107- private Duration duration (String duration ) {
108- return duration != null ? Duration .parse (duration ) : null ;
38+ private VaultConfigSource (VaultInvoker vault , String secretsPath ) {
39+ this .vault = vault ;
40+ this .secretsPath = secretsPath ;
10941 }
11042
11143 @ Override
11244 public Map <String , ConfigProperty > loadConfig () {
11345 try {
114- checkVaultStatus ();
115- LogicalResponse response = vault .logical ().read (this .secretsPath );
46+ LogicalResponse response = vault .invoke (vault -> vault .logical ().read (secretsPath ));
11647 return response .getData ().entrySet ().stream ()
11748 .map (LoadedConfigProperty ::withNameAndValue )
11849 .map (LoadedConfigProperty .Builder ::build )
11950 .collect (Collectors .toMap (LoadedConfigProperty ::name , Function .identity ()));
120- } catch (VaultException vaultException ) {
121- LOGGER .warn ("unable to load config properties" , vaultException );
122- throw new ConfigSourceNotAvailableException (vaultException );
51+ } catch (Exception ex ) {
52+ LOGGER .warn ("unable to load config properties" , ex );
53+ throw new ConfigSourceNotAvailableException (ex );
12354 }
12455 }
12556
@@ -135,7 +66,7 @@ public Map<String, ConfigProperty> loadConfig() {
13566 * </ul>
13667 */
13768 public static Builder builder () {
138- return builder ( new EnvironmentLoader () );
69+ return new Builder ( );
13970 }
14071
14172 /**
@@ -144,38 +75,44 @@ public static Builder builder() {
14475 * @param environmentLoader an {@link EnvironmentLoader}
14576 */
14677 static Builder builder (EnvironmentLoader environmentLoader ) {
147- return new Builder (environmentLoader );
78+ final Builder builder = new Builder ();
79+ if (environmentLoader != null ) {
80+ builder .environmentLoader = environmentLoader ;
81+ }
82+ return builder ;
14883 }
14984
15085 public static final class Builder {
15186
152- private Function <VaultConfig , VaultConfig > config = Function .identity ();
153- private VaultTokenSupplier tokenSupplier = new VaultTokenSupplier () {} ;
154- private EnvironmentLoader environmentLoader ;
87+ private Function <VaultInvoker . Builder , VaultInvoker . Builder > vault = Function .identity ();
88+ private VaultInvoker invoker ;
89+ private EnvironmentLoader environmentLoader = VaultInvoker . Builder . ENVIRONMENT_LOADER ;
15590 private String secretsPath ;
156- private Duration renewEvery ;
15791
158- private Builder (EnvironmentLoader environmentLoader ) {
159- this .environmentLoader = environmentLoader ;
92+ private Builder () {}
93+
94+ public Builder secretsPath (String secretsPath ) {
95+ this .secretsPath = secretsPath ;
96+ return this ;
16097 }
16198
162- public Builder renewEvery ( Duration duration ) {
163- renewEvery = duration ;
99+ public Builder invoker ( VaultInvoker invoker ) {
100+ this . invoker = invoker ;
164101 return this ;
165102 }
166103
167- public Builder secretsPath ( String secretsPath ) {
168- this .secretsPath = secretsPath ;
104+ public Builder vault ( UnaryOperator < VaultInvoker . Builder > config ) {
105+ this .vault = this . vault . andThen ( config ) ;
169106 return this ;
170107 }
171108
172- public Builder config (UnaryOperator <VaultConfig > config ) {
173- this .config = this .config .andThen (config );
109+ public Builder config (UnaryOperator <VaultConfig > vaultConfig ) {
110+ this .vault = this .vault .andThen (c -> c . options ( vaultConfig ) );
174111 return this ;
175112 }
176113
177114 public Builder tokenSupplier (VaultTokenSupplier supplier ) {
178- this .tokenSupplier = supplier ;
115+ this .vault = this . vault . andThen ( c -> c . tokenSupplier ( supplier )) ;
179116 return this ;
180117 }
181118
@@ -185,12 +122,17 @@ public Builder tokenSupplier(VaultTokenSupplier supplier) {
185122 * @return instance of {@link VaultConfigSource}
186123 */
187124 public VaultConfigSource build () {
188- try {
189- return new VaultConfigSource (this );
190- } catch (VaultException e ) {
191- LOGGER .error ("Unable to build " + VaultConfigSource .class .getSimpleName (), e );
192- throw ThrowableUtil .propagate (e );
193- }
125+ VaultInvoker vaultInvoker =
126+ invoker != null
127+ ? invoker
128+ : vault .apply (new VaultInvoker .Builder (environmentLoader )).build ();
129+ secretsPath =
130+ Objects .requireNonNull (
131+ secretsPath != null
132+ ? secretsPath
133+ : environmentLoader .loadVariable (VAULT_SECRETS_PATH ),
134+ "Missing secretsPath" );
135+ return new VaultConfigSource (vaultInvoker , secretsPath );
194136 }
195137 }
196138}
0 commit comments