mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
bug 9651: Adding network tags
Also changes in Request logging.
This commit is contained in:
parent
e22d99f70d
commit
0dfc44582b
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -228,4 +228,6 @@ public interface Network extends ControlledEntity {
|
|||||||
|
|
||||||
boolean isSecurityGroupEnabled();
|
boolean isSecurityGroupEnabled();
|
||||||
|
|
||||||
|
List<String> getTags();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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 buf = new StringBuilder("Seq ");
|
StringBuilder content = new StringBuilder();
|
||||||
buf.append(_agentId).append("-").append(_seq).append(": ");
|
|
||||||
|
|
||||||
buf.append(msg);
|
|
||||||
buf.append("{ ").append(getType());
|
|
||||||
buf.append(", MgmtId: ").append(_mgmtId).append(", via: ").append(_via);
|
|
||||||
if (logContent) {
|
if (logContent) {
|
||||||
buf.append(", Ver: ").append(_ver.toString());
|
if (_cmds == null) {
|
||||||
buf.append(", Flags: ").append(Integer.toBinaryString(getFlags())).append(", ");
|
_cmds = s_gson.fromJson(_content, this instanceof Response ? Answer[].class : Command[].class);
|
||||||
if (_cmds != null) {
|
}
|
||||||
try {
|
try {
|
||||||
s_gogger.toJson(_cmds, buf);
|
s_gogger.toJson(_cmds, content);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
StringBuilder buff = new StringBuilder();
|
StringBuilder buff = new StringBuilder();
|
||||||
for (Command cmd : _cmds) {
|
for (Command cmd : _cmds) {
|
||||||
buff.append(cmd.getClass().getName()).append("/");
|
buff.append(cmd.getClass().getSimpleName()).append("/");
|
||||||
}
|
}
|
||||||
s_logger.error("Gson serialization error " + buff.toString(), e);
|
s_logger.error("Gson serialization error " + buff.toString(), e);
|
||||||
assert false : "More gson errors on " + buff.toString();
|
assert false : "More gson errors on " + buff.toString();
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
} else if (_content != null) {
|
if (content.length() <= 4) {
|
||||||
buf.append(_content.subSequence(0, 32));
|
return null;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
buf.append("I've got nada here!");
|
if (_cmds == null) {
|
||||||
assert false : "How can both commands and content be null? What are we sending here?";
|
_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(", MgmtId: ").append(_mgmtId).append(", via: ").append(_via);
|
||||||
|
buf.append(", Ver: ").append(_ver.toString());
|
||||||
|
buf.append(", Flags: ").append(Integer.toBinaryString(getFlags())).append(", ");
|
||||||
|
buf.append(content);
|
||||||
buf.append(" }");
|
buf.append(" }");
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,6 +83,7 @@ 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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
62
server/src/com/cloud/network/dao/NetworkTagDaoImpl.java
Normal file
62
server/src/com/cloud/network/dao/NetworkTagDaoImpl.java
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
68
server/src/com/cloud/network/dao/NetworkTagVO.java
Normal file
68
server/src/com/cloud/network/dao/NetworkTagVO.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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',
|
||||||
|
|||||||
@ -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',
|
||||||
|
|||||||
@ -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;
|
||||||
@ -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) {
|
||||||
@ -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
|
||||||
|
|||||||
@ -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;
|
||||||
@ -51,11 +54,13 @@ public class SqlGenerator {
|
|||||||
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>();
|
||||||
@ -135,9 +140,31 @@ public class SqlGenerator {
|
|||||||
attrs.add(attr);
|
attrs.add(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (field.getAnnotation(OneToMany.class) != null) {
|
||||||
|
assert supportsOneToMany(field) : "Doesn't support One To Many";
|
||||||
|
_otmAttrs.add(attr);
|
||||||
|
} else {
|
||||||
_attributes.add(attr);
|
_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)) {
|
||||||
|
|||||||
22
utils/src/javax/persistence/ElementCollection.java
Normal file
22
utils/src/javax/persistence/ElementCollection.java
Normal 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 {
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user