diff --git a/bundle/src/main/java/io/theurl/bundle/application/command/BundleCreateCommand.java b/bundle/src/main/java/io/theurl/bundle/application/command/BundleCreateCommand.java new file mode 100644 index 0000000..4e7f8b0 --- /dev/null +++ b/bundle/src/main/java/io/theurl/bundle/application/command/BundleCreateCommand.java @@ -0,0 +1,20 @@ +package io.theurl.bundle.application.command; + +import com.neroyun.mediator.Command; +import lombok.Data; + +@Data +public class BundleCreateCommand implements Command { + private final String type; + private final String vanity; + private String name; + private String description; + private String image; + private Long ownerId; + private String ownerName; + + public BundleCreateCommand(String type, String vanity) { + this.type = type; + this.vanity = vanity; + } +} diff --git a/bundle/src/main/java/io/theurl/bundle/application/contract/BundleApplicationService.java b/bundle/src/main/java/io/theurl/bundle/application/contract/BundleApplicationService.java new file mode 100644 index 0000000..186d7fd --- /dev/null +++ b/bundle/src/main/java/io/theurl/bundle/application/contract/BundleApplicationService.java @@ -0,0 +1,15 @@ +package io.theurl.bundle.application.contract; + +import io.theurl.bundle.application.dto.BundleCreateDto; +import io.theurl.bundle.application.dto.BundleUpdateDto; +import io.theurl.framework.application.ApplicationService; + +import java.util.concurrent.CompletableFuture; + +public interface BundleApplicationService extends ApplicationService { + CompletableFuture createAsync(BundleCreateDto data); + + CompletableFuture updateAsync(String vanity, BundleUpdateDto data); + + CompletableFuture deleteAsync(String vanity); +} diff --git a/bundle/src/main/java/io/theurl/bundle/application/dto/BundleBaseDto.java b/bundle/src/main/java/io/theurl/bundle/application/dto/BundleBaseDto.java new file mode 100644 index 0000000..fad2f0c --- /dev/null +++ b/bundle/src/main/java/io/theurl/bundle/application/dto/BundleBaseDto.java @@ -0,0 +1,10 @@ +package io.theurl.bundle.application.dto; + +import lombok.Data; + +@Data +public abstract class BundleBaseDto { + private String name; + private String description; + private String image; +} diff --git a/bundle/src/main/java/io/theurl/bundle/application/dto/BundleCreateDto.java b/bundle/src/main/java/io/theurl/bundle/application/dto/BundleCreateDto.java new file mode 100644 index 0000000..124c265 --- /dev/null +++ b/bundle/src/main/java/io/theurl/bundle/application/dto/BundleCreateDto.java @@ -0,0 +1,24 @@ +package io.theurl.bundle.application.dto; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * DTO for creating a bundle. It extends BundleBaseDto and includes additional fields specific to bundle creation. + * The fields include: + * - type: The type of the bundle. + * - vanity: A unique identifier for the bundle, often used in URLs. + * This DTO is used when a client wants to create a new bundle and needs to provide the necessary information for the creation process. + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class BundleCreateDto extends BundleBaseDto { + /** + * The type of the bundle. This field is used to categorize the bundle and can be used for filtering and searching bundles based on their type. + */ + private String type; + /** + * A unique identifier for the bundle, often used in URLs. This field is used to create a user-friendly and memorable URL for the bundle. + */ + private String vanity; +} diff --git a/bundle/src/main/java/io/theurl/bundle/application/dto/BundleListDto.java b/bundle/src/main/java/io/theurl/bundle/application/dto/BundleListDto.java new file mode 100644 index 0000000..e8f110e --- /dev/null +++ b/bundle/src/main/java/io/theurl/bundle/application/dto/BundleListDto.java @@ -0,0 +1,21 @@ +package io.theurl.bundle.application.dto; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; + +@EqualsAndHashCode(callSuper = true) +@Data +public class BundleListDto extends BundleBaseDto { + private String type; + private String vanity; + private int itemsCount; + private int favoriteCount; + private int commentCount; + private int visitCount; + private Long ownerId; + private String ownerName; + private LocalDateTime createdAt; + private LocalDateTime updatedAt; +} diff --git a/bundle/src/main/java/io/theurl/bundle/application/dto/BundleUpdateDto.java b/bundle/src/main/java/io/theurl/bundle/application/dto/BundleUpdateDto.java new file mode 100644 index 0000000..b51beb0 --- /dev/null +++ b/bundle/src/main/java/io/theurl/bundle/application/dto/BundleUpdateDto.java @@ -0,0 +1,12 @@ +package io.theurl.bundle.application.dto; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * DTO for updating a bundle. It extends BundleBaseDto and does not add any new fields, but it can be used to differentiate between create and update operations. + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class BundleUpdateDto extends BundleBaseDto { +} diff --git a/bundle/src/main/java/io/theurl/bundle/application/handler/BundleCreateCommandHandler.java b/bundle/src/main/java/io/theurl/bundle/application/handler/BundleCreateCommandHandler.java new file mode 100644 index 0000000..82f8812 --- /dev/null +++ b/bundle/src/main/java/io/theurl/bundle/application/handler/BundleCreateCommandHandler.java @@ -0,0 +1,54 @@ +package io.theurl.bundle.application.handler; + +import com.neroyun.mediator.Handler; +import com.neroyun.mediator.Mediator; +import com.neroyun.mediator.MessageContext; +import io.theurl.bundle.application.command.BundleCreateCommand; +import io.theurl.bundle.domain.aggregate.Bundle; +import io.theurl.bundle.domain.repository.BundleRepository; +import io.theurl.framework.core.BeanScope; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.util.Objects; +import java.util.concurrent.CompletableFuture; + +@Component +@Scope(BeanScope.PROTOTYPE) +public class BundleCreateCommandHandler implements Handler { + private final BundleRepository repository; + private final Mediator mediator; + + public BundleCreateCommandHandler(BundleRepository repository, Mediator mediator) { + this.repository = repository; + this.mediator = mediator; + } + + @Override + public CompletableFuture handleAsync(BundleCreateCommand message, MessageContext context) { + var userId = Long.getLong(Objects.requireNonNull(getRequest()).getUserPrincipal().getName()); + var aggregate = Bundle.create(message.getType(), message.getVanity(), message.getName()); + if (message.getDescription() != null) { + aggregate.setDescription(message.getDescription()); + } + if (message.getImage() != null) { + aggregate.setImage(message.getImage()); + } + aggregate.setOwner(message.getOwnerId(), message.getOwnerName()); + repository.save(aggregate, userId); + return CompletableFuture.completedFuture(null); + } + + private HttpServletRequest getRequest() { + var request = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + + if (request == null) { + return null; + } + + return request.getRequest(); + } +} diff --git a/bundle/src/main/java/io/theurl/bundle/application/implement/BundleApplicationServiceImpl.java b/bundle/src/main/java/io/theurl/bundle/application/implement/BundleApplicationServiceImpl.java new file mode 100644 index 0000000..0c7b88a --- /dev/null +++ b/bundle/src/main/java/io/theurl/bundle/application/implement/BundleApplicationServiceImpl.java @@ -0,0 +1,60 @@ +package io.theurl.bundle.application.implement; + +import io.theurl.bundle.application.command.BundleCreateCommand; +import io.theurl.bundle.application.contract.BundleApplicationService; +import io.theurl.bundle.application.dto.BundleCreateDto; +import io.theurl.bundle.application.dto.BundleUpdateDto; +import io.theurl.framework.application.BaseApplicationService; +import io.theurl.framework.utility.ShortUniqueId; +import org.modelmapper.ModelMapper; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Service; +import org.springframework.web.context.annotation.RequestScope; + +import java.nio.charset.StandardCharsets; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +@Service +@RequestScope +public class BundleApplicationServiceImpl extends BaseApplicationService implements BundleApplicationService { + + private final ModelMapper mapper; + + public BundleApplicationServiceImpl(ApplicationContext applicationContext, ModelMapper mapper) { + super(applicationContext); + this.mapper = mapper; + } + + @Override + public CompletableFuture createAsync(BundleCreateDto data) { + if (data.getVanity() == null || data.getVanity().isEmpty()) { + var uuid = UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8); + long number = 0; + for (int i = 0; i < 8 && i < uuid.length; i++) { + number = (number << 8) | (uuid[i] & 0xFF); + } + + var shortId = ShortUniqueId.getDefault().encode(number); + data.setVanity(shortId); + } + + var command = new BundleCreateCommand(data.getType(), data.getVanity()); + command.setName(data.getName()); + command.setDescription(data.getDescription()); + command.setImage(data.getImage()); + + return mediator.sendAsync(command) + .thenApply(_ -> command.getVanity()); + } + + @Override + public CompletableFuture updateAsync(String vanity, BundleUpdateDto data) { + return null; + } + + @Override + public CompletableFuture deleteAsync(String vanity) { + return null; + } +} diff --git a/bundle/src/main/java/io/theurl/bundle/domain/aggregate/Bundle.java b/bundle/src/main/java/io/theurl/bundle/domain/aggregate/Bundle.java index 37bff02..415bc9a 100644 --- a/bundle/src/main/java/io/theurl/bundle/domain/aggregate/Bundle.java +++ b/bundle/src/main/java/io/theurl/bundle/domain/aggregate/Bundle.java @@ -1,5 +1,7 @@ package io.theurl.bundle.domain.aggregate; +import io.theurl.bundle.domain.event.BundleCreatedEvent; +import io.theurl.bundle.domain.event.BundleDeletedEvent; import io.theurl.framework.domain.AggregateRoot; import io.theurl.framework.utility.SnowflakeId; @@ -32,13 +34,12 @@ public Bundle(long id) { private BundleExtend extend; private boolean deleted; - public static Bundle create(String type, String vanity, String name, Long ownerId, String ownerName) { + public static Bundle create(String type, String vanity, String name) { var aggregate = new Bundle(SnowflakeId.getInstance().nextId()); aggregate.type = type; aggregate.vanity = vanity; aggregate.name = name; - aggregate.ownerId = ownerId; - aggregate.ownerName = ownerName; + aggregate.raiseEvent(new BundleCreatedEvent(type, vanity, name)); return aggregate; } @@ -90,8 +91,13 @@ public String getOwnerName() { return ownerName; } - public void setOwnerName(String ownerName) { - this.ownerName = ownerName; + public void setOwner(Long ownerId, String ownerName) { + this.ownerId = ownerId; + if (ownerId == null) { + this.ownerName = "system"; + } else { + this.ownerName = ownerName; + } } public List getItems() { @@ -132,4 +138,9 @@ public BundleExtend getExtend() { public boolean isDeleted() { return deleted; } + + public void delete() { + deleted = true; + raiseEvent(new BundleDeletedEvent(this.getId(), vanity, name, ownerId)); + } } diff --git a/bundle/src/main/java/io/theurl/bundle/domain/event/BundleCreatedEvent.java b/bundle/src/main/java/io/theurl/bundle/domain/event/BundleCreatedEvent.java new file mode 100644 index 0000000..c5194b7 --- /dev/null +++ b/bundle/src/main/java/io/theurl/bundle/domain/event/BundleCreatedEvent.java @@ -0,0 +1,18 @@ +package io.theurl.bundle.domain.event; + +import com.neroyun.mediator.Event; +import io.theurl.framework.domain.DomainEvent; +import lombok.Getter; + +@Getter +public class BundleCreatedEvent extends DomainEvent implements Event { + private final String type; + private final String vanity; + private final String name; + + public BundleCreatedEvent(String type, String vanity, String name) { + this.type = type; + this.vanity = vanity; + this.name = name; + } +} diff --git a/bundle/src/main/java/io/theurl/bundle/domain/event/BundleDeletedEvent.java b/bundle/src/main/java/io/theurl/bundle/domain/event/BundleDeletedEvent.java new file mode 100644 index 0000000..1a5d545 --- /dev/null +++ b/bundle/src/main/java/io/theurl/bundle/domain/event/BundleDeletedEvent.java @@ -0,0 +1,20 @@ +package io.theurl.bundle.domain.event; + +import com.neroyun.mediator.Event; +import io.theurl.framework.domain.DomainEvent; +import lombok.Getter; + +@Getter +public class BundleDeletedEvent extends DomainEvent implements Event { + private final long id; + private final String vanity; + private final String name; + private final Long ownerId; + + public BundleDeletedEvent(long id, String vanity, String name, Long ownerId) { + this.id = id; + this.vanity = vanity; + this.name = name; + this.ownerId = ownerId; + } +} diff --git a/bundle/src/main/java/io/theurl/bundle/persistence/handler/BundleDetailQueryHandler.java b/bundle/src/main/java/io/theurl/bundle/persistence/handler/BundleDetailQueryHandler.java index 851d863..b3040cf 100644 --- a/bundle/src/main/java/io/theurl/bundle/persistence/handler/BundleDetailQueryHandler.java +++ b/bundle/src/main/java/io/theurl/bundle/persistence/handler/BundleDetailQueryHandler.java @@ -1,6 +1,7 @@ package io.theurl.bundle.persistence.handler; import com.neroyun.mediator.Handler; +import com.neroyun.mediator.MessageContext; import io.theurl.bundle.persistence.model.BundleDetailModel; import io.theurl.bundle.persistence.query.BundleDetailQuery; import io.theurl.bundle.persistence.repository.JpaBundleRepository; @@ -25,13 +26,13 @@ public BundleDetailQueryHandler(JpaBundleRepository repository, ModelMapper mapp } @Override - public CompletableFuture handleAsync(BundleDetailQuery message) { + public CompletableFuture handleAsync(BundleDetailQuery message, MessageContext context) { var entity = repository.findByVanity(message.vanity()) .orElse(null); if (entity == null || entity.isDeleted()) { throw new EntityNotFoundException("Bundle not found with vanity: " + message.vanity()); } - + var detail = mapper.map(entity, BundleDetailModel.class); return CompletableFuture.completedFuture(detail); } diff --git a/bundle/src/main/java/io/theurl/bundle/persistence/profile/BundleMapProfile.java b/bundle/src/main/java/io/theurl/bundle/persistence/profile/BundleMapProfile.java index 399f423..58e13c3 100644 --- a/bundle/src/main/java/io/theurl/bundle/persistence/profile/BundleMapProfile.java +++ b/bundle/src/main/java/io/theurl/bundle/persistence/profile/BundleMapProfile.java @@ -39,6 +39,8 @@ public void configure() { .addMappings(expression -> { expression.map(Bundle::getType, (dest, value) -> setValue(dest, "type", value)); expression.map(Bundle::getVanity, (dest, value) -> setValue(dest, "vanity", value)); + expression.map(Bundle::getOwnerId, (dest, value) -> setValue(dest, "ownerId", value)); + expression.map(Bundle::getOwnerName, (dest, value) -> setValue(dest, "ownerName", value)); expression.map(Bundle::getName, io.theurl.bundle.domain.aggregate.Bundle::setName); expression.map(Bundle::getDescription, io.theurl.bundle.domain.aggregate.Bundle::setDescription); expression.map(Bundle::getImage, io.theurl.bundle.domain.aggregate.Bundle::setImage); diff --git a/identity/src/main/java/io/theurl/identity/application/handler/AuthlogCreateCommandHandler.java b/identity/src/main/java/io/theurl/identity/application/handler/AuthlogCreateCommandHandler.java index d3831ef..d14061a 100644 --- a/identity/src/main/java/io/theurl/identity/application/handler/AuthlogCreateCommandHandler.java +++ b/identity/src/main/java/io/theurl/identity/application/handler/AuthlogCreateCommandHandler.java @@ -1,6 +1,7 @@ package io.theurl.identity.application.handler; import com.neroyun.mediator.Handler; +import com.neroyun.mediator.MessageContext; import io.theurl.framework.core.BeanScope; import io.theurl.identity.application.command.AuthlogCreateCommand; import io.theurl.identity.domain.repository.AuthlogRepository; @@ -26,7 +27,7 @@ public AuthlogCreateCommandHandler(AuthlogRepository repository, ModelMapper map } @Override - public CompletableFuture handleAsync(AuthlogCreateCommand message) { + public CompletableFuture handleAsync(AuthlogCreateCommand message, MessageContext context) { try { var authlog = Authlog.create(message.getRequestId(), message.getUsername(), message.isSuccess()); mapper.map(message, authlog); diff --git a/identity/src/main/java/io/theurl/identity/application/handler/OnetimePasswordCreateCommandHandler.java b/identity/src/main/java/io/theurl/identity/application/handler/OnetimePasswordCreateCommandHandler.java index 2e8f917..6acd1ba 100644 --- a/identity/src/main/java/io/theurl/identity/application/handler/OnetimePasswordCreateCommandHandler.java +++ b/identity/src/main/java/io/theurl/identity/application/handler/OnetimePasswordCreateCommandHandler.java @@ -3,6 +3,7 @@ import com.neroyun.mediator.Event; import com.neroyun.mediator.Handler; import com.neroyun.mediator.Mediator; +import com.neroyun.mediator.MessageContext; import io.theurl.framework.core.BeanScope; import io.theurl.identity.application.command.OnetimePasswordCreateCommand; import io.theurl.identity.domain.aggregate.OnetimePassword; @@ -24,7 +25,7 @@ public OnetimePasswordCreateCommandHandler(OnetimePasswordRepository repository, } @Override - public CompletableFuture handleAsync(OnetimePasswordCreateCommand message) { + public CompletableFuture handleAsync(OnetimePasswordCreateCommand message, MessageContext context) { var aggregate = OnetimePassword.create(message.getRequestId(), message.getRecipient(), message.getCode(), message.getDuration()); aggregate.setUsage(message.getUsage()); repository.save(aggregate); diff --git a/identity/src/main/java/io/theurl/identity/application/handler/TokenCreateCommandHandler.java b/identity/src/main/java/io/theurl/identity/application/handler/TokenCreateCommandHandler.java index 19e121d..1fa7863 100644 --- a/identity/src/main/java/io/theurl/identity/application/handler/TokenCreateCommandHandler.java +++ b/identity/src/main/java/io/theurl/identity/application/handler/TokenCreateCommandHandler.java @@ -1,6 +1,7 @@ package io.theurl.identity.application.handler; import com.neroyun.mediator.Handler; +import com.neroyun.mediator.MessageContext; import io.theurl.framework.core.BeanScope; import io.theurl.identity.application.command.TokenCreateCommand; import io.theurl.identity.domain.aggregate.Token; @@ -25,10 +26,8 @@ public TokenCreateCommandHandler(TokenRepository repository) { } @Override - public CompletableFuture handleAsync(TokenCreateCommand message) { + public CompletableFuture handleAsync(TokenCreateCommand message, MessageContext context) { try { - - var token = Token.create(message.getJti(), message.getContent(), message.getSubject()); token.setExpiresAt(message.getExpiresAt()); token.setIssuedAt(message.getIssuedAt()); diff --git a/identity/src/main/java/io/theurl/identity/application/handler/TokenRevokeCommandHandler.java b/identity/src/main/java/io/theurl/identity/application/handler/TokenRevokeCommandHandler.java index e1d0c66..b662bd3 100644 --- a/identity/src/main/java/io/theurl/identity/application/handler/TokenRevokeCommandHandler.java +++ b/identity/src/main/java/io/theurl/identity/application/handler/TokenRevokeCommandHandler.java @@ -1,6 +1,7 @@ package io.theurl.identity.application.handler; import com.neroyun.mediator.Handler; +import com.neroyun.mediator.MessageContext; import io.theurl.framework.core.BeanScope; import io.theurl.identity.application.command.TokenRevokeCommand; import io.theurl.identity.domain.repository.TokenRepository; @@ -23,7 +24,7 @@ public TokenRevokeCommandHandler(TokenRepository repository) { } @Override - public CompletableFuture handleAsync(TokenRevokeCommand message) { + public CompletableFuture handleAsync(TokenRevokeCommand message, MessageContext context) { try { var token = repository.findByJti(message.jti()); if (token != null) { diff --git a/identity/src/main/java/io/theurl/identity/application/handler/UserAccessFailureCountCommandHandler.java b/identity/src/main/java/io/theurl/identity/application/handler/UserAccessFailureCountCommandHandler.java index b198bf8..a5a30a8 100644 --- a/identity/src/main/java/io/theurl/identity/application/handler/UserAccessFailureCountCommandHandler.java +++ b/identity/src/main/java/io/theurl/identity/application/handler/UserAccessFailureCountCommandHandler.java @@ -1,6 +1,7 @@ package io.theurl.identity.application.handler; import com.neroyun.mediator.Handler; +import com.neroyun.mediator.MessageContext; import io.theurl.framework.core.BeanScope; import io.theurl.identity.application.command.UserAccessFailureCountCommand; import io.theurl.identity.domain.repository.UserRepository; @@ -22,7 +23,7 @@ public UserAccessFailureCountCommandHandler(UserRepository repository) { } @Override - public CompletableFuture handleAsync(UserAccessFailureCountCommand message) { + public CompletableFuture handleAsync(UserAccessFailureCountCommand message, MessageContext context) { try { var user = repository.findById(message.userId()); if (user == null) { diff --git a/identity/src/main/java/io/theurl/identity/application/handler/UserAuthorityCreateCommandHandler.java b/identity/src/main/java/io/theurl/identity/application/handler/UserAuthorityCreateCommandHandler.java index 3de988a..1af0698 100644 --- a/identity/src/main/java/io/theurl/identity/application/handler/UserAuthorityCreateCommandHandler.java +++ b/identity/src/main/java/io/theurl/identity/application/handler/UserAuthorityCreateCommandHandler.java @@ -1,6 +1,7 @@ package io.theurl.identity.application.handler; import com.neroyun.mediator.Handler; +import com.neroyun.mediator.MessageContext; import io.theurl.framework.core.BeanScope; import io.theurl.identity.application.command.UserAuthorityCreateCommand; import io.theurl.identity.domain.repository.UserRepository; @@ -23,7 +24,7 @@ public UserAuthorityCreateCommandHandler(UserRepository repository) { } @Override - public CompletableFuture handleAsync(UserAuthorityCreateCommand message) { + public CompletableFuture handleAsync(UserAuthorityCreateCommand message, MessageContext context) { try { var user = repository.findById(message.id()); if (user == null) { diff --git a/identity/src/main/java/io/theurl/identity/application/handler/UserAuthorityRemoveCommandHandler.java b/identity/src/main/java/io/theurl/identity/application/handler/UserAuthorityRemoveCommandHandler.java index 26e4e16..35acdd7 100644 --- a/identity/src/main/java/io/theurl/identity/application/handler/UserAuthorityRemoveCommandHandler.java +++ b/identity/src/main/java/io/theurl/identity/application/handler/UserAuthorityRemoveCommandHandler.java @@ -1,6 +1,7 @@ package io.theurl.identity.application.handler; import com.neroyun.mediator.Handler; +import com.neroyun.mediator.MessageContext; import io.theurl.framework.core.BeanScope; import io.theurl.identity.application.command.UserAuthorityRemoveCommand; import io.theurl.identity.domain.repository.UserRepository; @@ -23,7 +24,7 @@ public UserAuthorityRemoveCommandHandler(UserRepository repository) { } @Override - public CompletableFuture handleAsync(UserAuthorityRemoveCommand message) { + public CompletableFuture handleAsync(UserAuthorityRemoveCommand message, MessageContext context) { try { var user = repository.findById(message.id()); if (user == null) { diff --git a/identity/src/main/java/io/theurl/identity/application/handler/UserCreateCommandHandler.java b/identity/src/main/java/io/theurl/identity/application/handler/UserCreateCommandHandler.java index cca7ba9..079a2ff 100644 --- a/identity/src/main/java/io/theurl/identity/application/handler/UserCreateCommandHandler.java +++ b/identity/src/main/java/io/theurl/identity/application/handler/UserCreateCommandHandler.java @@ -1,6 +1,7 @@ package io.theurl.identity.application.handler; import com.neroyun.mediator.Handler; +import com.neroyun.mediator.MessageContext; import io.theurl.framework.core.BeanScope; import io.theurl.identity.application.command.UserCreateCommand; import io.theurl.identity.domain.aggregate.User; @@ -27,7 +28,7 @@ public UserCreateCommandHandler(UserRepository repository) { @Async @Transactional @Override - public CompletableFuture handleAsync(UserCreateCommand message) { + public CompletableFuture handleAsync(UserCreateCommand message, MessageContext context) { try { var exists = repository.findByAnyOf(message.getUsername(), message.getEmail(), message.getPhone()); diff --git a/identity/src/main/java/io/theurl/identity/application/handler/UserPasswordChangeCommandHandler.java b/identity/src/main/java/io/theurl/identity/application/handler/UserPasswordChangeCommandHandler.java index 2967fd7..9ff6dbc 100644 --- a/identity/src/main/java/io/theurl/identity/application/handler/UserPasswordChangeCommandHandler.java +++ b/identity/src/main/java/io/theurl/identity/application/handler/UserPasswordChangeCommandHandler.java @@ -1,6 +1,7 @@ package io.theurl.identity.application.handler; import com.neroyun.mediator.Handler; +import com.neroyun.mediator.MessageContext; import io.theurl.framework.core.BeanScope; import io.theurl.identity.application.command.UserPasswordChangeCommand; import io.theurl.identity.domain.repository.UserRepository; @@ -22,7 +23,7 @@ public UserPasswordChangeCommandHandler(UserRepository repository) { } @Override - public CompletableFuture handleAsync(UserPasswordChangeCommand message) { + public CompletableFuture handleAsync(UserPasswordChangeCommand message, MessageContext context) { try { var user = repository.findById(message.userId()); if (user == null) { diff --git a/identity/src/main/java/io/theurl/identity/application/handler/UserUpdateCommandHandler.java b/identity/src/main/java/io/theurl/identity/application/handler/UserUpdateCommandHandler.java index 4e6c5c5..02c473a 100644 --- a/identity/src/main/java/io/theurl/identity/application/handler/UserUpdateCommandHandler.java +++ b/identity/src/main/java/io/theurl/identity/application/handler/UserUpdateCommandHandler.java @@ -1,6 +1,7 @@ package io.theurl.identity.application.handler; import com.neroyun.mediator.Handler; +import com.neroyun.mediator.MessageContext; import io.theurl.framework.core.BeanScope; import io.theurl.identity.application.command.UserUpdateCommand; import io.theurl.identity.domain.repository.UserRepository; @@ -23,7 +24,7 @@ public UserUpdateCommandHandler(UserRepository repository) { } @Override - public CompletableFuture handleAsync(UserUpdateCommand message) { + public CompletableFuture handleAsync(UserUpdateCommand message, MessageContext context) { try { var user = repository.findById(message.getId()); diff --git a/identity/src/main/java/io/theurl/identity/persistence/handler/OnetimePasswordDetailQueryHandler.java b/identity/src/main/java/io/theurl/identity/persistence/handler/OnetimePasswordDetailQueryHandler.java index c427bdc..731d487 100644 --- a/identity/src/main/java/io/theurl/identity/persistence/handler/OnetimePasswordDetailQueryHandler.java +++ b/identity/src/main/java/io/theurl/identity/persistence/handler/OnetimePasswordDetailQueryHandler.java @@ -1,6 +1,7 @@ package io.theurl.identity.persistence.handler; import com.neroyun.mediator.Handler; +import com.neroyun.mediator.MessageContext; import io.theurl.framework.core.BeanScope; import io.theurl.identity.persistence.model.OnetimePasswordDetail; import io.theurl.identity.persistence.query.OnetimePasswordDetailQuery; @@ -10,7 +11,6 @@ import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; -import org.springframework.web.context.WebApplicationContext; import java.util.concurrent.CompletableFuture; @@ -19,16 +19,16 @@ public class OnetimePasswordDetailQueryHandler implements Handler { @PersistenceContext - private EntityManager context; + private EntityManager manager; @Override @Async - public CompletableFuture handleAsync(OnetimePasswordDetailQuery message) { - var builder = context.getCriteriaBuilder(); + public CompletableFuture handleAsync(OnetimePasswordDetailQuery message, MessageContext context) { + var builder = manager.getCriteriaBuilder(); var criteria = builder.createQuery(OnetimePasswordDetail.class); var entity = criteria.from(OnetimePasswordDetail.class); criteria.where(builder.equal(entity.get("requestId"), message.requestId())); - var typedQuery = context.createQuery(criteria); + var typedQuery = manager.createQuery(criteria); return CompletableFuture.completedFuture(typedQuery.getSingleResult()); } } diff --git a/identity/src/main/java/io/theurl/identity/persistence/handler/TokenDetailQueryHandler.java b/identity/src/main/java/io/theurl/identity/persistence/handler/TokenDetailQueryHandler.java index 03f47e4..6bf0751 100644 --- a/identity/src/main/java/io/theurl/identity/persistence/handler/TokenDetailQueryHandler.java +++ b/identity/src/main/java/io/theurl/identity/persistence/handler/TokenDetailQueryHandler.java @@ -1,6 +1,7 @@ package io.theurl.identity.persistence.handler; import com.neroyun.mediator.Handler; +import com.neroyun.mediator.MessageContext; import io.theurl.framework.core.BeanScope; import io.theurl.identity.persistence.model.TokenDetail; import io.theurl.identity.persistence.query.TokenDetailQuery; @@ -24,7 +25,7 @@ public TokenDetailQueryHandler(JpaTokenRepository repository, ModelMapper mapper } @Override - public CompletableFuture handleAsync(TokenDetailQuery message) { + public CompletableFuture handleAsync(TokenDetailQuery message, MessageContext context) { var entity = repository.findByJti(message.jti()) .orElse(null); diff --git a/identity/src/main/java/io/theurl/identity/persistence/handler/UserAuthInfoQueryHandler.java b/identity/src/main/java/io/theurl/identity/persistence/handler/UserAuthInfoQueryHandler.java index b47dd68..9c197b7 100644 --- a/identity/src/main/java/io/theurl/identity/persistence/handler/UserAuthInfoQueryHandler.java +++ b/identity/src/main/java/io/theurl/identity/persistence/handler/UserAuthInfoQueryHandler.java @@ -1,6 +1,7 @@ package io.theurl.identity.persistence.handler; import com.neroyun.mediator.Handler; +import com.neroyun.mediator.MessageContext; import io.theurl.framework.core.BeanScope; import io.theurl.identity.persistence.entity.User; import io.theurl.identity.persistence.entity.UserRole; @@ -15,7 +16,6 @@ import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; -import org.springframework.web.context.WebApplicationContext; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -27,7 +27,7 @@ public class UserAuthInfoQueryHandler implements Handler { @PersistenceContext - private EntityManager context; + private EntityManager manager; /** * Handles the given query and returns the corresponding UserAuthInfo. @@ -37,11 +37,11 @@ public class UserAuthInfoQueryHandler implements Handler handleAsync(UserAuthInfoQuery query) { + public CompletableFuture handleAsync(UserAuthInfoQuery query, MessageContext context) { return supplyAsync(() -> { String sql = getSql(query); - var typedQuery = context.createQuery(sql, User.class); + var typedQuery = manager.createQuery(sql, User.class); switch (query.provider()) { case "id" -> typedQuery.setParameter("id", Long.parseLong(query.name())); @@ -66,7 +66,7 @@ public CompletableFuture handleAsync(UserAuthInfoQuery query) { return null; } - List roles = context.createQuery("SELECT u from UserRole u where u.userId = :userId", UserRole.class).setParameter("userId", user.getId()).getResultList(); + List roles = manager.createQuery("SELECT u from UserRole u where u.userId = :userId", UserRole.class).setParameter("userId", user.getId()).getResultList(); return new UserAuthInfo() {{ setId(user.getId()); diff --git a/identity/src/main/java/io/theurl/identity/persistence/handler/UserDetailQueryHandler.java b/identity/src/main/java/io/theurl/identity/persistence/handler/UserDetailQueryHandler.java index 1068664..8df08c6 100644 --- a/identity/src/main/java/io/theurl/identity/persistence/handler/UserDetailQueryHandler.java +++ b/identity/src/main/java/io/theurl/identity/persistence/handler/UserDetailQueryHandler.java @@ -1,6 +1,7 @@ package io.theurl.identity.persistence.handler; import com.neroyun.mediator.Handler; +import com.neroyun.mediator.MessageContext; import io.theurl.framework.core.BeanScope; import io.theurl.identity.persistence.model.UserDetail; import io.theurl.identity.persistence.query.UserDetailQuery; @@ -24,7 +25,7 @@ public UserDetailQueryHandler(JpaUserRepository repository, ModelMapper mapper) } @Override - public CompletableFuture handleAsync(UserDetailQuery message) { + public CompletableFuture handleAsync(UserDetailQuery message, MessageContext context) { var user = repository.findById(message.id()).orElse(null); UserDetail detail; diff --git a/pom.xml b/pom.xml index 540d9dd..26e2473 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ 2025.1.0.0 4.0.6 true - 1.1.2 + 1.1.3 3.2.0 3.2.6