package org.openstack.atlas.service.domain.services.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openstack.atlas.docs.loadbalancers.api.v1.faults.BadRequest;
import org.openstack.atlas.service.domain.entities.LoadBalancer;
import org.openstack.atlas.service.domain.entities.LoadBalancerStatus;
import org.openstack.atlas.service.domain.entities.SessionPersistence;
import org.openstack.atlas.service.domain.exceptions.*;
import org.openstack.atlas.service.domain.services.LoadBalancerStatusHistoryService;
import org.openstack.atlas.service.domain.services.SessionPersistenceService;
import org.openstack.atlas.service.domain.services.helpers.StringHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.openstack.atlas.service.domain.entities.LoadBalancerProtocol;
import static org.openstack.atlas.service.domain.entities.LoadBalancerProtocol.*;
import static org.openstack.atlas.service.domain.entities.SessionPersistence.*;
@Service
public class SessionPersistenceServiceImpl extends BaseService implements SessionPersistenceService {
private final Log LOG = LogFactory.getLog(SessionPersistenceServiceImpl.class);
@Autowired
private LoadBalancerStatusHistoryService loadBalancerStatusHistoryService;
@Override
public SessionPersistence get(Integer accountId, Integer lbId) throws EntityNotFoundException, BadRequestException, DeletedStatusException {
return loadBalancerRepository.getSessionPersistenceByAccountIdLoadBalancerId(accountId, lbId);
}
@Override
@Transactional(rollbackFor = {EntityNotFoundException.class, ImmutableEntityException.class, BadRequestException.class})
public void update(LoadBalancer queueLb) throws EntityNotFoundException, ImmutableEntityException, BadRequestException, UnprocessableEntityException {
LOG.debug("Entering " + getClass());
LoadBalancer dbLoadBalancer = loadBalancerRepository.getByIdAndAccountId(queueLb.getId(), queueLb.getAccountId());
validateSessionPersistenceProtocolCompatibility(queueLb, dbLoadBalancer);
LOG.debug("Updating the lb status to pending_update");
if (!loadBalancerRepository.testAndSetStatus(dbLoadBalancer.getAccountId(), dbLoadBalancer.getId(), LoadBalancerStatus.PENDING_UPDATE, false)) {
String message = StringHelper.immutableLoadBalancer(dbLoadBalancer);
LOG.warn(message);
throw new ImmutableEntityException(message);
} else {
//Set status record
loadBalancerStatusHistoryService.save(dbLoadBalancer.getAccountId(), dbLoadBalancer.getId(), LoadBalancerStatus.PENDING_UPDATE);
}
dbLoadBalancer.setSessionPersistence(queueLb.getSessionPersistence());
loadBalancerRepository.update(dbLoadBalancer);
LOG.debug("Leaving " + getClass());
}
@Override
@Transactional(rollbackFor = {EntityNotFoundException.class, ImmutableEntityException.class, UnprocessableEntityException.class})
public void delete(LoadBalancer requestLb) throws Exception {
LOG.debug("Entering " + getClass());
LoadBalancer dbLb = loadBalancerRepository.getByIdAndAccountId(requestLb.getId(), requestLb.getAccountId());
if (dbLb.getSessionPersistence().equals(SessionPersistence.NONE)) {
throw new UnprocessableEntityException("Session persistence is already deleted.");
}
if (!loadBalancerRepository.testAndSetStatus(dbLb.getAccountId(), dbLb.getId(), LoadBalancerStatus.PENDING_UPDATE, false)) {
String message = StringHelper.immutableLoadBalancer(dbLb);
LOG.warn(message);
throw new ImmutableEntityException(message);
} else {
//Set status record
loadBalancerStatusHistoryService.save(dbLb.getAccountId(), dbLb.getId(), LoadBalancerStatus.PENDING_UPDATE);
}
}
public void validateSessionPersistenceProtocolCompatibility(LoadBalancer inLb, LoadBalancer dbLb) throws BadRequestException, UnprocessableEntityException {
SessionPersistence persistenceType = inLb.getSessionPersistence();
LoadBalancerProtocol dbProtocol = dbLb.getProtocol();
String httpErrMsg = "HTTP_COOKIE Session persistence is only valid with HTTP protocol with or without SSL termination.";
String sslErrMsg = "SSL_ID session persistence is only valid with the HTTPS protocol. ";
LOG.info("Verifying session persistence protocol..." + persistenceType);
if (persistenceType != NONE) {
if (persistenceType == HTTP_COOKIE && (dbProtocol != HTTP)) {
LOG.info(httpErrMsg);
throw new BadRequestException(httpErrMsg);
}
if (persistenceType == SSL_ID && (dbProtocol != HTTPS)) {
LOG.info(sslErrMsg);
throw new BadRequestException(sslErrMsg);
}
}
LOG.info("Successfully verified session persistence protocol..." + inLb.getSessionPersistence());
}
}