package org.springside.examples.bootapi.service;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.metrics.CounterService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springside.examples.bootapi.domain.Account;
import org.springside.examples.bootapi.repository.AccountDao;
import org.springside.examples.bootapi.service.exception.ErrorCode;
import org.springside.examples.bootapi.service.exception.ServiceException;
import org.springside.modules.utils.text.HashUtil;
import org.springside.modules.utils.misc.IdGenerator;
import org.springside.modules.utils.text.EncodeUtil;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
// Spring Bean的标识.
@Service
public class AccountService {
private static Logger logger = LoggerFactory.getLogger(AccountService.class);
@Autowired
private AccountDao accountDao;
// 注入配置值
@Value("${app.loginTimeoutSecs:600}")
private int loginTimeoutSecs;
// codehale metrics
@Autowired
private CounterService counterService;
// guava cache
private Cache<String, Account> loginUsers;
@PostConstruct
public void init() {
loginUsers = CacheBuilder.newBuilder().maximumSize(1000).expireAfterAccess(loginTimeoutSecs, TimeUnit.SECONDS)
.build();
}
@Transactional(readOnly = true)
public String login(String email, String password) {
Account account = accountDao.findByEmail(email);
if (account == null) {
throw new ServiceException("User not exist", ErrorCode.UNAUTHORIZED);
}
if (!account.hashPassword.equals(hashPassword(password))) {
throw new ServiceException("Password wrong", ErrorCode.UNAUTHORIZED);
}
String token = IdGenerator.uuid2();
loginUsers.put(token, account);
counterService.increment("loginUser");
return token;
}
public void logout(String token) {
Account account = loginUsers.getIfPresent(token);
if (account == null) {
logger.warn("logout an alreay logout token:" + token);
} else {
loginUsers.invalidate(token);
counterService.decrement("loginUser");
}
}
public Account getLoginUser(String token) {
Account account = loginUsers.getIfPresent(token);
if (account == null) {
throw new ServiceException("User doesn't login", ErrorCode.UNAUTHORIZED);
}
return account;
}
@Transactional
public void register(String email, String name, String password) {
if (StringUtils.isBlank(email) || StringUtils.isBlank(password)) {
throw new ServiceException("Invalid parameter", ErrorCode.BAD_REQUEST);
}
Account account = new Account();
account.email = email;
account.name = name;
account.hashPassword = hashPassword(password);
accountDao.save(account);
}
protected static String hashPassword(String password) {
return EncodeUtil.encodeBase64(HashUtil.sha1(password));
}
}