refactored features to be components instead, so we have more runtime config (for example template config etc), this can be done, because features depend on the code anyway and do not need to be done via property files, the property files only define the default values when starting up

fixed feature disabled message not being templated and refactored the way condition checks are handled by the command received handler, so we do not use exceptions for this, this handled by a specified state in the result and a separate post execution handler
added separate config module to the commands
added command to see which features are available, and their current state
fixed scheduler test
This commit is contained in:
Sheldan
2020-04-26 11:38:27 +02:00
parent bd554537cc
commit 4800470f86
136 changed files with 950 additions and 332 deletions

View File

@@ -2,7 +2,11 @@ package dev.sheldan.abstracto.core.command.condition;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.models.FeatureDisabledMessage;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.service.FeatureFlagService;
import dev.sheldan.abstracto.core.service.management.FeatureFlagManagementService;
import dev.sheldan.abstracto.templating.service.TemplateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -12,14 +16,24 @@ public class FeatureEnabledCondition implements CommandCondition {
@Autowired
private FeatureFlagManagementService featureFlagManagementService;
@Autowired
private TemplateService templateService;
@Autowired
private FeatureFlagService featureFlagService;
@Override
public ConditionResult shouldExecute(CommandContext context, Command command) {
String featureName = command.getFeature();
FeatureEnum feature = command.getFeature();
boolean featureFlagValue = true;
String reason = "";
if(featureName != null) {
featureFlagValue = featureFlagManagementService.getFeatureFlagValue(featureName, context.getGuild().getIdLong());
reason = "Feature has been disabled. Necessary feature is: " + featureName;
if(feature != null) {
featureFlagValue = featureFlagManagementService.getFeatureFlagValue(feature, context.getGuild().getIdLong());
FeatureDisabledMessage featureDisabledMessage = FeatureDisabledMessage
.builder()
.featureDisplay(featureFlagService.getFeatureDisplayforFeature(feature))
.build();
reason = templateService.renderTemplate("feature_disabled_message", featureDisabledMessage);
}
return ConditionResult.builder().reason(reason).result(featureFlagValue).build();
}

View File

@@ -1,15 +1,19 @@
package dev.sheldan.abstracto.core.command.execution;
import dev.sheldan.abstracto.core.command.condition.ConditionResult;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter @Setter @Builder
@Getter
@Setter
@Builder
public class CommandResult {
private ResultState result;
private String message;
private Throwable throwable;
private ConditionResult conditionResult;
public static CommandResult fromSuccess() {
return CommandResult.builder().result(ResultState.SUCCESSFUL).build();
@@ -22,4 +26,8 @@ public class CommandResult {
public static CommandResult fromError(String message, Throwable throwable) {
return CommandResult.builder().result(ResultState.ERROR).message(message).throwable(throwable).build();
}
public static CommandResult fromCondition(ConditionResult result) {
return CommandResult.builder().conditionResult(result).result(ResultState.CONDITION).build();
}
}

View File

@@ -1,5 +1,5 @@
package dev.sheldan.abstracto.core.command.execution;
public enum ResultState {
ERROR, SUCCESSFUL, IGNORED
ERROR, SUCCESSFUL, IGNORED, CONDITION
}

View File

@@ -0,0 +1,13 @@
package dev.sheldan.abstracto.core.command.models;
import dev.sheldan.abstracto.core.config.FeatureDisplay;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
@Builder
public class FeatureDisabledMessage {
private FeatureDisplay featureDisplay;
}

View File

@@ -1,8 +1,10 @@
package dev.sheldan.abstracto.core.command.models.database;
import dev.sheldan.abstracto.core.models.database.ARole;
import lombok.*;
import javax.persistence.*;
import java.util.List;
@Entity
@Table(name = "command")
@@ -24,4 +26,10 @@ public class ACommand {
@JoinColumn(name = "module_id", nullable = false)
private AModule module;
@ManyToMany(fetch = FetchType.LAZY)
@Getter
@JoinColumn(name = "allowed_role_id")
private List<ARole> allowedRoles;
}

View File

@@ -0,0 +1,5 @@
package dev.sheldan.abstracto.core.config;
public interface FeatureDisplay {
FeatureEnum getFeature();
}

View File

@@ -0,0 +1,5 @@
package dev.sheldan.abstracto.core.config;
public interface FeatureEnum {
String getKey();
}

View File

@@ -1,5 +1,7 @@
package dev.sheldan.abstracto.core.listener;
import dev.sheldan.abstracto.core.config.FeatureEnum;
public interface FeatureAware {
String getFeature();
FeatureEnum getFeature();
}

View File

@@ -0,0 +1,15 @@
package dev.sheldan.abstracto.core.models.template.commands;
import dev.sheldan.abstracto.core.models.context.UserInitiatedServerContext;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import java.util.List;
@Getter
@Setter
@SuperBuilder
public class EnableModel extends UserInitiatedServerContext {
private List<String> features;
}

View File

@@ -0,0 +1,15 @@
package dev.sheldan.abstracto.core.models.template.commands;
import dev.sheldan.abstracto.core.config.FeatureDisplay;
import dev.sheldan.abstracto.core.models.database.AFeatureFlag;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class FeatureFlagDisplay {
private AFeatureFlag featureFlag;
private FeatureDisplay featureDisplay;
}

View File

@@ -0,0 +1,16 @@
package dev.sheldan.abstracto.core.models.template.commands;
import dev.sheldan.abstracto.core.models.context.UserInitiatedServerContext;
import dev.sheldan.abstracto.core.models.database.AFeatureFlag;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import java.util.List;
@Getter
@SuperBuilder
@Setter
public class FeaturesModel extends UserInitiatedServerContext {
private List<FeatureFlagDisplay> features;
}

View File

@@ -1,7 +1,18 @@
package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.config.FeatureDisplay;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import java.util.List;
public interface FeatureFlagService {
boolean isFeatureEnabled(String name, Long serverId);
void enableFeature(String name, Long serverId);
void disableFeature(String name, Long serverId);
boolean isFeatureEnabled(FeatureEnum name, Long serverId);
void enableFeature(FeatureEnum name, Long serverId);
void disableFeature(FeatureEnum name, Long serverId);
List<String> getAllFeatures();
List<FeatureDisplay> getAllFeatureDisplays();
FeatureDisplay getFeatureDisplayforFeature(FeatureEnum featureEnum);
boolean doesFeatureExist(FeatureEnum name);
List<String> getFeaturesAsList();
FeatureEnum getFeatureEnum(String key);
}

View File

@@ -1,14 +1,17 @@
package dev.sheldan.abstracto.core.service.management;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.models.database.AFeatureFlag;
import dev.sheldan.abstracto.core.models.database.AServer;
import java.util.List;
import java.util.Optional;
public interface FeatureFlagManagementService {
void createFeatureFlag(String key, Long serverId, Boolean newValue);
void createFeatureFlag(String key, AServer server, Boolean newValue);
boolean getFeatureFlagValue(String key, Long serverId);
void updateFeatureFlag(String key, Long serverId, Boolean newValue);
Optional<AFeatureFlag> getFeatureFlag(String key, Long serverId);
void createFeatureFlag(FeatureEnum key, Long serverId, Boolean newValue);
void createFeatureFlag(FeatureEnum key, AServer server, Boolean newValue);
boolean getFeatureFlagValue(FeatureEnum key, Long serverId);
void updateFeatureFlag(FeatureEnum key, Long serverId, Boolean newValue);
Optional<AFeatureFlag> getFeatureFlag(FeatureEnum key, Long serverId);
List<AFeatureFlag> getFeatureFlagsOfServer(AServer server);
}