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