bug 9651: Adding network tags

Also changes in Request logging.
This commit is contained in:
Alex Huang 2011-05-23 15:51:42 -07:00
parent e22d99f70d
commit 0dfc44582b
18 changed files with 810 additions and 487 deletions

View File

@ -18,6 +18,7 @@
package com.cloud.agent.api.to; package com.cloud.agent.api.to;
import java.net.URI; import java.net.URI;
import java.util.List;
import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.TrafficType; import com.cloud.network.Networks.TrafficType;
@ -38,10 +39,11 @@ public class NetworkTO {
protected URI broadcastUri; protected URI broadcastUri;
protected URI isolationUri; protected URI isolationUri;
protected boolean isSecurityGroupEnabled; protected boolean isSecurityGroupEnabled;
protected String[] tags;
public NetworkTO() { public NetworkTO() {
} }
public String getUuid() { public String getUuid() {
return uuid; return uuid;
} }
@ -85,11 +87,19 @@ public class NetworkTO {
public void setType(TrafficType type) { public void setType(TrafficType type) {
this.type = type; this.type = type;
} }
public void setTags(List<String> tags) {
this.tags = tags.toArray(new String[tags.size()]);
}
public String[] getTags() {
return tags;
}
public void setSecurityGroupEnabled(boolean enabled) { public void setSecurityGroupEnabled(boolean enabled) {
this.isSecurityGroupEnabled = enabled; this.isSecurityGroupEnabled = enabled;
} }
/** /**
* This constructor is usually for hosts where the other information are not important. * This constructor is usually for hosts where the other information are not important.
* *
@ -100,7 +110,7 @@ public class NetworkTO {
public NetworkTO(String ip, String netmask, String mac) { public NetworkTO(String ip, String netmask, String mac) {
this(ip, netmask, mac, null, null, null); this(ip, netmask, mac, null, null, null);
} }
/** /**
* This is the full constructor and should be used for VM's network as it contains * This is the full constructor and should be used for VM's network as it contains
* the full information about what is needed. * the full information about what is needed.
@ -145,27 +155,27 @@ public class NetworkTO {
public String getDns2() { public String getDns2() {
return dns2; return dns2;
} }
public TrafficType getType() { public TrafficType getType() {
return type; return type;
} }
public URI getBroadcastUri() { public URI getBroadcastUri() {
return broadcastUri; return broadcastUri;
} }
public void setBroadcastUri(URI broadcastUri) { public void setBroadcastUri(URI broadcastUri) {
this.broadcastUri = broadcastUri; this.broadcastUri = broadcastUri;
} }
public URI getIsolationUri() { public URI getIsolationUri() {
return isolationUri; return isolationUri;
} }
public void setIsolationuri(URI isolationUri) { public void setIsolationuri(URI isolationUri) {
this.isolationUri = isolationUri; this.isolationUri = isolationUri;
} }
public boolean isSecurityGroupEnabled() { public boolean isSecurityGroupEnabled() {
return this.isSecurityGroupEnabled; return this.isSecurityGroupEnabled;
} }

View File

@ -37,14 +37,14 @@ import com.cloud.utils.fsm.StateMachine;
* owned by an account. * owned by an account.
*/ */
public interface Network extends ControlledEntity { public interface Network extends ControlledEntity {
public enum GuestIpType { public enum GuestIpType {
Virtual, Virtual,
Direct, Direct,
} }
public static class Service { public static class Service {
public static final Service Vpn = new Service("Vpn", Capability.SupportedVpnTypes); public static final Service Vpn = new Service("Vpn", Capability.SupportedVpnTypes);
public static final Service Dhcp = new Service("Dhcp"); public static final Service Dhcp = new Service("Dhcp");
public static final Service Dns = new Service("Dns"); public static final Service Dns = new Service("Dns");
@ -52,7 +52,7 @@ public interface Network extends ControlledEntity {
public static final Service Firewall = new Service("Firewall", Capability.PortForwarding, Capability.StaticNat, Capability.SupportedProtocols, Capability.MultipleIps, Capability.SupportedSourceNatTypes, Capability.TrafficStatistics); public static final Service Firewall = new Service("Firewall", Capability.PortForwarding, Capability.StaticNat, Capability.SupportedProtocols, Capability.MultipleIps, Capability.SupportedSourceNatTypes, Capability.TrafficStatistics);
public static final Service Lb = new Service("Lb", Capability.SupportedLBAlgorithms, Capability.SupportedProtocols, Capability.TrafficStatistics, Capability.LoadBalancingSupportedIps); public static final Service Lb = new Service("Lb", Capability.SupportedLBAlgorithms, Capability.SupportedProtocols, Capability.TrafficStatistics, Capability.LoadBalancingSupportedIps);
public static final Service UserData = new Service("UserData"); public static final Service UserData = new Service("UserData");
private String name; private String name;
private Capability[] caps; private Capability[] caps;
@ -60,15 +60,15 @@ public interface Network extends ControlledEntity {
this.name = name; this.name = name;
this.caps = caps; this.caps = caps;
} }
public String getName() { public String getName() {
return name; return name;
} }
public Capability[] getCapabilities() { public Capability[] getCapabilities() {
return caps; return caps;
} }
public boolean containsCapability(Capability cap) { public boolean containsCapability(Capability cap) {
boolean success = false; boolean success = false;
if (caps != null) { if (caps != null) {
@ -80,13 +80,13 @@ public interface Network extends ControlledEntity {
} }
} }
} }
return success; return success;
} }
} }
public static class Provider { public static class Provider {
public static final Provider VirtualRouter = new Provider("VirtualRouter"); public static final Provider VirtualRouter = new Provider("VirtualRouter");
public static final Provider DhcpServer = new Provider("DhcpServer"); public static final Provider DhcpServer = new Provider("DhcpServer");
public static final Provider JuniperSRX = new Provider("JuniperSRX"); public static final Provider JuniperSRX = new Provider("JuniperSRX");
@ -94,20 +94,20 @@ public interface Network extends ControlledEntity {
public static final Provider ExternalDhcpServer = new Provider("ExternalDhcpServer"); public static final Provider ExternalDhcpServer = new Provider("ExternalDhcpServer");
public static final Provider ExternalGateWay = new Provider("ExternalGateWay"); public static final Provider ExternalGateWay = new Provider("ExternalGateWay");
public static final Provider None = new Provider("None"); public static final Provider None = new Provider("None");
private String name; private String name;
public Provider(String name) { public Provider(String name) {
this.name = name; this.name = name;
} }
public String getName() { public String getName() {
return name; return name;
} }
} }
public static class Capability { public static class Capability {
public static final Capability PortForwarding = new Capability("PortForwarding"); public static final Capability PortForwarding = new Capability("PortForwarding");
public static final Capability StaticNat = new Capability("StaticNat"); public static final Capability StaticNat = new Capability("StaticNat");
public static final Capability SupportedProtocols = new Capability("SupportedProtocols"); public static final Capability SupportedProtocols = new Capability("SupportedProtocols");
@ -117,25 +117,25 @@ public interface Network extends ControlledEntity {
public static final Capability SupportedVpnTypes = new Capability("SupportedVpnTypes"); public static final Capability SupportedVpnTypes = new Capability("SupportedVpnTypes");
public static final Capability TrafficStatistics = new Capability("TrafficStatistics"); public static final Capability TrafficStatistics = new Capability("TrafficStatistics");
public static final Capability LoadBalancingSupportedIps = new Capability("LoadBalancingSupportedIps"); public static final Capability LoadBalancingSupportedIps = new Capability("LoadBalancingSupportedIps");
private String name; private String name;
public Capability(String name) { public Capability(String name) {
this.name = name; this.name = name;
} }
public String getName() { public String getName() {
return name; return name;
} }
} }
enum Event { enum Event {
ImplementNetwork, ImplementNetwork,
DestroyNetwork, DestroyNetwork,
OperationSucceeded, OperationSucceeded,
OperationFailed; OperationFailed;
} }
enum State implements FiniteState<State, Event> { enum State implements FiniteState<State, Event> {
Allocated("Indicates the network configuration is in allocated but not setup"), Allocated("Indicates the network configuration is in allocated but not setup"),
Setup("Indicates the network configuration is setup"), Setup("Indicates the network configuration is setup"),
@ -143,7 +143,7 @@ public interface Network extends ControlledEntity {
Implemented("Indicates the network configuration is in use"), Implemented("Indicates the network configuration is in use"),
Shutdown("Indicates the network configuration is being destroyed"), Shutdown("Indicates the network configuration is being destroyed"),
Destroy("Indicates that the network is destroyed"); Destroy("Indicates that the network is destroyed");
@Override @Override
public StateMachine<State, Event> getStateMachine() { public StateMachine<State, Event> getStateMachine() {
@ -164,18 +164,18 @@ public interface Network extends ControlledEntity {
public Set<Event> getPossibleEvents() { public Set<Event> getPossibleEvents() {
return s_fsm.getPossibleEvents(this); return s_fsm.getPossibleEvents(this);
} }
String _description; String _description;
@Override @Override
public String getDescription() { public String getDescription() {
return _description; return _description;
} }
private State(String description) { private State(String description) {
_description = description; _description = description;
} }
private static StateMachine<State, Event> s_fsm = new StateMachine<State, Event>(); private static StateMachine<State, Event> s_fsm = new StateMachine<State, Event>();
static { static {
s_fsm.addTransition(State.Allocated, Event.ImplementNetwork, State.Implementing); s_fsm.addTransition(State.Allocated, Event.ImplementNetwork, State.Implementing);
@ -186,12 +186,12 @@ public interface Network extends ControlledEntity {
s_fsm.addTransition(State.Shutdown, Event.OperationFailed, State.Implemented); s_fsm.addTransition(State.Shutdown, Event.OperationFailed, State.Implemented);
} }
} }
/** /**
* @return id of the network profile. Null means the network profile is not from the database. * @return id of the network profile. Null means the network profile is not from the database.
*/ */
long getId(); long getId();
String getName(); String getName();
Mode getMode(); Mode getMode();
@ -205,27 +205,29 @@ public interface Network extends ControlledEntity {
String getCidr(); String getCidr();
long getDataCenterId(); long getDataCenterId();
long getNetworkOfferingId(); long getNetworkOfferingId();
State getState(); State getState();
long getRelated(); long getRelated();
URI getBroadcastUri(); URI getBroadcastUri();
GuestIpType getGuestType(); GuestIpType getGuestType();
String getDisplayText(); String getDisplayText();
boolean getIsShared(); boolean getIsShared();
String getReservationId(); String getReservationId();
boolean isDefault(); boolean isDefault();
String getNetworkDomain(); String getNetworkDomain();
boolean isSecurityGroupEnabled(); boolean isSecurityGroupEnabled();
List<String> getTags();
} }

View File

@ -19,13 +19,14 @@
package com.cloud.network; package com.cloud.network;
import java.net.URI; import java.net.URI;
import java.util.List;
import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.Mode;
import com.cloud.network.Networks.TrafficType; import com.cloud.network.Networks.TrafficType;
public class NetworkProfile implements Network{ public class NetworkProfile implements Network {
private long id; private long id;
private long dataCenterId; private long dataCenterId;
private long ownerId; private long ownerId;
@ -49,6 +50,7 @@ public class NetworkProfile implements Network{
private boolean isDefault; private boolean isDefault;
private String networkDomain; private String networkDomain;
private boolean isSecurityGroupEnabled; private boolean isSecurityGroupEnabled;
private List<String> tags;
public NetworkProfile(Network network) { public NetworkProfile(Network network) {
this.id = network.getId(); this.id = network.getId();
@ -74,6 +76,11 @@ public class NetworkProfile implements Network{
this.isSecurityGroupEnabled = network.isSecurityGroupEnabled(); this.isSecurityGroupEnabled = network.isSecurityGroupEnabled();
} }
@Override
public List<String> getTags() {
return tags;
}
public String getDns1() { public String getDns1() {
return dns1; return dns1;
} }
@ -89,7 +96,7 @@ public class NetworkProfile implements Network{
public void setDns2(String dns2) { public void setDns2(String dns2) {
this.dns2 = dns2; this.dns2 = dns2;
} }
public void setBroadcastUri(URI broadcastUri) { public void setBroadcastUri(URI broadcastUri) {
this.broadcastUri = broadcastUri; this.broadcastUri = broadcastUri;
} }
@ -103,22 +110,22 @@ public class NetworkProfile implements Network{
public long getId() { public long getId() {
return id; return id;
} }
@Override @Override
public long getDataCenterId() { public long getDataCenterId() {
return dataCenterId; return dataCenterId;
} }
@Override @Override
public long getAccountId() { public long getAccountId() {
return ownerId; return ownerId;
} }
@Override @Override
public State getState() { public State getState() {
return state; return state;
} }
@Override @Override
public String getName() { public String getName() {
return name; return name;
@ -153,37 +160,37 @@ public class NetworkProfile implements Network{
public long getNetworkOfferingId() { public long getNetworkOfferingId() {
return networkOfferingId; return networkOfferingId;
} }
@Override @Override
public long getRelated() { public long getRelated() {
return related; return related;
} }
@Override @Override
public GuestIpType getGuestType() { public GuestIpType getGuestType() {
return guestIpType; return guestIpType;
} }
@Override @Override
public String getDisplayText() { public String getDisplayText() {
return displayText; return displayText;
} }
@Override @Override
public boolean getIsShared() { public boolean getIsShared() {
return isShared; return isShared;
} }
@Override @Override
public String getReservationId() { public String getReservationId() {
return reservationId; return reservationId;
} }
@Override @Override
public boolean isDefault() { public boolean isDefault() {
return isDefault; return isDefault;
} }
@Override @Override
public String getNetworkDomain() { public String getNetworkDomain() {
return networkDomain; return networkDomain;
@ -193,7 +200,7 @@ public class NetworkProfile implements Network{
public long getDomainId() { public long getDomainId() {
return domainId; return domainId;
} }
@Override @Override
public boolean isSecurityGroupEnabled() { public boolean isSecurityGroupEnabled() {
return isSecurityGroupEnabled; return isSecurityGroupEnabled;

View File

@ -22,6 +22,7 @@
package com.cloud.vm; package com.cloud.vm;
import java.net.URI; import java.net.URI;
import java.util.List;
import com.cloud.network.Network; import com.cloud.network.Network;
import com.cloud.network.Networks.AddressFormat; import com.cloud.network.Networks.AddressFormat;
@ -53,11 +54,16 @@ public class NicProfile {
String dns2; String dns2;
Integer networkRate; Integer networkRate;
boolean isSecurityGroupEnabled; boolean isSecurityGroupEnabled;
List<String> tags;
public String getDns1() { public String getDns1() {
return dns1; return dns1;
} }
public List<String> getTags() {
return tags;
}
public String getDns2() { public String getDns2() {
return dns2; return dns2;
} }
@ -226,6 +232,7 @@ public class NicProfile {
this.netmask = nic.getNetmask(); this.netmask = nic.getNetmask();
this.isSecurityGroupEnabled = network.isSecurityGroupEnabled(); this.isSecurityGroupEnabled = network.isSecurityGroupEnabled();
this.vmId = nic.getInstanceId(); this.vmId = nic.getInstanceId();
this.tags = network.getTags();
if (networkRate != null) { if (networkRate != null) {
this.networkRate = networkRate; this.networkRate = networkRate;

View File

@ -23,8 +23,10 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.apache.log4j.Level;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command; import com.cloud.agent.api.Command;
import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig; import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig;
import com.cloud.exception.UnsupportedVersionException; import com.cloud.exception.UnsupportedVersionException;
@ -64,6 +66,7 @@ public class Request {
protected static final Gson s_gson = GsonHelper.getGson(); protected static final Gson s_gson = GsonHelper.getGson();
protected static final Gson s_gogger = GsonHelper.getGsonLogger(); protected static final Gson s_gogger = GsonHelper.getGsonLogger();
protected static final Logger s_gsonLogger = GsonHelper.getLogger();
public enum Version { public enum Version {
v1, // using gson to marshall v1, // using gson to marshall
@ -278,47 +281,69 @@ public class Request {
public void logD(String msg, boolean logContent) { public void logD(String msg, boolean logContent) {
if (s_logger.isDebugEnabled()) { if (s_logger.isDebugEnabled()) {
s_logger.debug(log(msg, logContent)); String log = log(msg, logContent, Level.DEBUG);
if (log != null) {
s_logger.debug(log);
}
} }
} }
public void logT(String msg, boolean logD) { public void logT(String msg, boolean logD) {
if (s_logger.isTraceEnabled()) { if (s_logger.isTraceEnabled()) {
s_logger.trace(log(msg, true)); String log = log(msg, true, Level.TRACE);
if (log != null) {
s_logger.trace(log);
}
} else if (logD && s_logger.isDebugEnabled()) { } else if (logD && s_logger.isDebugEnabled()) {
s_logger.debug(log(msg, false)); String log = log(msg, false, Level.DEBUG);
if (log != null) {
s_logger.debug(log);
}
} }
} }
protected String log(String msg, boolean logContent) { protected String log(String msg, boolean logContent, Level level) {
StringBuilder content = new StringBuilder();
if (logContent) {
if (_cmds == null) {
_cmds = s_gson.fromJson(_content, this instanceof Response ? Answer[].class : Command[].class);
}
try {
s_gogger.toJson(_cmds, content);
} catch (Throwable e) {
StringBuilder buff = new StringBuilder();
for (Command cmd : _cmds) {
buff.append(cmd.getClass().getSimpleName()).append("/");
}
s_logger.error("Gson serialization error " + buff.toString(), e);
assert false : "More gson errors on " + buff.toString();
return "";
}
if (content.length() <= 4) {
return null;
}
} else {
if (_cmds == null) {
_cmds = s_gson.fromJson(_content, this instanceof Response ? Answer[].class : Command[].class);
}
content.append("{ ");
for (Command cmd : _cmds) {
content.append(cmd.getClass().getSimpleName()).append(", ");
}
content.replace(content.length() - 2, content.length(), " }");
}
StringBuilder buf = new StringBuilder("Seq "); StringBuilder buf = new StringBuilder("Seq ");
buf.append(_agentId).append("-").append(_seq).append(": "); buf.append(_agentId).append("-").append(_seq).append(": ");
buf.append(msg); buf.append(msg);
buf.append("{ ").append(getType()); buf.append(" { ").append(getType());
buf.append(", MgmtId: ").append(_mgmtId).append(", via: ").append(_via); buf.append(", MgmtId: ").append(_mgmtId).append(", via: ").append(_via);
if (logContent) { buf.append(", Ver: ").append(_ver.toString());
buf.append(", Ver: ").append(_ver.toString()); buf.append(", Flags: ").append(Integer.toBinaryString(getFlags())).append(", ");
buf.append(", Flags: ").append(Integer.toBinaryString(getFlags())).append(", "); buf.append(content);
if (_cmds != null) {
try {
s_gogger.toJson(_cmds, buf);
} catch (Throwable e) {
StringBuilder buff = new StringBuilder();
for (Command cmd : _cmds) {
buff.append(cmd.getClass().getName()).append("/");
}
s_logger.error("Gson serialization error " + buff.toString(), e);
assert false : "More gson errors on " + buff.toString();
return "";
}
} else if (_content != null) {
buf.append(_content.subSequence(0, 32));
} else {
buf.append("I've got nada here!");
assert false : "How can both commands and content be null? What are we sending here?";
}
}
buf.append(" }"); buf.append(" }");
return buf.toString(); return buf.toString();
} }

View File

@ -75,4 +75,8 @@ public class GsonHelper {
public final static Gson getGsonLogger() { public final static Gson getGsonLogger() {
return s_gogger; return s_gogger;
} }
public final static Logger getLogger() {
return s_logger;
}
} }

View File

@ -54,7 +54,7 @@ public class RequestTest extends TestCase {
Level level = logger.getLevel(); Level level = logger.getLevel();
logger.setLevel(Level.DEBUG); logger.setLevel(Level.DEBUG);
String log = sreq.log("Debug", true); String log = sreq.log("Debug", true, Level.DEBUG);
assert (log.contains(UpdateHostPasswordCommand.class.getSimpleName())); assert (log.contains(UpdateHostPasswordCommand.class.getSimpleName()));
assert (log.contains(SecStorageFirewallCfgCommand.class.getSimpleName())); assert (log.contains(SecStorageFirewallCfgCommand.class.getSimpleName()));
assert (!log.contains(GetHostStatsCommand.class.getSimpleName())); assert (!log.contains(GetHostStatsCommand.class.getSimpleName()));
@ -62,7 +62,7 @@ public class RequestTest extends TestCase {
assert (!log.contains("password")); assert (!log.contains("password"));
logger.setLevel(Level.TRACE); logger.setLevel(Level.TRACE);
log = sreq.log("Trace", true); log = sreq.log("Trace", true, Level.TRACE);
assert (log.contains(UpdateHostPasswordCommand.class.getSimpleName())); assert (log.contains(UpdateHostPasswordCommand.class.getSimpleName()));
assert (log.contains(SecStorageFirewallCfgCommand.class.getSimpleName())); assert (log.contains(SecStorageFirewallCfgCommand.class.getSimpleName()));
assert (log.contains(GetHostStatsCommand.class.getSimpleName())); assert (log.contains(GetHostStatsCommand.class.getSimpleName()));
@ -70,7 +70,7 @@ public class RequestTest extends TestCase {
assert (!log.contains("password")); assert (!log.contains("password"));
logger.setLevel(Level.INFO); logger.setLevel(Level.INFO);
sreq.log("Info", true); sreq.log("Info", true, Level.INFO);
assert (log.contains(UpdateHostPasswordCommand.class.getSimpleName())); assert (log.contains(UpdateHostPasswordCommand.class.getSimpleName()));
assert (log.contains(SecStorageFirewallCfgCommand.class.getSimpleName())); assert (log.contains(SecStorageFirewallCfgCommand.class.getSimpleName()));
assert (!log.contains(GetHostStatsCommand.class.getSimpleName())); assert (!log.contains(GetHostStatsCommand.class.getSimpleName()));
@ -127,6 +127,28 @@ public class RequestTest extends TestCase {
} }
public void testLogging() {
GetHostStatsCommand cmd3 = new GetHostStatsCommand("hostguid", "hostname", 101);
Request sreq = new Request(2, 3, new Command[] { cmd3 }, true, true);
sreq.setSequence(1);
Logger logger = Logger.getLogger(GsonHelper.class);
Level level = logger.getLevel();
logger.setLevel(Level.DEBUG);
String log = sreq.log("Debug", true, Level.DEBUG);
assert (log == null);
log = sreq.log("Debug", false, Level.DEBUG);
assert (log != null);
logger.setLevel(Level.TRACE);
log = sreq.log("Trace", true, Level.TRACE);
assert (log.contains(GetHostStatsCommand.class.getSimpleName()));
s_logger.debug(log);
logger.setLevel(level);
}
protected void compareRequest(Request req1, Request req2) { protected void compareRequest(Request req1, Request req2) {
assert req1.getSequence() == req2.getSequence(); assert req1.getSequence() == req2.getSequence();
assert req1.getAgentId() == req2.getAgentId(); assert req1.getAgentId() == req2.getAgentId();

View File

@ -33,7 +33,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
protected HypervisorGuruBase() { protected HypervisorGuruBase() {
super(); super();
} }
protected NicTO toNicTO(NicProfile profile) { protected NicTO toNicTO(NicProfile profile) {
NicTO to = new NicTO(); NicTO to = new NicTO();
to.setDeviceId(profile.getDeviceId()); to.setDeviceId(profile.getDeviceId());
@ -50,39 +50,41 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
to.setIsolationuri(profile.getIsolationUri()); to.setIsolationuri(profile.getIsolationUri());
to.setNetworkRateMbps(profile.getNetworkRate()); to.setNetworkRateMbps(profile.getNetworkRate());
to.setSecurityGroupEnabled(profile.isSecurityGroupEnabled()); to.setSecurityGroupEnabled(profile.isSecurityGroupEnabled());
to.setTags(profile.getTags());
return to; return to;
} }
protected <T extends VirtualMachine> VirtualMachineTO toVirtualMachineTO(VirtualMachineProfile<T> vmProfile) { protected <T extends VirtualMachine> VirtualMachineTO toVirtualMachineTO(VirtualMachineProfile<T> vmProfile) {
ServiceOffering offering = vmProfile.getServiceOffering(); ServiceOffering offering = vmProfile.getServiceOffering();
VirtualMachine vm = vmProfile.getVirtualMachine(); VirtualMachine vm = vmProfile.getVirtualMachine();
VirtualMachineTO to = new VirtualMachineTO(vm.getId(), vm.getInstanceName(), vm.getType(), offering.getCpu(), offering.getSpeed(), VirtualMachineTO to = new VirtualMachineTO(vm.getId(), vm.getInstanceName(), vm.getType(), offering.getCpu(), offering.getSpeed(),
offering.getRamSize() * 1024l * 1024l, offering.getRamSize() * 1024l * 1024l, null, null, vm.isHaEnabled(), vm.limitCpuUse(), vm.getVncPassword()); offering.getRamSize() * 1024l * 1024l, offering.getRamSize() * 1024l * 1024l, null, null, vm.isHaEnabled(), vm.limitCpuUse(), vm.getVncPassword());
to.setBootArgs(vmProfile.getBootArgs()); to.setBootArgs(vmProfile.getBootArgs());
List<NicProfile> nicProfiles = vmProfile.getNics(); List<NicProfile> nicProfiles = vmProfile.getNics();
NicTO[] nics = new NicTO[nicProfiles.size()]; NicTO[] nics = new NicTO[nicProfiles.size()];
int i = 0; int i = 0;
for (NicProfile nicProfile : nicProfiles) { for (NicProfile nicProfile : nicProfiles) {
nics[i++] = toNicTO(nicProfile); nics[i++] = toNicTO(nicProfile);
} }
to.setNics(nics); to.setNics(nics);
to.setDisks(vmProfile.getDisks().toArray(new VolumeTO[vmProfile.getDisks().size()])); to.setDisks(vmProfile.getDisks().toArray(new VolumeTO[vmProfile.getDisks().size()]));
if(vmProfile.getTemplate().getBits() == 32) { if(vmProfile.getTemplate().getBits() == 32) {
to.setArch("i686"); to.setArch("i686");
} else { } else {
to.setArch("x86_64"); to.setArch("x86_64");
} }
return to; return to;
} }
@Override
public long getCommandHostDelegation(long hostId, Command cmd) { public long getCommandHostDelegation(long hostId, Command cmd) {
return hostId; return hostId;
} }
} }

View File

@ -234,7 +234,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
@DB @DB
public PublicIp fetchNewPublicIp(long dcId, Long podId, Long vlanDbId, Account owner, VlanType vlanUse, Long networkId, boolean sourceNat, boolean assign) public PublicIp fetchNewPublicIp(long dcId, Long podId, Long vlanDbId, Account owner, VlanType vlanUse, Long networkId, boolean sourceNat, boolean assign)
throws InsufficientAddressCapacityException { throws InsufficientAddressCapacityException {
Transaction txn = Transaction.currentTxn(); Transaction txn = Transaction.currentTxn();
txn.start(); txn.start();
SearchCriteria<IPAddressVO> sc = null; SearchCriteria<IPAddressVO> sc = null;
@ -570,7 +570,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
boolean isSourceNat = false; boolean isSourceNat = false;
txn.start(); txn.start();
NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId()); NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
if (!offering.isSharedSourceNatService()) { if (!offering.isSharedSourceNatService()) {
// First IP address should be source nat when it's being associated with Guest Virtual network // First IP address should be source nat when it's being associated with Guest Virtual network
@ -828,7 +828,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
@Override @Override
public List<NetworkVO> setupNetwork(Account owner, NetworkOfferingVO offering, DeploymentPlan plan, String name, String displayText, boolean isShared, boolean isDefault) public List<NetworkVO> setupNetwork(Account owner, NetworkOfferingVO offering, DeploymentPlan plan, String name, String displayText, boolean isShared, boolean isDefault)
throws ConcurrentOperationException { throws ConcurrentOperationException {
return setupNetwork(owner, offering, null, plan, name, displayText, isShared, isDefault, false, null); return setupNetwork(owner, offering, null, plan, name, displayText, isShared, isDefault, false, null);
} }
@ -1098,7 +1098,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
@Override @Override
@DB @DB
public Pair<NetworkGuru, NetworkVO> implementNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, public Pair<NetworkGuru, NetworkVO> implementNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException,
InsufficientCapacityException { InsufficientCapacityException {
Transaction.currentTxn(); Transaction.currentTxn();
Pair<NetworkGuru, NetworkVO> implemented = new Pair<NetworkGuru, NetworkVO>(null, null); Pair<NetworkGuru, NetworkVO> implemented = new Pair<NetworkGuru, NetworkVO>(null, null);
@ -1193,7 +1193,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
@Override @Override
public void prepare(VirtualMachineProfile<? extends VMInstanceVO> vmProfile, DeployDestination dest, ReservationContext context) throws InsufficientCapacityException, public void prepare(VirtualMachineProfile<? extends VMInstanceVO> vmProfile, DeployDestination dest, ReservationContext context) throws InsufficientCapacityException,
ConcurrentOperationException, ResourceUnavailableException { ConcurrentOperationException, ResourceUnavailableException {
List<NicVO> nics = _nicDao.listByVmId(vmProfile.getId()); List<NicVO> nics = _nicDao.listByVmId(vmProfile.getId());
// we have to implement default nics first - to ensure that default network elements start up first in multiple nics // we have to implement default nics first - to ensure that default network elements start up first in multiple nics
@ -1667,7 +1667,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
if (!NetUtils.verifyDomainName(networkDomain)) { if (!NetUtils.verifyDomainName(networkDomain)) {
throw new InvalidParameterValueException( throw new InvalidParameterValueException(
"Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', " "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
+ "and the hyphen ('-'); can't start or end with \"-\""); + "and the hyphen ('-'); can't start or end with \"-\"");
} }
} }
@ -2500,7 +2500,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
@Override @Override
@DB @DB
public boolean associateIpAddressListToAccount(long userId, long accountId, long zoneId, Long vlanId, Network network) throws InsufficientCapacityException, ConcurrentOperationException, public boolean associateIpAddressListToAccount(long userId, long accountId, long zoneId, Long vlanId, Network network) throws InsufficientCapacityException, ConcurrentOperationException,
ResourceUnavailableException { ResourceUnavailableException {
Account owner = _accountMgr.getActiveAccount(accountId); Account owner = _accountMgr.getActiveAccount(accountId);
boolean createNetwork = false; boolean createNetwork = false;

View File

@ -18,7 +18,9 @@
package com.cloud.network; package com.cloud.network;
import java.net.URI; import java.net.URI;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
@ -32,6 +34,7 @@ import javax.persistence.Transient;
import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.Mode;
import com.cloud.network.Networks.TrafficType; import com.cloud.network.Networks.TrafficType;
import com.cloud.network.dao.NetworkDao;
import com.cloud.utils.NumbersUtil; import com.cloud.utils.NumbersUtil;
import com.cloud.utils.db.GenericDao; import com.cloud.utils.db.GenericDao;
import com.cloud.utils.net.NetUtils; import com.cloud.utils.net.NetUtils;
@ -47,99 +50,102 @@ public class NetworkVO implements Network {
@TableGenerator(name="networks_sq", table="sequence", pkColumnName="name", valueColumnName="value", pkColumnValue="networks_seq", allocationSize=1) @TableGenerator(name="networks_sq", table="sequence", pkColumnName="name", valueColumnName="value", pkColumnValue="networks_seq", allocationSize=1)
@Column(name="id") @Column(name="id")
long id; long id;
@Column(name="mode") @Column(name="mode")
@Enumerated(value=EnumType.STRING) @Enumerated(value=EnumType.STRING)
Mode mode; Mode mode;
@Column(name="broadcast_domain_type") @Column(name="broadcast_domain_type")
@Enumerated(value=EnumType.STRING) @Enumerated(value=EnumType.STRING)
BroadcastDomainType broadcastDomainType; BroadcastDomainType broadcastDomainType;
@Column(name="traffic_type") @Column(name="traffic_type")
@Enumerated(value=EnumType.STRING) @Enumerated(value=EnumType.STRING)
TrafficType trafficType; TrafficType trafficType;
@Column(name="guest_type") @Column(name="guest_type")
GuestIpType guestType; GuestIpType guestType;
@Column(name="name") @Column(name="name")
String name; String name;
@Column(name="display_text") @Column(name="display_text")
String displayText;; String displayText;;
@Column(name="broadcast_uri") @Column(name="broadcast_uri")
URI broadcastUri; URI broadcastUri;
@Column(name="gateway") @Column(name="gateway")
String gateway; String gateway;
@Column(name="cidr") @Column(name="cidr")
String cidr; String cidr;
@Column(name="network_offering_id") @Column(name="network_offering_id")
long networkOfferingId; long networkOfferingId;
@Column(name="data_center_id") @Column(name="data_center_id")
long dataCenterId; long dataCenterId;
@Column(name="related") @Column(name="related")
long related; long related;
@Column(name="guru_name") @Column(name="guru_name")
String guruName; String guruName;
@Column(name="state") @Column(name="state")
@Enumerated(value=EnumType.STRING) @Enumerated(value=EnumType.STRING)
State state; State state;
@Column(name="dns1") @Column(name="dns1")
String dns1; String dns1;
@Column(name="domain_id") @Column(name="domain_id")
long domainId; long domainId;
@Column(name="account_id") @Column(name="account_id")
long accountId; long accountId;
@Column(name="set_fields") @Column(name="set_fields")
long setFields; long setFields;
@TableGenerator(name="mac_address_seq", table="op_networks", pkColumnName="id", valueColumnName="mac_address_seq", allocationSize=1) @TableGenerator(name="mac_address_seq", table="op_networks", pkColumnName="id", valueColumnName="mac_address_seq", allocationSize=1)
@Transient @Transient
long macAddress = 1; long macAddress = 1;
@Column(name="guru_data") @Column(name="guru_data")
String guruData; String guruData;
@Column(name="dns2") @Column(name="dns2")
String dns2; String dns2;
@Column(name="shared") @Column(name="shared")
boolean isShared; boolean isShared;
@Column(name="network_domain") @Column(name="network_domain")
String networkDomain; String networkDomain;
@Column(name=GenericDao.REMOVED_COLUMN) @Column(name=GenericDao.REMOVED_COLUMN)
Date removed; Date removed;
@Column(name=GenericDao.CREATED_COLUMN) @Column(name=GenericDao.CREATED_COLUMN)
Date created; Date created;
@Column(name="reservation_id") @Column(name="reservation_id")
String reservationId; String reservationId;
@Column(name="is_default") @Column(name="is_default")
boolean isDefault; boolean isDefault;
@Column(name="is_security_group_enabled") @Column(name="is_security_group_enabled")
boolean securityGroupEnabled; boolean securityGroupEnabled;
@Transient
List<String> tags;
public NetworkVO() { public NetworkVO() {
} }
/** /**
* Constructor to be used for the adapters because it only initializes what's needed. * Constructor to be used for the adapters because it only initializes what's needed.
* @param trafficType * @param trafficType
@ -163,7 +169,7 @@ public class NetworkVO implements Network {
this.id = -1; this.id = -1;
this.guestType = guestType; this.guestType = guestType;
} }
public NetworkVO(long id, Network that, long offeringId, long dataCenterId, String guruName, long domainId, long accountId, long related, String name, String displayText, Boolean isShared, boolean isDefault, boolean isSecurityGroupEnabled) { public NetworkVO(long id, Network that, long offeringId, long dataCenterId, String guruName, long domainId, long accountId, long related, String name, String displayText, Boolean isShared, boolean isDefault, boolean isSecurityGroupEnabled) {
this(id, that.getTrafficType(), that.getGuestType(), that.getMode(), that.getBroadcastDomainType(), offeringId, dataCenterId, domainId, accountId, related, name, displayText, isShared, isDefault); this(id, that.getTrafficType(), that.getGuestType(), that.getMode(), that.getBroadcastDomainType(), offeringId, dataCenterId, domainId, accountId, related, name, displayText, isShared, isDefault);
this.gateway = that.getGateway(); this.gateway = that.getGateway();
@ -204,25 +210,25 @@ public class NetworkVO implements Network {
this.isShared = isShared; this.isShared = isShared;
this.isDefault = isDefault; this.isDefault = isDefault;
} }
@Override @Override
public String getReservationId() { public String getReservationId() {
return reservationId; return reservationId;
} }
public void setReservationId(String reservationId) { public void setReservationId(String reservationId) {
this.reservationId = reservationId; this.reservationId = reservationId;
} }
@Override @Override
public State getState() { public State getState() {
return state; return state;
} }
public void setState(State state) { public void setState(State state) {
this.state = state; this.state = state;
} }
@Override @Override
public long getRelated() { public long getRelated() {
return related; return related;
@ -232,7 +238,23 @@ public class NetworkVO implements Network {
public long getId() { public long getId() {
return id; return id;
} }
@Override
public List<String> getTags() {
return tags != null ? tags : new ArrayList<String>();
}
public void addTag(String tag) {
if (tags == null) {
tags = new ArrayList<String>();
}
tags.add(tag);
}
public void setTags(List<String> tags) {
this.tags = tags;
}
@Override @Override
public GuestIpType getGuestType() { public GuestIpType getGuestType() {
return guestType; return guestType;
@ -242,17 +264,17 @@ public class NetworkVO implements Network {
public Mode getMode() { public Mode getMode() {
return mode; return mode;
} }
@Override @Override
public long getAccountId() { public long getAccountId() {
return accountId; return accountId;
} }
@Override @Override
public long getDomainId() { public long getDomainId() {
return domainId; return domainId;
} }
@Override @Override
public long getNetworkOfferingId() { public long getNetworkOfferingId() {
return networkOfferingId; return networkOfferingId;
@ -266,19 +288,19 @@ public class NetworkVO implements Network {
public BroadcastDomainType getBroadcastDomainType() { public BroadcastDomainType getBroadcastDomainType() {
return broadcastDomainType; return broadcastDomainType;
} }
public String getGuruData() { public String getGuruData() {
return guruData; return guruData;
} }
public void setGuruData(String guruData) { public void setGuruData(String guruData) {
this.guruData = guruData; this.guruData = guruData;
} }
public String getGuruName() { public String getGuruName() {
return guruName; return guruName;
} }
public void setGuruName(String guruName) { public void setGuruName(String guruName) {
this.guruName = guruName; this.guruName = guruName;
} }
@ -286,12 +308,12 @@ public class NetworkVO implements Network {
public void setBroadcastDomainType(BroadcastDomainType broadcastDomainType) { public void setBroadcastDomainType(BroadcastDomainType broadcastDomainType) {
this.broadcastDomainType = broadcastDomainType; this.broadcastDomainType = broadcastDomainType;
} }
@Override @Override
public String getNetworkDomain() { public String getNetworkDomain() {
return networkDomain; return networkDomain;
} }
public void setNetworkDomain(String networkDomain) { public void setNetworkDomain(String networkDomain) {
this.networkDomain = networkDomain; this.networkDomain = networkDomain;
} }
@ -322,7 +344,7 @@ public class NetworkVO implements Network {
public void setCidr(String cidr) { public void setCidr(String cidr) {
this.cidr = cidr; this.cidr = cidr;
} }
@Override @Override
public URI getBroadcastUri() { public URI getBroadcastUri() {
return broadcastUri; return broadcastUri;
@ -331,33 +353,33 @@ public class NetworkVO implements Network {
public void setBroadcastUri(URI broadcastUri) { public void setBroadcastUri(URI broadcastUri) {
this.broadcastUri = broadcastUri; this.broadcastUri = broadcastUri;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return NumbersUtil.hash(id); return NumbersUtil.hash(id);
} }
@Override @Override
public long getDataCenterId() { public long getDataCenterId() {
return dataCenterId; return dataCenterId;
} }
public String getDns1() { public String getDns1() {
return dns1; return dns1;
} }
public void setDns1(String dns) { public void setDns1(String dns) {
this.dns1 = dns; this.dns1 = dns;
} }
public String getDns2() { public String getDns2() {
return dns2; return dns2;
} }
public void setDns2(String dns) { public void setDns2(String dns) {
this.dns2 = dns; this.dns2 = dns;
} }
@Override @Override
public String getName() { public String getName() {
return name; return name;
@ -366,7 +388,7 @@ public class NetworkVO implements Network {
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }
@Override @Override
public String getDisplayText() { public String getDisplayText() {
return displayText; return displayText;
@ -375,22 +397,22 @@ public class NetworkVO implements Network {
public void setDisplayText(String displayText) { public void setDisplayText(String displayText) {
this.displayText = displayText; this.displayText = displayText;
} }
@Override @Override
public boolean getIsShared() { public boolean getIsShared() {
return isShared; return isShared;
} }
@Override @Override
public boolean isDefault() { public boolean isDefault() {
return isDefault; return isDefault;
} }
@Override @Override
public boolean isSecurityGroupEnabled() { public boolean isSecurityGroupEnabled() {
return securityGroupEnabled; return securityGroupEnabled;
} }
public void setSecurityGroupEnabled(boolean enabled) { public void setSecurityGroupEnabled(boolean enabled) {
this.securityGroupEnabled = enabled; this.securityGroupEnabled = enabled;
} }
@ -424,26 +446,28 @@ public class NetworkVO implements Network {
if (this.trafficType != that.trafficType) { if (this.trafficType != that.trafficType) {
return false; return false;
} }
if ((this.cidr == null && that.cidr != null) || (this.cidr != null && that.cidr == null)) { if ((this.cidr == null && that.cidr != null) || (this.cidr != null && that.cidr == null)) {
return false; return false;
} }
if (this.cidr == null && that.cidr == null) { if (this.cidr == null && that.cidr == null) {
return true; return true;
} }
return NetUtils.isNetworkAWithinNetworkB(this.cidr, that.cidr); return NetUtils.isNetworkAWithinNetworkB(this.cidr, that.cidr);
} }
public boolean isImplemented() {
return broadcastUri != null && cidr != null && gateway != null && mode != null && broadcastDomainType != null;
}
@Override @Override
public String toString() { public String toString() {
StringBuilder buf = new StringBuilder("Ntwk["); StringBuilder buf = new StringBuilder("Ntwk[");
buf.append(id).append("|").append(trafficType.toString()).append("|").append(networkOfferingId).append("]"); buf.append(id).append("|").append(trafficType.toString()).append("|").append(networkOfferingId).append("]");
return buf.toString(); return buf.toString();
} }
private static NetworkDao _networkDao = null;
static void init(NetworkDao networkDao) {
_networkDao = networkDao;
}
} }

View File

@ -51,17 +51,19 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
final SearchBuilder<NetworkVO> AccountNetworkSearch; final SearchBuilder<NetworkVO> AccountNetworkSearch;
final SearchBuilder<NetworkVO> ZoneBroadcastUriSearch; final SearchBuilder<NetworkVO> ZoneBroadcastUriSearch;
final SearchBuilder<NetworkVO> ZoneSecurityGroupSearch; final SearchBuilder<NetworkVO> ZoneSecurityGroupSearch;
NetworkAccountDaoImpl _accountsDao = ComponentLocator.inject(NetworkAccountDaoImpl.class); NetworkAccountDaoImpl _accountsDao = ComponentLocator.inject(NetworkAccountDaoImpl.class);
NetworkDomainDaoImpl _domainsDao = ComponentLocator.inject(NetworkDomainDaoImpl.class); NetworkDomainDaoImpl _domainsDao = ComponentLocator.inject(NetworkDomainDaoImpl.class);
NetworkOpDaoImpl _opDao = ComponentLocator.inject(NetworkOpDaoImpl.class); NetworkOpDaoImpl _opDao = ComponentLocator.inject(NetworkOpDaoImpl.class);
NetworkTagDaoImpl _tagDao = ComponentLocator.inject(NetworkTagDaoImpl.class);
final TableGenerator _tgMacAddress; final TableGenerator _tgMacAddress;
Random _rand = new Random(System.currentTimeMillis()); Random _rand = new Random(System.currentTimeMillis());
long _prefix = 0x2; long _prefix = 0x2;
protected NetworkDaoImpl() { protected NetworkDaoImpl() {
super(); super();
AllFieldsSearch = createSearchBuilder(); AllFieldsSearch = createSearchBuilder();
AllFieldsSearch.and("trafficType", AllFieldsSearch.entity().getTrafficType(), Op.EQ); AllFieldsSearch.and("trafficType", AllFieldsSearch.entity().getTrafficType(), Op.EQ);
AllFieldsSearch.and("cidr", AllFieldsSearch.entity().getCidr(), Op.EQ); AllFieldsSearch.and("cidr", AllFieldsSearch.entity().getCidr(), Op.EQ);
@ -73,7 +75,7 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
AllFieldsSearch.and("related", AllFieldsSearch.entity().getRelated(), Op.EQ); AllFieldsSearch.and("related", AllFieldsSearch.entity().getRelated(), Op.EQ);
AllFieldsSearch.and("isShared", AllFieldsSearch.entity().getIsShared(), Op.EQ); AllFieldsSearch.and("isShared", AllFieldsSearch.entity().getIsShared(), Op.EQ);
AllFieldsSearch.done(); AllFieldsSearch.done();
AccountSearch = createSearchBuilder(); AccountSearch = createSearchBuilder();
AccountSearch.and("offering", AccountSearch.entity().getNetworkOfferingId(), Op.EQ); AccountSearch.and("offering", AccountSearch.entity().getNetworkOfferingId(), Op.EQ);
SearchBuilder<NetworkAccountVO> join = _accountsDao.createSearchBuilder(); SearchBuilder<NetworkAccountVO> join = _accountsDao.createSearchBuilder();
@ -82,7 +84,7 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
AccountSearch.and("datacenter", AccountSearch.entity().getDataCenterId(), Op.EQ); AccountSearch.and("datacenter", AccountSearch.entity().getDataCenterId(), Op.EQ);
AccountSearch.and("cidr", AccountSearch.entity().getCidr(), Op.EQ); AccountSearch.and("cidr", AccountSearch.entity().getCidr(), Op.EQ);
AccountSearch.done(); AccountSearch.done();
RelatedConfigSearch = createSearchBuilder(); RelatedConfigSearch = createSearchBuilder();
RelatedConfigSearch.and("offering", RelatedConfigSearch.entity().getNetworkOfferingId(), Op.EQ); RelatedConfigSearch.and("offering", RelatedConfigSearch.entity().getNetworkOfferingId(), Op.EQ);
RelatedConfigSearch.and("datacenter", RelatedConfigSearch.entity().getDataCenterId(), Op.EQ); RelatedConfigSearch.and("datacenter", RelatedConfigSearch.entity().getDataCenterId(), Op.EQ);
@ -90,29 +92,29 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
join2.and("account", join2.entity().getAccountId(), Op.EQ); join2.and("account", join2.entity().getAccountId(), Op.EQ);
RelatedConfigSearch.join("account", join2, join2.entity().getNetworkId(), RelatedConfigSearch.entity().getId(), JoinType.INNER); RelatedConfigSearch.join("account", join2, join2.entity().getNetworkId(), RelatedConfigSearch.entity().getId(), JoinType.INNER);
RelatedConfigSearch.done(); RelatedConfigSearch.done();
AccountNetworkSearch = createSearchBuilder(); AccountNetworkSearch = createSearchBuilder();
AccountNetworkSearch.and("networkId", AccountNetworkSearch.entity().getId(), Op.EQ); AccountNetworkSearch.and("networkId", AccountNetworkSearch.entity().getId(), Op.EQ);
SearchBuilder<NetworkAccountVO> mapJoin = _accountsDao.createSearchBuilder(); SearchBuilder<NetworkAccountVO> mapJoin = _accountsDao.createSearchBuilder();
mapJoin.and("accountId", mapJoin.entity().getAccountId(), Op.EQ); mapJoin.and("accountId", mapJoin.entity().getAccountId(), Op.EQ);
AccountNetworkSearch.join("networkSearch", mapJoin, AccountNetworkSearch.entity().getId(), mapJoin.entity().getNetworkId(), JoinBuilder.JoinType.INNER); AccountNetworkSearch.join("networkSearch", mapJoin, AccountNetworkSearch.entity().getId(), mapJoin.entity().getNetworkId(), JoinBuilder.JoinType.INNER);
AccountNetworkSearch.done(); AccountNetworkSearch.done();
ZoneBroadcastUriSearch = createSearchBuilder(); ZoneBroadcastUriSearch = createSearchBuilder();
ZoneBroadcastUriSearch.and("dataCenterId", ZoneBroadcastUriSearch.entity().getDataCenterId(), Op.EQ); ZoneBroadcastUriSearch.and("dataCenterId", ZoneBroadcastUriSearch.entity().getDataCenterId(), Op.EQ);
ZoneBroadcastUriSearch.and("broadcastUri", ZoneBroadcastUriSearch.entity().getBroadcastUri(), Op.EQ); ZoneBroadcastUriSearch.and("broadcastUri", ZoneBroadcastUriSearch.entity().getBroadcastUri(), Op.EQ);
ZoneBroadcastUriSearch.done(); ZoneBroadcastUriSearch.done();
ZoneSecurityGroupSearch = createSearchBuilder(); ZoneSecurityGroupSearch = createSearchBuilder();
ZoneSecurityGroupSearch.and("dataCenterId", ZoneSecurityGroupSearch.entity().getDataCenterId(), Op.EQ); ZoneSecurityGroupSearch.and("dataCenterId", ZoneSecurityGroupSearch.entity().getDataCenterId(), Op.EQ);
ZoneSecurityGroupSearch.and("securityGroup", ZoneSecurityGroupSearch.entity().isSecurityGroupEnabled(), Op.EQ); ZoneSecurityGroupSearch.and("securityGroup", ZoneSecurityGroupSearch.entity().isSecurityGroupEnabled(), Op.EQ);
ZoneSecurityGroupSearch.done(); ZoneSecurityGroupSearch.done();
_tgMacAddress = _tgs.get("macAddress"); _tgMacAddress = _tgs.get("macAddress");
} }
@Override @Override
public List<NetworkVO> listBy(long accountId, long dataCenterId, GuestIpType type) { public List<NetworkVO> listBy(long accountId, long dataCenterId, GuestIpType type) {
SearchCriteria<NetworkVO> sc = AllFieldsSearch.create(); SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
@ -123,37 +125,42 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
} }
return listBy(sc, null); return listBy(sc, null);
} }
public List<NetworkVO> findBy(TrafficType trafficType, Mode mode, BroadcastDomainType broadcastType, long networkOfferingId, long dataCenterId) { public List<NetworkVO> findBy(TrafficType trafficType, Mode mode, BroadcastDomainType broadcastType, long networkOfferingId, long dataCenterId) {
SearchCriteria<NetworkVO> sc = AllFieldsSearch.create(); SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
sc.setParameters("trafficType", trafficType); sc.setParameters("trafficType", trafficType);
sc.setParameters("broadcastType", broadcastType); sc.setParameters("broadcastType", broadcastType);
sc.setParameters("offering", networkOfferingId); sc.setParameters("offering", networkOfferingId);
sc.setParameters("datacenter", dataCenterId); sc.setParameters("datacenter", dataCenterId);
return search(sc, null); return search(sc, null);
} }
@Override @Override
public List<NetworkVO> listBy(long accountId) { public List<NetworkVO> listBy(long accountId) {
SearchCriteria<NetworkVO> sc = AccountSearch.create(); SearchCriteria<NetworkVO> sc = AccountSearch.create();
sc.setParameters("account", accountId); sc.setParameters("account", accountId);
sc.setJoinParameters("accounts", "account", accountId); sc.setJoinParameters("accounts", "account", accountId);
return listBy(sc); return listBy(sc);
} }
// @Override
// public void loadTags(NetworkVO network) {
// network.setTags(_tagDao.getTags(network.getId()));
// }
@Override @Override
public List<NetworkVO> listBy(long accountId, long offeringId, long dataCenterId) { public List<NetworkVO> listBy(long accountId, long offeringId, long dataCenterId) {
SearchCriteria<NetworkVO> sc = AccountSearch.create(); SearchCriteria<NetworkVO> sc = AccountSearch.create();
sc.setParameters("offering", offeringId); sc.setParameters("offering", offeringId);
sc.setJoinParameters("accounts", "account", accountId); sc.setJoinParameters("accounts", "account", accountId);
sc.setParameters("datacenter", dataCenterId); sc.setParameters("datacenter", dataCenterId);
return listBy(sc); return listBy(sc);
} }
@Override @Override
public List<NetworkVO> listBy(long accountId, long offeringId, long dataCenterId, String cidr) { public List<NetworkVO> listBy(long accountId, long offeringId, long dataCenterId, String cidr) {
SearchCriteria<NetworkVO> sc = AccountSearch.create(); SearchCriteria<NetworkVO> sc = AccountSearch.create();
@ -161,37 +168,41 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
sc.setJoinParameters("accounts", "account", accountId); sc.setJoinParameters("accounts", "account", accountId);
sc.setParameters("datacenter", dataCenterId); sc.setParameters("datacenter", dataCenterId);
sc.setParameters("cidr", cidr); sc.setParameters("cidr", cidr);
return listBy(sc); return listBy(sc);
} }
@Override @DB @Override @DB
public NetworkVO persist(NetworkVO config, boolean gc) { public NetworkVO persist(NetworkVO network, boolean gc) {
Transaction txn = Transaction.currentTxn(); Transaction txn = Transaction.currentTxn();
txn.start(); txn.start();
config = super.persist(config); NetworkVO newNetwork = super.persist(network);
addAccountToNetworkConfiguration(config.getId(), config.getAccountId(), true); addAccountToNetwork(network.getId(), network.getAccountId(), true);
NetworkOpVO op = new NetworkOpVO(config.getId(), gc); NetworkOpVO op = new NetworkOpVO(network.getId(), gc);
_opDao.persist(op); _opDao.persist(op);
for (String tag : network.getTags()) {
_tagDao.persist(new NetworkTagVO(network.getId(), tag));
}
txn.commit(); txn.commit();
return config; newNetwork.setTags(network.getTags());
return newNetwork;
} }
@Override @Override
public void addAccountToNetwork(long configurationId, long accountId) { public void addAccountToNetwork(long networkId, long accountId) {
addAccountToNetworkConfiguration(configurationId, accountId, false); addAccountToNetwork(networkId, accountId, false);
} }
protected void addAccountToNetworkConfiguration(long configurationId, long accountId, boolean isOwner) { protected void addAccountToNetwork(long networkId, long accountId, boolean isOwner) {
NetworkAccountVO account = new NetworkAccountVO(configurationId, accountId, isOwner); NetworkAccountVO account = new NetworkAccountVO(networkId, accountId, isOwner);
_accountsDao.persist(account); _accountsDao.persist(account);
} }
@Override @Override
public SearchBuilder<NetworkAccountVO> createSearchBuilderForAccount() { public SearchBuilder<NetworkAccountVO> createSearchBuilderForAccount() {
return _accountsDao.createSearchBuilder(); return _accountsDao.createSearchBuilder();
} }
@Override @Override
public List<NetworkVO> getNetworksForOffering(long offeringId, long dataCenterId, long accountId) { public List<NetworkVO> getNetworksForOffering(long offeringId, long dataCenterId, long accountId) {
SearchCriteria<NetworkVO> sc = RelatedConfigSearch.create(); SearchCriteria<NetworkVO> sc = RelatedConfigSearch.create();
@ -200,23 +211,23 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
sc.setJoinParameters("account", "account", accountId); sc.setJoinParameters("account", "account", accountId);
return search(sc, null); return search(sc, null);
} }
@Override @Override
public List<NetworkVO> getRelatedNetworks(long related) { public List<NetworkVO> getRelatedNetworks(long related) {
SearchCriteria<NetworkVO> sc = AllFieldsSearch.create(); SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
sc.setParameters("related", related); sc.setParameters("related", related);
return search(sc, null); return search(sc, null);
} }
@Override @Override
public String getNextAvailableMacAddress(long networkConfigId) { public String getNextAvailableMacAddress(long networkConfigId) {
SequenceFetcher fetch = SequenceFetcher.getInstance(); SequenceFetcher fetch = SequenceFetcher.getInstance();
long seq = fetch.getNextSequence(Long.class, _tgMacAddress, networkConfigId); long seq = fetch.getNextSequence(Long.class, _tgMacAddress, networkConfigId);
seq = seq | _prefix << 40| ((_rand.nextInt(Short.MAX_VALUE) << 16) & 0x00000000ffff0000l); seq = seq | _prefix << 40| ((_rand.nextInt(Short.MAX_VALUE) << 16) & 0x00000000ffff0000l);
return NetUtils.long2Mac(seq); return NetUtils.long2Mac(seq);
} }
@Override @Override
public List<NetworkVO> listBy(long accountId, long networkId) { public List<NetworkVO> listBy(long accountId, long networkId) {
SearchCriteria<NetworkVO> sc = AccountNetworkSearch.create(); SearchCriteria<NetworkVO> sc = AccountNetworkSearch.create();
@ -224,7 +235,7 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
sc.setJoinParameters("networkSearch", "accountId", accountId); sc.setJoinParameters("networkSearch", "accountId", accountId);
return listBy(sc); return listBy(sc);
} }
@Override @Override
public List<NetworkVO> listBy(long zoneId, String broadcastUri) { public List<NetworkVO> listBy(long zoneId, String broadcastUri) {
SearchCriteria<NetworkVO> sc = ZoneBroadcastUriSearch.create(); SearchCriteria<NetworkVO> sc = ZoneBroadcastUriSearch.create();
@ -232,67 +243,68 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
sc.setParameters("broadcastUri", broadcastUri); sc.setParameters("broadcastUri", broadcastUri);
return search(sc, null); return search(sc, null);
} }
@Override @Override
public List<NetworkVO> listByZone(long zoneId) { public List<NetworkVO> listByZone(long zoneId) {
SearchCriteria<NetworkVO> sc = ZoneBroadcastUriSearch.create(); SearchCriteria<NetworkVO> sc = ZoneBroadcastUriSearch.create();
sc.setParameters("dataCenterId", zoneId); sc.setParameters("dataCenterId", zoneId);
return search(sc, null); return search(sc, null);
} }
@Override @Override
public List<NetworkVO> listByZoneSecurityGroup(Long zoneId) { public List<NetworkVO> listByZoneSecurityGroup(Long zoneId) {
SearchCriteria<NetworkVO> sc = ZoneSecurityGroupSearch.create(); SearchCriteria<NetworkVO> sc = ZoneSecurityGroupSearch.create();
if (zoneId != null) if (zoneId != null) {
sc.setParameters("dataCenterId", zoneId); sc.setParameters("dataCenterId", zoneId);
}
sc.setParameters("securityGroup", true); sc.setParameters("securityGroup", true);
return search(sc, null); return search(sc, null);
} }
@Override @Override
public void changeActiveNicsBy(long networkId, int count) { public void changeActiveNicsBy(long networkId, int count) {
_opDao.changeActiveNicsBy(networkId, count); _opDao.changeActiveNicsBy(networkId, count);
} }
@Override @Override
public int getActiveNicsIn(long networkId) { public int getActiveNicsIn(long networkId) {
return _opDao.getActiveNics(networkId); return _opDao.getActiveNics(networkId);
} }
@Override @Override
public List<Long> findNetworksToGarbageCollect() { public List<Long> findNetworksToGarbageCollect() {
return _opDao.getNetworksToGarbageCollect(); return _opDao.getNetworksToGarbageCollect();
} }
@Override @Override
public void clearCheckForGc(long networkId) { public void clearCheckForGc(long networkId) {
_opDao.clearCheckForGc(networkId); _opDao.clearCheckForGc(networkId);
} }
@Override @Override
public List<NetworkVO> listByOwner(long ownerId) { public List<NetworkVO> listByOwner(long ownerId) {
SearchCriteria<NetworkVO> sc = AllFieldsSearch.create(); SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
sc.setParameters("account", ownerId); sc.setParameters("account", ownerId);
return listBy(sc); return listBy(sc);
} }
@Override @Override
public void addDomainToNetwork(long configurationId, long domainId) { public void addDomainToNetwork(long networkId, long domainId) {
addDomainToNetworkConfiguration(configurationId, domainId); addDomainToNetworknetwork(networkId, domainId);
} }
protected void addDomainToNetworkConfiguration(long configurationId, long domainId) { protected void addDomainToNetworknetwork(long networkId, long domainId) {
NetworkDomainVO domain = new NetworkDomainVO(configurationId, domainId); NetworkDomainVO domain = new NetworkDomainVO(networkId, domainId);
_domainsDao.persist(domain); _domainsDao.persist(domain);
} }
@Override @Override
public List<NetworkVO> listNetworksBy(boolean isShared) { public List<NetworkVO> listNetworksBy(boolean isShared) {
SearchCriteria<NetworkVO> sc = AllFieldsSearch.create(); SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
sc.setParameters("isShared", isShared); sc.setParameters("isShared", isShared);
return listBy(sc); return listBy(sc);
} }
@Override @Override
public List<NetworkVO> listByZoneIncludingRemoved(long zoneId) { public List<NetworkVO> listByZoneIncludingRemoved(long zoneId) {
SearchCriteria<NetworkVO> sc = ZoneBroadcastUriSearch.create(); SearchCriteria<NetworkVO> sc = ZoneBroadcastUriSearch.create();

View File

@ -0,0 +1,62 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.network.dao;
import java.util.List;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
public class NetworkTagDaoImpl extends GenericDaoBase<NetworkTagVO, Long> implements GenericDao<NetworkTagVO, Long> {
private final GenericSearchBuilder<NetworkTagVO, String> TagSearch;
private final SearchBuilder<NetworkTagVO> AllFieldsSearch;
protected NetworkTagDaoImpl() {
super();
TagSearch = createSearchBuilder(String.class);
TagSearch.selectField(TagSearch.entity().getTag());
TagSearch.and("networkid", TagSearch.entity().getNetworkId(), Op.EQ);
TagSearch.done();
AllFieldsSearch = createSearchBuilder();
AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ);
AllFieldsSearch.and("networkid", AllFieldsSearch.entity().getNetworkId(), Op.EQ);
AllFieldsSearch.and("tag", AllFieldsSearch.entity().getTag(), Op.EQ);
AllFieldsSearch.done();
}
public List<String> getTags(long networkId) {
SearchCriteria<String> sc = TagSearch.create();
sc.setParameters("networkid", networkId);
return customSearch(sc, null);
}
public int clearTags(long networkId) {
SearchCriteria<NetworkTagVO> sc = AllFieldsSearch.create();
sc.setParameters("networkid", networkId);
return remove(sc);
}
}

View File

@ -0,0 +1,68 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.network.dao;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* This class is just used to work with the DAO. It shouldn't be used anywhere.
*
*/
@Entity
@Table(name = "network_tags")
public class NetworkTagVO {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "network_id")
private long networkId;
@Column(name = "tag")
private String tag;
/**
* There should never be a public constructor for this class. Since it's
* only here to define the table for the DAO class.
*/
protected NetworkTagVO() {
}
protected NetworkTagVO(long networkId, String tag) {
this.networkId = networkId;
this.tag = tag;
}
public long getId() {
return id;
}
public long getNetworkId() {
return networkId;
}
public String getTag() {
return tag;
}
}

View File

@ -112,6 +112,7 @@ DROP TABLE IF EXISTS `cloud`.`storage_pool_work`;
DROP TABLE IF EXISTS `cloud`.`user_vm_details`; DROP TABLE IF EXISTS `cloud`.`user_vm_details`;
DROP TABLE IF EXISTS `cloud`.`vpn_users`; DROP TABLE IF EXISTS `cloud`.`vpn_users`;
DROP TABLE IF EXISTS `cloud`.`data_center_details`; DROP TABLE IF EXISTS `cloud`.`data_center_details`;
DROP TABLE IF EXISTS `cloud`.`network_tags`;
CREATE TABLE `cloud`.`version` ( CREATE TABLE `cloud`.`version` (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
@ -190,6 +191,15 @@ CREATE TABLE `cloud`.`networks` (
INDEX `i_networks__removed`(`removed`) INDEX `i_networks__removed`(`removed`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`network_tags` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`network_id` bigint unsigned NOT NULL COMMENT 'id of the network',
`tag` varchar(255) NOT NULL COMMENT 'tag',
PRIMARY KEY (`id`),
CONSTRAINT `fk_network_tags__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`),
UNIQUE KEY(`network_id`, `tag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`account_network_ref` ( CREATE TABLE `cloud`.`account_network_ref` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`account_id` bigint unsigned NOT NULL COMMENT 'account id', `account_id` bigint unsigned NOT NULL COMMENT 'account id',

View File

@ -31,6 +31,14 @@ CREATE TABLE `cloud`.`cmd_exec_log` (
CONSTRAINT `fk_cmd_exec_log_ref__inst_id` FOREIGN KEY (`instance_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE CONSTRAINT `fk_cmd_exec_log_ref__inst_id` FOREIGN KEY (`instance_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`network_tags` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`network_id` bigint unsigned NOT NULL COMMENT 'id of the network',
`tag` varchar(255) NOT NULL COMMENT 'tag',
PRIMARY KEY (`id`),
CONSTRAINT `fk_network_tags__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`),
UNIQUE KEY(`network_id`, `tag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `cloud`.`firewall_rules_cidrs` ( CREATE TABLE IF NOT EXISTS `cloud`.`firewall_rules_cidrs` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',

View File

@ -49,6 +49,7 @@ import javax.persistence.EmbeddedId;
import javax.persistence.EntityExistsException; import javax.persistence.EntityExistsException;
import javax.persistence.EnumType; import javax.persistence.EnumType;
import javax.persistence.Enumerated; import javax.persistence.Enumerated;
import javax.persistence.OneToMany;
import javax.persistence.TableGenerator; import javax.persistence.TableGenerator;
import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.Callback;
@ -107,14 +108,14 @@ import com.cloud.utils.net.NetUtils;
@DB @DB
public abstract class GenericDaoBase<T, ID extends Serializable> implements GenericDao<T, ID> { public abstract class GenericDaoBase<T, ID extends Serializable> implements GenericDao<T, ID> {
private final static Logger s_logger = Logger.getLogger(GenericDaoBase.class); private final static Logger s_logger = Logger.getLogger(GenericDaoBase.class);
protected final static TimeZone s_gmtTimeZone = TimeZone.getTimeZone("GMT"); protected final static TimeZone s_gmtTimeZone = TimeZone.getTimeZone("GMT");
protected final static Map<Class<?>, GenericDao<?, ? extends Serializable>> s_daoMaps = new HashMap<Class<?>, GenericDao<?, ? extends Serializable>>(71); protected final static Map<Class<?>, GenericDao<?, ? extends Serializable>> s_daoMaps = new HashMap<Class<?>, GenericDao<?, ? extends Serializable>>(71);
protected Class<T> _entityBeanType; protected Class<T> _entityBeanType;
protected String _table; protected String _table;
protected String _tables; protected String _tables;
protected Field[] _embeddedFields; protected Field[] _embeddedFields;
@ -134,6 +135,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
protected Map<String, Attribute[]> _idAttributes; protected Map<String, Attribute[]> _idAttributes;
protected Map<String, TableGenerator> _tgs; protected Map<String, TableGenerator> _tgs;
protected final Map<String, Attribute> _allAttributes; protected final Map<String, Attribute> _allAttributes;
protected List<Attribute> _oneToManyAttributes;
protected final Map<Pair<String, String>, Attribute> _allColumns; protected final Map<Pair<String, String>, Attribute> _allColumns;
protected Enhancer _enhancer; protected Enhancer _enhancer;
protected Factory _factory; protected Factory _factory;
@ -141,37 +143,37 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
protected int _timeoutSeconds; protected int _timeoutSeconds;
protected final static CallbackFilter s_callbackFilter = new UpdateFilter(); protected final static CallbackFilter s_callbackFilter = new UpdateFilter();
protected static final String FOR_UPDATE_CLAUSE = " FOR UPDATE "; protected static final String FOR_UPDATE_CLAUSE = " FOR UPDATE ";
protected static final String SHARE_MODE_CLAUSE = " LOCK IN SHARE MODE"; protected static final String SHARE_MODE_CLAUSE = " LOCK IN SHARE MODE";
protected static final String SELECT_LAST_INSERT_ID_SQL = "SELECT LAST_INSERT_ID()"; protected static final String SELECT_LAST_INSERT_ID_SQL = "SELECT LAST_INSERT_ID()";
protected static final SequenceFetcher s_seqFetcher = SequenceFetcher.getInstance(); protected static final SequenceFetcher s_seqFetcher = SequenceFetcher.getInstance();
protected static PreparedStatement s_initStmt; protected static PreparedStatement s_initStmt;
static { static {
Connection conn = Transaction.getStandaloneConnection(); Connection conn = Transaction.getStandaloneConnection();
try { try {
s_initStmt = conn.prepareStatement("SELECT 1"); s_initStmt = conn.prepareStatement("SELECT 1");
} catch (final SQLException e) { } catch (final SQLException e) {
} finally { } finally {
try { try {
conn.close(); conn.close();
} catch (SQLException e) { } catch (SQLException e) {
} }
} }
} }
protected String _name; protected String _name;
public static <J> GenericDao<? extends J, ? extends Serializable> getDao(Class<J> entityType) { public static <J> GenericDao<? extends J, ? extends Serializable> getDao(Class<J> entityType) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
GenericDao<? extends J, ? extends Serializable> dao = (GenericDao<? extends J, ? extends Serializable>)s_daoMaps.get(entityType); GenericDao<? extends J, ? extends Serializable> dao = (GenericDao<? extends J, ? extends Serializable>)s_daoMaps.get(entityType);
assert dao != null : "Unable to find DAO for " + entityType + ". Are you sure you waited for the DAO to be initialized before asking for it?"; assert dao != null : "Unable to find DAO for " + entityType + ". Are you sure you waited for the DAO to be initialized before asking for it?";
return dao; return dao;
} }
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <J> GenericSearchBuilder<T, J> createSearchBuilder(Class<J> resultType) { public <J> GenericSearchBuilder<T, J> createSearchBuilder(Class<J> resultType) {
@ -181,7 +183,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
factory.setCallback(0, builder); factory.setCallback(0, builder);
return builder; return builder;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected GenericDaoBase() { protected GenericDaoBase() {
Type t = getClass().getGenericSuperclass(); Type t = getClass().getGenericSuperclass();
@ -189,9 +191,9 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
_entityBeanType = (Class<T>)((ParameterizedType)t).getActualTypeArguments()[0]; _entityBeanType = (Class<T>)((ParameterizedType)t).getActualTypeArguments()[0];
} else { } else {
_entityBeanType = (Class<T>)((ParameterizedType)((Class<?>)t).getGenericSuperclass()).getActualTypeArguments()[0]; _entityBeanType = (Class<T>)((ParameterizedType)((Class<?>)t).getGenericSuperclass()).getActualTypeArguments()[0];
} }
s_daoMaps.put(_entityBeanType, this); s_daoMaps.put(_entityBeanType, this);
Class<?>[] interphaces = _entityBeanType.getInterfaces(); Class<?>[] interphaces = _entityBeanType.getInterfaces();
if (interphaces != null) { if (interphaces != null) {
@ -211,7 +213,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
_idAttributes = generator.getIdAttributes(); _idAttributes = generator.getIdAttributes();
_idField = _idAttributes.get(_table).length > 0 ? _idAttributes.get(_table)[0].field : null; _idField = _idAttributes.get(_table).length > 0 ? _idAttributes.get(_table)[0].field : null;
_tables = generator.buildTableReferences(); _tables = generator.buildTableReferences();
_allAttributes = generator.getAllAttributes(); _allAttributes = generator.getAllAttributes();
@ -222,7 +224,8 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
_deleteSqls = generator.buildDeleteSqls(); _deleteSqls = generator.buildDeleteSqls();
_removed = generator.getRemovedAttribute(); _removed = generator.getRemovedAttribute();
_tgs = generator.getTableGenerators(); _tgs = generator.getTableGenerators();
_oneToManyAttributes = generator.getOneToManyAttributes();
TableGenerator tg = this.getClass().getAnnotation(TableGenerator.class); TableGenerator tg = this.getClass().getAnnotation(TableGenerator.class);
if (tg != null) { if (tg != null) {
_tgs.put(tg.name(), tg); _tgs.put(tg.name(), tg);
@ -231,19 +234,19 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
if (tg != null) { if (tg != null) {
_tgs.put(tg.name(), tg); _tgs.put(tg.name(), tg);
} }
Callback[] callbacks = new Callback[] { NoOp.INSTANCE, new UpdateBuilder(_allAttributes) }; Callback[] callbacks = new Callback[] { NoOp.INSTANCE, new UpdateBuilder(_allAttributes) };
_enhancer = new Enhancer(); _enhancer = new Enhancer();
_enhancer.setSuperclass(_entityBeanType); _enhancer.setSuperclass(_entityBeanType);
_enhancer.setCallbackFilter(s_callbackFilter); _enhancer.setCallbackFilter(s_callbackFilter);
_enhancer.setCallbacks(callbacks); _enhancer.setCallbacks(callbacks);
_factory = (Factory)_enhancer.create(); _factory = (Factory)_enhancer.create();
_searchEnhancer = new Enhancer(); _searchEnhancer = new Enhancer();
_searchEnhancer.setSuperclass(_entityBeanType); _searchEnhancer.setSuperclass(_entityBeanType);
_searchEnhancer.setCallback(new UpdateBuilder(_allAttributes)); _searchEnhancer.setCallback(new UpdateBuilder(_allAttributes));
if (s_logger.isTraceEnabled()) { if (s_logger.isTraceEnabled()) {
s_logger.trace("Select SQL: " + _partialSelectSql.first().toString()); s_logger.trace("Select SQL: " + _partialSelectSql.first().toString());
s_logger.trace("Remove SQL: " + (_removeSql != null ? _removeSql.first() : "No remove sql")); s_logger.trace("Remove SQL: " + (_removeSql != null ? _removeSql.first() : "No remove sql"));
@ -315,9 +318,9 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
public List<T> searchIncludingRemoved(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache) { public List<T> searchIncludingRemoved(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache) {
String clause = sc != null ? sc.getWhereClause() : null; String clause = sc != null ? sc.getWhereClause() : null;
if (clause != null && clause.length() == 0) { if (clause != null && clause.length() == 0) {
clause = null; clause = null;
} }
final StringBuilder str = createPartialSelectSql(sc, clause != null); final StringBuilder str = createPartialSelectSql(sc, clause != null);
if (clause != null) { if (clause != null) {
str.append(clause); str.append(clause);
@ -330,7 +333,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
addJoins(str, joins); addJoins(str, joins);
} }
} }
List<Object> groupByValues = addGroupBy(str, sc); List<Object> groupByValues = addGroupBy(str, sc);
addFilter(str, filter); addFilter(str, filter);
@ -348,15 +351,15 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
pstmt = txn.prepareAutoCloseStatement(sql); pstmt = txn.prepareAutoCloseStatement(sql);
int i = 0; int i = 0;
if (clause != null) { if (clause != null) {
for (final Pair<Attribute, Object> value : sc.getValues()) { for (final Pair<Attribute, Object> value : sc.getValues()) {
prepareAttribute(++i, pstmt, value.first(), value.second()); prepareAttribute(++i, pstmt, value.first(), value.second());
} }
} }
if (joins != null) { if (joins != null) {
i = addJoinAttributes(i, pstmt, joins); i = addJoinAttributes(i, pstmt, joins);
} }
if (groupByValues != null) { if (groupByValues != null) {
for (Object value : groupByValues) { for (Object value : groupByValues) {
pstmt.setObject(i++, value); pstmt.setObject(i++, value);
@ -364,7 +367,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
} }
if (s_logger.isDebugEnabled() && lock != null) { if (s_logger.isDebugEnabled() && lock != null) {
txn.registerLock(pstmt.toString()); txn.registerLock(pstmt.toString());
} }
final ResultSet rs = pstmt.executeQuery(); final ResultSet rs = pstmt.executeQuery();
while (rs.next()) { while (rs.next()) {
@ -377,14 +380,14 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
throw new CloudRuntimeException("Caught: " + pstmt.toString(), e); throw new CloudRuntimeException("Caught: " + pstmt.toString(), e);
} }
} }
@Override @SuppressWarnings("unchecked") @DB @Override @SuppressWarnings("unchecked") @DB
public <M> List<M> customSearchIncludingRemoved(SearchCriteria<M> sc, final Filter filter) { public <M> List<M> customSearchIncludingRemoved(SearchCriteria<M> sc, final Filter filter) {
String clause = sc != null ? sc.getWhereClause() : null; String clause = sc != null ? sc.getWhereClause() : null;
if (clause != null && clause.length() == 0) { if (clause != null && clause.length() == 0) {
clause = null; clause = null;
} }
final StringBuilder str = createPartialSelectSql(sc, clause != null); final StringBuilder str = createPartialSelectSql(sc, clause != null);
if (clause != null) { if (clause != null) {
str.append(clause); str.append(clause);
@ -397,7 +400,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
addJoins(str, joins); addJoins(str, joins);
} }
} }
List<Object> groupByValues = addGroupBy(str, sc); List<Object> groupByValues = addGroupBy(str, sc);
addFilter(str, filter); addFilter(str, filter);
@ -417,13 +420,13 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
if (joins != null) { if (joins != null) {
i = addJoinAttributes(i, pstmt, joins); i = addJoinAttributes(i, pstmt, joins);
} }
if (groupByValues != null) { if (groupByValues != null) {
for (Object value : groupByValues) { for (Object value : groupByValues) {
pstmt.setObject(i++, value); pstmt.setObject(i++, value);
} }
} }
ResultSet rs = pstmt.executeQuery(); ResultSet rs = pstmt.executeQuery();
SelectType st = sc.getSelectType(); SelectType st = sc.getSelectType();
ArrayList<M> results = new ArrayList<M>(); ArrayList<M> results = new ArrayList<M>();
@ -449,35 +452,35 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
throw new CloudRuntimeException("Caught: " + pstmt.toString(), e); throw new CloudRuntimeException("Caught: " + pstmt.toString(), e);
} }
} }
@Override @DB(txn=false) @Override @DB(txn=false)
public <M> List<M> customSearch(SearchCriteria<M> sc, final Filter filter) { public <M> List<M> customSearch(SearchCriteria<M> sc, final Filter filter) {
if (_removed != null) { if (_removed != null) {
sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL); sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
} }
return customSearchIncludingRemoved(sc, filter); return customSearchIncludingRemoved(sc, filter);
} }
@DB(txn=false) @DB(txn=false)
protected void setField(Object entity, Field field, ResultSet rs, int index) throws SQLException { protected void setField(Object entity, Field field, ResultSet rs, int index) throws SQLException {
try { try {
final Class<?> type = field.getType(); final Class<?> type = field.getType();
if (type == String.class) { if (type == String.class) {
byte[] bytes = rs.getBytes(index); byte[] bytes = rs.getBytes(index);
if(bytes != null) { if(bytes != null) {
try { try {
field.set(entity, new String(bytes, "UTF-8")); field.set(entity, new String(bytes, "UTF-8"));
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
assert(false); assert(false);
throw new CloudRuntimeException("IllegalArgumentException when converting UTF-8 data"); throw new CloudRuntimeException("IllegalArgumentException when converting UTF-8 data");
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
assert(false); assert(false);
throw new CloudRuntimeException("UnsupportedEncodingException when converting UTF-8 data"); throw new CloudRuntimeException("UnsupportedEncodingException when converting UTF-8 data");
} }
} else { } else {
field.set(entity, null); field.set(entity, null);
} }
} else if (type == long.class) { } else if (type == long.class) {
field.setLong(entity, rs.getLong(index)); field.setLong(entity, rs.getLong(index));
} else if (type == Long.class) { } else if (type == Long.class) {
@ -493,7 +496,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
final Enum<?>[] enums = (Enum<?>[])field.getType().getEnumConstants(); final Enum<?>[] enums = (Enum<?>[])field.getType().getEnumConstants();
for (final Enum<?> e : enums) { for (final Enum<?> e : enums) {
if ((enumType == EnumType.STRING && e.name().equalsIgnoreCase(rs.getString(index))) || if ((enumType == EnumType.STRING && e.name().equalsIgnoreCase(rs.getString(index))) ||
(enumType == EnumType.ORDINAL && e.ordinal() == rs.getInt(index))) { (enumType == EnumType.ORDINAL && e.ordinal() == rs.getInt(index))) {
field.set(entity, e); field.set(entity, e);
return; return;
} }
@ -597,20 +600,20 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
throw new CloudRuntimeException("Yikes! ", e); throw new CloudRuntimeException("Yikes! ", e);
} }
} }
@DB(txn=false) @SuppressWarnings("unchecked") @DB(txn=false) @SuppressWarnings("unchecked")
protected <M> M getObject(Class<M> type, ResultSet rs, int index) throws SQLException { protected <M> M getObject(Class<M> type, ResultSet rs, int index) throws SQLException {
if (type == String.class) { if (type == String.class) {
byte[] bytes = rs.getBytes(index); byte[] bytes = rs.getBytes(index);
if(bytes != null) { if(bytes != null) {
try { try {
return (M)new String(bytes, "UTF-8"); return (M)new String(bytes, "UTF-8");
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
throw new CloudRuntimeException("UnsupportedEncodingException exception while converting UTF-8 data"); throw new CloudRuntimeException("UnsupportedEncodingException exception while converting UTF-8 data");
} }
} else { } else {
return null; return null;
} }
} else if (type == int.class) { } else if (type == int.class) {
return (M)new Integer(rs.getInt(index)); return (M)new Integer(rs.getInt(index));
} else if (type == Integer.class) { } else if (type == Integer.class) {
@ -712,13 +715,13 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
@DB(txn=false) @DB(txn=false)
protected int update(final ID id, final UpdateBuilder ub) { protected int update(final ID id, final UpdateBuilder ub) {
SearchCriteria<T> sc = createSearchCriteria(); SearchCriteria<T> sc = createSearchCriteria();
sc.addAnd(_idAttributes.get(_table)[0], SearchCriteria.Op.EQ, id); sc.addAnd(_idAttributes.get(_table)[0], SearchCriteria.Op.EQ, id);
int rowsUpdated = update(ub, sc, null); int rowsUpdated = update(ub, sc, null);
if (_cache != null) { if (_cache != null) {
_cache.remove(id); _cache.remove(id);
} }
return rowsUpdated; return rowsUpdated;
} }
// @Override // @Override
@ -727,33 +730,33 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
PreparedStatement pstmt = s_initStmt; PreparedStatement pstmt = s_initStmt;
final Transaction txn = Transaction.currentTxn(); final Transaction txn = Transaction.currentTxn();
try { try {
final String searchClause = sc.getWhereClause(); final String searchClause = sc.getWhereClause();
sql = ub.toSql(_tables); sql = ub.toSql(_tables);
if (sql == null) { if (sql == null) {
return 0; return 0;
} }
sql.append(searchClause); sql.append(searchClause);
if (rows != null) { if (rows != null) {
sql.append(" LIMIT ").append(rows); sql.append(" LIMIT ").append(rows);
} }
txn.start(); txn.start();
pstmt = txn.prepareAutoCloseStatement(sql.toString()); pstmt = txn.prepareAutoCloseStatement(sql.toString());
Collection<Ternary<Attribute, Boolean, Object>> changes = ub.getChanges(); Collection<Ternary<Attribute, Boolean, Object>> changes = ub.getChanges();
int i = 1; int i = 1;
for (final Ternary<Attribute, Boolean, Object> value : changes) { for (final Ternary<Attribute, Boolean, Object> value : changes) {
prepareAttribute(i++, pstmt, value.first(), value.third()); prepareAttribute(i++, pstmt, value.first(), value.third());
} }
for (Pair<Attribute, Object> value : sc.getValues()) { for (Pair<Attribute, Object> value : sc.getValues()) {
prepareAttribute(i++, pstmt, value.first(), value.second()); prepareAttribute(i++, pstmt, value.first(), value.second());
} }
int result = pstmt.executeUpdate(); int result = pstmt.executeUpdate();
txn.commit(); txn.commit();
ub.clear(); ub.clear();
@ -766,10 +769,10 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
throw new CloudRuntimeException("DB Exception on: " + sqlStr, e); throw new CloudRuntimeException("DB Exception on: " + sqlStr, e);
} }
} }
@DB(txn=false) @DB(txn=false)
protected Attribute findAttributeByFieldName(String name) { protected Attribute findAttributeByFieldName(String name) {
return _allAttributes.get(name); return _allAttributes.get(name);
} }
@DB(txn=false) @DB(txn=false)
@ -846,29 +849,29 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
return lockRow(id, null); return lockRow(id, null);
} }
} }
@Override @DB(txn=false) @Override @DB(txn=false)
public T findByIdIncludingRemoved(ID id) { public T findByIdIncludingRemoved(ID id) {
return findById(id, true, null); return findById(id, true, null);
} }
@Override @DB(txn=false) @Override @DB(txn=false)
public T findById(final ID id, boolean fresh) { public T findById(final ID id, boolean fresh) {
if(!fresh) { if(!fresh) {
return findById(id); return findById(id);
} }
if (_cache != null) { if (_cache != null) {
_cache.remove(id); _cache.remove(id);
} }
return lockRow(id, null); return lockRow(id, null);
} }
@Override @Override
public T lockRow(ID id, Boolean lock) { public T lockRow(ID id, Boolean lock) {
return findById(id, false, lock); return findById(id, false, lock);
} }
protected T findById(ID id, boolean removed, Boolean lock) { protected T findById(ID id, boolean removed, Boolean lock) {
StringBuilder sql = new StringBuilder(_selectByIdSql); StringBuilder sql = new StringBuilder(_selectByIdSql);
if (!removed && _removed != null) { if (!removed && _removed != null) {
@ -883,9 +886,9 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
pstmt = txn.prepareAutoCloseStatement(sql.toString()); pstmt = txn.prepareAutoCloseStatement(sql.toString());
if (_idField.getAnnotation(EmbeddedId.class) == null) { if (_idField.getAnnotation(EmbeddedId.class) == null) {
prepareAttribute(1, pstmt, _idAttributes.get(_table)[0], id); prepareAttribute(1, pstmt, _idAttributes.get(_table)[0], id);
} }
ResultSet rs = pstmt.executeQuery(); ResultSet rs = pstmt.executeQuery();
return rs.next() ? toEntityBean(rs, true) : null; return rs.next() ? toEntityBean(rs, true) : null;
} catch (SQLException e) { } catch (SQLException e) {
@ -895,9 +898,9 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
@Override @DB(txn=false) @Override @DB(txn=false)
public T acquireInLockTable(ID id) { public T acquireInLockTable(ID id) {
return acquireInLockTable(id, _timeoutSeconds); return acquireInLockTable(id, _timeoutSeconds);
} }
@Override @Override
public T acquireInLockTable(final ID id, int seconds) { public T acquireInLockTable(final ID id, int seconds) {
Transaction txn = Transaction.currentTxn(); Transaction txn = Transaction.currentTxn();
@ -905,35 +908,35 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
boolean locked = false; boolean locked = false;
try { try {
if (!txn.lock(_table + id.toString(), seconds)) { if (!txn.lock(_table + id.toString(), seconds)) {
return null; return null;
} }
locked = true; locked = true;
t = findById(id); t = findById(id);
return t; return t;
} finally { } finally {
if (t == null && locked) { if (t == null && locked) {
txn.release(_table + id.toString()); txn.release(_table + id.toString());
} }
} }
} }
@Override @Override
public boolean releaseFromLockTable(final ID id) { public boolean releaseFromLockTable(final ID id) {
final Transaction txn = Transaction.currentTxn(); final Transaction txn = Transaction.currentTxn();
return txn.release(_table + id); return txn.release(_table + id);
} }
@Override @DB(txn=false) @Override @DB(txn=false)
public boolean lockInLockTable(final String id) { public boolean lockInLockTable(final String id) {
return lockInLockTable(id, _timeoutSeconds); return lockInLockTable(id, _timeoutSeconds);
} }
@Override @Override
public boolean lockInLockTable(final String id, int seconds) { public boolean lockInLockTable(final String id, int seconds) {
Transaction txn = Transaction.currentTxn(); Transaction txn = Transaction.currentTxn();
return txn.lock(_table + id, seconds); return txn.lock(_table + id, seconds);
} }
@Override @Override
public boolean unlockFromLockTable(final String id) { public boolean unlockFromLockTable(final String id) {
@ -948,15 +951,15 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
@DB(txn=false) @DB(txn=false)
protected List<Object> addGroupBy(final StringBuilder sql, SearchCriteria<?> sc) { protected List<Object> addGroupBy(final StringBuilder sql, SearchCriteria<?> sc) {
Pair<GroupBy<?, ?>, List<Object>> groupBys = sc.getGroupBy(); Pair<GroupBy<?, ?>, List<Object>> groupBys = sc.getGroupBy();
if (groupBys != null) { if (groupBys != null) {
groupBys.first().toSql(sql); groupBys.first().toSql(sql);
return groupBys.second(); return groupBys.second();
} else { } else {
return null; return null;
} }
} }
@DB(txn=false) @DB(txn=false)
protected void addFilter(final StringBuilder sql, final Filter filter) { protected void addFilter(final StringBuilder sql, final Filter filter) {
if (filter != null) { if (filter != null) {
@ -1071,7 +1074,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
pstmt = txn.prepareAutoCloseStatement(sql); pstmt = txn.prepareAutoCloseStatement(sql);
int i = 0; int i = 0;
for (final Pair<Attribute, Object> value : sc.getValues()) { for (final Pair<Attribute, Object> value : sc.getValues()) {
prepareAttribute(++i, pstmt, value.first(), value.second()); prepareAttribute(++i, pstmt, value.first(), value.second());
} }
return pstmt.executeUpdate(); return pstmt.executeUpdate();
} catch (final SQLException e) { } catch (final SQLException e) {
@ -1088,14 +1091,14 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
sql.delete(7, sql.indexOf(" FROM")); sql.delete(7, sql.indexOf(" FROM"));
sc.getSelect(sql, 7); sc.getSelect(sql, 7);
} }
if (!whereClause) { if (!whereClause) {
sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length()); sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
} }
return sql; return sql;
} }
@DB(txn = false) @DB(txn = false)
protected void addJoins(StringBuilder str, Collection<JoinBuilder<SearchCriteria<?>>> joins) { protected void addJoins(StringBuilder str, Collection<JoinBuilder<SearchCriteria<?>>> joins) {
@ -1110,9 +1113,9 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
for (JoinBuilder<SearchCriteria<?>> join : joins) { for (JoinBuilder<SearchCriteria<?>> join : joins) {
StringBuilder onClause = new StringBuilder(); StringBuilder onClause = new StringBuilder();
onClause.append(" ").append(join.getType().getName()).append(" ").append(join.getSecondAttribute().table) onClause.append(" ").append(join.getType().getName()).append(" ").append(join.getSecondAttribute().table)
.append(" ON ").append(join.getFirstAttribute().table).append(".").append(join.getFirstAttribute().columnName) .append(" ON ").append(join.getFirstAttribute().table).append(".").append(join.getFirstAttribute().columnName)
.append("=").append(join.getSecondAttribute().table).append(".").append(join.getSecondAttribute().columnName) .append("=").append(join.getSecondAttribute().table).append(".").append(join.getSecondAttribute().columnName)
.append(" "); .append(" ");
str.insert(fromIndex, onClause); str.insert(fromIndex, onClause);
String whereClause = join.getT().getWhereClause(); String whereClause = join.getT().getWhereClause();
if ((whereClause != null) && !"".equals(whereClause)) { if ((whereClause != null) && !"".equals(whereClause)) {
@ -1149,7 +1152,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
final UpdateBuilder ub = getUpdateBuilder(entity); final UpdateBuilder ub = getUpdateBuilder(entity);
return update(ub, sc, rows); return update(ub, sc, rows);
} }
@DB(txn=false) @DB(txn=false)
public int update(final T entity, final SearchCriteria<T> sc) { public int update(final T entity, final SearchCriteria<T> sc) {
final UpdateBuilder ub = getUpdateBuilder(entity); final UpdateBuilder ub = getUpdateBuilder(entity);
@ -1170,7 +1173,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
update(id, entity); update(id, entity);
return entity; return entity;
} }
assert false : "Can't call persit if you don't have primary key"; assert false : "Can't call persit if you don't have primary key";
} }
@ -1218,7 +1221,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
throw new CloudRuntimeException("DB Exception on: " + sqlStr, e); throw new CloudRuntimeException("DB Exception on: " + sqlStr, e);
} }
} }
return _idField != null ? findByIdIncludingRemoved(id) : null; return _idField != null ? findByIdIncludingRemoved(id) : null;
} }
@ -1267,21 +1270,21 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
// to support generic localization, utilize MySql UTF-8 support // to support generic localization, utilize MySql UTF-8 support
if (length < str.length()) { if (length < str.length()) {
try { try {
pstmt.setBytes(j, str.substring(0, column.length()).getBytes("UTF-8")); pstmt.setBytes(j, str.substring(0, column.length()).getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
// no-way it can't support UTF-8 encoding // no-way it can't support UTF-8 encoding
assert(false); assert(false);
throw new CloudRuntimeException("UnsupportedEncodingException when saving string as UTF-8 data"); throw new CloudRuntimeException("UnsupportedEncodingException when saving string as UTF-8 data");
} }
} else { } else {
try { try {
pstmt.setBytes(j, str.getBytes("UTF-8")); pstmt.setBytes(j, str.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
// no-way it can't support UTF-8 encoding // no-way it can't support UTF-8 encoding
assert(false); assert(false);
throw new CloudRuntimeException("UnsupportedEncodingException when saving string as UTF-8 data"); throw new CloudRuntimeException("UnsupportedEncodingException when saving string as UTF-8 data");
} }
} }
} else if (attr.field.getType() == Date.class) { } else if (attr.field.getType() == Date.class) {
final Date date = (Date)value; final Date date = (Date)value;
@ -1376,6 +1379,10 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
for (int index = 1, max = meta.getColumnCount(); index <= max; index++) { for (int index = 1, max = meta.getColumnCount(); index <= max; index++) {
setField(entity, result, meta, index); setField(entity, result, meta, index);
} }
for (Attribute attr : _oneToManyAttributes) {
OneToMany otm = attr.field.getAnnotation(OneToMany.class);
}
} }
@Override @Override
@ -1398,7 +1405,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
throw new CloudRuntimeException("DB Exception on " + sqlStr, e); throw new CloudRuntimeException("DB Exception on " + sqlStr, e);
} }
} }
@DB(txn=false) @DB(txn=false)
protected void setField(final Object entity, final ResultSet rs, ResultSetMetaData meta, final int index) throws SQLException { protected void setField(final Object entity, final ResultSet rs, ResultSetMetaData meta, final int index) throws SQLException {
Attribute attr = _allColumns.get(new Pair<String, String>(meta.getTableName(index), meta.getColumnName(index))); Attribute attr = _allColumns.get(new Pair<String, String>(meta.getTableName(index), meta.getColumnName(index)));
@ -1441,14 +1448,14 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
if (_removeSql == null) { if (_removeSql == null) {
return expunge(sc); return expunge(sc);
} }
T vo = createForUpdate(); T vo = createForUpdate();
UpdateBuilder ub = getUpdateBuilder(vo); UpdateBuilder ub = getUpdateBuilder(vo);
ub.set(vo, _removed.second(), new Date()); ub.set(vo, _removed.second(), new Date());
return update(ub, sc, null); return update(ub, sc, null);
} }
protected Cache _cache; protected Cache _cache;
@DB(txn=false) @DB(txn=false)
protected void createCache(final Map<String, ? extends Object> params) { protected void createCache(final Map<String, ? extends Object> params) {
@ -1487,14 +1494,14 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
public String getName() { public String getName() {
return _name; return _name;
} }
@DB(txn=false) @DB(txn=false)
public static <T> UpdateBuilder getUpdateBuilder(final T entityObject) { public static <T> UpdateBuilder getUpdateBuilder(final T entityObject) {
final Factory factory = (Factory)entityObject; final Factory factory = (Factory)entityObject;
assert(factory != null); assert(factory != null);
return (UpdateBuilder)factory.getCallback(1); return (UpdateBuilder)factory.getCallback(1);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @DB(txn=false) @Override @DB(txn=false)
public SearchBuilder<T> createSearchBuilder() { public SearchBuilder<T> createSearchBuilder() {
@ -1504,11 +1511,11 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
factory.setCallback(0, builder); factory.setCallback(0, builder);
return builder; return builder;
} }
@Override @DB(txn=false) @Override @DB(txn=false)
public SearchCriteria<T> createSearchCriteria() { public SearchCriteria<T> createSearchCriteria() {
SearchBuilder<T> builder = createSearchBuilder(); SearchBuilder<T> builder = createSearchBuilder();
return builder.create(); return builder.create();
} }
} }

View File

@ -29,6 +29,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverride;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn; import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType; import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue; import javax.persistence.DiscriminatorValue;
@ -36,6 +37,8 @@ import javax.persistence.Embeddable;
import javax.persistence.Embedded; import javax.persistence.Embedded;
import javax.persistence.EmbeddedId; import javax.persistence.EmbeddedId;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.SecondaryTable; import javax.persistence.SecondaryTable;
import javax.persistence.TableGenerator; import javax.persistence.TableGenerator;
@ -45,30 +48,32 @@ import com.cloud.utils.Ternary;
import com.cloud.utils.db.Attribute.Flag; import com.cloud.utils.db.Attribute.Flag;
public class SqlGenerator { public class SqlGenerator {
Class<?> _clazz; Class<?> _clazz;
ArrayList<Attribute> _attributes; ArrayList<Attribute> _attributes;
ArrayList<Field> _embeddeds; ArrayList<Field> _embeddeds;
ArrayList<Class<?>> _tables; ArrayList<Class<?>> _tables;
LinkedHashMap<String, List<Attribute>> _ids; LinkedHashMap<String, List<Attribute>> _ids;
HashMap<String, TableGenerator> _generators; HashMap<String, TableGenerator> _generators;
ArrayList<Attribute> _otmAttrs;
public SqlGenerator(Class<?> clazz) { public SqlGenerator(Class<?> clazz) {
_clazz = clazz; _clazz = clazz;
_tables = new ArrayList<Class<?>>(); _tables = new ArrayList<Class<?>>();
_attributes = new ArrayList<Attribute>(); _attributes = new ArrayList<Attribute>();
_otmAttrs = new ArrayList<Attribute>();
_embeddeds = new ArrayList<Field>(); _embeddeds = new ArrayList<Field>();
_ids = new LinkedHashMap<String, List<Attribute>>(); _ids = new LinkedHashMap<String, List<Attribute>>();
_generators = new HashMap<String, TableGenerator>(); _generators = new HashMap<String, TableGenerator>();
buildAttributes(clazz, DbUtil.getTableName(clazz), DbUtil.getAttributeOverrides(clazz), false, false); buildAttributes(clazz, DbUtil.getTableName(clazz), DbUtil.getAttributeOverrides(clazz), false, false);
assert (_tables.size() > 0) : "Did you forget to put @Entity on " + clazz.getName(); assert (_tables.size() > 0) : "Did you forget to put @Entity on " + clazz.getName();
handleDaoAttributes(clazz); handleDaoAttributes(clazz);
} }
protected boolean checkMethods(Class<?> clazz, Map<String, Attribute> attrs) { protected boolean checkMethods(Class<?> clazz, Map<String, Attribute> attrs) {
Method[] methods = clazz.getMethods(); Method[] methods = clazz.getMethods();
for (Method method : methods) { for (Method method : methods) {
String name = method.getName(); String name = method.getName();
if (name.startsWith("get")) { if (name.startsWith("get")) {
String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4); String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4);
assert !attrs.containsKey(fieldName) : "Mismatch in " + clazz.getSimpleName() + " for " + name; assert !attrs.containsKey(fieldName) : "Mismatch in " + clazz.getSimpleName() + " for " + name;
@ -79,39 +84,39 @@ public class SqlGenerator {
String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4); String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4);
assert !attrs.containsKey(fieldName) : "Mismatch in " + clazz.getSimpleName() + " for " + name; assert !attrs.containsKey(fieldName) : "Mismatch in " + clazz.getSimpleName() + " for " + name;
} }
} }
return true; return true;
} }
protected void buildAttributes(Class<?> clazz, String tableName, AttributeOverride[] overrides, boolean embedded, boolean isId) { protected void buildAttributes(Class<?> clazz, String tableName, AttributeOverride[] overrides, boolean embedded, boolean isId) {
if (!embedded && clazz.getAnnotation(Entity.class) == null) { if (!embedded && clazz.getAnnotation(Entity.class) == null) {
return; return;
} }
Class<?> parent = clazz.getSuperclass(); Class<?> parent = clazz.getSuperclass();
if (parent != null) { if (parent != null) {
buildAttributes(parent, DbUtil.getTableName(parent), DbUtil.getAttributeOverrides(parent), false, false); buildAttributes(parent, DbUtil.getTableName(parent), DbUtil.getAttributeOverrides(parent), false, false);
} }
if (!embedded) { if (!embedded) {
_tables.add(clazz); _tables.add(clazz);
_ids.put(tableName, new ArrayList<Attribute>()); _ids.put(tableName, new ArrayList<Attribute>());
} }
Field[] fields = clazz.getDeclaredFields(); Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) { for (Field field : fields) {
field.setAccessible(true); field.setAccessible(true);
TableGenerator tg = field.getAnnotation(TableGenerator.class); TableGenerator tg = field.getAnnotation(TableGenerator.class);
if (tg != null) { if (tg != null) {
_generators.put(field.getName(), tg); _generators.put(field.getName(), tg);
} }
if (!DbUtil.isPersistable(field)) { if (!DbUtil.isPersistable(field)) {
continue; continue;
} }
if (field.getAnnotation(Embedded.class) != null) { if (field.getAnnotation(Embedded.class) != null) {
_embeddeds.add(field); _embeddeds.add(field);
Class<?> embeddedClass = field.getType(); Class<?> embeddedClass = field.getType();
@ -119,7 +124,7 @@ public class SqlGenerator {
buildAttributes(embeddedClass, tableName, DbUtil.getAttributeOverrides(field), true, false); buildAttributes(embeddedClass, tableName, DbUtil.getAttributeOverrides(field), true, false);
continue; continue;
} }
if (field.getAnnotation(EmbeddedId.class) != null) { if (field.getAnnotation(EmbeddedId.class) != null) {
_embeddeds.add(field); _embeddeds.add(field);
Class<?> embeddedClass = field.getType(); Class<?> embeddedClass = field.getType();
@ -127,22 +132,44 @@ public class SqlGenerator {
buildAttributes(embeddedClass, tableName, DbUtil.getAttributeOverrides(field), true, true); buildAttributes(embeddedClass, tableName, DbUtil.getAttributeOverrides(field), true, true);
continue; continue;
} }
Attribute attr = new Attribute(clazz, overrides, field, tableName, embedded, isId); Attribute attr = new Attribute(clazz, overrides, field, tableName, embedded, isId);
if (attr.isId()) { if (attr.isId()) {
List<Attribute> attrs = _ids.get(tableName); List<Attribute> attrs = _ids.get(tableName);
attrs.add(attr); attrs.add(attr);
} }
_attributes.add(attr); if (field.getAnnotation(OneToMany.class) != null) {
assert supportsOneToMany(field) : "Doesn't support One To Many";
_otmAttrs.add(attr);
} else {
_attributes.add(attr);
}
} }
} }
protected boolean supportsOneToMany(Field field) {
OneToMany otm = field.getAnnotation(OneToMany.class);
if (otm.fetch() == FetchType.LAZY) {
assert (false) : "Doesn't support laz fetch: " + field.getName();
return false;
}
for (CascadeType cascade : otm.cascade()) {
if (cascade == CascadeType.ALL || cascade == CascadeType.PERSIST || cascade == CascadeType.MERGE || cascade == CascadeType.REMOVE) {
assert (false) : "Doesn't support " + cascade + " for " + field.getName();
return false;
}
}
return true;
}
public Map<String, TableGenerator> getTableGenerators() { public Map<String, TableGenerator> getTableGenerators() {
return _generators; return _generators;
} }
protected void handleDaoAttributes(Class<?> clazz) { protected void handleDaoAttributes(Class<?> clazz) {
Attribute attr; Attribute attr;
Class<?> current = clazz; Class<?> current = clazz;
@ -173,7 +200,7 @@ public class SqlGenerator {
attr.setTrue(Attribute.Flag.IntegerDT); attr.setTrue(Attribute.Flag.IntegerDT);
} }
} }
PrimaryKeyJoinColumn[] pkjcs = DbUtil.getPrimaryKeyJoinColumns(current); PrimaryKeyJoinColumn[] pkjcs = DbUtil.getPrimaryKeyJoinColumns(current);
if (pkjcs != null) { if (pkjcs != null) {
for (PrimaryKeyJoinColumn pkjc : pkjcs) { for (PrimaryKeyJoinColumn pkjc : pkjcs) {
@ -199,7 +226,7 @@ public class SqlGenerator {
} }
current = current.getSuperclass(); current = current.getSuperclass();
} }
attr = findAttribute(GenericDao.CREATED_COLUMN); attr = findAttribute(GenericDao.CREATED_COLUMN);
if (attr != null && attr.field.getType() == Date.class) { if (attr != null && attr.field.getType() == Date.class) {
attr.setTrue(Attribute.Flag.DaoGenerated); attr.setTrue(Attribute.Flag.DaoGenerated);
@ -211,7 +238,7 @@ public class SqlGenerator {
attr.setFalse(Attribute.Flag.Nullable); attr.setFalse(Attribute.Flag.Nullable);
attr.setTrue(Attribute.Flag.Created); attr.setTrue(Attribute.Flag.Created);
} }
attr = findAttribute(GenericDao.REMOVED_COLUMN); attr = findAttribute(GenericDao.REMOVED_COLUMN);
if (attr != null && attr.field.getType() == Date.class) { if (attr != null && attr.field.getType() == Date.class) {
attr.setTrue(Attribute.Flag.DaoGenerated); attr.setTrue(Attribute.Flag.DaoGenerated);
@ -223,7 +250,7 @@ public class SqlGenerator {
attr.setTrue(Attribute.Flag.Nullable); attr.setTrue(Attribute.Flag.Nullable);
attr.setTrue(Attribute.Flag.Removed); attr.setTrue(Attribute.Flag.Removed);
} }
attr = findAttribute(GenericDao.XID_COLUMN); attr = findAttribute(GenericDao.XID_COLUMN);
if (attr != null && attr.field.getType() == String.class) { if (attr != null && attr.field.getType() == String.class) {
attr.setTrue(Attribute.Flag.DaoGenerated); attr.setTrue(Attribute.Flag.DaoGenerated);
@ -236,17 +263,21 @@ public class SqlGenerator {
attr.setFalse(Attribute.Flag.Removed); attr.setFalse(Attribute.Flag.Removed);
} }
} }
public List<Attribute> getOneToManyAttributes() {
return _otmAttrs;
}
public Attribute findAttribute(String name) { public Attribute findAttribute(String name) {
for (Attribute attr : _attributes) { for (Attribute attr : _attributes) {
if (attr.columnName == name || attr.columnName.equals(name)) { if (attr.columnName == name || attr.columnName.equals(name)) {
return attr; return attr;
} }
} }
return null; return null;
} }
public static StringBuilder buildUpdateSql(String tableName, List<Attribute> attrs) { public static StringBuilder buildUpdateSql(String tableName, List<Attribute> attrs) {
StringBuilder sql = new StringBuilder("UPDATE "); StringBuilder sql = new StringBuilder("UPDATE ");
sql.append(tableName).append(" SET "); sql.append(tableName).append(" SET ");
@ -255,10 +286,10 @@ public class SqlGenerator {
} }
sql.delete(sql.length() - 2, sql.length()); sql.delete(sql.length() - 2, sql.length());
sql.append(" WHERE "); sql.append(" WHERE ");
return sql; return sql;
} }
public List<Pair<StringBuilder, Attribute[]>> buildUpdateSqls() { public List<Pair<StringBuilder, Attribute[]>> buildUpdateSqls() {
ArrayList<Pair<StringBuilder, Attribute[]>> sqls = new ArrayList<Pair<StringBuilder, Attribute[]>>(_tables.size()); ArrayList<Pair<StringBuilder, Attribute[]>> sqls = new ArrayList<Pair<StringBuilder, Attribute[]>>(_tables.size());
for (Class<?> table : _tables) { for (Class<?> table : _tables) {
@ -272,45 +303,45 @@ public class SqlGenerator {
if (attrs.size() != 0) { if (attrs.size() != 0) {
Pair<StringBuilder, Attribute[]> pair = Pair<StringBuilder, Attribute[]> pair =
new Pair<StringBuilder, Attribute[]>(buildUpdateSql(tableName, attrs), attrs.toArray(new Attribute[attrs.size()])); new Pair<StringBuilder, Attribute[]>(buildUpdateSql(tableName, attrs), attrs.toArray(new Attribute[attrs.size()]));
sqls.add(pair); sqls.add(pair);
} }
} }
return sqls; return sqls;
} }
public static StringBuilder buildMysqlUpdateSql(String joins, Collection<Ternary<Attribute, Boolean, Object>> setters) { public static StringBuilder buildMysqlUpdateSql(String joins, Collection<Ternary<Attribute, Boolean, Object>> setters) {
if (setters.size() == 0) { if (setters.size() == 0) {
return null; return null;
} }
StringBuilder sql = new StringBuilder("UPDATE "); StringBuilder sql = new StringBuilder("UPDATE ");
sql.append(joins); sql.append(joins);
sql.append(" SET "); sql.append(" SET ");
for (Ternary<Attribute, Boolean, Object> setter : setters) { for (Ternary<Attribute, Boolean, Object> setter : setters) {
Attribute attr = setter.first(); Attribute attr = setter.first();
sql.append(attr.table).append(".").append(attr.columnName).append("="); sql.append(attr.table).append(".").append(attr.columnName).append("=");
if (setter.second() != null) { if (setter.second() != null) {
sql.append(attr.table).append(".").append(attr.columnName).append(setter.second() ? "+" : "-"); sql.append(attr.table).append(".").append(attr.columnName).append(setter.second() ? "+" : "-");
} }
sql.append("?, "); sql.append("?, ");
} }
sql.delete(sql.length() - 2, sql.length()); sql.delete(sql.length() - 2, sql.length());
sql.append(" WHERE "); sql.append(" WHERE ");
return sql; return sql;
} }
public List<Pair<String, Attribute[]>> buildInsertSqls() { public List<Pair<String, Attribute[]>> buildInsertSqls() {
LinkedHashMap<String, ArrayList<Attribute>> map = new LinkedHashMap<String, ArrayList<Attribute>>(); LinkedHashMap<String, ArrayList<Attribute>> map = new LinkedHashMap<String, ArrayList<Attribute>>();
for (Class<?> table : _tables) { for (Class<?> table : _tables) {
map.put(DbUtil.getTableName(table), new ArrayList<Attribute>()); map.put(DbUtil.getTableName(table), new ArrayList<Attribute>());
} }
for (Attribute attr : _attributes) { for (Attribute attr : _attributes) {
if (attr.isInsertable()) { if (attr.isInsertable()) {
ArrayList<Attribute> attrs = map.get(attr.table); ArrayList<Attribute> attrs = map.get(attr.table);
@ -318,7 +349,7 @@ public class SqlGenerator {
attrs.add(attr); attrs.add(attr);
} }
} }
List<Pair<String, Attribute[]>> sqls = new ArrayList<Pair<String, Attribute[]>>(map.size()); List<Pair<String, Attribute[]>> sqls = new ArrayList<Pair<String, Attribute[]>>(map.size());
for (Map.Entry<String, ArrayList<Attribute>> entry : map.entrySet()) { for (Map.Entry<String, ArrayList<Attribute>> entry : map.entrySet()) {
ArrayList<Attribute> attrs = entry.getValue(); ArrayList<Attribute> attrs = entry.getValue();
@ -326,10 +357,10 @@ public class SqlGenerator {
Pair<String, Attribute[]> pair = new Pair<String, Attribute[]>(sql.toString(), attrs.toArray(new Attribute[attrs.size()])); Pair<String, Attribute[]> pair = new Pair<String, Attribute[]>(sql.toString(), attrs.toArray(new Attribute[attrs.size()]));
sqls.add(pair); sqls.add(pair);
} }
return sqls; return sqls;
} }
protected StringBuilder buildInsertSql(String table, ArrayList<Attribute> attrs) { protected StringBuilder buildInsertSql(String table, ArrayList<Attribute> attrs) {
StringBuilder sql = new StringBuilder("INSERT INTO "); StringBuilder sql = new StringBuilder("INSERT INTO ");
sql.append(table).append(" ("); sql.append(table).append(" (");
@ -339,27 +370,27 @@ public class SqlGenerator {
if (attrs.size() > 0) { if (attrs.size() > 0) {
sql.delete(sql.length() - 2, sql.length()); sql.delete(sql.length() - 2, sql.length());
} }
sql.append(") VALUES ("); sql.append(") VALUES (");
for (Attribute attr : attrs) { for (Attribute attr : attrs) {
sql.append("?, "); sql.append("?, ");
} }
if (attrs.size() > 0) { if (attrs.size() > 0) {
sql.delete(sql.length() - 2, sql.length()); sql.delete(sql.length() - 2, sql.length());
} }
sql.append(")"); sql.append(")");
return sql; return sql;
} }
protected List<Pair<String, Attribute[]>> buildDeleteSqls() { protected List<Pair<String, Attribute[]>> buildDeleteSqls() {
LinkedHashMap<String, ArrayList<Attribute>> map = new LinkedHashMap<String, ArrayList<Attribute>>(); LinkedHashMap<String, ArrayList<Attribute>> map = new LinkedHashMap<String, ArrayList<Attribute>>();
for (Class<?> table : _tables) { for (Class<?> table : _tables) {
map.put(DbUtil.getTableName(table), new ArrayList<Attribute>()); map.put(DbUtil.getTableName(table), new ArrayList<Attribute>());
} }
for (Attribute attr : _attributes) { for (Attribute attr : _attributes) {
if (attr.isId()) { if (attr.isId()) {
ArrayList<Attribute> attrs = map.get(attr.table); ArrayList<Attribute> attrs = map.get(attr.table);
@ -367,7 +398,7 @@ public class SqlGenerator {
attrs.add(attr); attrs.add(attr);
} }
} }
List<Pair<String, Attribute[]>> sqls = new ArrayList<Pair<String, Attribute[]>>(map.size()); List<Pair<String, Attribute[]>> sqls = new ArrayList<Pair<String, Attribute[]>>(map.size());
for (Map.Entry<String, ArrayList<Attribute>> entry : map.entrySet()) { for (Map.Entry<String, ArrayList<Attribute>> entry : map.entrySet()) {
ArrayList<Attribute> attrs = entry.getValue(); ArrayList<Attribute> attrs = entry.getValue();
@ -375,11 +406,11 @@ public class SqlGenerator {
Pair<String, Attribute[]> pair = new Pair<String, Attribute[]>(sql, attrs.toArray(new Attribute[attrs.size()])); Pair<String, Attribute[]> pair = new Pair<String, Attribute[]>(sql, attrs.toArray(new Attribute[attrs.size()]));
sqls.add(pair); sqls.add(pair);
} }
Collections.reverse(sqls); Collections.reverse(sqls);
return sqls; return sqls;
} }
protected String buildDeleteSql(String table, ArrayList<Attribute> attrs) { protected String buildDeleteSql(String table, ArrayList<Attribute> attrs) {
StringBuilder sql = new StringBuilder("DELETE FROM "); StringBuilder sql = new StringBuilder("DELETE FROM ");
sql.append(table).append(" WHERE "); sql.append(table).append(" WHERE ");
@ -389,50 +420,50 @@ public class SqlGenerator {
sql.delete(sql.length() - 5, sql.length()); sql.delete(sql.length() - 5, sql.length());
return sql.toString(); return sql.toString();
} }
public Pair<String, Attribute[]> buildRemoveSql() { public Pair<String, Attribute[]> buildRemoveSql() {
Attribute attribute = findAttribute(GenericDao.REMOVED_COLUMN); Attribute attribute = findAttribute(GenericDao.REMOVED_COLUMN);
if (attribute == null) { if (attribute == null) {
return null; return null;
} }
StringBuilder sql = new StringBuilder("UPDATE "); StringBuilder sql = new StringBuilder("UPDATE ");
sql.append(attribute.table).append(" SET "); sql.append(attribute.table).append(" SET ");
sql.append(attribute.columnName).append(" = ? WHERE "); sql.append(attribute.columnName).append(" = ? WHERE ");
List<Attribute> ids = _ids.get(attribute.table); List<Attribute> ids = _ids.get(attribute.table);
// if ids == null, that means the removed column was added as a JOIN // if ids == null, that means the removed column was added as a JOIN
// value to another table. We ignore it here. // value to another table. We ignore it here.
if (ids == null) { if (ids == null) {
return null; return null;
} }
if (ids.size() == 0) { if (ids.size() == 0) {
return null; return null;
} }
for (Attribute id : ids) { for (Attribute id : ids) {
sql.append(id.table).append(".").append(id.columnName).append(" = ? AND "); sql.append(id.table).append(".").append(id.columnName).append(" = ? AND ");
} }
sql.delete(sql.length() - 5, sql.length()); sql.delete(sql.length() - 5, sql.length());
Attribute[] attrs = ids.toArray(new Attribute[ids.size() + 1]); Attribute[] attrs = ids.toArray(new Attribute[ids.size() + 1]);
attrs[attrs.length - 1] = attribute; attrs[attrs.length - 1] = attribute;
return new Pair<String, Attribute[]>(sql.toString(), attrs); return new Pair<String, Attribute[]>(sql.toString(), attrs);
} }
public Map<String, Attribute[]> getIdAttributes() { public Map<String, Attribute[]> getIdAttributes() {
LinkedHashMap<String, Attribute[]> ids = new LinkedHashMap<String, Attribute[]>(_ids.size()); LinkedHashMap<String, Attribute[]> ids = new LinkedHashMap<String, Attribute[]>(_ids.size());
for (Map.Entry<String, List<Attribute>> entry : _ids.entrySet()) { for (Map.Entry<String, List<Attribute>> entry : _ids.entrySet()) {
ids.put(entry.getKey(), entry.getValue().toArray(new Attribute[entry.getValue().size()])); ids.put(entry.getKey(), entry.getValue().toArray(new Attribute[entry.getValue().size()]));
} }
return ids; return ids;
} }
/** /**
* @return a map of tables and maps of field names to attributes. * @return a map of tables and maps of field names to attributes.
*/ */
@ -443,10 +474,10 @@ public class SqlGenerator {
attrs.put(attr.field.getName(), attr); attrs.put(attr.field.getName(), attr);
} }
} }
return attrs; return attrs;
} }
public Map<Pair<String, String>, Attribute> getAllColumns() { public Map<Pair<String, String>, Attribute> getAllColumns() {
Map<Pair<String, String>, Attribute> attrs = new LinkedHashMap<Pair<String, String>, Attribute>(_attributes.size()); Map<Pair<String, String>, Attribute> attrs = new LinkedHashMap<Pair<String, String>, Attribute>(_attributes.size());
for (Attribute attr : _attributes) { for (Attribute attr : _attributes) {
@ -454,10 +485,10 @@ public class SqlGenerator {
attrs.put(new Pair<String, String>(attr.table, attr.columnName), attr); attrs.put(new Pair<String, String>(attr.table, attr.columnName), attr);
} }
} }
return attrs; return attrs;
} }
protected static void addPrimaryKeyJoinColumns(StringBuilder sql, String fromTable, String toTable, String joinType, PrimaryKeyJoinColumn[] pkjcs) { protected static void addPrimaryKeyJoinColumns(StringBuilder sql, String fromTable, String toTable, String joinType, PrimaryKeyJoinColumn[] pkjcs) {
if ("right".equalsIgnoreCase(joinType)) { if ("right".equalsIgnoreCase(joinType)) {
sql.append(" RIGHT JOIN ").append(toTable).append(" ON "); sql.append(" RIGHT JOIN ").append(toTable).append(" ON ");
@ -472,33 +503,33 @@ public class SqlGenerator {
sql.append("=").append(toTable).append(".").append(refColumn).append(" "); sql.append("=").append(toTable).append(".").append(refColumn).append(" ");
} }
} }
public Pair<String, Attribute> getRemovedAttribute() { public Pair<String, Attribute> getRemovedAttribute() {
Attribute removed = findAttribute(GenericDao.REMOVED_COLUMN); Attribute removed = findAttribute(GenericDao.REMOVED_COLUMN);
if (removed == null) { if (removed == null) {
return null; return null;
} }
if (removed.field.getType() != Date.class) { if (removed.field.getType() != Date.class) {
return null; return null;
} }
StringBuilder sql = new StringBuilder(); StringBuilder sql = new StringBuilder();
sql.append(removed.table).append(".").append(removed.columnName).append(" IS NULL "); sql.append(removed.table).append(".").append(removed.columnName).append(" IS NULL ");
return new Pair<String, Attribute>(sql.toString(), removed); return new Pair<String, Attribute>(sql.toString(), removed);
} }
protected static void buildJoins(StringBuilder innerJoin, Class<?> clazz) { protected static void buildJoins(StringBuilder innerJoin, Class<?> clazz) {
String tableName = DbUtil.getTableName(clazz); String tableName = DbUtil.getTableName(clazz);
SecondaryTable[] sts = DbUtil.getSecondaryTables(clazz); SecondaryTable[] sts = DbUtil.getSecondaryTables(clazz);
ArrayList<String> secondaryTables = new ArrayList<String>(); ArrayList<String> secondaryTables = new ArrayList<String>();
for (SecondaryTable st : sts) { for (SecondaryTable st : sts) {
addPrimaryKeyJoinColumns(innerJoin, tableName, st.name(), st.join(), st.pkJoinColumns()); addPrimaryKeyJoinColumns(innerJoin, tableName, st.name(), st.join(), st.pkJoinColumns());
secondaryTables.add(st.name()); secondaryTables.add(st.name());
} }
Class<?> parent = clazz.getSuperclass(); Class<?> parent = clazz.getSuperclass();
if (parent.getAnnotation(Entity.class) != null) { if (parent.getAnnotation(Entity.class) != null) {
String table = DbUtil.getTableName(parent); String table = DbUtil.getTableName(parent);
@ -508,63 +539,63 @@ public class SqlGenerator {
} }
} }
public String buildTableReferences() { public String buildTableReferences() {
StringBuilder sql = new StringBuilder(); StringBuilder sql = new StringBuilder();
sql.append(DbUtil.getTableName(_tables.get(_tables.size() - 1))); sql.append(DbUtil.getTableName(_tables.get(_tables.size() - 1)));
for (Class<?> table : _tables) { for (Class<?> table : _tables) {
buildJoins(sql, table); buildJoins(sql, table);
} }
return sql.toString(); return sql.toString();
} }
public Pair<StringBuilder, Attribute[]> buildSelectSql() { public Pair<StringBuilder, Attribute[]> buildSelectSql() {
StringBuilder sql = new StringBuilder("SELECT "); StringBuilder sql = new StringBuilder("SELECT ");
ArrayList<Attribute> attrs = new ArrayList<Attribute>(); ArrayList<Attribute> attrs = new ArrayList<Attribute>();
for (Attribute attr : _attributes) { for (Attribute attr : _attributes) {
if (attr.isSelectable()) { if (attr.isSelectable()) {
attrs.add(attr); attrs.add(attr);
sql.append(attr.table).append(".").append(attr.columnName).append(", "); sql.append(attr.table).append(".").append(attr.columnName).append(", ");
} }
} }
if (attrs.size() > 0) { if (attrs.size() > 0) {
sql.delete(sql.length() - 2, sql.length()); sql.delete(sql.length() - 2, sql.length());
} }
sql.append(" FROM ").append(buildTableReferences()); sql.append(" FROM ").append(buildTableReferences());
sql.append(" WHERE "); sql.append(" WHERE ");
sql.append(buildDiscriminatorClause().first()); sql.append(buildDiscriminatorClause().first());
return new Pair<StringBuilder, Attribute[]>(sql, attrs.toArray(new Attribute[attrs.size()])); return new Pair<StringBuilder, Attribute[]>(sql, attrs.toArray(new Attribute[attrs.size()]));
} }
public Pair<StringBuilder, Attribute[]> buildSelectSql(Attribute[] attrs) { public Pair<StringBuilder, Attribute[]> buildSelectSql(Attribute[] attrs) {
StringBuilder sql = new StringBuilder("SELECT "); StringBuilder sql = new StringBuilder("SELECT ");
for (Attribute attr : attrs) { for (Attribute attr : attrs) {
sql.append(attr.table).append(".").append(attr.columnName).append(", "); sql.append(attr.table).append(".").append(attr.columnName).append(", ");
} }
if (attrs.length > 0) { if (attrs.length > 0) {
sql.delete(sql.length() - 2, sql.length()); sql.delete(sql.length() - 2, sql.length());
} }
sql.append(" FROM ").append(buildTableReferences()); sql.append(" FROM ").append(buildTableReferences());
sql.append(" WHERE "); sql.append(" WHERE ");
sql.append(buildDiscriminatorClause().first()); sql.append(buildDiscriminatorClause().first());
return new Pair<StringBuilder, Attribute[]>(sql, attrs); return new Pair<StringBuilder, Attribute[]>(sql, attrs);
} }
/** /**
* buildDiscriminatorClause builds the join clause when there are multiple tables. * buildDiscriminatorClause builds the join clause when there are multiple tables.
* *
@ -573,7 +604,7 @@ public class SqlGenerator {
public Pair<StringBuilder, Map<String, Object>> buildDiscriminatorClause() { public Pair<StringBuilder, Map<String, Object>> buildDiscriminatorClause() {
StringBuilder sql = new StringBuilder(); StringBuilder sql = new StringBuilder();
Map<String, Object> values = new HashMap<String, Object>(); Map<String, Object> values = new HashMap<String, Object>();
for (Class<?> table : _tables) { for (Class<?> table : _tables) {
DiscriminatorValue dv = table.getAnnotation(DiscriminatorValue.class); DiscriminatorValue dv = table.getAnnotation(DiscriminatorValue.class);
if (dv != null) { if (dv != null) {
@ -601,10 +632,10 @@ public class SqlGenerator {
sql.append(" AND "); sql.append(" AND ");
} }
} }
return new Pair<StringBuilder, Map<String, Object>>(sql, values); return new Pair<StringBuilder, Map<String, Object>>(sql, values);
} }
public Field[] getEmbeddedFields() { public Field[] getEmbeddedFields() {
return _embeddeds.toArray(new Field[_embeddeds.size()]); return _embeddeds.toArray(new Field[_embeddeds.size()]);
} }

View File

@ -0,0 +1,22 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package javax.persistence;
public interface ElementCollection {
}