1 package com.atlassian.sal.api.features;
2
3 import com.atlassian.sal.api.user.UserKey;
4
5 import javax.annotation.Nullable;
6
7 /**
8 * <p>Provides a cross-product method for determining whether a dark feature is enabled.</p>
9 *
10 * <p>Implementing products can back these checks with their own internal dark feature management system, but must
11 * follow the enable and disable dark features on startup based on system properties and the contents of an optional
12 * properties file. To avoid clashes with other system properties all features specified as system property must be
13 * prefixed with {@link DarkFeatureManager#ATLASSIAN_DARKFEATURE_PREFIX}. The prefix is removed from the feature key
14 * when it is processed later. Values must be either true or false. The location of the dark features property file can
15 * be overridden with the {@link DarkFeatureManager#DARKFEATURES_PROPERTIES_FILE_PROPERTY} system property.</p>
16 *
17 * <p>See SystemDarkFeatureInitializer in sal-core for an implementation.</p>
18 *
19 * @since 2.10
20 */
21 public interface DarkFeatureManager
22 {
23 /**
24 * Prefix for all dark feature specified as system property.
25 */
26 public static final String ATLASSIAN_DARKFEATURE_PREFIX = "atlassian.darkfeature.";
27
28 /**
29 * System property for disabling all dark features.
30 */
31 public static final String DISABLE_ALL_DARKFEATURES_PROPERTY = "atlassian.darkfeature.disabled";
32
33 /**
34 * System property for overriding location of dark features property file.
35 */
36 public static final String DARKFEATURES_PROPERTIES_FILE_PROPERTY = "darkfeatures.properties.file";
37
38 /**
39 * Default properties file name.
40 */
41 public static final String DARKFEATURES_PROPERTIES_FILE_PROPERTY_DEFAULT = "atlassian-darkfeatures.properties";
42
43 /**
44 * Checks if a dark feature is enabled for all users, regardless whether the feature can be changed during runtime
45 * or not.
46 * @param featureKey key of the feature to be checked
47 * @return <code>true</code> if the feature key is valid and enabled, false otherwise
48 * @see ValidFeatureKeyPredicate
49 */
50 boolean isFeatureEnabledForAllUsers(String featureKey);
51
52 /**
53 * Checks if a dark feature is enabled for all users or for the current user only (must be called within the context
54 * of a request). If the user couldn't be resolved or is anonymous, only features enabled for all users are
55 * considered.
56 * @param featureKey key of the feature to be checked
57 * @return <code>true</code> if the feature is valid and enabled, either for all users or the current user only;
58 * <code>false</code> otherwise.
59 * @see ValidFeatureKeyPredicate
60 */
61 boolean isFeatureEnabledForCurrentUser(String featureKey);
62
63 /**
64 * Checks if a dark feature is enabled for all users or just for the given user. In case the user is anonymous,
65 * only features enabled for all users are considered.
66 * @param userKey the key of the user being queried; <code>null</code> represents the anonymous user
67 * @param featureKey key of the feature to be checked
68 * @return <code>true</code> if the feature key is valid and enabled, either for all users or the current user only;
69 * <code>false</code> otherwise.
70 * @throws IllegalArgumentException if the user doesn't exist
71 * @see ValidFeatureKeyPredicate
72 */
73 boolean isFeatureEnabledForUser(@Nullable UserKey userKey, String featureKey);
74
75 /**
76 * Returns true if the current acting user has permission to change dark features for all users. This is a nothrow
77 * method and should return a value instead of throw an exception.
78 * @return <code>true</code> iff the current acting user has permission to change dark features for all users,
79 * <code>false</code> otherwise
80 */
81 boolean canManageFeaturesForAllUsers();
82
83 /**
84 * Enable the given dark feature all users. The acting user must have permission to change dark features for all
85 * users.
86 * @param featureKey key of the feature to be enabled
87 * @throws InvalidFeatureKeyException if the feature key is not valid
88 * @throws MissingPermissionException if the user has not the required permission
89 * @throws IllegalStateException if the update failed
90 * @see ValidFeatureKeyPredicate
91 * @see #canManageFeaturesForAllUsers()
92 */
93 void enableFeatureForAllUsers(String featureKey);
94
95 /**
96 * Disable the given dark feature for all users. The acting user must have permission to change dark features for
97 * all users.
98 * @param featureKey key of the feature to be disabled
99 * @throws InvalidFeatureKeyException if the feature key is not valid
100 * @throws MissingPermissionException if the user has not the required permission
101 * @throws IllegalStateException if the update failed
102 * @see ValidFeatureKeyPredicate
103 * @see #canManageFeaturesForAllUsers()
104 */
105 void disableFeatureForAllUsers(String featureKey);
106
107 /**
108 * Enable a dark feature for the current user only. Anonymous users are not supported. <strong>If the feature is
109 * already enabled for all users, the user will still be able to use it.</strong>
110 * @param featureKey key of the feature to enable
111 * @throws InvalidFeatureKeyException if the feature key is not valid
112 * @throws IllegalStateException if the current user could not be resolved, is anonymous or the update failed due to
113 * any other reason
114 * @see ValidFeatureKeyPredicate
115 */
116 void enableFeatureForCurrentUser(String featureKey);
117
118 /**
119 * Enable a dark feature for the given user only. Anonymous users are not supported. <strong>If the feature is
120 * already enabled for all users, the user will still be able to use it.</strong>
121 * @param userKey key of the user to enable the feature for; not <code>null</code>
122 * @param featureKey key of the feature to be enabled
123 * @throws IllegalArgumentException if the user does not exist or is anonymous
124 * @throws InvalidFeatureKeyException if the feature key is not valid
125 * @throws IllegalStateException if the update failed
126 * @see ValidFeatureKeyPredicate
127 */
128 void enableFeatureForUser(UserKey userKey, String featureKey);
129
130 /**
131 * Disable a dark feature for the current user only. Anonymous users are not supported. <strong>If the feature is
132 * enabled for all users, the current user will still be able to use it.</strong>
133 * @param featureKey key of the feature to be disabled
134 * @throws InvalidFeatureKeyException if the feature key is not valid
135 * @throws IllegalStateException if the current user could not be resolved, is anonymous or the update failed due to
136 * any other reason
137 * @see ValidFeatureKeyPredicate
138 */
139 void disableFeatureForCurrentUser(String featureKey);
140
141 /**
142 * Disable a dark feature for the given user only. Anonymous users are not supported. <strong>If the feature is
143 * enabled for all users, the user will still be able to use it.</strong>
144 * @param userKey key of the user to disable the feature for; not <code>null</code>
145 * @param featureKey key of the feature to be disabled
146 * @throws IllegalArgumentException if the user does not exist or is anonymous
147 * @throws InvalidFeatureKeyException if the feature key is not valid
148 * @throws IllegalStateException if the update failed
149 * @see ValidFeatureKeyPredicate
150 */
151 void disableFeatureForUser(UserKey userKey, String featureKey);
152
153 /**
154 * @return all dark features enabled for all users.
155 */
156 EnabledDarkFeatures getFeaturesEnabledForAllUsers();
157
158 /**
159 * Return features enabled for the current user (must be called within the context of a request). In case the
160 * current user could not be resolved or is anonymous, all dark features enabled for all users are returned instead.
161 * @return all dark features applicable for the current user.
162 */
163 EnabledDarkFeatures getFeaturesEnabledForCurrentUser();
164
165 /**
166 * Return enabled features for a given user. In case the current user is anonymous, all global enabled features are
167 * returned.
168 * @param userKey key of the user being queried; <code>null</code> represents the anonymous user
169 * @return all dark features applicable for the given user
170 * @throws IllegalArgumentException if the user doesn't exist
171 */
172 EnabledDarkFeatures getFeaturesEnabledForUser(@Nullable UserKey userKey);
173
174 }