/* (c) Copyright 2011 Telefonica, I+D. Printed in Spain (Europe). All Rights Reserved. The copyright to the software program(s) is property of Telefonica I+D. The program(s) may be used and or copied only with the express written consent of Telefonica I+D or in accordance with the terms and conditions stipulated in the agreement/contract under which the program(s) have been supplied. */ package com.telefonica.claudia.slm.deployment; import java.util.ArrayList; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.Transient; import org.apache.log4j.Logger; import org.hibernate.annotations.CollectionOfElements; import com.telefonica.claudia.slm.common.PersistentObject; import com.telefonica.claudia.slm.monitoring.MeasurableElement; import com.telefonica.claudia.slm.naming.DirectoryEntry; import com.telefonica.claudia.slm.naming.FQN; import com.telefonica.claudia.slm.naming.ReservoirDirectory; @Entity public class ServiceApplication extends DirectoryEntry implements PersistentObject, MeasurableElement { @Id @GeneratedValue public long internalId; private String serviceName = null; @ManyToOne private VDC vdc = null; @Transient private FQN serAppFQN = null; @OneToMany(mappedBy="serviceApplication", cascade={CascadeType.MERGE, CascadeType.REFRESH, CascadeType.REMOVE}, fetch=FetchType.EAGER) private Set<VEE> vees = new HashSet<VEE>(); @OneToMany(mappedBy="measuredApplication", cascade=CascadeType.ALL) private Set<MeasuredValue> serviceKPIs = new HashSet<MeasuredValue>(); @OneToMany(mappedBy="serviceApplication", cascade=CascadeType.ALL) private Set<RuleSet> rules = new HashSet<RuleSet>(); @CollectionOfElements private Set<String> hostAffinities = new HashSet<String>(); @CollectionOfElements private Set<String> siteAffinities = new HashSet<String>(); @CollectionOfElements private Set<String> domainAffinities = new HashSet<String>(); @CollectionOfElements private Set<String> hostAntiAffinity = new HashSet<String>(); @CollectionOfElements private Set<String> siteAntiAffinities = new HashSet<String>(); @CollectionOfElements private Set<String> domainAntiAffinities = new HashSet<String>(); @ManyToMany private List<Network> networks = new ArrayList<Network>(); private long initialTime; private double savings; private long vmCount; private long maxVm; private long vmPerHourLimit; private long savingsCalculationFrequency; @Column(columnDefinition = "MEDIUMTEXT") private String ovfDescriptor; public ServiceApplication() {} public ServiceApplication(String appName, VDC vdc) { if(appName == null) throw new IllegalArgumentException("Application name cannot be null"); if(vdc == null) throw new IllegalArgumentException("VDC cannot be null"); this.serviceName = appName; this.vdc = vdc; } public void addHostAffinity(String vee){ hostAffinities.add(vee); } public Set<String> getHostAffinities() { return hostAffinities; } public void addSiteAffinity(String vee){ siteAffinities.add(vee); } public Set<String> getSiteAffinities() { return siteAffinities; } public void addDomainAffinity(String vee){ domainAffinities.add(vee); } public Set<String> getDomainAffinities() { return domainAffinities; } public void addHostAntiAffinity(String vee) { hostAntiAffinity.add(vee); } public Set<String> getHostAntiAffinities() { return hostAntiAffinity; } public void addSiteAntiAffinity(String vee) { siteAntiAffinities.add(vee); } public Set<String> getSiteAntiAffinities() { return siteAntiAffinities; } public void addDomainAntiAffinity(String vee) { domainAntiAffinities.add(vee); } public Set<String> getDomainAntiAffinities() { return domainAntiAffinities; } public String getServiceName(){ return serviceName; } public void setServiceName(String name) { this.serviceName=name; } public VDC getVdc(){ return vdc; } public Set<VEE> getVEEs(){ return vees; } public void registerVEE(VEE vee){ if(vee == null) throw new IllegalArgumentException("Cannot register null VEE"); vee.setServiceApplication(this); vees.add(vee); } public boolean isVEERegistered(VEE vee) { return vees.contains(vee); } public void unregisterVEE(VEE vee) { vees.remove(vee); } public Set<MeasuredValue> getServiceKPIs() { return serviceKPIs; } public void registerServiceKPI(MeasuredValue serviceKPI) { if(serviceKPI == null) throw new IllegalArgumentException("Cannot register null service KPI"); if(!serviceKPI.getServiceApplication().equals(this)) throw new IllegalArgumentException("Trying to register service KPI " + serviceKPI + " on a different Service " + this); serviceKPIs.add(serviceKPI); } public boolean isServiceKPIRegistered(MeasuredValue serviceKPI) { return serviceKPIs.contains(serviceKPI); } public void unregisterServiceKPI(MeasuredValue serviceKPI) { serviceKPIs.remove(serviceKPI); } public Set<Network> getNetworksSet() { Set<Network> networks = new HashSet<Network>(); for(VEE vee : vees) { List<NICConf> nicConfs = vee.getNICsConf(); for(NICConf nicConf: nicConfs) networks.add(nicConf.getNetwork()); } return networks; } public List<Network> getNetworks() { return networks; } public void registerNetwork(Network network) { if(network == null) throw new IllegalArgumentException("Cannot register null network"); networks.add(network); } public boolean isNetworkRegistered(Network network) { return networks.contains(network); } public void unregisterNetwork(Network network) { networks.remove(network); } public Set<RuleSet> getServiceRules() { return rules; } public void registerServiceRule(RuleSet rule) { rules.add(rule); } public boolean isServiceRuleRegistered(RuleSet rule) { return rules.contains(rule); } public void unregisterRule(RuleSet rule) { rules.remove(rule); } public FQN getFQN(){ if(serAppFQN == null) serAppFQN = ReservoirDirectory.getInstance().buildFQN(this); return serAppFQN; } @Override public String toString() { return getFQN().toString(); } @Override public int hashCode() { return (int) (internalId%5); } @Override public boolean equals(Object object) { if(object == null) return false; if(!(object instanceof ServiceApplication)) return false; return ((ServiceApplication)object).internalId == internalId; } public Set<Object> getDescendants() { Set<Object> result = new HashSet<Object>(); result.add(this); result.add(vdc); for (VEE vee: getVEEs()) result.addAll(vee.getDescendants()); for (MeasuredValue kpi: getServiceKPIs()) result.addAll(kpi.getDescendants()); for (Network net: getNetworks()) result.addAll(net.getDescendants()); return result; } public void releaseNetworks() { networks.clear(); } public void setOvfDescriptor(String ovfDescriptor) { this.ovfDescriptor = ovfDescriptor; } public String getOvfDescriptor() { return ovfDescriptor; } public long getObjectId() { return internalId; } public void setInitialTime(long initialTime) { this.initialTime = initialTime; } public long getInitialTime() { return initialTime; } public void setSavings(double savings) { this.savings = savings; } public double getSavings() { return savings; } public long getVmCount() { return this.vmCount; } public void setVmCount(long vmCount) { this.vmCount = vmCount; } public void setMaxVm(long maxVm) { this.maxVm = maxVm; } public long getMaxVm() { return maxVm; } public void setVmPerHourLimit(long vmPerHourLimit) { this.vmPerHourLimit = vmPerHourLimit; } public long getVmPerHourLimit() { return vmPerHourLimit; } public void setSavingsCalculationFrequency(long savingsCalculationFrequency) { this.savingsCalculationFrequency = savingsCalculationFrequency; } public long getSavingsCalculationFrequency() { return savingsCalculationFrequency; } } class VEEReplicasComparator implements Comparator<VEEReplica> { public int compare(VEEReplica replica1, VEEReplica replica2) { return replica2.getId() - replica1.getId(); } }