xref: /aosp_15_r20/external/aws-sdk-java-v2/utils/src/main/java/software/amazon/awssdk/utils/SystemSetting.java (revision 8a52c7834d808308836a99fc2a6e0ed8db339086)
1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 package software.amazon.awssdk.utils;
17 
18 import java.util.Optional;
19 import software.amazon.awssdk.annotations.SdkProtectedApi;
20 import software.amazon.awssdk.utils.internal.SystemSettingUtils;
21 
22 /**
23  * An interface implemented by enums in other packages in order to define the system settings the want loaded. An enum
24  * is expected to implement this interface, and then have values loaded from the {@link System} using methods like
25  * {@link #getStringValue()}.
26  */
27 @SdkProtectedApi
28 public interface SystemSetting {
29     /**
30      * The system property of the setting (or null if there is no property for this setting).
31      */
property()32     String property();
33 
34     /**
35      * The environment variable of the setting (or null if there is no environment variable for this setting).
36      */
environmentVariable()37     String environmentVariable();
38 
39     /**
40      * The default value of the setting (or empty if there is no default). This value will be applied if the customer did not
41      * specify a setting.
42      */
defaultValue()43     String defaultValue();
44 
45     /**
46      * Attempt to load a system setting from {@link System#getProperty(String)} and {@link System#getenv(String)}. This should be
47      * used in favor of those methods because the SDK should support both methods of configuration.
48      *
49      * {@link System#getProperty(String)} takes precedent over {@link System#getenv(String)} if both are specified.
50      *
51      * @return The requested setting, or {@link Optional#empty()} if the values were not set, or the security manager did not
52      *         allow reading the setting.
53      */
getStringValue()54     default Optional<String> getStringValue() {
55         return SystemSettingUtils.resolveSetting(this);
56     }
57 
58     /**
59      * Attempt to load a system setting from {@link System#getenv(String)}. This should NOT BE USED, so checkstyle will
60      * complain about using it. The only reason this is made available is for when we ABSOLUTELY CANNOT support a system
61      * property for a specific setting. That should be the exception, NOT the rule. We should almost always provide a system
62      * property alternative for all environment variables.
63      *
64      * @return The requested setting, or {@link Optional#empty()} if the values were not set, or the security manager did not
65      *         allow reading the setting.
66      */
getStringValueFromEnvironmentVariable(String key)67     static Optional<String> getStringValueFromEnvironmentVariable(String key) {
68         return SystemSettingUtils.resolveEnvironmentVariable(key);
69     }
70 
71     /**
72      * Attempt to load a system setting from {@link System#getProperty(String)} and {@link System#getenv(String)}. This should be
73      * used in favor of those methods because the SDK should support both methods of configuration.
74      *
75      * {@link System#getProperty(String)} takes precedent over {@link System#getenv(String)} if both are specified.
76      * <p>
77      * Similar to {@link #getStringValue()}, but does not fall back to the default value.
78      *
79      * @return The requested setting, or {@link Optional#empty()} if the values were not set, or the security manager did not
80      *         allow reading the setting.
81      */
getNonDefaultStringValue()82     default Optional<String> getNonDefaultStringValue() {
83         return SystemSettingUtils.resolveNonDefaultSetting(this);
84     }
85 
86     /**
87      * Load the requested system setting as per the documentation in {@link #getStringValue()}, throwing an exception if the value
88      * was not set and had no default.
89      *
90      * @return The requested setting.
91      */
getStringValueOrThrow()92     default String getStringValueOrThrow() {
93         return getStringValue().orElseThrow(() ->
94                 new IllegalStateException("Either the environment variable " + environmentVariable() + " or the java"
95                                           + "property " + property() + " must be set."));
96     }
97 
98     /**
99      * Attempt to load a system setting from {@link System#getProperty(String)} and {@link System#getenv(String)}. This should be
100      * used in favor of those methods because the SDK should support both methods of configuration.
101      *
102      * The result will be converted to an integer.
103      *
104      * {@link System#getProperty(String)} takes precedent over {@link System#getenv(String)} if both are specified.
105      *
106      * @return The requested setting, or {@link Optional#empty()} if the values were not set, or the security manager did not
107      *         allow reading the setting.
108      */
getIntegerValue()109     default Optional<Integer> getIntegerValue() {
110         return getStringValue().map(Integer::parseInt);
111     }
112 
113 
114     /**
115      * Load the requested system setting as per the documentation in {@link #getIntegerValue()}, throwing an exception if the
116      * value was not set and had no default.
117      *
118      * @return The requested setting.
119      */
getIntegerValueOrThrow()120     default Integer getIntegerValueOrThrow() {
121         return Integer.parseInt(getStringValueOrThrow());
122     }
123 
124     /**
125      * Attempt to load a system setting from {@link System#getProperty(String)} and {@link System#getenv(String)}. This should be
126      * used in favor of those methods because the SDK should support both methods of configuration.
127      *
128      * The result will be converted to a boolean.
129      *
130      * {@link System#getProperty(String)} takes precedent over {@link System#getenv(String)} if both are specified.
131      *
132      * @return The requested setting, or {@link Optional#empty()} if the values were not set, or the security manager did not
133      *         allow reading the setting.
134      */
getBooleanValue()135     default Optional<Boolean> getBooleanValue() {
136         return getStringValue().map(value -> SystemSettingUtils.safeStringToBoolean(this, value));
137     }
138 
139     /**
140      * Load the requested system setting as per the documentation in {@link #getBooleanValue()}, throwing an
141      * exception if the value was not set and had no default.
142      *
143      * @return The requested setting.
144      */
getBooleanValueOrThrow()145     default Boolean getBooleanValueOrThrow() {
146         return getBooleanValue().orElseThrow(() ->
147                 new IllegalStateException("Either the environment variable " + environmentVariable() + " or the java"
148                                           + "property " + property() + " must be set."));
149     }
150 }
151