Feature flag impl
This commit is contained in:
parent
25b96b3be9
commit
af667970e4
46
src/main/java/cc/pulseapp/api/model/Feature.java
Normal file
46
src/main/java/cc/pulseapp/api/model/Feature.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package cc.pulseapp.api.model;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A feature flag.
|
||||||
|
*
|
||||||
|
* @author Braydon
|
||||||
|
*/
|
||||||
|
@RequiredArgsConstructor @Getter @ToString
|
||||||
|
public enum Feature {
|
||||||
|
USER_REGISTRATION_ENABLED("user-registration"),
|
||||||
|
ORG_CREATION_ENABLED("org-creation");
|
||||||
|
|
||||||
|
public static final Feature[] VALUES = values();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of this feature.
|
||||||
|
*/
|
||||||
|
@NonNull private final String id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this feature is enabled.
|
||||||
|
*/
|
||||||
|
@Setter private boolean enabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value of this feature, if any.
|
||||||
|
*/
|
||||||
|
@Setter private Object value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a feature by its id.
|
||||||
|
*
|
||||||
|
* @param id the feature id
|
||||||
|
* @return the feature, null if none
|
||||||
|
*/
|
||||||
|
public static Feature getById(@NonNull String id) {
|
||||||
|
for (Feature feature : VALUES) {
|
||||||
|
if (feature.getId().equals(id)) {
|
||||||
|
return feature;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
61
src/main/java/cc/pulseapp/api/service/FlagsService.java
Normal file
61
src/main/java/cc/pulseapp/api/service/FlagsService.java
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package cc.pulseapp.api.service;
|
||||||
|
|
||||||
|
import cc.pulseapp.api.model.Feature;
|
||||||
|
import com.flagsmith.FlagsmithClient;
|
||||||
|
import com.flagsmith.models.BaseFlag;
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This service is responsible for
|
||||||
|
* fetching remote feature flags.
|
||||||
|
*
|
||||||
|
* @author Braydon
|
||||||
|
*/
|
||||||
|
@Service @Log4j2(topic = "Flags")
|
||||||
|
public final class FlagsService {
|
||||||
|
private static final long FETCH_INTERVAL = TimeUnit.SECONDS.toMillis(30L);
|
||||||
|
|
||||||
|
@Value("${flagsmith.api-url}")
|
||||||
|
private String apiUrl;
|
||||||
|
|
||||||
|
@Value("${flagsmith.api-key}")
|
||||||
|
private String apiKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Flagsmith client.
|
||||||
|
*/
|
||||||
|
private FlagsmithClient client;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void onInitialize() {
|
||||||
|
client = FlagsmithClient.newBuilder()
|
||||||
|
.withApiUrl(apiUrl)
|
||||||
|
.setApiKey(apiKey)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Schedule a task to fetch all flags
|
||||||
|
new Timer().scheduleAtFixedRate(new TimerTask() {
|
||||||
|
@Override @SneakyThrows
|
||||||
|
public void run() {
|
||||||
|
for (BaseFlag flag : client.getEnvironmentFlags().getAllFlags()) {
|
||||||
|
Feature feature = Feature.getById(flag.getFeatureName());
|
||||||
|
if (feature == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Object value = flag.getValue();
|
||||||
|
feature.setEnabled(flag.getEnabled());
|
||||||
|
feature.setValue(value instanceof String stringedValue && (stringedValue.isBlank()) ? null : value);
|
||||||
|
}
|
||||||
|
log.info("Fetched new flags (:");
|
||||||
|
}
|
||||||
|
}, 0L, FETCH_INTERVAL);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user