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,6 +39,7 @@ 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() {
} }
@ -86,6 +88,14 @@ public class NetworkTO {
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;
} }

View File

@ -228,4 +228,6 @@ public interface Network extends ControlledEntity {
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;
} }

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

@ -50,6 +50,7 @@ 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;
} }
@ -60,7 +61,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
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();
@ -82,7 +83,8 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
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;
@ -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;
@ -137,6 +140,9 @@ public class NetworkVO implements Network {
@Column(name="is_security_group_enabled") @Column(name="is_security_group_enabled")
boolean securityGroupEnabled; boolean securityGroupEnabled;
@Transient
List<String> tags;
public NetworkVO() { public NetworkVO() {
} }
@ -233,6 +239,22 @@ public class NetworkVO implements Network {
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;
@ -436,14 +458,16 @@ public class NetworkVO implements Network {
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

@ -55,6 +55,8 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
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;
@ -143,6 +145,11 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
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) {
@ -166,24 +173,28 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
} }
@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);
} }
@ -243,8 +254,9 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
@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);
} }
@ -277,12 +289,12 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
} }
@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);
} }

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;
@ -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;
@ -150,15 +152,15 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
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) {
} }
} }
} }
@ -222,6 +224,7 @@ 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) {
@ -315,7 +318,7 @@ 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);
@ -348,9 +351,9 @@ 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) {
@ -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()) {
@ -464,20 +467,20 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
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;
} }
@ -601,16 +604,16 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
@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,17 +730,17 @@ 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();
@ -751,7 +754,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
} }
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();
@ -769,7 +772,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
@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)
@ -854,12 +857,12 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
@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);
} }
@ -883,7 +886,7 @@ 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();
@ -895,7 +898,7 @@ 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
@ -905,23 +908,23 @@ 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)
@ -933,7 +936,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
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,13 +951,13 @@ 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)
@ -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) {
@ -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)) {
@ -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
@ -1507,8 +1514,8 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
@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,17 +48,19 @@ 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>();
@ -66,9 +71,9 @@ public class SqlGenerator {
} }
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,8 +84,8 @@ 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;
} }
@ -135,10 +140,32 @@ public class SqlGenerator {
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;
} }
@ -237,6 +264,10 @@ public class SqlGenerator {
} }
} }
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)) {
@ -272,28 +303,28 @@ 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("?, ");
} }
@ -405,7 +436,7 @@ public class SqlGenerator {
// 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;
@ -510,7 +541,7 @@ 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) {

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 {
}