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;
import java.net.URI;
import java.util.List;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.TrafficType;
@ -38,10 +39,11 @@ public class NetworkTO {
protected URI broadcastUri;
protected URI isolationUri;
protected boolean isSecurityGroupEnabled;
protected String[] tags;
public NetworkTO() {
}
public String getUuid() {
return uuid;
}
@ -85,11 +87,19 @@ public class NetworkTO {
public void setType(TrafficType 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) {
this.isSecurityGroupEnabled = enabled;
}
/**
* 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) {
this(ip, netmask, mac, null, null, null);
}
/**
* This is the full constructor and should be used for VM's network as it contains
* the full information about what is needed.
@ -145,27 +155,27 @@ public class NetworkTO {
public String getDns2() {
return dns2;
}
public TrafficType getType() {
return type;
}
public URI getBroadcastUri() {
return broadcastUri;
}
public void setBroadcastUri(URI broadcastUri) {
this.broadcastUri = broadcastUri;
}
public URI getIsolationUri() {
return isolationUri;
}
public void setIsolationuri(URI isolationUri) {
this.isolationUri = isolationUri;
}
public boolean isSecurityGroupEnabled() {
return this.isSecurityGroupEnabled;
}

View File

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

View File

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

View File

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

View File

@ -23,8 +23,10 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig;
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_gogger = GsonHelper.getGsonLogger();
protected static final Logger s_gsonLogger = GsonHelper.getLogger();
public enum Version {
v1, // using gson to marshall
@ -278,47 +281,69 @@ public class Request {
public void logD(String msg, boolean logContent) {
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) {
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()) {
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 ");
buf.append(_agentId).append("-").append(_seq).append(": ");
buf.append(msg);
buf.append("{ ").append(getType());
buf.append(" { ").append(getType());
buf.append(", MgmtId: ").append(_mgmtId).append(", via: ").append(_via);
if (logContent) {
buf.append(", Ver: ").append(_ver.toString());
buf.append(", Flags: ").append(Integer.toBinaryString(getFlags())).append(", ");
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(", Ver: ").append(_ver.toString());
buf.append(", Flags: ").append(Integer.toBinaryString(getFlags())).append(", ");
buf.append(content);
buf.append(" }");
return buf.toString();
}

View File

@ -75,4 +75,8 @@ public class GsonHelper {
public final static Gson getGsonLogger() {
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();
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(SecStorageFirewallCfgCommand.class.getSimpleName()));
assert (!log.contains(GetHostStatsCommand.class.getSimpleName()));
@ -62,7 +62,7 @@ public class RequestTest extends TestCase {
assert (!log.contains("password"));
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(SecStorageFirewallCfgCommand.class.getSimpleName()));
assert (log.contains(GetHostStatsCommand.class.getSimpleName()));
@ -70,7 +70,7 @@ public class RequestTest extends TestCase {
assert (!log.contains("password"));
logger.setLevel(Level.INFO);
sreq.log("Info", true);
sreq.log("Info", true, Level.INFO);
assert (log.contains(UpdateHostPasswordCommand.class.getSimpleName()));
assert (log.contains(SecStorageFirewallCfgCommand.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) {
assert req1.getSequence() == req2.getSequence();
assert req1.getAgentId() == req2.getAgentId();

View File

@ -33,7 +33,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
protected HypervisorGuruBase() {
super();
}
protected NicTO toNicTO(NicProfile profile) {
NicTO to = new NicTO();
to.setDeviceId(profile.getDeviceId());
@ -50,39 +50,41 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
to.setIsolationuri(profile.getIsolationUri());
to.setNetworkRateMbps(profile.getNetworkRate());
to.setSecurityGroupEnabled(profile.isSecurityGroupEnabled());
to.setTags(profile.getTags());
return to;
}
protected <T extends VirtualMachine> VirtualMachineTO toVirtualMachineTO(VirtualMachineProfile<T> vmProfile) {
ServiceOffering offering = vmProfile.getServiceOffering();
VirtualMachine vm = vmProfile.getVirtualMachine();
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());
List<NicProfile> nicProfiles = vmProfile.getNics();
NicTO[] nics = new NicTO[nicProfiles.size()];
int i = 0;
for (NicProfile nicProfile : nicProfiles) {
nics[i++] = toNicTO(nicProfile);
}
to.setNics(nics);
to.setDisks(vmProfile.getDisks().toArray(new VolumeTO[vmProfile.getDisks().size()]));
if(vmProfile.getTemplate().getBits() == 32) {
to.setArch("i686");
} else {
to.setArch("x86_64");
}
return to;
}
@Override
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
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();
txn.start();
SearchCriteria<IPAddressVO> sc = null;
@ -570,7 +570,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
boolean isSourceNat = false;
txn.start();
NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
if (!offering.isSharedSourceNatService()) {
// 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
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);
}
@ -1098,7 +1098,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
@Override
@DB
public Pair<NetworkGuru, NetworkVO> implementNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException,
InsufficientCapacityException {
InsufficientCapacityException {
Transaction.currentTxn();
Pair<NetworkGuru, NetworkVO> implemented = new Pair<NetworkGuru, NetworkVO>(null, null);
@ -1193,7 +1193,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
@Override
public void prepare(VirtualMachineProfile<? extends VMInstanceVO> vmProfile, DeployDestination dest, ReservationContext context) throws InsufficientCapacityException,
ConcurrentOperationException, ResourceUnavailableException {
ConcurrentOperationException, ResourceUnavailableException {
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
@ -1667,7 +1667,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
if (!NetUtils.verifyDomainName(networkDomain)) {
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', "
+ "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
@DB
public boolean associateIpAddressListToAccount(long userId, long accountId, long zoneId, Long vlanId, Network network) throws InsufficientCapacityException, ConcurrentOperationException,
ResourceUnavailableException {
ResourceUnavailableException {
Account owner = _accountMgr.getActiveAccount(accountId);
boolean createNetwork = false;

View File

@ -18,7 +18,9 @@
package com.cloud.network;
import java.net.URI;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
@ -32,6 +34,7 @@ import javax.persistence.Transient;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.Mode;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.dao.NetworkDao;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.db.GenericDao;
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)
@Column(name="id")
long id;
@Column(name="mode")
@Enumerated(value=EnumType.STRING)
Mode mode;
@Column(name="broadcast_domain_type")
@Enumerated(value=EnumType.STRING)
BroadcastDomainType broadcastDomainType;
@Column(name="traffic_type")
@Enumerated(value=EnumType.STRING)
TrafficType trafficType;
@Column(name="guest_type")
GuestIpType guestType;
@Column(name="name")
String name;
@Column(name="display_text")
String displayText;;
@Column(name="broadcast_uri")
URI broadcastUri;
@Column(name="gateway")
String gateway;
@Column(name="cidr")
String cidr;
@Column(name="network_offering_id")
long networkOfferingId;
@Column(name="data_center_id")
long dataCenterId;
@Column(name="related")
long related;
@Column(name="guru_name")
String guruName;
@Column(name="state")
@Enumerated(value=EnumType.STRING)
State state;
@Column(name="dns1")
String dns1;
@Column(name="domain_id")
long domainId;
@Column(name="account_id")
long accountId;
@Column(name="set_fields")
long setFields;
@TableGenerator(name="mac_address_seq", table="op_networks", pkColumnName="id", valueColumnName="mac_address_seq", allocationSize=1)
@Transient
long macAddress = 1;
@Column(name="guru_data")
String guruData;
@Column(name="dns2")
String dns2;
@Column(name="shared")
boolean isShared;
@Column(name="network_domain")
String networkDomain;
@Column(name=GenericDao.REMOVED_COLUMN)
Date removed;
@Column(name=GenericDao.CREATED_COLUMN)
Date created;
@Column(name="reservation_id")
String reservationId;
@Column(name="is_default")
boolean isDefault;
@Column(name="is_security_group_enabled")
boolean securityGroupEnabled;
@Transient
List<String> tags;
public NetworkVO() {
}
/**
* Constructor to be used for the adapters because it only initializes what's needed.
* @param trafficType
@ -163,7 +169,7 @@ public class NetworkVO implements Network {
this.id = -1;
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) {
this(id, that.getTrafficType(), that.getGuestType(), that.getMode(), that.getBroadcastDomainType(), offeringId, dataCenterId, domainId, accountId, related, name, displayText, isShared, isDefault);
this.gateway = that.getGateway();
@ -204,25 +210,25 @@ public class NetworkVO implements Network {
this.isShared = isShared;
this.isDefault = isDefault;
}
@Override
public String getReservationId() {
return reservationId;
}
public void setReservationId(String reservationId) {
this.reservationId = reservationId;
}
@Override
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
@Override
public long getRelated() {
return related;
@ -232,7 +238,23 @@ public class NetworkVO implements Network {
public long getId() {
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
public GuestIpType getGuestType() {
return guestType;
@ -242,17 +264,17 @@ public class NetworkVO implements Network {
public Mode getMode() {
return mode;
}
@Override
public long getAccountId() {
return accountId;
}
@Override
public long getDomainId() {
return domainId;
}
@Override
public long getNetworkOfferingId() {
return networkOfferingId;
@ -266,19 +288,19 @@ public class NetworkVO implements Network {
public BroadcastDomainType getBroadcastDomainType() {
return broadcastDomainType;
}
public String getGuruData() {
return guruData;
}
public void setGuruData(String guruData) {
this.guruData = guruData;
}
public String getGuruName() {
return guruName;
}
public void setGuruName(String guruName) {
this.guruName = guruName;
}
@ -286,12 +308,12 @@ public class NetworkVO implements Network {
public void setBroadcastDomainType(BroadcastDomainType broadcastDomainType) {
this.broadcastDomainType = broadcastDomainType;
}
@Override
public String getNetworkDomain() {
return networkDomain;
}
public void setNetworkDomain(String networkDomain) {
this.networkDomain = networkDomain;
}
@ -322,7 +344,7 @@ public class NetworkVO implements Network {
public void setCidr(String cidr) {
this.cidr = cidr;
}
@Override
public URI getBroadcastUri() {
return broadcastUri;
@ -331,33 +353,33 @@ public class NetworkVO implements Network {
public void setBroadcastUri(URI broadcastUri) {
this.broadcastUri = broadcastUri;
}
@Override
public int hashCode() {
return NumbersUtil.hash(id);
}
@Override
public long getDataCenterId() {
return dataCenterId;
}
public String getDns1() {
return dns1;
}
public void setDns1(String dns) {
this.dns1 = dns;
}
public String getDns2() {
return dns2;
}
public void setDns2(String dns) {
this.dns2 = dns;
}
@Override
public String getName() {
return name;
@ -366,7 +388,7 @@ public class NetworkVO implements Network {
public void setName(String name) {
this.name = name;
}
@Override
public String getDisplayText() {
return displayText;
@ -375,22 +397,22 @@ public class NetworkVO implements Network {
public void setDisplayText(String displayText) {
this.displayText = displayText;
}
@Override
public boolean getIsShared() {
return isShared;
}
@Override
public boolean isDefault() {
return isDefault;
}
@Override
public boolean isSecurityGroupEnabled() {
return securityGroupEnabled;
}
public void setSecurityGroupEnabled(boolean enabled) {
this.securityGroupEnabled = enabled;
}
@ -424,26 +446,28 @@ public class NetworkVO implements Network {
if (this.trafficType != that.trafficType) {
return false;
}
if ((this.cidr == null && that.cidr != null) || (this.cidr != null && that.cidr == null)) {
return false;
}
if (this.cidr == null && that.cidr == null) {
return true;
}
return NetUtils.isNetworkAWithinNetworkB(this.cidr, that.cidr);
}
public boolean isImplemented() {
return broadcastUri != null && cidr != null && gateway != null && mode != null && broadcastDomainType != null;
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder("Ntwk[");
buf.append(id).append("|").append(trafficType.toString()).append("|").append(networkOfferingId).append("]");
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> ZoneBroadcastUriSearch;
final SearchBuilder<NetworkVO> ZoneSecurityGroupSearch;
NetworkAccountDaoImpl _accountsDao = ComponentLocator.inject(NetworkAccountDaoImpl.class);
NetworkDomainDaoImpl _domainsDao = ComponentLocator.inject(NetworkDomainDaoImpl.class);
NetworkOpDaoImpl _opDao = ComponentLocator.inject(NetworkOpDaoImpl.class);
NetworkTagDaoImpl _tagDao = ComponentLocator.inject(NetworkTagDaoImpl.class);
final TableGenerator _tgMacAddress;
Random _rand = new Random(System.currentTimeMillis());
long _prefix = 0x2;
protected NetworkDaoImpl() {
super();
AllFieldsSearch = createSearchBuilder();
AllFieldsSearch.and("trafficType", AllFieldsSearch.entity().getTrafficType(), 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("isShared", AllFieldsSearch.entity().getIsShared(), Op.EQ);
AllFieldsSearch.done();
AccountSearch = createSearchBuilder();
AccountSearch.and("offering", AccountSearch.entity().getNetworkOfferingId(), Op.EQ);
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("cidr", AccountSearch.entity().getCidr(), Op.EQ);
AccountSearch.done();
RelatedConfigSearch = createSearchBuilder();
RelatedConfigSearch.and("offering", RelatedConfigSearch.entity().getNetworkOfferingId(), 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);
RelatedConfigSearch.join("account", join2, join2.entity().getNetworkId(), RelatedConfigSearch.entity().getId(), JoinType.INNER);
RelatedConfigSearch.done();
AccountNetworkSearch = createSearchBuilder();
AccountNetworkSearch.and("networkId", AccountNetworkSearch.entity().getId(), Op.EQ);
SearchBuilder<NetworkAccountVO> mapJoin = _accountsDao.createSearchBuilder();
mapJoin.and("accountId", mapJoin.entity().getAccountId(), Op.EQ);
AccountNetworkSearch.join("networkSearch", mapJoin, AccountNetworkSearch.entity().getId(), mapJoin.entity().getNetworkId(), JoinBuilder.JoinType.INNER);
AccountNetworkSearch.done();
ZoneBroadcastUriSearch = createSearchBuilder();
ZoneBroadcastUriSearch.and("dataCenterId", ZoneBroadcastUriSearch.entity().getDataCenterId(), Op.EQ);
ZoneBroadcastUriSearch.and("broadcastUri", ZoneBroadcastUriSearch.entity().getBroadcastUri(), Op.EQ);
ZoneBroadcastUriSearch.done();
ZoneSecurityGroupSearch = createSearchBuilder();
ZoneSecurityGroupSearch.and("dataCenterId", ZoneSecurityGroupSearch.entity().getDataCenterId(), Op.EQ);
ZoneSecurityGroupSearch.and("securityGroup", ZoneSecurityGroupSearch.entity().isSecurityGroupEnabled(), Op.EQ);
ZoneSecurityGroupSearch.done();
_tgMacAddress = _tgs.get("macAddress");
}
@Override
public List<NetworkVO> listBy(long accountId, long dataCenterId, GuestIpType type) {
SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
@ -123,37 +125,42 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
}
return listBy(sc, null);
}
public List<NetworkVO> findBy(TrafficType trafficType, Mode mode, BroadcastDomainType broadcastType, long networkOfferingId, long dataCenterId) {
SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
sc.setParameters("trafficType", trafficType);
sc.setParameters("broadcastType", broadcastType);
sc.setParameters("offering", networkOfferingId);
sc.setParameters("datacenter", dataCenterId);
return search(sc, null);
}
@Override
public List<NetworkVO> listBy(long accountId) {
SearchCriteria<NetworkVO> sc = AccountSearch.create();
sc.setParameters("account", accountId);
sc.setJoinParameters("accounts", "account", accountId);
return listBy(sc);
}
// @Override
// public void loadTags(NetworkVO network) {
// network.setTags(_tagDao.getTags(network.getId()));
// }
@Override
public List<NetworkVO> listBy(long accountId, long offeringId, long dataCenterId) {
SearchCriteria<NetworkVO> sc = AccountSearch.create();
sc.setParameters("offering", offeringId);
sc.setJoinParameters("accounts", "account", accountId);
sc.setParameters("datacenter", dataCenterId);
return listBy(sc);
}
@Override
public List<NetworkVO> listBy(long accountId, long offeringId, long dataCenterId, String cidr) {
SearchCriteria<NetworkVO> sc = AccountSearch.create();
@ -161,37 +168,41 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
sc.setJoinParameters("accounts", "account", accountId);
sc.setParameters("datacenter", dataCenterId);
sc.setParameters("cidr", cidr);
return listBy(sc);
}
@Override @DB
public NetworkVO persist(NetworkVO config, boolean gc) {
public NetworkVO persist(NetworkVO network, boolean gc) {
Transaction txn = Transaction.currentTxn();
txn.start();
config = super.persist(config);
addAccountToNetworkConfiguration(config.getId(), config.getAccountId(), true);
NetworkOpVO op = new NetworkOpVO(config.getId(), gc);
NetworkVO newNetwork = super.persist(network);
addAccountToNetwork(network.getId(), network.getAccountId(), true);
NetworkOpVO op = new NetworkOpVO(network.getId(), gc);
_opDao.persist(op);
for (String tag : network.getTags()) {
_tagDao.persist(new NetworkTagVO(network.getId(), tag));
}
txn.commit();
return config;
newNetwork.setTags(network.getTags());
return newNetwork;
}
@Override
public void addAccountToNetwork(long configurationId, long accountId) {
addAccountToNetworkConfiguration(configurationId, accountId, false);
public void addAccountToNetwork(long networkId, long accountId) {
addAccountToNetwork(networkId, accountId, false);
}
protected void addAccountToNetworkConfiguration(long configurationId, long accountId, boolean isOwner) {
NetworkAccountVO account = new NetworkAccountVO(configurationId, accountId, isOwner);
protected void addAccountToNetwork(long networkId, long accountId, boolean isOwner) {
NetworkAccountVO account = new NetworkAccountVO(networkId, accountId, isOwner);
_accountsDao.persist(account);
}
@Override
public SearchBuilder<NetworkAccountVO> createSearchBuilderForAccount() {
return _accountsDao.createSearchBuilder();
}
@Override
public List<NetworkVO> getNetworksForOffering(long offeringId, long dataCenterId, long accountId) {
SearchCriteria<NetworkVO> sc = RelatedConfigSearch.create();
@ -200,23 +211,23 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
sc.setJoinParameters("account", "account", accountId);
return search(sc, null);
}
@Override
public List<NetworkVO> getRelatedNetworks(long related) {
SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
sc.setParameters("related", related);
return search(sc, null);
}
@Override
public String getNextAvailableMacAddress(long networkConfigId) {
SequenceFetcher fetch = SequenceFetcher.getInstance();
long seq = fetch.getNextSequence(Long.class, _tgMacAddress, networkConfigId);
seq = seq | _prefix << 40| ((_rand.nextInt(Short.MAX_VALUE) << 16) & 0x00000000ffff0000l);
return NetUtils.long2Mac(seq);
}
@Override
public List<NetworkVO> listBy(long accountId, long networkId) {
SearchCriteria<NetworkVO> sc = AccountNetworkSearch.create();
@ -224,7 +235,7 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
sc.setJoinParameters("networkSearch", "accountId", accountId);
return listBy(sc);
}
@Override
public List<NetworkVO> listBy(long zoneId, String broadcastUri) {
SearchCriteria<NetworkVO> sc = ZoneBroadcastUriSearch.create();
@ -232,67 +243,68 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
sc.setParameters("broadcastUri", broadcastUri);
return search(sc, null);
}
@Override
public List<NetworkVO> listByZone(long zoneId) {
SearchCriteria<NetworkVO> sc = ZoneBroadcastUriSearch.create();
sc.setParameters("dataCenterId", zoneId);
return search(sc, null);
}
@Override
public List<NetworkVO> listByZoneSecurityGroup(Long zoneId) {
SearchCriteria<NetworkVO> sc = ZoneSecurityGroupSearch.create();
if (zoneId != null)
if (zoneId != null) {
sc.setParameters("dataCenterId", zoneId);
}
sc.setParameters("securityGroup", true);
return search(sc, null);
}
@Override
public void changeActiveNicsBy(long networkId, int count) {
_opDao.changeActiveNicsBy(networkId, count);
}
@Override
public int getActiveNicsIn(long networkId) {
return _opDao.getActiveNics(networkId);
}
@Override
public List<Long> findNetworksToGarbageCollect() {
return _opDao.getNetworksToGarbageCollect();
}
@Override
public void clearCheckForGc(long networkId) {
_opDao.clearCheckForGc(networkId);
}
@Override
public List<NetworkVO> listByOwner(long ownerId) {
SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
sc.setParameters("account", ownerId);
return listBy(sc);
}
@Override
public void addDomainToNetwork(long configurationId, long domainId) {
addDomainToNetworkConfiguration(configurationId, domainId);
public void addDomainToNetwork(long networkId, long domainId) {
addDomainToNetworknetwork(networkId, domainId);
}
protected void addDomainToNetworkConfiguration(long configurationId, long domainId) {
NetworkDomainVO domain = new NetworkDomainVO(configurationId, domainId);
protected void addDomainToNetworknetwork(long networkId, long domainId) {
NetworkDomainVO domain = new NetworkDomainVO(networkId, domainId);
_domainsDao.persist(domain);
}
@Override
public List<NetworkVO> listNetworksBy(boolean isShared) {
SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
sc.setParameters("isShared", isShared);
return listBy(sc);
}
@Override
public List<NetworkVO> listByZoneIncludingRemoved(long zoneId) {
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`.`vpn_users`;
DROP TABLE IF EXISTS `cloud`.`data_center_details`;
DROP TABLE IF EXISTS `cloud`.`network_tags`;
CREATE TABLE `cloud`.`version` (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
@ -190,6 +191,15 @@ CREATE TABLE `cloud`.`networks` (
INDEX `i_networks__removed`(`removed`)
) 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` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '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
) 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` (
`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.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.OneToMany;
import javax.persistence.TableGenerator;
import net.sf.cglib.proxy.Callback;
@ -107,14 +108,14 @@ import com.cloud.utils.net.NetUtils;
@DB
public abstract class GenericDaoBase<T, ID extends Serializable> implements GenericDao<T, ID> {
private final static Logger s_logger = Logger.getLogger(GenericDaoBase.class);
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 Class<T> _entityBeanType;
protected String _table;
protected String _tables;
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, TableGenerator> _tgs;
protected final Map<String, Attribute> _allAttributes;
protected List<Attribute> _oneToManyAttributes;
protected final Map<Pair<String, String>, Attribute> _allColumns;
protected Enhancer _enhancer;
protected Factory _factory;
@ -141,37 +143,37 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
protected int _timeoutSeconds;
protected final static CallbackFilter s_callbackFilter = new UpdateFilter();
protected static final String FOR_UPDATE_CLAUSE = " FOR UPDATE ";
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 SequenceFetcher s_seqFetcher = SequenceFetcher.getInstance();
protected static PreparedStatement s_initStmt;
static {
Connection conn = Transaction.getStandaloneConnection();
Connection conn = Transaction.getStandaloneConnection();
try {
s_initStmt = conn.prepareStatement("SELECT 1");
} catch (final SQLException e) {
} finally {
try {
conn.close();
} catch (SQLException e) {
}
try {
conn.close();
} catch (SQLException e) {
}
}
}
protected String _name;
public static <J> GenericDao<? extends J, ? extends Serializable> getDao(Class<J> entityType) {
@SuppressWarnings("unchecked")
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?";
return dao;
}
@Override
@SuppressWarnings("unchecked")
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);
return builder;
}
@SuppressWarnings("unchecked")
protected GenericDaoBase() {
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];
} else {
_entityBeanType = (Class<T>)((ParameterizedType)((Class<?>)t).getGenericSuperclass()).getActualTypeArguments()[0];
}
s_daoMaps.put(_entityBeanType, this);
Class<?>[] interphaces = _entityBeanType.getInterfaces();
if (interphaces != null) {
@ -211,7 +213,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
_idAttributes = generator.getIdAttributes();
_idField = _idAttributes.get(_table).length > 0 ? _idAttributes.get(_table)[0].field : null;
_tables = generator.buildTableReferences();
_allAttributes = generator.getAllAttributes();
@ -222,7 +224,8 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
_deleteSqls = generator.buildDeleteSqls();
_removed = generator.getRemovedAttribute();
_tgs = generator.getTableGenerators();
_oneToManyAttributes = generator.getOneToManyAttributes();
TableGenerator tg = this.getClass().getAnnotation(TableGenerator.class);
if (tg != null) {
_tgs.put(tg.name(), tg);
@ -231,19 +234,19 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
if (tg != null) {
_tgs.put(tg.name(), tg);
}
Callback[] callbacks = new Callback[] { NoOp.INSTANCE, new UpdateBuilder(_allAttributes) };
_enhancer = new Enhancer();
_enhancer.setSuperclass(_entityBeanType);
_enhancer.setCallbackFilter(s_callbackFilter);
_enhancer.setCallbacks(callbacks);
_factory = (Factory)_enhancer.create();
_searchEnhancer = new Enhancer();
_searchEnhancer.setSuperclass(_entityBeanType);
_searchEnhancer.setCallback(new UpdateBuilder(_allAttributes));
if (s_logger.isTraceEnabled()) {
s_logger.trace("Select SQL: " + _partialSelectSql.first().toString());
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) {
String clause = sc != null ? sc.getWhereClause() : null;
if (clause != null && clause.length() == 0) {
clause = null;
clause = null;
}
final StringBuilder str = createPartialSelectSql(sc, clause != null);
if (clause != null) {
str.append(clause);
@ -330,7 +333,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
addJoins(str, joins);
}
}
List<Object> groupByValues = addGroupBy(str, sc);
addFilter(str, filter);
@ -348,15 +351,15 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
pstmt = txn.prepareAutoCloseStatement(sql);
int i = 0;
if (clause != null) {
for (final Pair<Attribute, Object> value : sc.getValues()) {
prepareAttribute(++i, pstmt, value.first(), value.second());
}
for (final Pair<Attribute, Object> value : sc.getValues()) {
prepareAttribute(++i, pstmt, value.first(), value.second());
}
}
if (joins != null) {
i = addJoinAttributes(i, pstmt, joins);
}
if (groupByValues != null) {
for (Object value : groupByValues) {
pstmt.setObject(i++, value);
@ -364,7 +367,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
}
if (s_logger.isDebugEnabled() && lock != null) {
txn.registerLock(pstmt.toString());
txn.registerLock(pstmt.toString());
}
final ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
@ -377,14 +380,14 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
throw new CloudRuntimeException("Caught: " + pstmt.toString(), e);
}
}
@Override @SuppressWarnings("unchecked") @DB
public <M> List<M> customSearchIncludingRemoved(SearchCriteria<M> sc, final Filter filter) {
String clause = sc != null ? sc.getWhereClause() : null;
if (clause != null && clause.length() == 0) {
clause = null;
}
final StringBuilder str = createPartialSelectSql(sc, clause != null);
if (clause != null) {
str.append(clause);
@ -397,7 +400,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
addJoins(str, joins);
}
}
List<Object> groupByValues = addGroupBy(str, sc);
addFilter(str, filter);
@ -417,13 +420,13 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
if (joins != null) {
i = addJoinAttributes(i, pstmt, joins);
}
if (groupByValues != null) {
for (Object value : groupByValues) {
pstmt.setObject(i++, value);
}
}
ResultSet rs = pstmt.executeQuery();
SelectType st = sc.getSelectType();
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);
}
}
@Override @DB(txn=false)
public <M> List<M> customSearch(SearchCriteria<M> sc, final Filter filter) {
if (_removed != null) {
sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
}
return customSearchIncludingRemoved(sc, filter);
}
@DB(txn=false)
protected void setField(Object entity, Field field, ResultSet rs, int index) throws SQLException {
try {
final Class<?> type = field.getType();
if (type == String.class) {
byte[] bytes = rs.getBytes(index);
if(bytes != null) {
try {
field.set(entity, new String(bytes, "UTF-8"));
} catch (IllegalArgumentException e) {
assert(false);
throw new CloudRuntimeException("IllegalArgumentException when converting UTF-8 data");
} catch (UnsupportedEncodingException e) {
assert(false);
throw new CloudRuntimeException("UnsupportedEncodingException when converting UTF-8 data");
}
} else {
field.set(entity, null);
}
byte[] bytes = rs.getBytes(index);
if(bytes != null) {
try {
field.set(entity, new String(bytes, "UTF-8"));
} catch (IllegalArgumentException e) {
assert(false);
throw new CloudRuntimeException("IllegalArgumentException when converting UTF-8 data");
} catch (UnsupportedEncodingException e) {
assert(false);
throw new CloudRuntimeException("UnsupportedEncodingException when converting UTF-8 data");
}
} else {
field.set(entity, null);
}
} else if (type == long.class) {
field.setLong(entity, rs.getLong(index));
} 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();
for (final Enum<?> e : enums) {
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);
return;
}
@ -597,20 +600,20 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
throw new CloudRuntimeException("Yikes! ", e);
}
}
@DB(txn=false) @SuppressWarnings("unchecked")
protected <M> M getObject(Class<M> type, ResultSet rs, int index) throws SQLException {
if (type == String.class) {
byte[] bytes = rs.getBytes(index);
if(bytes != null) {
try {
return (M)new String(bytes, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new CloudRuntimeException("UnsupportedEncodingException exception while converting UTF-8 data");
}
} else {
return null;
}
byte[] bytes = rs.getBytes(index);
if(bytes != null) {
try {
return (M)new String(bytes, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new CloudRuntimeException("UnsupportedEncodingException exception while converting UTF-8 data");
}
} else {
return null;
}
} else if (type == int.class) {
return (M)new Integer(rs.getInt(index));
} else if (type == Integer.class) {
@ -712,13 +715,13 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
@DB(txn=false)
protected int update(final ID id, final UpdateBuilder ub) {
SearchCriteria<T> sc = createSearchCriteria();
sc.addAnd(_idAttributes.get(_table)[0], SearchCriteria.Op.EQ, id);
int rowsUpdated = update(ub, sc, null);
if (_cache != null) {
SearchCriteria<T> sc = createSearchCriteria();
sc.addAnd(_idAttributes.get(_table)[0], SearchCriteria.Op.EQ, id);
int rowsUpdated = update(ub, sc, null);
if (_cache != null) {
_cache.remove(id);
}
return rowsUpdated;
}
return rowsUpdated;
}
// @Override
@ -727,33 +730,33 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
PreparedStatement pstmt = s_initStmt;
final Transaction txn = Transaction.currentTxn();
try {
final String searchClause = sc.getWhereClause();
final String searchClause = sc.getWhereClause();
sql = ub.toSql(_tables);
if (sql == null) {
return 0;
return 0;
}
sql.append(searchClause);
if (rows != null) {
sql.append(" LIMIT ").append(rows);
sql.append(" LIMIT ").append(rows);
}
txn.start();
pstmt = txn.prepareAutoCloseStatement(sql.toString());
Collection<Ternary<Attribute, Boolean, Object>> changes = ub.getChanges();
int i = 1;
for (final Ternary<Attribute, Boolean, Object> value : changes) {
prepareAttribute(i++, pstmt, value.first(), value.third());
}
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();
txn.commit();
ub.clear();
@ -766,10 +769,10 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
throw new CloudRuntimeException("DB Exception on: " + sqlStr, e);
}
}
@DB(txn=false)
protected Attribute findAttributeByFieldName(String name) {
return _allAttributes.get(name);
return _allAttributes.get(name);
}
@DB(txn=false)
@ -846,29 +849,29 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
return lockRow(id, null);
}
}
@Override @DB(txn=false)
public T findByIdIncludingRemoved(ID id) {
return findById(id, true, null);
}
@Override @DB(txn=false)
public T findById(final ID id, boolean fresh) {
if(!fresh) {
if(!fresh) {
return findById(id);
}
if (_cache != null) {
_cache.remove(id);
_cache.remove(id);
}
return lockRow(id, null);
}
@Override
public T lockRow(ID id, Boolean lock) {
return findById(id, false, lock);
}
protected T findById(ID id, boolean removed, Boolean lock) {
StringBuilder sql = new StringBuilder(_selectByIdSql);
if (!removed && _removed != null) {
@ -883,9 +886,9 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
pstmt = txn.prepareAutoCloseStatement(sql.toString());
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();
return rs.next() ? toEntityBean(rs, true) : null;
} catch (SQLException e) {
@ -895,9 +898,9 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
@Override @DB(txn=false)
public T acquireInLockTable(ID id) {
return acquireInLockTable(id, _timeoutSeconds);
return acquireInLockTable(id, _timeoutSeconds);
}
@Override
public T acquireInLockTable(final ID id, int seconds) {
Transaction txn = Transaction.currentTxn();
@ -905,35 +908,35 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
boolean locked = false;
try {
if (!txn.lock(_table + id.toString(), seconds)) {
return null;
return null;
}
locked = true;
t = findById(id);
return t;
} finally {
if (t == null && locked) {
txn.release(_table + id.toString());
}
if (t == null && locked) {
txn.release(_table + id.toString());
}
}
}
@Override
public boolean releaseFromLockTable(final ID id) {
final Transaction txn = Transaction.currentTxn();
return txn.release(_table + id);
return txn.release(_table + id);
}
@Override @DB(txn=false)
public boolean lockInLockTable(final String id) {
return lockInLockTable(id, _timeoutSeconds);
}
@Override
public boolean lockInLockTable(final String id, int seconds) {
Transaction txn = Transaction.currentTxn();
return txn.lock(_table + id, seconds);
}
}
@Override
public boolean unlockFromLockTable(final String id) {
@ -948,15 +951,15 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
@DB(txn=false)
protected List<Object> addGroupBy(final StringBuilder sql, SearchCriteria<?> sc) {
Pair<GroupBy<?, ?>, List<Object>> groupBys = sc.getGroupBy();
if (groupBys != null) {
groupBys.first().toSql(sql);
return groupBys.second();
} else {
return null;
}
Pair<GroupBy<?, ?>, List<Object>> groupBys = sc.getGroupBy();
if (groupBys != null) {
groupBys.first().toSql(sql);
return groupBys.second();
} else {
return null;
}
}
@DB(txn=false)
protected void addFilter(final StringBuilder sql, final Filter filter) {
if (filter != null) {
@ -1071,7 +1074,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
pstmt = txn.prepareAutoCloseStatement(sql);
int i = 0;
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();
} catch (final SQLException e) {
@ -1088,14 +1091,14 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
sql.delete(7, sql.indexOf(" FROM"));
sc.getSelect(sql, 7);
}
if (!whereClause) {
sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
}
return sql;
}
@DB(txn = false)
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) {
StringBuilder onClause = new StringBuilder();
onClause.append(" ").append(join.getType().getName()).append(" ").append(join.getSecondAttribute().table)
.append(" ON ").append(join.getFirstAttribute().table).append(".").append(join.getFirstAttribute().columnName)
.append("=").append(join.getSecondAttribute().table).append(".").append(join.getSecondAttribute().columnName)
.append(" ");
.append(" ON ").append(join.getFirstAttribute().table).append(".").append(join.getFirstAttribute().columnName)
.append("=").append(join.getSecondAttribute().table).append(".").append(join.getSecondAttribute().columnName)
.append(" ");
str.insert(fromIndex, onClause);
String whereClause = join.getT().getWhereClause();
if ((whereClause != null) && !"".equals(whereClause)) {
@ -1149,7 +1152,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
final UpdateBuilder ub = getUpdateBuilder(entity);
return update(ub, sc, rows);
}
@DB(txn=false)
public int update(final T entity, final SearchCriteria<T> sc) {
final UpdateBuilder ub = getUpdateBuilder(entity);
@ -1170,7 +1173,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
update(id, entity);
return entity;
}
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);
}
}
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
if (length < str.length()) {
try {
pstmt.setBytes(j, str.substring(0, column.length()).getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
// no-way it can't support UTF-8 encoding
assert(false);
throw new CloudRuntimeException("UnsupportedEncodingException when saving string as UTF-8 data");
}
try {
pstmt.setBytes(j, str.substring(0, column.length()).getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
// no-way it can't support UTF-8 encoding
assert(false);
throw new CloudRuntimeException("UnsupportedEncodingException when saving string as UTF-8 data");
}
} else {
try {
pstmt.setBytes(j, str.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
// no-way it can't support UTF-8 encoding
assert(false);
throw new CloudRuntimeException("UnsupportedEncodingException when saving string as UTF-8 data");
}
try {
pstmt.setBytes(j, str.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
// no-way it can't support UTF-8 encoding
assert(false);
throw new CloudRuntimeException("UnsupportedEncodingException when saving string as UTF-8 data");
}
}
} else if (attr.field.getType() == Date.class) {
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++) {
setField(entity, result, meta, index);
}
for (Attribute attr : _oneToManyAttributes) {
OneToMany otm = attr.field.getAnnotation(OneToMany.class);
}
}
@Override
@ -1398,7 +1405,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
throw new CloudRuntimeException("DB Exception on " + sqlStr, e);
}
}
@DB(txn=false)
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)));
@ -1441,14 +1448,14 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
if (_removeSql == null) {
return expunge(sc);
}
T vo = createForUpdate();
UpdateBuilder ub = getUpdateBuilder(vo);
ub.set(vo, _removed.second(), new Date());
return update(ub, sc, null);
}
protected Cache _cache;
@DB(txn=false)
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() {
return _name;
}
@DB(txn=false)
public static <T> UpdateBuilder getUpdateBuilder(final T entityObject) {
final Factory factory = (Factory)entityObject;
assert(factory != null);
return (UpdateBuilder)factory.getCallback(1);
}
@SuppressWarnings("unchecked")
@Override @DB(txn=false)
public SearchBuilder<T> createSearchBuilder() {
@ -1504,11 +1511,11 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
factory.setCallback(0, builder);
return builder;
}
@Override @DB(txn=false)
public SearchCriteria<T> createSearchCriteria() {
SearchBuilder<T> builder = createSearchBuilder();
return builder.create();
SearchBuilder<T> builder = createSearchBuilder();
return builder.create();
}
}

View File

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