RegisterUseCaseImpl.java
package com.wilzwert.myjobs.core.application.usecase;
import com.wilzwert.myjobs.core.domain.model.user.command.RegisterUserCommand;
import com.wilzwert.myjobs.core.domain.model.user.command.ValidateEmailCommand;
import com.wilzwert.myjobs.core.domain.model.user.event.integration.UserCreatedEvent;
import com.wilzwert.myjobs.core.domain.model.user.exception.UserAlreadyExistsException;
import com.wilzwert.myjobs.core.domain.model.user.exception.UserNotFoundException;
import com.wilzwert.myjobs.core.domain.model.user.User;
import com.wilzwert.myjobs.core.domain.model.user.ports.driven.AccountCreationMessageProvider;
import com.wilzwert.myjobs.core.domain.model.user.ports.driven.PasswordHasher;
import com.wilzwert.myjobs.core.domain.model.user.ports.driven.UserDataManager;
import com.wilzwert.myjobs.core.domain.model.user.ports.driving.CheckUserAvailabilityUseCase;
import com.wilzwert.myjobs.core.domain.model.user.ports.driving.RegisterUseCase;
import com.wilzwert.myjobs.core.domain.model.user.ports.driving.ValidateEmailUseCase;
import com.wilzwert.myjobs.core.domain.shared.event.integration.IntegrationEventId;
import com.wilzwert.myjobs.core.domain.shared.ports.driven.event.IntegrationEventPublisher;
import com.wilzwert.myjobs.core.domain.shared.ports.driven.transaction.TransactionProvider;
import java.util.Collections;
import java.util.Optional;
/**
* @author Wilhelm Zwertvaegher
*/
public class RegisterUseCaseImpl implements RegisterUseCase, CheckUserAvailabilityUseCase, ValidateEmailUseCase {
private final TransactionProvider transactionProvider;
private final IntegrationEventPublisher integrationEventPublisher;
private final UserDataManager userDataManager;
private final PasswordHasher passwordHasher;
private final AccountCreationMessageProvider accountCreationMessageProvider;
public RegisterUseCaseImpl(
TransactionProvider transactionProvider,
IntegrationEventPublisher integrationEventPublisher,
UserDataManager userDataManager,
PasswordHasher passwordHasher,
AccountCreationMessageProvider accountCreationMessageProvider) {
this.transactionProvider = transactionProvider;
this.integrationEventPublisher = integrationEventPublisher;
this.userDataManager = userDataManager;
this.passwordHasher = passwordHasher;
this.accountCreationMessageProvider = accountCreationMessageProvider;
}
@Override
public User registerUser(RegisterUserCommand registerUserCommand) {
// TODO : this should be transactional, i.e. checking availability and register should be atomic
// to avoid e.g. another register command to succeed
// while we are processing here a command with the same username/email
// this will require to provide some kind of transaction management interface
// and enforce its implementation in infra
if(userDataManager.findByEmailOrUsername(registerUserCommand.email(), registerUserCommand.username()).isPresent()) {
throw new UserAlreadyExistsException();
}
return transactionProvider.executeInTransaction(() -> {
User user = userDataManager.save(User.create(
User.builder()
.email(registerUserCommand.email())
.password(passwordHasher.hashPassword(registerUserCommand.password()))
.username(registerUserCommand.username())
.firstName(registerUserCommand.firstName())
.lastName(registerUserCommand.lastName())
.jobFollowUpReminderDays(registerUserCommand.jobFollowUpReminderDays())
.lang(registerUserCommand.lang())
.jobs(Collections.emptyList()),
registerUserCommand.password()
));
// send account creation message
accountCreationMessageProvider.send(user);
integrationEventPublisher.publish(new UserCreatedEvent(IntegrationEventId.generate(), user.getId()));
return user;
});
}
@Override
public boolean isEmailTaken(String email) {
return userDataManager.emailExists(email);
}
@Override
public boolean isUsernameTaken(String username) {
return userDataManager.usernameExists(username);
}
@Override
public User validateEmail(ValidateEmailCommand command) {
Optional<User> userOptional = userDataManager.findMinimalByEmailValidationCode(command.validationCode());
if(userOptional.isPresent()) {
User user = userOptional.get();
user = user.validateEmail(command.validationCode());
return userDataManager.save(user);
}
throw new UserNotFoundException();
}
}