// Copyright © 2015 HSL <https://www.hsl.fi> // This program is dual-licensed under the EUPL v1.2 and AGPLv3 licenses. package fi.hsl.parkandride.dev; import com.querydsl.sql.RelationalPath; import com.querydsl.sql.postgresql.PostgreSQLQueryFactory; import fi.hsl.parkandride.FeatureProfile; import fi.hsl.parkandride.back.sql.*; import fi.hsl.parkandride.core.back.UserRepository; import fi.hsl.parkandride.core.domain.*; import fi.hsl.parkandride.core.service.*; import org.springframework.context.annotation.Profile; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; import javax.annotation.Resource; import javax.inject.Inject; import java.util.Objects; import static fi.hsl.parkandride.back.ContactDao.CONTACT_ID_SEQ; import static fi.hsl.parkandride.back.FacilityDao.FACILITY_ID_SEQ; import static fi.hsl.parkandride.back.HubDao.HUB_ID_SEQ; import static fi.hsl.parkandride.back.OperatorDao.OPERATOR_ID_SEQ; import static fi.hsl.parkandride.back.UserDao.USER_ID_SEQ; import static fi.hsl.parkandride.back.prediction.PredictorDao.PREDICTOR_ID_SEQ; import static java.lang.String.format; @Component @Profile({FeatureProfile.DEV_API}) public class DevHelper { private final PostgreSQLQueryFactory queryFactory; private final JdbcTemplate jdbcTemplate; @Resource UserRepository userRepository; @Resource UserService userService; @Resource AuthenticationService authenticationService; @Resource BatchingRequestLogService batchingRequestLogService; @Inject public DevHelper(PostgreSQLQueryFactory queryFactory, JdbcTemplate jdbcTemplate) { this.queryFactory = queryFactory; this.jdbcTemplate = jdbcTemplate; } @TransactionalWrite public void deleteAll() { deleteHubs(); deleteFacilities(); deleteContacts(); deleteUsers(); deleteOperators(); deleteRequestLog(); deleteLocks(); } @TransactionalWrite private void deleteLocks() { delete(QLock.lock); } @TransactionalWrite public void deleteContacts() { delete(QContact.contact); resetContactSequence(); } @TransactionalWrite public void deleteUsers() { delete(QAppUser.appUser); resetUserSequence(); } @TransactionalWrite public User createOrUpdateUser(NewUser newUser) { UserSecret userSecret; try { userSecret = userRepository.getUser(newUser.username); if (newUser.operatorId != null && !Objects.equals(newUser.operatorId, userSecret.user.operatorId)) { throw new IllegalArgumentException("Tried to create user '" + newUser.username + "' with operatorId " + newUser.operatorId + ", but there already was a user with same name and operatorId " + userSecret.user.operatorId + " and we can't change the operatorId afterwards"); } if (newUser.role != userSecret.user.role) { userRepository.updateUser(userSecret.user.id, newUser); } if (newUser.password != null) { userRepository.updatePassword(userSecret.user.id, authenticationService.encryptPassword(newUser.password)); } } catch (NotFoundException e) { userSecret = new UserSecret(); userSecret.user = userService.createUserNoValidate(newUser); } return userSecret.user; } @TransactionalRead public Login login(String username) { UserSecret userSecret = userRepository.getUser(username); Login login = new Login(); login.token = authenticationService.token(userSecret.user); login.username = userSecret.user.username; login.role = userSecret.user.role; login.operatorId = userSecret.user.operatorId; login.permissions = login.role.permissions; return login; } @TransactionalWrite public void deleteOperators() { delete(QOperator.operator); resetOperatorSequence(); } @TransactionalWrite public void deleteFacilities() { delete( QFacilityPredictionHistory.facilityPredictionHistory, QFacilityPrediction.facilityPrediction, QPredictor.predictor, QFacilityUtilization.facilityUtilization, QFacilityService.facilityService, QFacilityPaymentMethod.facilityPaymentMethod, QFacilityAlias.facilityAlias, QPricing.pricing, QPort.port, QUnavailableCapacity.unavailableCapacity, QFacilityStatusHistory.facilityStatusHistory, QUnavailableCapacityHistory.unavailableCapacityHistory, QFacilityCapacityHistory.facilityCapacityHistory, QFacility.facility); resetPredictorSequence(); resetFacilitySequence(); } @TransactionalWrite public void deleteHubs() { delete(QHubFacility.hubFacility, QHub.hub); resetHubSequence(); } @TransactionalWrite private void deleteRequestLog() { batchingRequestLogService.clearLogStash(); delete(QRequestLog.requestLog); delete(QRequestLogSource.requestLogSource); delete(QRequestLogUrl.requestLogUrl); } @TransactionalWrite public void resetHubSequence() { resetSequence(HUB_ID_SEQ, queryFactory.from(QHub.hub).select(QHub.hub.id.max()).fetchOne()); } @TransactionalWrite public void resetFacilitySequence() { resetSequence(FACILITY_ID_SEQ, queryFactory.from(QFacility.facility).select(QFacility.facility.id.max()).fetchOne()); } @TransactionalWrite public void resetPredictorSequence() { resetSequence(PREDICTOR_ID_SEQ, queryFactory.from(QPredictor.predictor).select(QPredictor.predictor.id.max()).fetchOne()); } @TransactionalWrite public void resetContactSequence() { resetSequence(CONTACT_ID_SEQ, queryFactory.from(QContact.contact).select(QContact.contact.id.max()).fetchOne()); } @TransactionalWrite public void resetUserSequence() { resetSequence(USER_ID_SEQ, queryFactory.from(QAppUser.appUser).select(QAppUser.appUser.id.max()).fetchOne()); } @TransactionalWrite public void resetOperatorSequence() { resetSequence(OPERATOR_ID_SEQ, queryFactory.from(QOperator.operator).select(QOperator.operator.id.max()).fetchOne()); } private void delete(RelationalPath... tables) { for (RelationalPath table : tables) { queryFactory.delete(table).execute(); } } private void resetSequence(String sequence, Long currentMax) { if (currentMax == null) { currentMax = 0L; } jdbcTemplate.execute(format("drop sequence %s", sequence)); jdbcTemplate.execute(format("create sequence %s increment by 1 start with %s", sequence, currentMax + 1)); } }