introduced eh-cache as a caching provider instead of caffeine to be used in hibernate (only ram cache is currently possible)

added caching configuration for 2nd level caching in hibernate
added command to clear hibernate caches
changed some interfaces so the api looks a bit more consistent (return the created/updated value)
split user management and user in server management
added try catch block to message received listener execution, to make them independent
moved some feature flag methods to the feature flag service bean instead of the management service, as they used the FeatureEnum directly
fixed feature disable text always rendering
removed some non embed logging
fixed message embed template
added exception logging to message embedding
This commit is contained in:
Sheldan
2020-05-01 22:42:12 +02:00
parent 59dc8c602a
commit f2ce402256
117 changed files with 1125 additions and 288 deletions

View File

@@ -39,7 +39,7 @@ public class SetExpRole extends AbstractConditionableCommand {
public CommandResult execute(CommandContext commandContext) {
Integer level = (Integer) commandContext.getParameters().getParameters().get(0);
Long roleId = (Long) commandContext.getParameters().getParameters().get(1);
ARole role = roleManagementService.findRole(roleId);
ARole role = roleManagementService.findRole(roleId, commandContext.getUserInitiatedContext().getServer());
AServer server = commandContext.getUserInitiatedContext().getServer();
if(!roleService.isRoleInServer(role)) {
throw new RoleException("Role not found.");

View File

@@ -3,6 +3,7 @@ package dev.sheldan.abstracto.experience.config;
import dev.sheldan.abstracto.core.listener.ServerConfigListener;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.ConfigService;
import dev.sheldan.abstracto.core.service.management.ConfigManagementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -19,13 +20,13 @@ public class ExperienceConfigListener implements ServerConfigListener {
private ExperienceConfig experienceConfig;
@Autowired
private ConfigService service;
private ConfigManagementService service;
@Override
public void updateServerConfig(AServer server) {
log.info("Setting up experience configuration for server {}.", server.getId());
service.createDoubleValueIfNotExist("minExp", server.getId(), experienceConfig.getMinExp().doubleValue());
service.createDoubleValueIfNotExist("maxExp", server.getId(), experienceConfig.getMaxExp().doubleValue());
service.createDoubleValueIfNotExist("expMultiplier", server.getId(), experienceConfig.getExpMultiplier().doubleValue());
service.createIfNotExists(server.getId(), "minExp", experienceConfig.getMinExp().doubleValue());
service.createIfNotExists(server.getId(), "maxExp", experienceConfig.getMaxExp().doubleValue());
service.createIfNotExists(server.getId(), "expMultiplier", experienceConfig.getExpMultiplier().doubleValue());
}
}

View File

@@ -3,7 +3,7 @@ package dev.sheldan.abstracto.experience.listener;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.listener.MessageReceivedListener;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.experience.config.features.ExperienceFeature;
import dev.sheldan.abstracto.experience.service.AUserExperienceService;
import net.dv8tion.jda.api.entities.Message;
@@ -23,12 +23,12 @@ public class ExperienceTrackerListener implements MessageReceivedListener {
private AUserExperienceService userExperienceService;
@Autowired
private UserManagementService userManagementService;
private UserInServerManagementService userInServerManagementService;
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void execute(Message message) {
AUserInAServer cause = userManagementService.loadUser(message.getMember());
AUserInAServer cause = userInServerManagementService.loadUser(message.getMember());
userExperienceService.addExperience(cause);
}

View File

@@ -5,8 +5,10 @@ import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.experience.models.database.AExperienceLevel;
import dev.sheldan.abstracto.experience.models.database.AExperienceRole;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.stereotype.Repository;
import javax.persistence.QueryHint;
import java.util.List;
/**
@@ -20,6 +22,7 @@ public interface ExperienceRoleRepository extends JpaRepository<AExperienceRole,
* @param role The {@link ARole} to filter for
* @return The {@link AExperienceRole} found or null if the query did not return any results
*/
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
AExperienceRole findByRoleServerAndRole(AServer server, ARole role);
/**
@@ -29,6 +32,7 @@ public interface ExperienceRoleRepository extends JpaRepository<AExperienceRole,
* @param server The {@link AServer} to search for
* @return The list of {@link AExperienceRole} found by the given parameters
*/
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<AExperienceRole> findByLevelAndRoleServer(AExperienceLevel level, AServer server);
/**
@@ -36,5 +40,6 @@ public interface ExperienceRoleRepository extends JpaRepository<AExperienceRole,
* @param server The {@link AServer} to load the list of {@link AExperienceRole} for
* @return A list of {@link AExperienceRole} configured to be used on the given {@link AServer}
*/
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<AExperienceRole> findByRoleServer(AServer server);
}

View File

@@ -6,9 +6,11 @@ import dev.sheldan.abstracto.experience.models.database.AUserExperience;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import javax.persistence.QueryHint;
import java.util.List;
/**
@@ -22,6 +24,7 @@ public interface UserExperienceRepository extends JpaRepository<AUserExperience
* @param server The {@link AServer} to retriev ethe {@link AUserExperience} for
* @return A complete list of {@link AUserExperience} of the given {@link AServer}
*/
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<AUserExperience> findByUser_ServerReference(AServer server);
/**
@@ -31,6 +34,7 @@ public interface UserExperienceRepository extends JpaRepository<AUserExperience
* @return A list of {@link AUserExperience} of the given {@link AServer} ordered by the experience of the users, paginated by the given
* configuration
*/
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<AUserExperience> findTop10ByUser_ServerReferenceOrderByExperienceDesc(AServer server, Pageable pageable);
/**

View File

@@ -1,11 +1,14 @@
package dev.sheldan.abstracto.experience.models.database;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.Objects;
/**
* Represents an existing level to reach and the total necessary experience needed to reach that level.
@@ -17,6 +20,8 @@ import java.io.Serializable;
@Table(name = "experience_level")
@Getter
@Setter
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class AExperienceLevel implements Serializable {
/**
* The unique level from 0 to as defined in the configuration. Will be created on startup.
@@ -27,4 +32,18 @@ public class AExperienceLevel implements Serializable {
* The total amount of experience needed for this level.
*/
private Long experienceNeeded;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AExperienceLevel that = (AExperienceLevel) o;
return Objects.equals(level, that.level) &&
Objects.equals(experienceNeeded, that.experienceNeeded);
}
@Override
public int hashCode() {
return Objects.hash(level, experienceNeeded);
}
}

View File

@@ -3,11 +3,13 @@ package dev.sheldan.abstracto.experience.models.database;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.AServer;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* Represents a role which is given when the user reaches a certain level. These roles are configurable per server and
@@ -20,6 +22,8 @@ import java.util.List;
@Table(name = "experience_role")
@Getter
@Setter
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class AExperienceRole implements Serializable {
/**
@@ -58,5 +62,23 @@ public class AExperienceRole implements Serializable {
@OneToMany(fetch = FetchType.LAZY)
@Builder.Default
@JoinColumn(name = "experience_role_id")
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<AUserExperience> users = new ArrayList<>();
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AExperienceRole that = (AExperienceRole) o;
return Objects.equals(id, that.id) &&
Objects.equals(level, that.level) &&
Objects.equals(roleServer, that.roleServer) &&
Objects.equals(role, that.role) &&
Objects.equals(users, that.users);
}
@Override
public int hashCode() {
return Objects.hash(id, level, roleServer, role, users);
}
}

View File

@@ -2,9 +2,11 @@ package dev.sheldan.abstracto.experience.models.database;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Objects;
/**
@@ -18,6 +20,8 @@ import java.io.Serializable;
@Table(name = "user_experience")
@Getter
@Setter
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class AUserExperience implements Serializable {
/**
@@ -53,4 +57,22 @@ public class AUserExperience implements Serializable {
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinColumn(name = "experience_role_id")
private AExperienceRole currentExperienceRole;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AUserExperience that = (AUserExperience) o;
return Objects.equals(id, that.id) &&
Objects.equals(user, that.user) &&
Objects.equals(experience, that.experience) &&
Objects.equals(messageCount, that.messageCount) &&
Objects.equals(currentLevel, that.currentLevel) &&
Objects.equals(currentExperienceRole, that.currentExperienceRole);
}
@Override
public int hashCode() {
return Objects.hash(id, user, experience, messageCount, currentLevel, currentExperienceRole);
}
}

View File

@@ -36,8 +36,6 @@ public class MessageDeleteLogListener implements MessageDeletedListener {
log.trace("Message {} in channel {} in guild {} was deleted.", messageFromCache.getMessageId(), messageFromCache.getChannelId(), messageFromCache.getServerId());
MessageDeletedLog logModel = (MessageDeletedLog) contextUtils.fromMessage(messageFromCache, MessageDeletedLog.class);
logModel.setMessage(messageFromCache);
String simpleMessageUpdatedMessage = templateService.renderTemplate(MESSAGE_DELETED_TEMPLATE, logModel);
postTargetService.sendTextInPostTarget(simpleMessageUpdatedMessage, DELETE_LOG_TARGET, messageFromCache.getServerId());
MessageToSend message = templateService.renderEmbedTemplate(MESSAGE_DELETED_TEMPLATE, logModel);
postTargetService.sendEmbedInPostTarget(message, DELETE_LOG_TARGET, messageFromCache.getServerId());
for (int i = 0; i < messageFromCache.getAttachmentUrls().size(); i++) {

View File

@@ -3,13 +3,20 @@ package dev.sheldan.abstracto.moderation.repository;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.moderation.models.database.Mute;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.stereotype.Repository;
import javax.persistence.QueryHint;
import java.util.List;
@Repository
public interface MuteRepository extends JpaRepository<Mute, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
boolean existsByMutedUserAndMuteEndedFalse(AUserInAServer userInAServer);
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
Mute findTopByMutedUserAndMuteEndedFalse(AUserInAServer userInAServer);
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<Mute> findAllByMutedUserAndMuteEndedFalseOrderByIdDesc(AUserInAServer aUserInAServer);
}

View File

@@ -3,12 +3,18 @@ package dev.sheldan.abstracto.moderation.repository;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.moderation.models.database.MuteRole;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.stereotype.Repository;
import javax.persistence.QueryHint;
import java.util.List;
@Repository
public interface MuteRoleRepository extends JpaRepository<MuteRole, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
MuteRole findByRoleServer(AServer server);
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<MuteRole> findAllByRoleServer(AServer server);
}

View File

@@ -3,12 +3,15 @@ package dev.sheldan.abstracto.moderation.repository;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.moderation.models.database.Warning;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.stereotype.Repository;
import javax.persistence.QueryHint;
import java.time.Instant;
import java.util.List;
@Repository
public interface WarnRepository extends JpaRepository<Warning, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<Warning> findAllByWarnedUser_ServerReferenceAndDecayedFalseAndWarnDateLessThan(AServer server, Instant cutOffDate);
}

View File

@@ -7,7 +7,7 @@ import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.moderation.exception.MuteException;
import dev.sheldan.abstracto.moderation.models.database.Mute;
import dev.sheldan.abstracto.moderation.models.database.MuteRole;
@@ -48,7 +48,7 @@ public class MuteServiceBean implements MuteService {
private RoleService roleService;
@Autowired
private UserManagementService userManagementService;
private UserInServerManagementService userInServerManagementService;
@Autowired
private SchedulerService schedulerService;
@@ -83,13 +83,13 @@ public class MuteServiceBean implements MuteService {
public Mute muteMember(Member memberToMute, Member mutingMember, String reason, Instant unmuteDate, Message message) {
FullUser mutedUser = FullUser
.builder()
.aUserInAServer(userManagementService.loadUser(memberToMute))
.aUserInAServer(userInServerManagementService.loadUser(memberToMute))
.member(memberToMute)
.build();
FullUser mutingUser = FullUser
.builder()
.aUserInAServer(userManagementService.loadUser(mutingMember))
.aUserInAServer(userInServerManagementService.loadUser(mutingMember))
.member(mutingMember)
.build();
return muteUser(mutedUser, mutingUser, reason, unmuteDate, message);
@@ -264,6 +264,6 @@ public class MuteServiceBean implements MuteService {
@Override
public void completelyUnmuteUser(Member member) {
completelyUnmuteUser(userManagementService.loadUser(member));
completelyUnmuteUser(userInServerManagementService.loadUser(member));
}
}

View File

@@ -12,7 +12,7 @@ import dev.sheldan.abstracto.moderation.models.template.commands.WarnLog;
import dev.sheldan.abstracto.moderation.models.template.commands.WarnNotification;
import dev.sheldan.abstracto.moderation.models.database.Warning;
import dev.sheldan.abstracto.moderation.service.management.WarnManagementService;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.PostTargetService;
@@ -35,7 +35,7 @@ public class WarnServiceBean implements WarnService {
public static final String WARN_LOG_TARGET = "warnLog";
@Autowired
private UserManagementService userManagementService;
private UserInServerManagementService userInServerManagementService;
@Autowired
private WarnManagementService warnManagementService;
@@ -78,13 +78,13 @@ public class WarnServiceBean implements WarnService {
public Warning warnUser(Member warnedMember, Member warningMember, String reason, TextChannel feedbackChannel) {
FullUser warnedUser = FullUser
.builder()
.aUserInAServer(userManagementService.loadUser(warnedMember))
.aUserInAServer(userInServerManagementService.loadUser(warnedMember))
.member(warnedMember)
.build();
FullUser warningUser = FullUser
.builder()
.aUserInAServer(userManagementService.loadUser(warningMember))
.aUserInAServer(userInServerManagementService.loadUser(warningMember))
.member(warningMember)
.build();
return warnUser(warnedUser, warningUser, reason, feedbackChannel);

View File

@@ -2,7 +2,7 @@ package dev.sheldan.abstracto.moderation.service.management;
import dev.sheldan.abstracto.core.models.AServerAChannelMessage;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.moderation.models.database.Mute;
import dev.sheldan.abstracto.moderation.repository.MuteRepository;
import lombok.extern.slf4j.Slf4j;
@@ -21,7 +21,7 @@ public class MuteManagementServiceBean implements MuteManagementService {
private MuteRepository muteRepository;
@Autowired
private UserManagementService userManagementService;
private UserInServerManagementService userInServerManagementService;
@Override
public Mute createMute(AUserInAServer aUserInAServer, AUserInAServer mutingUser, String reason, Instant unmuteDate, AServerAChannelMessage origin) {
@@ -66,7 +66,7 @@ public class MuteManagementServiceBean implements MuteManagementService {
@Override
public Mute getAMuteOf(Member userInAServer) {
return getAMuteOf(userManagementService.loadUser(userInAServer));
return getAMuteOf(userInServerManagementService.loadUser(userInAServer));
}
@Override

View File

@@ -7,6 +7,7 @@ import lombok.*;
import javax.persistence.*;
import java.time.Instant;
import java.util.Objects;
@Entity
@Table(name="mute")
@@ -50,5 +51,26 @@ public class Mute {
private String triggerKey;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Mute mute = (Mute) o;
return Objects.equals(id, mute.id) &&
Objects.equals(mutedUser, mute.mutedUser) &&
Objects.equals(mutingUser, mute.mutingUser) &&
Objects.equals(reason, mute.reason) &&
Objects.equals(muteDate, mute.muteDate) &&
Objects.equals(muteTargetDate, mute.muteTargetDate) &&
Objects.equals(muteEnded, mute.muteEnded) &&
Objects.equals(messageId, mute.messageId) &&
Objects.equals(mutingServer, mute.mutingServer) &&
Objects.equals(mutingChannel, mute.mutingChannel) &&
Objects.equals(triggerKey, mute.triggerKey);
}
@Override
public int hashCode() {
return Objects.hash(id, mutedUser, mutingUser, reason, muteDate, muteTargetDate, muteEnded, messageId, mutingServer, mutingChannel, triggerKey);
}
}

View File

@@ -5,6 +5,7 @@ import dev.sheldan.abstracto.core.models.database.AServer;
import lombok.*;
import javax.persistence.*;
import java.util.Objects;
/**
* Represents a role to be used for muting users on a certain server
@@ -40,4 +41,19 @@ public class MuteRole {
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "role_id", nullable = false)
private ARole role;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MuteRole muteRole = (MuteRole) o;
return Objects.equals(id, muteRole.id) &&
Objects.equals(roleServer, muteRole.roleServer) &&
Objects.equals(role, muteRole.role);
}
@Override
public int hashCode() {
return Objects.hash(id, roleServer, role);
}
}

View File

@@ -5,6 +5,7 @@ import lombok.*;
import javax.persistence.*;
import java.time.Instant;
import java.util.Objects;
@Entity
@Table(name="warning")
@@ -42,5 +43,22 @@ public class Warning {
@Setter
private Instant decayDate;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Warning warning = (Warning) o;
return Objects.equals(id, warning.id) &&
Objects.equals(warnedUser, warning.warnedUser) &&
Objects.equals(warningUser, warning.warningUser) &&
Objects.equals(reason, warning.reason) &&
Objects.equals(warnDate, warning.warnDate) &&
Objects.equals(decayed, warning.decayed) &&
Objects.equals(decayDate, warning.decayDate);
}
@Override
public int hashCode() {
return Objects.hash(id, warnedUser, warningUser, reason, warnDate, decayed, decayDate);
}
}

View File

@@ -5,7 +5,7 @@ import dev.sheldan.abstracto.core.listener.MessageReceivedListener;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.MessageCache;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.utility.models.MessageEmbedLink;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.service.MessageEmbedService;
@@ -25,10 +25,8 @@ public class MessageEmbedListener implements MessageReceivedListener {
@Autowired
private MessageCache messageCache;
public static final String MESSAGE_EMBED_TEMPLATE = "message";
@Autowired
private UserManagementService userManagementService;
private UserInServerManagementService userInServerManagementService;
@Autowired
private MessageEmbedService messageEmbedService;
@@ -39,9 +37,13 @@ public class MessageEmbedListener implements MessageReceivedListener {
List<MessageEmbedLink> links = messageEmbedService.getLinksInMessage(messageRaw);
for (MessageEmbedLink messageEmbedLink : links) {
messageRaw = messageRaw.replace(messageEmbedLink.getWholeUrl(), "");
AUserInAServer cause = userManagementService.loadUser(message.getMember());
AUserInAServer cause = userInServerManagementService.loadUser(message.getMember());
Consumer<CachedMessage> cachedMessageConsumer = cachedMessage -> messageEmbedService.embedLink(cachedMessage, message.getTextChannel(), cause, message);
messageCache.getMessageFromCache(messageEmbedLink.getServerId(), messageEmbedLink.getChannelId(), messageEmbedLink.getMessageId()).thenAccept(cachedMessageConsumer);
messageCache.getMessageFromCache(messageEmbedLink.getServerId(), messageEmbedLink.getChannelId(), messageEmbedLink.getMessageId()).thenAccept(cachedMessageConsumer)
.exceptionally(throwable -> {
log.error("Error when embedding link.", throwable);
return null;
});
}
if(StringUtils.isBlank(messageRaw) && !links.isEmpty()) {
message.delete().queue();

View File

@@ -11,7 +11,7 @@ import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.EmoteService;
import dev.sheldan.abstracto.core.service.management.ConfigManagementService;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.utils.EmoteUtils;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.database.StarboardPost;
@@ -51,7 +51,7 @@ public class StarboardListener implements ReactedAddedListener, ReactedRemovedLi
private StarboardPostReactorManagementService starboardPostReactorManagementService;
@Autowired
private UserManagementService userManagementService;
private UserInServerManagementService userInServerManagementService;
@Autowired
private EmoteService emoteService;
@@ -81,7 +81,7 @@ public class StarboardListener implements ReactedAddedListener, ReactedRemovedLi
if (userExceptAuthor.size() >= starMinimum) {
log.info("Post reached starboard minimum. Message {} in channel {} in server {} will be starred/updated.",
message.getMessageId(), message.getChannelId(), message.getServerId());
AUserInAServer author = userManagementService.loadUser(message.getServerId(), message.getAuthorId());
AUserInAServer author = userInServerManagementService.loadUser(message.getServerId(), message.getAuthorId());
if(starboardPostOptional.isPresent()) {
StarboardPost starboardPost = starboardPostOptional.get();
starboardPost.setIgnored(false);

View File

@@ -2,7 +2,12 @@ package dev.sheldan.abstracto.utility.repository;
import dev.sheldan.abstracto.utility.models.database.EmbeddedMessage;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import javax.persistence.QueryHint;
public interface EmbeddedMessageRepository extends JpaRepository<EmbeddedMessage, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
EmbeddedMessage findByEmbeddingMessageId(Long messageId);
}

View File

@@ -3,9 +3,15 @@ package dev.sheldan.abstracto.utility.repository;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.utility.models.database.Reminder;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.stereotype.Repository;
import javax.persistence.QueryHint;
import java.util.List;
@Repository
public interface ReminderRepository extends JpaRepository<Reminder, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<Reminder> getByRemindedUserAndRemindedFalse(AUserInAServer aUserInAServer);
}

View File

@@ -5,11 +5,17 @@ import dev.sheldan.abstracto.utility.models.database.StarboardPost;
import dev.sheldan.abstracto.utility.models.database.StarboardPostReaction;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.QueryHints;
import javax.persistence.QueryHint;
import java.util.List;
public interface StarboardPostReactionRepository extends JpaRepository<StarboardPostReaction, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
void deleteByReactorAndStarboardPost(AUser user, StarboardPost post);
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
void deleteByStarboardPost(StarboardPost post);
@Query(value = "SELECT r.reactor_id as userId, COUNT(*) AS starCount \n" +

View File

@@ -2,12 +2,22 @@ package dev.sheldan.abstracto.utility.repository;
import dev.sheldan.abstracto.utility.models.database.StarboardPost;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.stereotype.Repository;
import javax.persistence.QueryHint;
import java.util.List;
@Repository
public interface StarboardPostRepository extends JpaRepository<StarboardPost, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
StarboardPost findByPostMessageId(Long messageId);
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
StarboardPost findByStarboardMessageId(Long messageId);
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<StarboardPost> findByStarboardChannelServerId(Long serverId);
}

View File

@@ -2,6 +2,8 @@ package dev.sheldan.abstracto.utility.repository;
import dev.sheldan.abstracto.utility.models.database.Suggestion;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface SuggestionRepository extends JpaRepository<Suggestion, Long> {
}

View File

@@ -12,7 +12,7 @@ import dev.sheldan.abstracto.core.service.MessageCache;
import dev.sheldan.abstracto.core.service.MessageService;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.utility.models.MessageEmbedLink;
import dev.sheldan.abstracto.utility.service.management.MessageEmbedPostManagementService;
@@ -48,7 +48,7 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
private ServerManagementService serverManagementService;
@Autowired
private UserManagementService userManagementService;
private UserInServerManagementService userInServerManagementService;
@Autowired
private BotService botService;
@@ -128,7 +128,7 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
private MessageEmbeddedModel buildTemplateParameter(Message message, CachedMessage embeddedMessage) {
AChannel channel = channelManagementService.loadChannel(message.getChannel().getIdLong());
AServer server = serverManagementService.loadOrCreate(message.getGuild().getIdLong());
AUserInAServer user = userManagementService.loadUser(message.getMember());
AUserInAServer user = userInServerManagementService.loadUser(message.getMember());
Member author = botService.getMemberInServer(embeddedMessage.getServerId(), embeddedMessage.getAuthorId());
Optional<TextChannel> textChannelFromServer = botService.getTextChannelFromServer(embeddedMessage.getServerId(), embeddedMessage.getChannelId());
TextChannel sourceChannel = null;

View File

@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.utility.models.database.EmbeddedMessage;
import dev.sheldan.abstracto.utility.repository.EmbeddedMessageRepository;
import lombok.extern.slf4j.Slf4j;
@@ -23,7 +23,7 @@ public class MessageEmbedPostManagementServiceBean implements MessageEmbedPostMa
private EmbeddedMessageRepository embeddedMessageRepository;
@Autowired
private UserManagementService userManagementService;
private UserInServerManagementService userInServerManagementService;
@Override
@Transactional
@@ -32,7 +32,7 @@ public class MessageEmbedPostManagementServiceBean implements MessageEmbedPostMa
AChannel embeddedChannel = AChannel.builder().id(embeddedMessage.getChannelId()).build();
AServer embeddingServer = AServer.builder().id(messageContainingEmbed.getGuild().getIdLong()).build();
AChannel embeddingChannel = AChannel.builder().id(messageContainingEmbed.getTextChannel().getIdLong()).build();
AUserInAServer embeddedAuthor = userManagementService.loadUser(embeddedMessage.getServerId(), embeddedMessage.getAuthorId());
AUserInAServer embeddedAuthor = userInServerManagementService.loadUser(embeddedMessage.getServerId(), embeddedMessage.getAuthorId());
EmbeddedMessage messageEmbedPost = EmbeddedMessage
.builder()
.embeddedMessageId(embeddedMessage.getMessageId())

View File

@@ -2,7 +2,7 @@ package dev.sheldan.abstracto.utility.service.management;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
@@ -26,14 +26,14 @@ public class SuggestionManagementServiceBean implements SuggestionManagementServ
private ChannelManagementService channelManagementService;
@Autowired
private UserManagementService userManagementService;
private UserInServerManagementService userInServerManagementService;
@Autowired
private ServerManagementService serverManagementService;
@Override
public Suggestion createSuggestion(Member suggester, String text) {
AUserInAServer user = userManagementService.loadUser(suggester);
AUserInAServer user = userInServerManagementService.loadUser(suggester);
return this.createSuggestion(user, text);
}

View File

@@ -4,8 +4,10 @@ import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.util.Objects;
@Entity
@Table(name="embedded_message")
@@ -14,6 +16,8 @@ import javax.persistence.*;
@NoArgsConstructor
@Getter
@Setter
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class EmbeddedMessage {
@Getter
@@ -52,4 +56,24 @@ public class EmbeddedMessage {
@Column
@Id
private Long embeddingMessageId;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EmbeddedMessage that = (EmbeddedMessage) o;
return Objects.equals(embeddedUser, that.embeddedUser) &&
Objects.equals(embeddingUser, that.embeddingUser) &&
Objects.equals(embeddedServer, that.embeddedServer) &&
Objects.equals(embeddedChannel, that.embeddedChannel) &&
Objects.equals(embeddedMessageId, that.embeddedMessageId) &&
Objects.equals(embeddingServer, that.embeddingServer) &&
Objects.equals(embeddingChannel, that.embeddingChannel) &&
Objects.equals(embeddingMessageId, that.embeddingMessageId);
}
@Override
public int hashCode() {
return Objects.hash(embeddedUser, embeddingUser, embeddedServer, embeddedChannel, embeddedMessageId, embeddingServer, embeddingChannel, embeddingMessageId);
}
}

View File

@@ -4,9 +4,11 @@ import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.time.Instant;
import java.util.Objects;
@Entity
@Table(name="reminder")
@@ -15,6 +17,8 @@ import java.time.Instant;
@NoArgsConstructor
@Getter
@Setter
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Reminder {
@Id
@@ -52,4 +56,24 @@ public class Reminder {
@Getter
private boolean reminded;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Reminder reminder = (Reminder) o;
return reminded == reminder.reminded &&
Objects.equals(id, reminder.id) &&
Objects.equals(remindedUser, reminder.remindedUser) &&
Objects.equals(messageId, reminder.messageId) &&
Objects.equals(channel, reminder.channel) &&
Objects.equals(server, reminder.server) &&
Objects.equals(reminderDate, reminder.reminderDate) &&
Objects.equals(targetDate, reminder.targetDate) &&
Objects.equals(text, reminder.text);
}
@Override
public int hashCode() {
return Objects.hash(id, remindedUser, messageId, channel, server, reminderDate, targetDate, text, reminded);
}
}

View File

@@ -3,10 +3,12 @@ package dev.sheldan.abstracto.utility.models.database;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AUser;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.time.Instant;
import java.util.List;
import java.util.Objects;
@Entity
@Table(name="starboard_post")
@@ -15,6 +17,8 @@ import java.util.List;
@NoArgsConstructor
@Getter
@Setter
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class StarboardPost {
@Id
@@ -52,6 +56,7 @@ public class StarboardPost {
orphanRemoval = true,
cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name="postId")
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<StarboardPostReaction> reactions;
@Column
@@ -66,4 +71,26 @@ public class StarboardPost {
}
return this.reactions.size();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StarboardPost post = (StarboardPost) o;
return ignored == post.ignored &&
Objects.equals(id, post.id) &&
Objects.equals(author, post.author) &&
Objects.equals(starboardMessageId, post.starboardMessageId) &&
Objects.equals(postMessageId, post.postMessageId) &&
Objects.equals(starboardChannel, post.starboardChannel) &&
Objects.equals(sourceChanel, post.sourceChanel) &&
Objects.equals(reactionCount, post.reactionCount) &&
Objects.equals(reactions, post.reactions) &&
Objects.equals(starredDate, post.starredDate);
}
@Override
public int hashCode() {
return Objects.hash(id, author, starboardMessageId, postMessageId, starboardChannel, sourceChanel, reactionCount, reactions, starredDate, ignored);
}
}

View File

@@ -2,8 +2,10 @@ package dev.sheldan.abstracto.utility.models.database;
import dev.sheldan.abstracto.core.models.database.AUser;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.util.Objects;
@Entity
@Table(name="starboard_post_reaction")
@@ -12,6 +14,8 @@ import javax.persistence.*;
@NoArgsConstructor
@Getter
@Setter
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class StarboardPostReaction {
@Id
@@ -26,4 +30,18 @@ public class StarboardPostReaction {
@JoinColumn(name = "postId", nullable = false)
private StarboardPost starboardPost;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StarboardPostReaction that = (StarboardPostReaction) o;
return Objects.equals(id, that.id) &&
Objects.equals(reactor, that.reactor) &&
Objects.equals(starboardPost, that.starboardPost);
}
@Override
public int hashCode() {
return Objects.hash(id, reactor, starboardPost);
}
}

View File

@@ -8,13 +8,15 @@ import lombok.*;
import javax.persistence.*;
import java.time.Instant;
import java.util.Objects;
@Entity
@Table(name="suggestion")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter @Setter
@Getter
@Setter
public class Suggestion {
@Id
@@ -48,4 +50,22 @@ public class Suggestion {
@Enumerated(EnumType.STRING)
private SuggestionState state;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Suggestion that = (Suggestion) o;
return Objects.equals(id, that.id) &&
Objects.equals(suggester, that.suggester) &&
Objects.equals(messageId, that.messageId) &&
Objects.equals(channel, that.channel) &&
Objects.equals(server, that.server) &&
Objects.equals(suggestionDate, that.suggestionDate) &&
state == that.state;
}
@Override
public int hashCode() {
return Objects.hash(id, suggester, messageId, channel, server, suggestionDate, state);
}
}

View File

@@ -89,8 +89,14 @@
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jcache</artifactId>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>

View File

@@ -16,7 +16,7 @@ import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.RoleManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.context.UserInitiatedServerContext;
@@ -52,7 +52,7 @@ public class CommandReceivedHandler extends ListenerAdapter {
private ServerManagementService serverManagementService;
@Autowired
private UserManagementService userManagementService;
private UserInServerManagementService userInServerManagementService;
@Autowired
private ChannelManagementService channelManagementService;
@@ -74,13 +74,14 @@ public class CommandReceivedHandler extends ListenerAdapter {
if(!commandManager.isCommand(event.getMessage())) {
return;
}
UserInitiatedServerContext userInitiatedContext = buildTemplateParameter(event);
CommandContext.CommandContextBuilder commandContextBuilder = CommandContext.builder()
.author(event.getMember())
.guild(event.getGuild())
.channel(event.getTextChannel())
.message(event.getMessage())
.jda(event.getJDA())
.userInitiatedContext(buildTemplateParameter(event));
.userInitiatedContext(userInitiatedContext);
Command foundCommand = null;
try {
String contentStripped = event.getMessage().getContentStripped();
@@ -88,7 +89,7 @@ public class CommandReceivedHandler extends ListenerAdapter {
UnParsedCommandParameter unparsedParameter = new UnParsedCommandParameter(contentStripped);
String commandName = commandManager.getCommandName(parameters.get(0), event.getGuild().getIdLong());
foundCommand = commandManager.findCommandByParameters(commandName, unparsedParameter);
Parameters parsedParameters = getParsedParameters(unparsedParameter, foundCommand, event.getMessage());
Parameters parsedParameters = getParsedParameters(unparsedParameter, foundCommand, event.getMessage(), userInitiatedContext);
CommandContext commandContext = commandContextBuilder.parameters(parsedParameters).build();
CommandResult commandResult;
if(foundCommand instanceof ConditionalCommand) {
@@ -134,7 +135,7 @@ public class CommandReceivedHandler extends ListenerAdapter {
private UserInitiatedServerContext buildTemplateParameter(MessageReceivedEvent event) {
AChannel channel = channelManagementService.loadChannel(event.getChannel().getIdLong());
AServer server = serverManagementService.loadOrCreate(event.getGuild().getIdLong());
AUserInAServer user = userManagementService.loadUser(event.getMember());
AUserInAServer user = userInServerManagementService.loadUser(event.getMember());
return UserInitiatedServerContext
.builder()
.channel(channel)
@@ -147,7 +148,7 @@ public class CommandReceivedHandler extends ListenerAdapter {
.build();
}
public Parameters getParsedParameters(UnParsedCommandParameter unParsedCommandParameter, Command command, Message message){
public Parameters getParsedParameters(UnParsedCommandParameter unParsedCommandParameter, Command command, Message message, UserInitiatedServerContext userInitiatedServerContext){
List<Object> parsedParameters = new ArrayList<>();
if(command.getConfiguration().getParameters() == null || command.getConfiguration().getParameters().isEmpty()) {
return Parameters.builder().parameters(parsedParameters).build();
@@ -189,9 +190,9 @@ public class CommandReceivedHandler extends ListenerAdapter {
}
} else if(param.getType().equals(ARole.class)) {
if(StringUtils.isNumeric(value)) {
parsedParameters.add(roleManagementService.findRole(Long.parseLong(value)));
parsedParameters.add(roleManagementService.findRole(Long.parseLong(value), userInitiatedServerContext.getServer()));
} else {
parsedParameters.add(roleManagementService.findRole(roleIterator.next().getIdLong()));
parsedParameters.add(roleManagementService.findRole(roleIterator.next().getIdLong(), userInitiatedServerContext.getServer()));
}
} else if(param.getType().equals(Boolean.class)) {
parsedParameters.add(Boolean.valueOf(value));

View File

@@ -4,10 +4,16 @@ import dev.sheldan.abstracto.core.command.models.database.ACommand;
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
import dev.sheldan.abstracto.core.models.database.AChannelGroupCommand;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import javax.persistence.QueryHint;
import java.util.List;
public interface ChannelGroupCommandRepository extends JpaRepository<AChannelGroupCommand, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
AChannelGroupCommand findByCommandAndGroup(ACommand command, AChannelGroup group);
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<AChannelGroupCommand> findByCommand(ACommand command);
}

View File

@@ -4,9 +4,14 @@ import dev.sheldan.abstracto.core.command.models.database.ACommand;
import dev.sheldan.abstracto.core.command.models.database.ACommandInAServer;
import dev.sheldan.abstracto.core.models.database.AServer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.stereotype.Repository;
import javax.persistence.QueryHint;
@Repository
public interface CommandInServerRepository extends JpaRepository<ACommandInAServer, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
ACommandInAServer findByServerReferenceAndCommandReference(AServer server, ACommand command);
}

View File

@@ -2,7 +2,12 @@ package dev.sheldan.abstracto.core.command.repository;
import dev.sheldan.abstracto.core.command.models.database.ACommand;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import javax.persistence.QueryHint;
public interface CommandRepository extends JpaRepository<ACommand, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
ACommand findByName(String name);
}

View File

@@ -2,7 +2,12 @@ package dev.sheldan.abstracto.core.command.repository;
import dev.sheldan.abstracto.core.command.models.database.AModule;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import javax.persistence.QueryHint;
public interface ModuleRepository extends JpaRepository<AModule, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
AModule findByName(String name);
}

View File

@@ -0,0 +1,48 @@
package dev.sheldan.abstracto.core.commands.config;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.features.CoreFeatures;
import dev.sheldan.abstracto.core.service.CacheServiceBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class ClearCache extends AbstractConditionableCommand {
@Autowired
private CacheServiceBean cacheServiceBean;
@Override
public CommandResult execute(CommandContext commandContext) {
cacheServiceBean.clearCaches();
return CommandResult.fromSuccess();
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("clearCache")
.module(ConfigModuleInterface.CONFIG)
.parameters(parameters)
.help(helpInfo)
.templated(true)
.causesReaction(true)
.build();
}
@Override
public FeatureEnum getFeature() {
return CoreFeatures.CORE_FEATURE;
}
}

View File

@@ -1,4 +1,4 @@
package dev.sheldan.abstracto.core;
package dev.sheldan.abstracto.core.config;
import lombok.Getter;
import lombok.Setter;

View File

@@ -35,7 +35,7 @@ public class FeatureFlagListener implements ServerConfigListener {
String featureKey = featureFlagKey.getFeature().getKey();
AFeature feature = featureManagementService.getFeature(featureKey);
boolean featureFlagValue = BooleanUtils.toBoolean(environment.getProperty("abstracto.features." + featureKey, "false"));
if(!service.getFeatureFlag(feature, server.getId()).isPresent()) {
if(service.getFeatureFlag(feature, server.getId()) == null) {
service.createFeatureFlag(feature, server.getId(), featureFlagValue);
}
});

View File

@@ -3,7 +3,7 @@ package dev.sheldan.abstracto.core.listener;
import dev.sheldan.abstracto.core.config.FeatureConfig;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.FeatureFlagService;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
@@ -26,7 +26,7 @@ public class JoinListenerBean extends ListenerAdapter {
private FeatureFlagService featureFlagService;
@Autowired
private UserManagementService userManagementService;
private UserInServerManagementService userInServerManagementService;
@Override
@Transactional
@@ -37,7 +37,7 @@ public class JoinListenerBean extends ListenerAdapter {
return;
}
try {
AUserInAServer aUserInAServer = userManagementService.loadUser(event.getMember());
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(event.getMember());
executeListener(event, joinListener, aUserInAServer);
} catch (Exception e) {
log.error("Listener {} failed with exception:", joinListener.getClass().getName(), e);

View File

@@ -27,16 +27,20 @@ public class MessageReceivedListenerBean extends ListenerAdapter {
private FeatureFlagService featureFlagService;
@Override
@Transactional
public void onGuildMessageReceived(@Nonnull GuildMessageReceivedEvent event) {
messageCache.putMessageInCache(event.getMessage());
listenerList.forEach(messageReceivedListener -> {
FeatureConfig feature = featureFlagService.getFeatureDisplayForFeature(messageReceivedListener.getFeature());
if(!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
return;
try {
FeatureConfig feature = featureFlagService.getFeatureDisplayForFeature(messageReceivedListener.getFeature());
if(!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
return;
}
messageReceivedListener.execute(event.getMessage());
} catch (Exception e) {
log.error("Listener {} had exception when executing.", messageReceivedListener, e);
}
messageReceivedListener.execute(event.getMessage());
});
}
}

View File

@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.config.FeatureConfig;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.FeatureFlagService;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.cache.CachedReaction;
import dev.sheldan.abstracto.core.models.database.AUser;
@@ -33,7 +33,7 @@ public class ReactionUpdatedListener extends ListenerAdapter {
private MessageCache messageCache;
@Autowired
private UserManagementService userManagementService;
private UserInServerManagementService userInServerManagementService;
@Autowired
private List<ReactedAddedListener> addedListenerList;
@@ -95,7 +95,7 @@ public class ReactionUpdatedListener extends ListenerAdapter {
@Transactional
public void callAddedListeners(@Nonnull GuildMessageReactionAddEvent event, CachedMessage cachedMessage, CachedReaction reaction) {
AUserInAServer userInAServer = userManagementService.loadUser(event.getGuild().getIdLong(), event.getUserIdLong());
AUserInAServer userInAServer = userInServerManagementService.loadUser(event.getGuild().getIdLong(), event.getUserIdLong());
addReactionIfNotThere(cachedMessage, reaction, userInAServer.getUserReference());
addedListenerList.forEach(reactedAddedListener -> {
FeatureConfig feature = featureFlagService.getFeatureDisplayForFeature(reactedAddedListener.getFeature());
@@ -130,7 +130,7 @@ public class ReactionUpdatedListener extends ListenerAdapter {
@Transactional
public void callRemoveListeners(@Nonnull GuildMessageReactionRemoveEvent event, CachedMessage cachedMessage, CachedReaction reaction) {
AUserInAServer userInAServer = userManagementService.loadUser(event.getGuild().getIdLong(), event.getUserIdLong());
AUserInAServer userInAServer = userInServerManagementService.loadUser(event.getGuild().getIdLong(), event.getUserIdLong());
removeReactionIfThere(cachedMessage, reaction, userInAServer.getUserReference());
reactionRemovedListener.forEach(reactionRemovedListener -> {
FeatureConfig feature = featureFlagService.getFeatureDisplayForFeature(reactionRemovedListener.getFeature());

View File

@@ -37,6 +37,7 @@ public class RoleListener extends ListenerAdapter {
@Override
@Transactional
public void onRoleDelete(@Nonnull RoleDeleteEvent event) {
roleService.markDeleted(event.getRole());
AServer server = serverManagementService.loadOrCreate(event.getGuild().getIdLong());
roleService.markDeleted(event.getRole(), server);
}
}

View File

@@ -3,10 +3,16 @@ package dev.sheldan.abstracto.core.repository;
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
import dev.sheldan.abstracto.core.models.database.AServer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import javax.persistence.QueryHint;
import java.util.List;
public interface ChannelGroupRepository extends JpaRepository<AChannelGroup, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
AChannelGroup findByGroupNameAndServer(String name, AServer server);
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<AChannelGroup> findByServer(AServer server);
}

View File

@@ -2,11 +2,15 @@ package dev.sheldan.abstracto.core.repository;
import dev.sheldan.abstracto.core.models.database.AChannel;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.stereotype.Repository;
import javax.persistence.QueryHint;
import java.util.List;
@Repository
public interface ChannelRepository extends JpaRepository<AChannel, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<AChannel> findAll();
}

View File

@@ -2,7 +2,12 @@ package dev.sheldan.abstracto.core.repository;
import dev.sheldan.abstracto.core.models.database.AConfig;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import javax.persistence.QueryHint;
public interface ConfigRepository extends JpaRepository<AConfig, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
AConfig findAConfigByServerIdAndName(Long serverId, String name);
}

View File

@@ -3,10 +3,17 @@ package dev.sheldan.abstracto.core.repository;
import dev.sheldan.abstracto.core.models.database.AEmote;
import dev.sheldan.abstracto.core.models.database.AServer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.stereotype.Repository;
import javax.persistence.QueryHint;
@Repository
public interface EmoteRepository extends JpaRepository<AEmote, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
AEmote findAEmoteByNameAndServerRef(String name, AServer server);
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
boolean existsByNameAndServerRef(String name, AServer server);
}

View File

@@ -4,10 +4,16 @@ import dev.sheldan.abstracto.core.models.database.AFeature;
import dev.sheldan.abstracto.core.models.database.AFeatureFlag;
import dev.sheldan.abstracto.core.models.database.AServer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import javax.persistence.QueryHint;
import java.util.List;
public interface FeatureFlagRepository extends JpaRepository<AFeatureFlag, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
AFeatureFlag findByServerAndFeature(AServer server, AFeature key);
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<AFeatureFlag> findAllByServer(AServer server);
}

View File

@@ -2,9 +2,14 @@ package dev.sheldan.abstracto.core.repository;
import dev.sheldan.abstracto.core.models.database.AFeature;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.stereotype.Repository;
import javax.persistence.QueryHint;
@Repository
public interface FeatureRepository extends JpaRepository<AFeature, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
AFeature findByKey(String key);
}

View File

@@ -3,11 +3,15 @@ package dev.sheldan.abstracto.core.repository;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.PostTarget;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.stereotype.Repository;
import javax.persistence.QueryHint;
@Repository
public interface PostTargetRepository extends JpaRepository<PostTarget, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
PostTarget findPostTargetByNameAndServerReference(String name, AServer server);
}

View File

@@ -4,10 +4,17 @@ import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUser;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.stereotype.Repository;
import javax.persistence.QueryHint;
@Repository
public interface UserInServerRepository extends JpaRepository<AUserInAServer, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
AUserInAServer findByServerReferenceAndUserReference(AServer serverId, AUser userId);
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
boolean existsByServerReferenceAndUserReference(AServer server, AUser user);
}

View File

@@ -0,0 +1,30 @@
package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.persistence.EntityManagerFactory;
@Component
@Slf4j
public class CacheServiceBean {
private SessionFactory sessionFactory;
@Autowired
public CacheServiceBean(EntityManagerFactory factory) {
SessionFactory unWrapped = factory.unwrap(SessionFactory.class);
if(unWrapped == null){
throw new AbstractoRunTimeException("Factory is not a hibernate factory.");
}
this.sessionFactory = unWrapped;
}
public void clearCaches() {
sessionFactory.getCache().evictAllRegions();
}
}

View File

@@ -35,11 +35,6 @@ public class ConfigServiceBean implements ConfigService{
return config.getStringValue();
}
@Override
public void createDoubleValueIfNotExist(String name, Long serverId, Double value) {
configManagementService.createIfNotExists(serverId, name, value);
}
@Override
public void setDoubleValue(String name, Long serverId, Double value) {
if(configManagementService.configExists(serverId, name)) {

View File

@@ -1,6 +1,6 @@
package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.DynamicKeyLoader;
import dev.sheldan.abstracto.core.config.DynamicKeyLoader;
import dev.sheldan.abstracto.core.exception.EmoteException;
import dev.sheldan.abstracto.core.models.database.AEmote;
import dev.sheldan.abstracto.core.service.management.EmoteManagementService;

View File

@@ -1,9 +1,12 @@
package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.command.service.management.FeatureManagementService;
import dev.sheldan.abstracto.core.config.FeatureConfig;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.exception.FeatureNotFoundException;
import dev.sheldan.abstracto.core.models.database.AFeature;
import dev.sheldan.abstracto.core.models.database.AFeatureFlag;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.FeatureFlagManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
@@ -20,6 +23,9 @@ public class FeatureFlagServiceBean implements FeatureFlagService {
@Autowired
private FeatureFlagManagementService managementService;
@Autowired
private FeatureManagementService featureManagementService;
@Autowired
private List<FeatureConfig> availableFeatures;
@@ -29,12 +35,12 @@ public class FeatureFlagServiceBean implements FeatureFlagService {
@Override
public boolean isFeatureEnabled(FeatureConfig name, Long serverId) {
return managementService.getFeatureFlagValue(name.getFeature(), serverId);
return getFeatureFlagValue(name.getFeature(), serverId);
}
@Override
public boolean isFeatureEnabled(FeatureConfig name, AServer server) {
return managementService.getFeatureFlagValue(name.getFeature(), server);
return getFeatureFlagValue(name.getFeature(), server);
}
@Override
@@ -49,7 +55,7 @@ public class FeatureFlagServiceBean implements FeatureFlagService {
if(!doesFeatureExist(name)) {
throw new FeatureNotFoundException("Feature not found.", feature.getKey(), getFeaturesAsList());
}
managementService.updateFeatureFlag(feature, server, true);
updateFeatureFlag(feature, server, true);
}
@Override
@@ -64,7 +70,7 @@ public class FeatureFlagServiceBean implements FeatureFlagService {
if(!doesFeatureExist(name)) {
throw new FeatureNotFoundException("Feature not found.", feature.getKey(), getFeaturesAsList());
}
managementService.updateFeatureFlag(feature, server, false);
updateFeatureFlag(feature, server, false);
}
@Override
@@ -115,4 +121,28 @@ public class FeatureFlagServiceBean implements FeatureFlagService {
}
throw new AbstractoRunTimeException(String.format("Feature %s not found.", key));
}
@Override
public boolean getFeatureFlagValue(FeatureEnum key, Long serverId) {
AServer server = serverManagementService.loadOrCreate(serverId);
return getFeatureFlagValue(key, server);
}
@Override
public boolean getFeatureFlagValue(FeatureEnum key, AServer server) {
AFeature feature = featureManagementService.getFeature(key.getKey());
AFeatureFlag featureFlag = managementService.getFeatureFlag(feature, server);
return featureFlag.isEnabled();
}
@Override
public AFeatureFlag updateFeatureFlag(FeatureEnum key, Long serverId, Boolean newValue) {
AServer server = serverManagementService.loadOrCreate(serverId);
return updateFeatureFlag(key, server, newValue);
}
@Override
public AFeatureFlag updateFeatureFlag(FeatureEnum key, AServer server, Boolean newValue) {
AFeature feature = featureManagementService.getFeature(key.getKey());
return managementService.setFeatureFlagValue(feature, server, newValue);
}
}

View File

@@ -10,6 +10,7 @@ import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.requests.restaction.pagination.ReactionPaginationAction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
@@ -26,6 +27,7 @@ import java.util.concurrent.ExecutionException;
@Component
@Slf4j
@CacheConfig(cacheNames = "messages")
public class MessageCacheBean implements MessageCache {
@Autowired
@@ -40,7 +42,7 @@ public class MessageCacheBean implements MessageCache {
private MessageCache self;
@Override
@CachePut(key = "#message.id", cacheNames = "messages")
@CachePut(key = "#message.id")
public CompletableFuture<CachedMessage> putMessageInCache(Message message) {
log.info("Adding message {} to cache", message.getId());
CompletableFuture<CachedMessage> future = new CompletableFuture<>();
@@ -56,14 +58,14 @@ public class MessageCacheBean implements MessageCache {
}
@Override
@Cacheable(key = "#message.id", cacheNames = "messages")
@Cacheable(key = "#message.id")
public CompletableFuture<CachedMessage> getMessageFromCache(Message message) {
log.info("Retrieving message {}", message.getId());
return getMessageFromCache(message.getGuild().getIdLong(), message.getChannel().getIdLong(), message.getIdLong());
}
@Override
@Cacheable(key = "#messageId.toString()", cacheNames = "messages")
@Cacheable(key = "#messageId.toString()")
public CompletableFuture<CachedMessage> getMessageFromCache(Long guildId, Long textChannelId, Long messageId) {
log.info("Retrieving message with parameters");
@@ -204,4 +206,5 @@ public class MessageCacheBean implements MessageCache {
return builder.build();
}
}

View File

@@ -1,6 +1,6 @@
package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.DynamicKeyLoader;
import dev.sheldan.abstracto.core.config.DynamicKeyLoader;
import dev.sheldan.abstracto.core.exception.ChannelException;
import dev.sheldan.abstracto.core.exception.GuildException;
import dev.sheldan.abstracto.core.service.management.PostTargetManagement;

View File

@@ -3,6 +3,7 @@ package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.exception.GuildException;
import dev.sheldan.abstracto.core.exception.RoleException;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.RoleManagementService;
import lombok.extern.slf4j.Slf4j;
@@ -59,13 +60,13 @@ public class RoleServiceBean implements RoleService {
}
@Override
public void markDeleted(Role role) {
markDeleted(role.getIdLong());
public void markDeleted(Role role, AServer server) {
markDeleted(role.getIdLong(), server);
}
@Override
public void markDeleted(Long id) {
ARole role = roleManagementService.findRole(id);
public void markDeleted(Long id, AServer server) {
ARole role = roleManagementService.findRole(id, server);
if(role != null) {
roleManagementService.markDeleted(role);
} else {

View File

@@ -54,7 +54,6 @@ public class ChannelGroupManagementServiceBean implements ChannelGroupManagement
}
channelGroup.getChannels().add(channel);
channel.getGroups().add(channelGroup);
channelGroupRepository.save(channelGroup);
return channelGroup;
}
@@ -66,7 +65,6 @@ public class ChannelGroupManagementServiceBean implements ChannelGroupManagement
}
channelGroup.getChannels().removeIf(channelInGroupPredicate);
channel.getGroups().removeIf(channelGroup1 -> channelGroup1.getId().equals(channelGroup.getId()));
channelGroupRepository.save(channelGroup);
}
@Override

View File

@@ -34,10 +34,10 @@ public class ChannelManagementServiceBean implements ChannelManagementService {
}
@Override
public void markAsDeleted(Long id) {
public AChannel markAsDeleted(Long id) {
AChannel channel = loadChannel(id);
channel.setDeleted(true);
repository.save(channel);
return channel;
}
@Override

View File

@@ -3,10 +3,12 @@ package dev.sheldan.abstracto.core.service.management;
import dev.sheldan.abstracto.core.models.database.AConfig;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.repository.ConfigRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class ConfigManagementServiceBean implements ConfigManagementService {
@Autowired
@@ -16,23 +18,25 @@ public class ConfigManagementServiceBean implements ConfigManagementService {
private ServerManagementService serverManagementService;
@Override
public void setOrCreateStringValue(Long serverId, String name, String value) {
public AConfig setOrCreateStringValue(Long serverId, String name, String value) {
AConfig config = loadConfig(serverId, name);
if(config == null) {
createConfig(serverId, name, value);
} else {
config.setStringValue(value);
}
return config;
}
@Override
public void setOrCreateDoubleValue(Long serverId, String name, Double value) {
public AConfig setOrCreateDoubleValue(Long serverId, String name, Double value) {
AConfig config = loadConfig(serverId, name);
if(config == null) {
createConfig(serverId, name, value);
} else {
config.setDoubleValue(value);
}
return config;
}
@Override
@@ -90,15 +94,17 @@ public class ConfigManagementServiceBean implements ConfigManagementService {
}
@Override
public void setDoubleValue(Long serverId, String name, Double value) {
public AConfig setDoubleValue(Long serverId, String name, Double value) {
AConfig config = loadConfig(serverId, name);
config.setDoubleValue(value);
return config;
}
@Override
public void setStringValue(Long serverId, String name, String value) {
public AConfig setStringValue(Long serverId, String name, String value) {
AConfig config = loadConfig(serverId, name);
config.setStringValue(value);
return config;
}
}

View File

@@ -1,6 +1,6 @@
package dev.sheldan.abstracto.core.service.management;
import dev.sheldan.abstracto.core.DynamicKeyLoader;
import dev.sheldan.abstracto.core.config.DynamicKeyLoader;
import dev.sheldan.abstracto.core.exception.EmoteException;
import dev.sheldan.abstracto.core.models.database.AEmote;
import dev.sheldan.abstracto.core.models.database.AServer;
@@ -145,30 +145,6 @@ public class EmoteManagementServiceBean implements EmoteManagementService {
return repository.existsByNameAndServerRef(name, server);
}
@Override
public AEmote createCustomEmote(String name, String emoteKey, Long emoteId, Boolean animated) {
AEmote emote = AEmote.builder()
.animated(animated)
.custom(true)
.emoteKey(emoteKey)
.emoteId(emoteId)
.name(name)
.build();
repository.save(emote);
return emote;
}
@Override
public AEmote createDefaultEmote(String name, String emoteKey) {
AEmote emote = AEmote.builder()
.custom(false)
.emoteKey(emoteKey)
.name(name)
.build();
repository.save(emote);
return emote;
}
private void validateEmoteName(String name) {
List<String> possibleEmotes = dynamicKeyLoader.getEmoteNamesAsList();
if(!possibleEmotes.contains(name)) {

View File

@@ -1,7 +1,6 @@
package dev.sheldan.abstracto.core.service.management;
import dev.sheldan.abstracto.core.command.service.management.FeatureManagementService;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.models.database.AFeature;
import dev.sheldan.abstracto.core.models.database.AFeatureFlag;
import dev.sheldan.abstracto.core.models.database.AServer;
@@ -25,13 +24,13 @@ public class FeatureFlagManagementServiceBean implements FeatureFlagManagementSe
private FeatureManagementService featureManagementService;
@Override
public void createFeatureFlag(AFeature feature, Long serverId, Boolean newValue) {
public AFeatureFlag createFeatureFlag(AFeature feature, Long serverId, Boolean newValue) {
AServer server = serverManagementService.loadOrCreate(serverId);
createFeatureFlag(feature, server, newValue);
return createFeatureFlag(feature, server, newValue);
}
@Override
public void createFeatureFlag(AFeature feature, AServer server, Boolean newValue) {
public AFeatureFlag createFeatureFlag(AFeature feature, AServer server, Boolean newValue) {
AFeatureFlag featureFlag = AFeatureFlag
.builder()
.enabled(newValue)
@@ -39,52 +38,37 @@ public class FeatureFlagManagementServiceBean implements FeatureFlagManagementSe
.server(server)
.build();
repository.save(featureFlag);
return featureFlag;
}
@Override
public boolean getFeatureFlagValue(FeatureEnum key, Long serverId) {
AServer server = serverManagementService.loadOrCreate(serverId);
return getFeatureFlagValue(key, server);
}
@Override
public boolean getFeatureFlagValue(FeatureEnum key, AServer server) {
AFeature feature = featureManagementService.getFeature(key.getKey());
Optional<AFeatureFlag> featureFlag = getFeatureFlag(feature, server);
return featureFlag.isPresent() && featureFlag.get().isEnabled();
}
@Override
public void updateFeatureFlag(FeatureEnum key, Long serverId, Boolean newValue) {
AServer server = serverManagementService.loadOrCreate(serverId);
updateFeatureFlag(key, server, newValue);
}
@Override
public void updateFeatureFlag(FeatureEnum key, AServer server, Boolean newValue) {
AFeature feature = featureManagementService.getFeature(key.getKey());
Optional<AFeatureFlag> existing = getFeatureFlag(feature, server);
if(existing.isPresent()) {
AFeatureFlag flag = existing.get();
flag.setEnabled(newValue);
repository.save(flag);
}
}
@Override
public Optional<AFeatureFlag> getFeatureFlag(AFeature feature, Long serverId) {
public AFeatureFlag getFeatureFlag(AFeature feature, Long serverId) {
AServer server = serverManagementService.loadOrCreate(serverId);
return getFeatureFlag(feature, server);
}
@Override
public Optional<AFeatureFlag> getFeatureFlag(AFeature key, AServer server) {
return Optional.ofNullable(repository.findByServerAndFeature(server, key));
public AFeatureFlag getFeatureFlag(AFeature feature, AServer server) {
return repository.findByServerAndFeature(server, feature);
}
@Override
public List<AFeatureFlag> getFeatureFlagsOfServer(AServer server) {
return repository.findAllByServer(server);
}
@Override
public AFeatureFlag setFeatureFlagValue(AFeature feature, Long serverId, Boolean newValue) {
AFeatureFlag featureFlag = getFeatureFlag(feature, serverId);
featureFlag.setEnabled(newValue);
return featureFlag;
}
@Override
public AFeatureFlag setFeatureFlagValue(AFeature feature, AServer server, Boolean newValue) {
AFeatureFlag featureFlag = getFeatureFlag(feature, server);
featureFlag.setEnabled(newValue);
return featureFlag;
}
}

View File

@@ -1,6 +1,6 @@
package dev.sheldan.abstracto.core.service.management;
import dev.sheldan.abstracto.core.DynamicKeyLoader;
import dev.sheldan.abstracto.core.config.DynamicKeyLoader;
import dev.sheldan.abstracto.core.exception.PostTargetException;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
@@ -9,7 +9,6 @@ import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.core.repository.PostTargetRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
@@ -32,39 +31,40 @@ public class PostTargetManagementBean implements PostTargetManagement {
private PostTargetService postTargetService;
@Override
public void createPostTarget(String name, AServer server, AChannel targetChannel) {
public PostTarget createPostTarget(String name, AServer server, AChannel targetChannel) {
if(!postTargetService.validPostTarget(name)) {
throw new PostTargetException("PostTarget not found. Possible values are: " + String.join(", ", dynamicKeyLoader.getPostTargetsAsList()));
}
log.info("Creating post target {} pointing towards {}", name, targetChannel);
postTargetRepository.save(PostTarget.builder().name(name).channelReference(targetChannel).serverReference(server).build());
PostTarget build = PostTarget.builder().name(name).channelReference(targetChannel).serverReference(server).build();
postTargetRepository.save(build);
return build;
}
@Override
public void createOrUpdate(String name, AServer server, AChannel targetChannel) {
public PostTarget createOrUpdate(String name, AServer server, AChannel targetChannel) {
PostTarget existing = postTargetRepository.findPostTargetByNameAndServerReference(name, server);
if(existing == null){
this.createPostTarget(name, server, targetChannel);
return this.createPostTarget(name, server, targetChannel);
} else {
this.updatePostTarget(existing, server, targetChannel);
return this.updatePostTarget(existing, server, targetChannel);
}
}
@Override
public void createOrUpdate(String name, AServer server, Long channelId) {
public PostTarget createOrUpdate(String name, AServer server, Long channelId) {
AChannel dbChannel = channelManagementService.loadChannel(channelId);
createOrUpdate(name, server, dbChannel);
return createOrUpdate(name, server, dbChannel);
}
@Override
public void createOrUpdate(String name, Long serverId, Long channelId) {
public PostTarget createOrUpdate(String name, Long serverId, Long channelId) {
AChannel dbChannel = channelManagementService.loadChannel(channelId);
AServer dbServer = serverManagementService.loadOrCreate(serverId);
createOrUpdate(name, dbServer, dbChannel);
return createOrUpdate(name, dbServer, dbChannel);
}
@Override
@Cacheable("posttargets")
public PostTarget getPostTarget(String name, AServer server) {
return postTargetRepository.findPostTargetByNameAndServerReference(name, server);
}
@@ -76,8 +76,9 @@ public class PostTargetManagementBean implements PostTargetManagement {
}
@Override
public void updatePostTarget(PostTarget target, AServer server, AChannel newTargetChannel) {
postTargetRepository.getOne(target.getId()).setChannelReference(newTargetChannel);
public PostTarget updatePostTarget(PostTarget target, AServer server, AChannel newTargetChannel) {
target.setChannelReference(newTargetChannel);
return target;
}
}

View File

@@ -24,7 +24,7 @@ public class RoleManagementServiceBean implements RoleManagementService {
}
@Override
public ARole findRole(Long id) {
public ARole findRole(Long id, AServer server) {
return repository.getOne(id);
}

View File

@@ -0,0 +1,58 @@
package dev.sheldan.abstracto.core.service.management;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUser;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.repository.UserInServerRepository;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class UserInServerManagementServiceBean implements UserInServerManagementService {
@Autowired
private UserInServerRepository userInServerRepository;
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private UserManagementService userManagementService;
@Override
public AUserInAServer loadUser(Long serverId, Long userId) {
AUser user = userManagementService.loadUser(userId);
AServer server = serverManagementService.loadOrCreate(serverId);
return loadUser(server, user);
}
@Override
public AUserInAServer loadUser(AServer server, AUser user) {
if(userInServerRepository.existsByServerReferenceAndUserReference(server, user)) {
return userInServerRepository.findByServerReferenceAndUserReference(server, user);
} else {
return this.createUserInServer(server.getId(), user.getId());
}
}
@Override
public AUserInAServer loadUser(Member member) {
return this.loadUser(member.getGuild().getIdLong(), member.getIdLong());
}
@Override
public AUserInAServer createUserInServer(Member member) {
return this.createUserInServer(member.getGuild().getIdLong(), member.getIdLong());
}
@Override
public AUserInAServer createUserInServer(Long guildId, Long userId) {
AUserInAServer aUserInAServer = serverManagementService.addUserToServer(guildId, userId);
userInServerRepository.save(aUserInAServer);
return aUserInAServer;
}
}

View File

@@ -1,9 +1,6 @@
package dev.sheldan.abstracto.core.service.management;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUser;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.repository.UserInServerRepository;
import dev.sheldan.abstracto.core.repository.UserRepository;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
@@ -14,57 +11,12 @@ import org.springframework.stereotype.Component;
@Slf4j
public class UserManagementServiceBean implements UserManagementService {
@Autowired
private UserInServerRepository userInServerRepository;
@Autowired
private UserRepository userRepository;
@Autowired
private ServerManagementService serverManagementService;
@Override
public AUserInAServer loadUser(Long serverId, Long userId) {
AUser user = this.loadUser(userId);
AServer server = serverManagementService.loadOrCreate(serverId);
return loadUser(server, user);
}
@Override
public AUserInAServer loadUser(AServer server, AUser user) {
if(userInServerRepository.existsByServerReferenceAndUserReference(server, user)) {
return userInServerRepository.findByServerReferenceAndUserReference(server, user);
} else {
return this.createUserInServer(server.getId(), user.getId());
}
}
@Override
public AUserInAServer loadUser(Member member) {
return this.loadUser(member.getGuild().getIdLong(), member.getIdLong());
}
@Override
public AUserInAServer loadUserInServer(Long userInServerId) {
return userInServerRepository.getOne(userInServerId);
}
@Override
public AUserInAServer createUserInServer(Member member) {
return this.createUserInServer(member.getGuild().getIdLong(), member.getIdLong());
}
@Override
public AUserInAServer createUserInServer(Long guildId, Long userId) {
AUserInAServer aUserInAServer = serverManagementService.addUserToServer(guildId, userId);
userInServerRepository.save(aUserInAServer);
return aUserInAServer;
}
@Override
public AUser createUser(Member member) {
return createUser(member.getIdLong());
return createUser(member.getIdLong());
}
@Override

View File

@@ -7,11 +7,19 @@ spring.jpa.show-sql = false
spring.jpa.hibernate.ddl-auto = update
spring.jpa.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.naming_strategy = org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.format_sql = false
log4j.logger.org.hibernate.SQL=info
log4j.logger.org.hibernate.type.descriptor.sql=trace
log4j.logger.org.hibernate.type=trace
spring.jpa.properties.hibernate.generate_statistics = false
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.use_query_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.jcache.JCacheRegionFactory
spring.jpa.properties.javax.persistence.sharedCache.mode=ENABLE_SELECTIVE
spring.jpa.properties.hibernate.javax.cache.missing_cache_strategy = create
spring.cache.jcache.config=classpath:ehcache.xml
logging.level.dev.sheldan=info
spring.cache.cache-names=messages
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s

View File

@@ -0,0 +1,26 @@
<config
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://www.ehcache.org/v3'
xsi:schemaLocation="
http://www.ehcache.org/v3
http://www.ehcache.org/schema/ehcache-core-3.8-1.xsd">
<cache uses-template="default" alias="messages">
<key-type>java.lang.String</key-type>
<value-type>java.util.concurrent.CompletableFuture</value-type>
<expiry>
<ttl unit="seconds">600</ttl>
</expiry>
<resources>
<heap unit="entries">500</heap>
</resources>
</cache>
<cache-template name="default">
<expiry>
<ttl unit="seconds">600</ttl>
</expiry>
<resources>
<heap>50</heap>
</resources>
</cache-template>
</config>

View File

@@ -5,7 +5,6 @@ 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;
@@ -13,9 +12,6 @@ import org.springframework.stereotype.Component;
@Component
public class FeatureEnabledCondition implements CommandCondition {
@Autowired
private FeatureFlagManagementService featureFlagManagementService;
@Autowired
private TemplateService templateService;
@@ -28,12 +24,14 @@ public class FeatureEnabledCondition implements CommandCondition {
boolean featureFlagValue = true;
String reason = "";
if(feature != null) {
featureFlagValue = featureFlagManagementService.getFeatureFlagValue(feature, context.getGuild().getIdLong());
FeatureDisabledMessage featureDisabledMessage = FeatureDisabledMessage
.builder()
.featureConfig(featureFlagService.getFeatureDisplayForFeature(feature))
.build();
reason = templateService.renderTemplate("feature_disabled_message", featureDisabledMessage);
featureFlagValue = featureFlagService.getFeatureFlagValue(feature, context.getGuild().getIdLong());
if(!featureFlagValue) {
FeatureDisabledMessage featureDisabledMessage = FeatureDisabledMessage
.builder()
.featureConfig(featureFlagService.getFeatureDisplayForFeature(feature))
.build();
reason = templateService.renderTemplate("feature_disabled_message", featureDisabledMessage);
}
}
return ConditionResult.builder().reason(reason).result(featureFlagValue).build();
}

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.command.exception;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.templating.Templatable;
public class CommandNotFound extends AbstractoRunTimeException implements Templatable {

View File

@@ -1,8 +1,8 @@
package dev.sheldan.abstracto.core.command.exception;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import java.util.HashMap;

View File

@@ -1,8 +1,8 @@
package dev.sheldan.abstracto.core.command.exception;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.templating.Templatable;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import java.util.HashMap;

View File

@@ -2,8 +2,10 @@ package dev.sheldan.abstracto.core.command.models.database;
import dev.sheldan.abstracto.core.models.database.AFeature;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.util.Objects;
@Entity
@Table(name = "command")
@@ -11,6 +13,8 @@ import javax.persistence.*;
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class ACommand {
@Id
@Column(name = "id")
@@ -31,4 +35,19 @@ public class ACommand {
@JoinColumn(name = "feature_id", nullable = false)
private AFeature feature;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ACommand aCommand = (ACommand) o;
return Objects.equals(id, aCommand.id) &&
Objects.equals(name, aCommand.name) &&
Objects.equals(module, aCommand.module) &&
Objects.equals(feature, aCommand.feature);
}
@Override
public int hashCode() {
return Objects.hash(id, name, module, feature);
}
}

View File

@@ -3,9 +3,11 @@ package dev.sheldan.abstracto.core.command.models.database;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.AServer;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.util.List;
import java.util.Objects;
@Entity
@Getter
@@ -13,6 +15,8 @@ import java.util.List;
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class ACommandInAServer {
@Id
@@ -30,11 +34,13 @@ public class ACommandInAServer {
@ManyToMany(fetch = FetchType.LAZY)
@Getter
@JoinColumn(name = "allowed_role_id")
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<ARole> allowedRoles;
@ManyToMany(fetch = FetchType.LAZY)
@Getter
@JoinColumn(name = "immune_role_id")
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<ARole> immuneRoles;
@Getter
@@ -42,7 +48,23 @@ public class ACommandInAServer {
@Column
private Boolean restricted;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ACommandInAServer that = (ACommandInAServer) o;
return Objects.equals(commandInServerId, that.commandInServerId) &&
Objects.equals(commandReference, that.commandReference) &&
Objects.equals(serverReference, that.serverReference) &&
Objects.equals(allowedRoles, that.allowedRoles) &&
Objects.equals(immuneRoles, that.immuneRoles) &&
Objects.equals(restricted, that.restricted);
}
@Override
public int hashCode() {
return Objects.hash(commandInServerId, commandReference, serverReference, allowedRoles, immuneRoles, restricted);
}
}

View File

@@ -4,10 +4,12 @@ import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Entity
@Table(name = "module")
@@ -15,6 +17,8 @@ import java.util.List;
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class AModule {
@Id
@@ -30,5 +34,21 @@ public class AModule {
orphanRemoval = true)
@Builder.Default
@JoinColumn(name = "module_id")
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<ACommand> commands = new ArrayList<>();
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AModule aModule = (AModule) o;
return Objects.equals(id, aModule.id) &&
Objects.equals(name, aModule.name) &&
Objects.equals(commands, aModule.commands);
}
@Override
public int hashCode() {
return Objects.hash(id, name, commands);
}
}

View File

@@ -5,13 +5,14 @@ import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.time.Instant;
import java.util.List;
@Getter
@Setter
@Builder
public class CachedMessage {
public class CachedMessage implements Serializable {
private Long serverId;
private Long channelId;
private Long messageId;

View File

@@ -3,15 +3,19 @@ package dev.sheldan.abstracto.core.models.database;
import dev.sheldan.abstracto.core.models.SnowFlake;
import lombok.*;
import net.dv8tion.jda.api.entities.ChannelType;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.util.List;
import java.util.Objects;
@Entity
@Table(name="channel")
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class AChannel implements SnowFlake {
@Id
@@ -21,6 +25,7 @@ public class AChannel implements SnowFlake {
@Getter
@ManyToMany(mappedBy = "channels")
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<AChannelGroup> groups;
@ManyToOne(fetch = FetchType.LAZY)
@@ -47,4 +52,21 @@ public class AChannel implements SnowFlake {
default: return AChannelType.UNKOWN;
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AChannel channel = (AChannel) o;
return Objects.equals(id, channel.id) &&
Objects.equals(groups, channel.groups) &&
Objects.equals(server, channel.server) &&
type == channel.type &&
Objects.equals(deleted, channel.deleted);
}
@Override
public int hashCode() {
return Objects.hash(id, groups, server, type, deleted);
}
}

View File

@@ -1,9 +1,11 @@
package dev.sheldan.abstracto.core.models.database;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.util.List;
import java.util.Objects;
@Entity
@Table(name="channelGroup")
@@ -11,6 +13,8 @@ import java.util.List;
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class AChannelGroup {
@Id
@@ -32,7 +36,22 @@ public class AChannelGroup {
name = "channel_in_group",
joinColumns = @JoinColumn(name = "group_id"),
inverseJoinColumns = @JoinColumn(name = "channel_id"))
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<AChannel> channels;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AChannelGroup that = (AChannelGroup) o;
return Objects.equals(id, that.id) &&
Objects.equals(groupName, that.groupName) &&
Objects.equals(server, that.server) &&
Objects.equals(channels, that.channels);
}
@Override
public int hashCode() {
return Objects.hash(id, groupName, server, channels);
}
}

View File

@@ -2,8 +2,10 @@ package dev.sheldan.abstracto.core.models.database;
import dev.sheldan.abstracto.core.command.models.database.ACommand;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.util.Objects;
@Entity
@Table(name = "channel_group_command")
@@ -11,6 +13,8 @@ import javax.persistence.*;
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class AChannelGroupCommand {
@Id
@@ -30,4 +34,19 @@ public class AChannelGroupCommand {
@Setter
private Boolean enabled;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AChannelGroupCommand that = (AChannelGroupCommand) o;
return Objects.equals(commandInGroupId, that.commandInGroupId) &&
Objects.equals(command, that.command) &&
Objects.equals(group, that.group) &&
Objects.equals(enabled, that.enabled);
}
@Override
public int hashCode() {
return Objects.hash(commandInGroupId, command, group, enabled);
}
}

View File

@@ -1,8 +1,10 @@
package dev.sheldan.abstracto.core.models.database;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.util.Objects;
@Entity
@Table(name="systemConfig")
@@ -10,6 +12,8 @@ import javax.persistence.*;
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class AConfig {
@Id
@@ -32,4 +36,21 @@ public class AConfig {
@Getter
@Setter
private AServer server;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AConfig config = (AConfig) o;
return Objects.equals(Id, config.Id) &&
Objects.equals(name, config.name) &&
Objects.equals(stringValue, config.stringValue) &&
Objects.equals(doubleValue, config.doubleValue) &&
Objects.equals(server, config.server);
}
@Override
public int hashCode() {
return Objects.hash(Id, name, stringValue, doubleValue, server);
}
}

View File

@@ -1,8 +1,10 @@
package dev.sheldan.abstracto.core.models.database;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.util.Objects;
@Entity
@Table(name = "emote")
@@ -10,6 +12,8 @@ import javax.persistence.*;
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class AEmote {
@javax.persistence.Id
@@ -39,5 +43,22 @@ public class AEmote {
@JoinColumn(name = "emote_server_id", nullable = false)
private AServer serverRef;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AEmote emote = (AEmote) o;
return Objects.equals(Id, emote.Id) &&
Objects.equals(name, emote.name) &&
Objects.equals(emoteKey, emote.emoteKey) &&
Objects.equals(emoteId, emote.emoteId) &&
Objects.equals(animated, emote.animated) &&
Objects.equals(custom, emote.custom) &&
Objects.equals(serverRef, emote.serverRef);
}
@Override
public int hashCode() {
return Objects.hash(Id, name, emoteKey, emoteId, animated, custom, serverRef);
}
}

View File

@@ -3,15 +3,19 @@ package dev.sheldan.abstracto.core.models.database;
import dev.sheldan.abstracto.core.command.models.database.ACommand;
import dev.sheldan.abstracto.core.models.SnowFlake;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.util.List;
import java.util.Objects;
@Entity
@Table(name="feature")
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class AFeature implements SnowFlake {
@Id
@@ -28,6 +32,21 @@ public class AFeature implements SnowFlake {
@Setter
@OneToMany
@JoinColumn(name = "feature_id")
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<ACommand> commands;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AFeature feature = (AFeature) o;
return Objects.equals(id, feature.id) &&
Objects.equals(key, feature.key) &&
Objects.equals(commands, feature.commands);
}
@Override
public int hashCode() {
return Objects.hash(id, key, commands);
}
}

View File

@@ -1,14 +1,18 @@
package dev.sheldan.abstracto.core.models.database;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.util.Objects;
@Entity
@Table(name="feature_flag")
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class AFeatureFlag {
@Id
@@ -32,4 +36,20 @@ public class AFeatureFlag {
@Getter
@Setter
private boolean enabled;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AFeatureFlag that = (AFeatureFlag) o;
return enabled == that.enabled &&
Objects.equals(id, that.id) &&
Objects.equals(server, that.server) &&
Objects.equals(feature, that.feature);
}
@Override
public int hashCode() {
return Objects.hash(id, server, feature, enabled);
}
}

View File

@@ -2,15 +2,19 @@ package dev.sheldan.abstracto.core.models.database;
import dev.sheldan.abstracto.core.models.SnowFlake;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Objects;
@Entity
@Table(name="role")
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class ARole implements SnowFlake, Serializable {
@Id
@@ -28,4 +32,18 @@ public class ARole implements SnowFlake, Serializable {
@Setter
private Boolean deleted;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ARole role = (ARole) o;
return Objects.equals(id, role.id) &&
Objects.equals(server, role.server) &&
Objects.equals(deleted, role.deleted);
}
@Override
public int hashCode() {
return Objects.hash(id, server, deleted);
}
}

View File

@@ -2,11 +2,13 @@ package dev.sheldan.abstracto.core.models.database;
import dev.sheldan.abstracto.core.models.SnowFlake;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Entity
@Table(name = "server")
@@ -14,6 +16,8 @@ import java.util.List;
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class AServer implements SnowFlake, Serializable {
@Id
@@ -27,6 +31,7 @@ public class AServer implements SnowFlake, Serializable {
orphanRemoval = true)
@Builder.Default
@JoinColumn(name = "role_server_id")
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<ARole> roles = new ArrayList<>();
@OneToMany(
@@ -35,6 +40,7 @@ public class AServer implements SnowFlake, Serializable {
orphanRemoval = true)
@Builder.Default
@JoinColumn(name = "server_id")
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<AChannel> channels = new ArrayList<>();
@OneToMany(
@@ -43,6 +49,7 @@ public class AServer implements SnowFlake, Serializable {
orphanRemoval = true)
@Builder.Default
@JoinColumn(name = "group_server")
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<AChannelGroup> channelGroups = new ArrayList<>();
@OneToMany(
@@ -51,6 +58,7 @@ public class AServer implements SnowFlake, Serializable {
orphanRemoval = true)
@JoinColumn(name = "serverReference")
@Builder.Default
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<AUserInAServer> users = new ArrayList<>();
@OneToMany(
@@ -59,8 +67,26 @@ public class AServer implements SnowFlake, Serializable {
orphanRemoval = true)
@JoinColumn(name = "emote_server_id")
@Builder.Default
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<AEmote> emotes = new ArrayList<>();
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AServer aServer = (AServer) o;
return Objects.equals(id, aServer.id) &&
Objects.equals(name, aServer.name) &&
Objects.equals(roles, aServer.roles) &&
Objects.equals(channels, aServer.channels) &&
Objects.equals(channelGroups, aServer.channelGroups) &&
Objects.equals(users, aServer.users) &&
Objects.equals(emotes, aServer.emotes);
}
@Override
public int hashCode() {
return Objects.hash(id, name, roles, channels, channelGroups, users, emotes);
}
}

View File

@@ -1,9 +1,11 @@
package dev.sheldan.abstracto.core.models.database;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.util.List;
import java.util.Objects;
@Entity
@Table(name="users")
@@ -11,6 +13,8 @@ import java.util.List;
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class AUser {
@Id
@@ -19,5 +23,20 @@ public class AUser {
@OneToMany(
fetch = FetchType.LAZY,
cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<AUserInAServer> servers;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AUser user = (AUser) o;
return Objects.equals(id, user.id) &&
Objects.equals(servers, user.servers);
}
@Override
public int hashCode() {
return Objects.hash(id, servers);
}
}

View File

@@ -1,9 +1,11 @@
package dev.sheldan.abstracto.core.models.database;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Objects;
@Entity
@Getter
@@ -11,6 +13,8 @@ import java.io.Serializable;
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class AUserInAServer implements Serializable {
@Id
@@ -24,4 +28,19 @@ public class AUserInAServer implements Serializable {
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "serverReference", nullable = false)
private AServer serverReference;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AUserInAServer that = (AUserInAServer) o;
return Objects.equals(userInServerId, that.userInServerId) &&
Objects.equals(userReference, that.userReference) &&
Objects.equals(serverReference, that.serverReference);
}
@Override
public int hashCode() {
return Objects.hash(userInServerId, userReference, serverReference);
}
}

View File

@@ -1,14 +1,18 @@
package dev.sheldan.abstracto.core.models.database;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.util.Objects;
@Entity
@Table(name="posttarget")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class PostTarget {
@Id
@@ -29,4 +33,19 @@ public class PostTarget {
@Getter @Setter
private AServer serverReference;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PostTarget that = (PostTarget) o;
return Objects.equals(id, that.id) &&
Objects.equals(name, that.name) &&
Objects.equals(channelReference, that.channelReference) &&
Objects.equals(serverReference, that.serverReference);
}
@Override
public int hashCode() {
return Objects.hash(id, name, channelReference, serverReference);
}
}

View File

@@ -4,7 +4,6 @@ public interface ConfigService {
Double getDoubleValue(String name, Long serverId);
Double getDoubleValue(String name, Long serverId, Double defaultValue);
String getStringValue(String name, Long serverId, String defaultValue);
void createDoubleValueIfNotExist(String name, Long serverId, Double value);
void setDoubleValue(String name, Long serverId, Double value);
void setStringValue(String name, Long serverId, String value);

View File

@@ -2,6 +2,7 @@ package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.config.FeatureConfig;
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;
@@ -20,4 +21,8 @@ public interface FeatureFlagService {
boolean doesFeatureExist(FeatureConfig name);
List<String> getFeaturesAsList();
FeatureEnum getFeatureEnum(String key);
boolean getFeatureFlagValue(FeatureEnum key, Long serverId);
boolean getFeatureFlagValue(FeatureEnum key, AServer server);
AFeatureFlag updateFeatureFlag(FeatureEnum key, Long serverId, Boolean newValue);
AFeatureFlag updateFeatureFlag(FeatureEnum key, AServer server, Boolean newValue);
}

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
@@ -10,8 +11,8 @@ import java.util.List;
public interface RoleService {
void addRoleToUser(AUserInAServer aUserInAServer, ARole role);
void removeRoleFromUser(AUserInAServer aUserInAServer, ARole role);
void markDeleted(Role role);
void markDeleted(Long id);
void markDeleted(Role role, AServer server);
void markDeleted(Long id, AServer server);
Role getRoleFromGuild(ARole role);
List<Role> getRolesFromGuild(List<ARole> roles);
boolean memberHasRole(Member member, Role role);

View File

@@ -7,6 +7,6 @@ import dev.sheldan.abstracto.core.models.database.AServer;
public interface ChannelManagementService {
AChannel loadChannel(Long id);
AChannel createChannel(Long id, AChannelType type, AServer server);
void markAsDeleted(Long id);
AChannel markAsDeleted(Long id);
void removeChannel(Long id);
}

View File

@@ -3,14 +3,14 @@ package dev.sheldan.abstracto.core.service.management;
import dev.sheldan.abstracto.core.models.database.AConfig;
public interface ConfigManagementService {
void setOrCreateStringValue(Long serverId, String name, String value);
void setOrCreateDoubleValue(Long serverId, String name, Double value);
AConfig setOrCreateStringValue(Long serverId, String name, String value);
AConfig setOrCreateDoubleValue(Long serverId, String name, Double value);
AConfig createConfig(Long serverId, String name, String value);
AConfig createConfig(Long serverId, String name, Double value);
AConfig createIfNotExists(Long serverId, String name, String value);
AConfig createIfNotExists(Long serverId, String name, Double value);
AConfig loadConfig(Long serverId, String name);
boolean configExists(Long serverId, String name);
void setDoubleValue(Long serverId, String name, Double value);
void setStringValue(Long serverId, String name, String value);
AConfig setDoubleValue(Long serverId, String name, Double value);
AConfig setStringValue(Long serverId, String name, String value);
}

View File

@@ -19,6 +19,4 @@ public interface EmoteManagementService {
AEmote setEmoteToDefaultEmote(String name, String emoteKey, Long serverId) ;
boolean emoteExists(String name, Long serverId);
boolean emoteExists(String name, AServer server);
AEmote createCustomEmote(String name, String emoteKey, Long emoteId, Boolean animated);
AEmote createDefaultEmote(String name, String emoteKey);
}

View File

@@ -1,21 +1,17 @@
package dev.sheldan.abstracto.core.service.management;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.models.database.AFeature;
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(AFeature feature, Long serverId, Boolean newValue);
void createFeatureFlag(AFeature feature, AServer server, Boolean newValue);
boolean getFeatureFlagValue(FeatureEnum key, Long serverId);
boolean getFeatureFlagValue(FeatureEnum key, AServer server);
void updateFeatureFlag(FeatureEnum key, Long serverId, Boolean newValue);
void updateFeatureFlag(FeatureEnum key, AServer server, Boolean newValue);
Optional<AFeatureFlag> getFeatureFlag(AFeature key, Long serverId);
Optional<AFeatureFlag> getFeatureFlag(AFeature key, AServer server);
AFeatureFlag createFeatureFlag(AFeature feature, Long serverId, Boolean newValue);
AFeatureFlag createFeatureFlag(AFeature feature, AServer server, Boolean newValue);
AFeatureFlag getFeatureFlag(AFeature key, Long serverId);
AFeatureFlag getFeatureFlag(AFeature key, AServer server);
List<AFeatureFlag> getFeatureFlagsOfServer(AServer server);
AFeatureFlag setFeatureFlagValue(AFeature feature, Long serverId, Boolean newValue);
AFeatureFlag setFeatureFlagValue(AFeature feature, AServer server, Boolean newValue);
}

View File

@@ -5,11 +5,11 @@ import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.PostTarget;
public interface PostTargetManagement {
void createPostTarget(String name, AServer server, AChannel targetChanel);
void createOrUpdate(String name, AServer server, AChannel targetChannel);
void createOrUpdate(String name, AServer server, Long channelId);
void createOrUpdate(String name, Long serverId, Long channelId);
PostTarget createPostTarget(String name, AServer server, AChannel targetChanel);
PostTarget createOrUpdate(String name, AServer server, AChannel targetChannel);
PostTarget createOrUpdate(String name, AServer server, Long channelId);
PostTarget createOrUpdate(String name, Long serverId, Long channelId);
PostTarget getPostTarget(String name, AServer server);
PostTarget getPostTarget(String name, Long serverId);
void updatePostTarget(PostTarget target, AServer server, AChannel newTargetChannel);
PostTarget updatePostTarget(PostTarget target, AServer server, AChannel newTargetChannel);
}

Some files were not shown because too many files have changed in this diff Show More