biblenotes-java/src/main/java/de/w665/biblenotes/db/RethinkDBService.java

116 lines
4.3 KiB
Java

package de.w665.biblenotes.db;
import com.rethinkdb.RethinkDB;
import com.rethinkdb.gen.exc.ReqlOpFailedError;
import com.rethinkdb.net.Connection;
import de.w665.biblenotes.db.repo.UserRepository;
import de.w665.biblenotes.model.User;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Slf4j
@Service
public class RethinkDBService {
private final RethinkDBConfig config;
private final RethinkDB r;
private final Connection connection;
private final UserRepository userRepository;
@Value("${biblenotes.auto-reset-on-startup}")
private boolean autoResetOnStartup;
@Value("${biblenotes.management.user.username}")
private String defaultUsername;
@Value("${biblenotes.management.user.password}")
private String defaultPassword;
private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
@Autowired
public RethinkDBService(RethinkDBConfig config, RethinkDBConnector connector, UserRepository userRepository) {
this.config = config;
// mapping to private vars for easier access
this.r = connector.getR();
this.connection = connector.getConnection();
this.userRepository = userRepository;
}
@PostConstruct
public void initialize() {
// rethinkdb check if database exists
try {
r.dbCreate(config.getDatabase()).run(connection).stream();
log.debug("Database " + config.getDatabase() + " created");
} catch (ReqlOpFailedError e) {
log.debug("Database " + config.getDatabase() + " already exists. Error: " + e.getClass().getSimpleName());
}
// rethinkdb check if table users exists
try {
r.db(config.getDatabase()).tableCreate("users").run(connection).stream();
log.debug("Table 'users' created successfully.");
} catch (ReqlOpFailedError e) {
log.debug("Table 'users' already exists.");
if(autoResetOnStartup) {
log.debug("Clearing content...");
r.db(config.getDatabase()).table("users").delete().run(connection);
log.debug("Table 'users' cleared successfully.");
}
}
// rethinkdb check if table user_logins exists
try {
r.db(config.getDatabase()).tableCreate("user_logins").run(connection).stream();
log.debug("Table 'user_logins' created successfully.");
} catch (ReqlOpFailedError e) {
log.debug("Table 'user_logins' already exists.");
if(autoResetOnStartup) {
log.debug("Clearing content...");
r.db(config.getDatabase()).table("user_logins").delete().run(connection);
log.debug("Table 'user_logins' cleared successfully.");
}
} finally {
try {
r.db(config.getDatabase()).table("user_logins").indexCreate("loginTime").run(connection);
log.debug("Secondary index 'loginTime' on table 'user_logins' successfully created.");
} catch (ReqlOpFailedError e) {
log.debug("Secondary index 'loginTime' already exists.");
} finally {
r.db(config.getDatabase()).table("user_logins").indexWait("loginTime").run(connection);
}
}
initializeAdminUser();
log.info("Database ready for operation!");
}
private void initializeAdminUser() {
Optional<User> adminUser = userRepository.retrieveUserByUsername("admin");
if(adminUser.isEmpty()) {
User user = new User();
user.setUsername(defaultUsername);
user.setPassword(passwordEncoder.encode(defaultPassword));
user.setRole("ADMIN");
userRepository.insertUser(user);
log.debug("Admin user created with default credentials. Username: admin, Password: admin");
}
}
@PreDestroy
public void close() {
if (connection != null) {
connection.close();
}
}
}