[AB-xxx] adding support for automatic setup steps

reducing eventwaiter threads
adding abstracto templated exception
adding json validation service
increasing threads for scheduling
adding convenience method to retrieve users
This commit is contained in:
Sheldan
2021-06-27 00:20:15 +02:00
parent 942a20700e
commit 7e2477a321
23 changed files with 472 additions and 11 deletions

View File

@@ -169,6 +169,11 @@ public class ChannelGroupServiceBean implements ChannelGroupService {
return channelGroupManagementService.findByNameAndServer(groupName, server) != null;
}
@Override
public boolean isChannelInGroup(AChannel channel, AChannelGroup aChannelGroup) {
return aChannelGroup.getChannels().contains(channel);
}
@Override
public List<AChannelGroup> getChannelGroupsOfChannelWithType(AChannel channel, String groupTypeKey) {
List<AChannelGroup> channelGroups = channelGroupManagementService.getAllChannelGroupsOfChannel(channel);

View File

@@ -511,6 +511,33 @@ public class ChannelServiceBean implements ChannelService {
}
}
@Override
public List<CompletableFuture<Message>> sendFileToChannel(String fileContent, String fileName, TextChannel channel) {
File tempFile = fileService.createTempFile(fileName);
try {
fileService.writeContentToFile(tempFile, fileContent);
long maxFileSize = channel.getGuild().getMaxFileSize();
// in this case, we cannot upload the file, so we need to fail
if(tempFile.length() > maxFileSize) {
throw new UploadFileTooLargeException(tempFile.length(), maxFileSize);
}
MessageToSend messageToSend = MessageToSend
.builder()
.fileToSend(tempFile)
.build();
return sendMessageToSendToChannel(messageToSend, channel);
} catch (IOException e) {
log.error("Failed to write local temporary file for template download.", e);
throw new AbstractoRunTimeException(e);
} finally {
try {
fileService.safeDelete(tempFile);
} catch (IOException e) {
log.error("Failed to safely delete local temporary file for template download.", e);
}
}
}
@PostConstruct
public void postConstruct() {

View File

@@ -106,23 +106,33 @@ public class FeatureSetupServiceBean implements FeatureSetupService {
TextChannel textChannel = textChannelInGuild.get();
String text = templateService.renderTemplate(FEATURE_SETUP_INITIAL_MESSAGE_TEMPLATE_KEY, setupInitialMessageModel, user.getGuildId());
channelService.sendTextToChannel(text, textChannel);
return executeFeatureSetup(featureConfig, steps, user, new ArrayList<>());
ArrayList<DelayedActionConfig> delayedActionConfigs = new ArrayList<>();
featureConfig
.getAutoSetupSteps()
.forEach(autoDelayedAction -> delayedActionConfigs.add(autoDelayedAction.getDelayedActionConfig(user)));
return executeFeatureSetup(featureConfig, steps, user, delayedActionConfigs);
}
throw new ChannelNotInGuildException(user.getChannelId());
}
@Override
public CompletableFuture<Void> executeFeatureSetup(FeatureConfig featureConfig, List<SetupExecution> steps, AServerChannelUserId user, List<DelayedActionConfig> delayedActionConfigs) {
SetupExecution nextStep = steps.get(0);
return executeStep(user, nextStep, delayedActionConfigs, featureConfig);
if(!steps.isEmpty()) {
SetupExecution nextStep = steps.get(0);
return executeStep(user, nextStep, delayedActionConfigs, featureConfig);
} else {
log.info("Feature had no setup steps. Executing post setups steps immediately. As there can be automatic steps.");
self.executePostSetupSteps(delayedActionConfigs, user, null, featureConfig);
return CompletableFuture.completedFuture(null);
}
}
private CompletableFuture<Void> executeStep(AServerChannelUserId aUserInAServer, SetupExecution execution, List<DelayedActionConfig> delayedActionConfigs, FeatureConfig featureConfig) {
log.debug("Executing step {} in server {} in channel {} for user {}.", execution.getStep().getClass(), aUserInAServer.getGuildId(), aUserInAServer.getChannelId(), aUserInAServer.getUserId());
return execution.getStep().execute(aUserInAServer, execution.getParameter()).thenAccept(aVoid -> {
if(aVoid.getResult().equals(SetupStepResultType.SUCCESS)) {
return execution.getStep().execute(aUserInAServer, execution.getParameter()).thenAccept(setpResult -> {
if(setpResult.getResult().equals(SetupStepResultType.SUCCESS)) {
log.info("Step {} in server {} has been executed successfully. Proceeding.", execution.getStep().getClass(), aUserInAServer.getGuildId());
delayedActionConfigs.addAll(aVoid.getDelayedActionConfigList());
delayedActionConfigs.addAll(setpResult.getDelayedActionConfigList());
if(execution.getNextStep() != null) {
log.debug("Executing next step {}.", execution.getNextStep().getStep().getClass());
executeStep(aUserInAServer, execution.getNextStep(), delayedActionConfigs, featureConfig);

View File

@@ -0,0 +1,91 @@
package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.models.JSONValidationResult;
import lombok.extern.slf4j.Slf4j;
import org.everit.json.schema.Schema;
import org.everit.json.schema.ValidationException;
import org.everit.json.schema.loader.SchemaLoader;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
@Component
@Slf4j
public class JSONValidationServiceBean implements JSONValidationService {
@Override
public JSONValidationResult validateJSONSchema(InputStream schemaStream, File jsonFile) throws IOException {
return validateJSONSchema(schemaStream, new FileInputStream(jsonFile));
}
@Override
public JSONValidationResult validateJSONSchema(InputStream schema, InputStream jsonFile) {
JSONObject jsonSchemaStream = new JSONObject(new JSONTokener(schema));
JSONTokener tokener = new JSONTokener(jsonFile);
return validateJSONSchema(jsonSchemaStream, tokener.nextValue());
}
@Override
public JSONValidationResult validateJSONSchema(JSONObject jsonSchema, Object json) {
Schema schema = SchemaLoader.load(jsonSchema);
JSONValidationResult jsonValidationResult = JSONValidationResult
.builder()
.result(Result.SUCCESSFUL)
.build();
try {
schema.validate(json);
} catch (ValidationException e) {
jsonValidationResult.setResult(Result.ERRONEOUS);
if(e.getCausingExceptions().isEmpty()) {
jsonValidationResult.setExceptions(new ArrayList<>(Arrays.asList(e)));
} else {
jsonValidationResult.setExceptions(e.getCausingExceptions());
}
}
return jsonValidationResult;
}
@Override
public JSONValidationResult validateJSONSchema(String schema, String json) {
return validateJSONSchema(new JSONObject(schema), new JSONTokener(json).nextValue());
}
@Override
public JSONValidationResult validateJSONSchema(File schema, File jsonFile) throws IOException {
try (InputStream schemaStream = new FileInputStream(schema); InputStream jsonInputStream = new FileInputStream(jsonFile)) {
return validateJSONSchema(schemaStream, jsonInputStream);
}
}
@Override
public List<ValidationException> getDetailedException(List<ValidationException> exceptions) {
return exceptions
.stream()
.map(this::getDeepestExceptions)
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
private List<ValidationException> getDeepestExceptions(ValidationException validationException) {
if(validationException.getCausingExceptions().isEmpty()) {
return Arrays.asList(validationException);
}
return validationException
.getCausingExceptions()
.stream()
.map(this::getDeepestExceptions)
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
}

View File

@@ -1,10 +1,14 @@
package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
import net.dv8tion.jda.api.entities.SelfUser;
import net.dv8tion.jda.api.entities.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@Component
public class UserServiceBean implements UserService {
@@ -16,4 +20,18 @@ public class UserServiceBean implements UserService {
public CompletableFuture<User> retrieveUserForId(Long id) {
return botService.getInstance().retrieveUserById(id).submit();
}
@Override
public CompletableFutureList<User> retrieveUsers(List<Long> ids) {
List<CompletableFuture<User>> userFutures = ids
.stream()
.map(this::retrieveUserForId)
.collect(Collectors.toList());
return new CompletableFutureList<>(userFutures);
}
@Override
public SelfUser getSelfUser() {
return botService.getInstance().getSelfUser();
}
}

View File

@@ -1,6 +1,6 @@
abstracto.startup.synchronize=true
abstracto.eventWaiter.threads=10
abstracto.eventWaiter.threads=3
server.port=8080
abstracto.allowedmention.everyone=false