package org.openstack.atlas.service.domain.repository;
import org.openstack.atlas.service.domain.entities.*;
import org.openstack.atlas.service.domain.exceptions.DeletedStatusException;
import org.openstack.atlas.service.domain.exceptions.EntityNotFoundException;
import org.openstack.atlas.service.domain.pojos.*;
import org.openstack.atlas.service.domain.util.Constants;
import org.openstack.atlas.util.converters.StringConverter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.*;
@Repository
@Transactional
public class NodeRepository {
final Log LOG = LogFactory.getLog(NodeRepository.class);
@PersistenceContext(unitName = "loadbalancing")
private EntityManager entityManager;/**/
public Set<Node> addNodes(LoadBalancer loadBalancer, Collection<Node> nodes) {
Set<Node> newNodes = new HashSet<Node>();
for (Node node : nodes) {
node.setLoadbalancer(loadBalancer);
newNodes.add(entityManager.merge(node));
}
loadBalancer.setUpdated(Calendar.getInstance());
loadBalancer = entityManager.merge(loadBalancer);
entityManager.flush();
return newNodes;
}
public LoadBalancer delNodes(LoadBalancer lb, Collection<Node> nodes) {
String qStr = "from LoadBalancer lb where lb.accountId=:aid and lb.id=:lid";
List<LoadBalancer> lbList;
Query q = entityManager.createQuery(qStr).setLockMode(LockModeType.PESSIMISTIC_WRITE).
setParameter("aid", lb.getAccountId()).
setParameter("lid", lb.getId());
lbList = q.getResultList();
if (lbList.size() < 1) {
LOG.error("The list is incomplete...");
}
lb = lbList.get(0);
NodeMap nodeMap = new NodeMap(nodes);
Set<Node> lbNodes = new HashSet<Node>(lb.getNodes());
for (Node node : lbNodes) {
Integer nodeId = node.getId();
if (nodeMap.containsKey(nodeId)) {
lb.getNodes().remove(node);
}
}
lb.setUpdated(Calendar.getInstance());
lb = entityManager.merge(lb);
entityManager.flush();
return lb;
}
public void deleteNodesByIds(Collection<Integer> nodeIds) {
List<Node> nodes;
String idsStr = StringConverter.integersAsString(nodeIds);
String qStr = String.format("from Node n where n.id in (%s)", StringConverter.integersAsString(nodeIds));
nodes = entityManager.createQuery(qStr).getResultList();
for (Node node : nodes) {
entityManager.remove(node);
}
entityManager.flush();
}
public void delNode(LoadBalancer lb, int nid) {
List<Node> nodes;
String qStr = String.format("from Node n where n.id == %s", String.valueOf(nid));
nodes = entityManager.createQuery(qStr).setLockMode(LockModeType.PESSIMISTIC_WRITE).getResultList();
for (Node node : nodes) {
entityManager.remove(node);
}
entityManager.flush();
}
public NodeMap getNodeMap(Integer accountId, Integer loadbalancerId) {
List<Node> nodes;
NodeMap nodeMap = new NodeMap();
String qStr = "from Node n where n.loadbalancer.id=:lid and n.loadbalancer.accountId=:aid";
Query q = entityManager.createQuery(qStr).setParameter("aid", accountId).
setParameter("lid", loadbalancerId);
nodes = q.getResultList();
for (Node node : nodes) {
nodeMap.addNode(node);
}
return nodeMap;
}
public List<Node> getNodesByIds(Collection<Integer> ids) {
List<Node> doomedNodes = new ArrayList<Node>();
String nodeIdsStr = StringConverter.integersAsString(ids);
String qStr = String.format("from Node n where n.id in (%s)", nodeIdsStr);
if (ids == null || ids.size() < 1) {
return doomedNodes;
}
doomedNodes = entityManager.createQuery(qStr).getResultList();
return doomedNodes;
}
public LoadBalancer update(LoadBalancer loadBalancer) {
final Set<LoadBalancerJoinVip> lbJoinVipsToLink = loadBalancer.getLoadBalancerJoinVipSet();
loadBalancer.setLoadBalancerJoinVipSet(null);
loadBalancer.setUpdated(Calendar.getInstance());
loadBalancer = entityManager.merge(loadBalancer);
// Now attach loadbalancer to vips
for (LoadBalancerJoinVip lbJoinVipToLink : lbJoinVipsToLink) {
VirtualIp virtualIp = entityManager.find(VirtualIp.class, lbJoinVipToLink.getVirtualIp().getId());
LoadBalancerJoinVip loadBalancerJoinVip = new LoadBalancerJoinVip(loadBalancer.getPort(), loadBalancer, virtualIp);
entityManager.merge(loadBalancerJoinVip);
entityManager.merge(lbJoinVipToLink.getVirtualIp());
}
entityManager.flush();
return loadBalancer;
}
public Node getNodeByLoadBalancerIdIpAddressAndPort(Integer lbId, String ipAddress, Integer port) throws EntityNotFoundException {
try {
return (Node) entityManager.createQuery("from Node n where n.loadbalancer.id = :loadbalancerId and n.ipAddress = :ipAddress and n.port = :port").setParameter("loadbalancerId", lbId).setParameter("ipAddress", ipAddress).setParameter("port", port).getSingleResult();
} catch (Exception e) {
throw new EntityNotFoundException(e);
}
}
public Node getNodeByAccountIdLoadBalancerIdNodeId(LoadBalancer loadBalancer,
Integer nid) throws EntityNotFoundException, DeletedStatusException {
if (loadBalancer.getStatus().equals(LoadBalancerStatus.DELETED)) {
throw new DeletedStatusException("The loadbalancer is marked as deleted.");
}
for (Node node : loadBalancer.getNodes()) {
if (!node.getId().equals(nid)) {
} else {
return node;
}
}
throw new EntityNotFoundException("Node not found");
}
public Node getNodeByAccountIdLoadBalancerIdNodeId(Integer accountId, Integer loadbalancerId, Integer nodeId) throws EntityNotFoundException {
String query = "from Node n where n.loadbalancer.id=:loadbalancerId and n.loadbalancer.accountId=:accountId AND n.id = :nodeId";
try {
return (Node)entityManager.createQuery(query).setParameter("accountId", accountId).setParameter("loadbalancerId",loadbalancerId).setParameter("nodeId", nodeId).getSingleResult();
} catch (Exception e) {
throw new EntityNotFoundException(e);
}
}
// Small check for existence
public boolean isLoadBalancerbyAccountIdLoadBalancerId(Integer aid, Integer lid) {
String qStr;
qStr = "SELECT l.id from LoadBalancer l";
qStr += " where l.accountId=:aid and l.id=:lid";
List<Object> results = entityManager.createQuery(qStr).setParameter("aid", aid).setParameter("lid", lid).getResultList();
if(results.size()<=0) {
return false;
}else{
return true;
}
}
// Get all Nodes regardless of weight status etc
public Set<Node> getAllNodesByAccountIdLoadBalancerId(Integer aid, Integer lid) throws EntityNotFoundException {
if(!isLoadBalancerbyAccountIdLoadBalancerId(aid, lid)){
throw new EntityNotFoundException(String.format("Loadbalancer %d not found for account %d",lid,aid));
}
String qStr = "SELECT n FROM Node n where n.loadbalancer.id = :lid";
List<Node> nodesList = entityManager.createQuery(qStr).setParameter("lid", lid)
.setLockMode(LockModeType.PESSIMISTIC_READ).getResultList();
Set<Node> nodes = new HashSet<Node>(nodesList);
return nodes;
}
public Set<Node> getNodesByAccountIdLoadBalancerId(LoadBalancer loadBalancer,
Integer... p) throws EntityNotFoundException, DeletedStatusException {
if (loadBalancer.getStatus().equals(LoadBalancerStatus.DELETED)) {
throw new DeletedStatusException("The loadbalancer is marked as deleted.");
}
Set<Node> nodes = loadBalancer.getNodes();
Set<Node> nodes_out = new LinkedHashSet<Node>();
if (p.length >= 2) {
Integer offset = p[0];
Integer limit = p[1];
Integer marker = p[2];
int i = 0;
if (offset == null) {
offset = 0;
}
if (limit == null || limit > 100) {
limit = 100;
}
if (marker == null) {
marker = 0;
}
for (Node node : nodes) {
i++;
if (node.getId() >= marker) {
if (i >= marker) {
nodes_out.add(node);
if (i >= marker + limit) {
break;
}
}
}
}
} else {
nodes_out = nodes;
}
return nodes_out;
}
public void setNodeCondition(Set<Node> nodes, String condition) {
StringBuilder sql = new StringBuilder("Update Node set condition = '" + condition + "' where id in (");
for (Node n : nodes) {
sql.append(n.getId());
sql.append(",");
}
sql.deleteCharAt(sql.toString().length() - 1);
sql.append(")");
entityManager.createQuery(sql.toString()).executeUpdate();
}
public void setNodeStatus(Node node) {
NodeStatus status = node.getStatus();
node = entityManager.find(Node.class, node.getId());
node.setStatus(status);
entityManager.merge(node);
}
public void deleteNodes(Set<Node> nodes) {
StringBuilder sql = new StringBuilder("delete from Node where id in (");
for (Node n : nodes) {
sql.append(n.getId());
sql.append(",");
}
sql.deleteCharAt(sql.toString().length() - 1);
sql.append(")");
entityManager.createQuery(sql.toString()).executeUpdate();
}
public void removeNodes(int loadbalancerId) {
entityManager.createQuery("delete from node s where s.loadbalancer.id = :lid").setParameter("lid",
loadbalancerId).executeUpdate();
}
public Node save(Node node) {
entityManager.persist(node);
return node;
}
public void delete(Object o) {
entityManager.remove(o);
entityManager.flush();
}
public Object save(Object o) {
entityManager.persist(o);
entityManager.flush();
return o;
}
// Its easier to duplicate then inject another repoisotyr here
public LoadBalancer getLoadBalancerById(Integer id) throws EntityNotFoundException {
LoadBalancer lb = entityManager.find(LoadBalancer.class, id);
if (lb == null) {
String message = Constants.LoadBalancerNotFound;
LOG.warn(message);
throw new EntityNotFoundException(message);
}
return lb;
}
}