diff --git a/agent/pom.xml b/agent/pom.xml index 7b00a93963f..14133226053 100644 --- a/agent/pom.xml +++ b/agent/pom.xml @@ -36,6 +36,10 @@ cloud-utils ${project.version} + + commons-io + commons-io + commons-daemon commons-daemon diff --git a/agent/src/com/cloud/agent/Agent.java b/agent/src/com/cloud/agent/Agent.java index c713e459262..c4f17b24ae7 100755 --- a/agent/src/com/cloud/agent/Agent.java +++ b/agent/src/com/cloud/agent/Agent.java @@ -45,7 +45,6 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.CronCommand; import com.cloud.agent.api.MaintainAnswer; import com.cloud.agent.api.MaintainCommand; -import com.cloud.agent.api.ModifySshKeysCommand; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.ShutdownCommand; diff --git a/agent/src/com/cloud/agent/AgentShell.java b/agent/src/com/cloud/agent/AgentShell.java index 42adac07165..900a13f4ab1 100644 --- a/agent/src/com/cloud/agent/AgentShell.java +++ b/agent/src/com/cloud/agent/AgentShell.java @@ -20,6 +20,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; @@ -36,7 +37,8 @@ import javax.naming.ConfigurationException; import org.apache.commons.daemon.Daemon; import org.apache.commons.daemon.DaemonContext; import org.apache.commons.daemon.DaemonInitException; -import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.math.NumberUtils; import org.apache.log4j.Logger; import org.apache.log4j.xml.DOMConfigurator; @@ -55,7 +57,6 @@ import com.cloud.utils.exception.CloudRuntimeException; public class AgentShell implements IAgentShell, Daemon { private static final Logger s_logger = Logger.getLogger(AgentShell.class .getName()); - private static final MultiThreadedHttpConnectionManager s_httpClientManager = new MultiThreadedHttpConnectionManager(); private final Properties _properties = new Properties(); private final Map _cmdLineProperties = new HashMap(); @@ -166,7 +167,7 @@ public class AgentShell implements IAgentShell, Daemon { _storage.persist(name, value); } - private void loadProperties() throws ConfigurationException { + void loadProperties() throws ConfigurationException { final File file = PropertiesUtil.findConfigFile("agent.properties"); if (file == null) { throw new ConfigurationException("Unable to find agent.properties."); @@ -174,14 +175,18 @@ public class AgentShell implements IAgentShell, Daemon { s_logger.info("agent.properties found at " + file.getAbsolutePath()); + InputStream propertiesStream = null; try { - _properties.load(new FileInputStream(file)); + propertiesStream = new FileInputStream(file); + _properties.load(propertiesStream); } catch (final FileNotFoundException ex) { throw new CloudRuntimeException("Cannot find the file: " + file.getAbsolutePath(), ex); } catch (final IOException ex) { throw new CloudRuntimeException("IOException in reading " + file.getAbsolutePath(), ex); + } finally { + IOUtils.closeQuietly(propertiesStream); } } @@ -193,30 +198,32 @@ public class AgentShell implements IAgentShell, Daemon { String zone = null; String pod = null; String guid = null; - for (int i = 0; i < args.length; i++) { - final String[] tokens = args[i].split("="); + for (String param : args) { + final String[] tokens = param.split("="); if (tokens.length != 2) { - System.out.println("Invalid Parameter: " + args[i]); + System.out.println("Invalid Parameter: " + param); continue; } + final String paramName = tokens[0]; + final String paramValue = tokens[1]; // save command line properties - _cmdLineProperties.put(tokens[0], tokens[1]); + _cmdLineProperties.put(paramName, paramValue); - if (tokens[0].equalsIgnoreCase("port")) { - port = tokens[1]; - } else if (tokens[0].equalsIgnoreCase("threads") || tokens[0].equalsIgnoreCase("workers")) { - workers = tokens[1]; - } else if (tokens[0].equalsIgnoreCase("host")) { - host = tokens[1]; - } else if (tokens[0].equalsIgnoreCase("zone")) { - zone = tokens[1]; - } else if (tokens[0].equalsIgnoreCase("pod")) { - pod = tokens[1]; - } else if (tokens[0].equalsIgnoreCase("guid")) { - guid = tokens[1]; - } else if (tokens[0].equalsIgnoreCase("eth1ip")) { - _privateIp = tokens[1]; + if (paramName.equalsIgnoreCase("port")) { + port = paramValue; + } else if (paramName.equalsIgnoreCase("threads") || paramName.equalsIgnoreCase("workers")) { + workers = paramValue; + } else if (paramName.equalsIgnoreCase("host")) { + host = paramValue; + } else if (paramName.equalsIgnoreCase("zone")) { + zone = paramValue; + } else if (paramName.equalsIgnoreCase("pod")) { + pod = paramValue; + } else if (paramName.equalsIgnoreCase("guid")) { + guid = paramValue; + } else if (paramName.equalsIgnoreCase("eth1ip")) { + _privateIp = paramValue; } } @@ -224,16 +231,16 @@ public class AgentShell implements IAgentShell, Daemon { port = getProperty(null, "port"); } - _port = NumbersUtil.parseInt(port, 8250); + _port = NumberUtils.toInt(port, 8250); - _proxyPort = NumbersUtil.parseInt( + _proxyPort = NumberUtils.toInt( getProperty(null, "consoleproxy.httpListenPort"), 443); if (workers == null) { workers = getProperty(null, "workers"); } - _workers = NumbersUtil.parseInt(workers, 5); + _workers = NumberUtils.toInt(workers, 5); if (host == null) { host = getProperty(null, "host"); @@ -303,7 +310,7 @@ public class AgentShell implements IAgentShell, Daemon { // For KVM agent, do it specially here File file = new File("/etc/cloudstack/agent/log4j-cloud.xml"); - if(file == null || !file.exists()) { + if(!file.exists()) { file = PropertiesUtil.findConfigFile("log4j-cloud.xml"); } DOMConfigurator.configureAndWatch(file.getAbsolutePath()); diff --git a/agent/test/com/cloud/agent/AgentShellTest.java b/agent/test/com/cloud/agent/AgentShellTest.java new file mode 100644 index 00000000000..d92accbd7e8 --- /dev/null +++ b/agent/test/com/cloud/agent/AgentShellTest.java @@ -0,0 +1,48 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent; + +import java.util.UUID; + +import javax.naming.ConfigurationException; + +import junit.framework.Assert; + +import org.junit.Test; + +public class AgentShellTest { + @Test + public void parseCommand() throws ConfigurationException { + AgentShell shell = new AgentShell(); + UUID anyUuid = UUID.randomUUID(); + shell.parseCommand(new String[] { "port=55555", "threads=4", + "host=localhost", "pod=pod1", "guid=" + anyUuid, "zone=zone1" }); + Assert.assertEquals(55555, shell.getPort()); + Assert.assertEquals(4, shell.getWorkers()); + Assert.assertEquals("localhost", shell.getHost()); + Assert.assertEquals(anyUuid.toString(), shell.getGuid()); + Assert.assertEquals("pod1", shell.getPod()); + Assert.assertEquals("zone1", shell.getZone()); + } + @Test + public void loadProperties() throws ConfigurationException { + AgentShell shell = new AgentShell(); + shell.loadProperties(); + Assert.assertNotNull(shell.getProperties()); + Assert.assertFalse(shell.getProperties().entrySet().isEmpty()); + } +} diff --git a/api/resources/META-INF/cloudstack/api-planner/module.properties b/api/resources/META-INF/cloudstack/api-planner/module.properties new file mode 100644 index 00000000000..8eed8791149 --- /dev/null +++ b/api/resources/META-INF/cloudstack/api-planner/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=api-planner +parent=planner \ No newline at end of file diff --git a/api/resources/META-INF/cloudstack/api-planner/spring-api-planner-context.xml b/api/resources/META-INF/cloudstack/api-planner/spring-api-planner-context.xml new file mode 100644 index 00000000000..2fd34a8ee0a --- /dev/null +++ b/api/resources/META-INF/cloudstack/api-planner/spring-api-planner-context.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/api/src/com/cloud/agent/api/to/S3TO.java b/api/src/com/cloud/agent/api/to/S3TO.java index ab08a696c96..ea7564d804c 100644 --- a/api/src/com/cloud/agent/api/to/S3TO.java +++ b/api/src/com/cloud/agent/api/to/S3TO.java @@ -40,6 +40,7 @@ public final class S3TO implements S3Utils.ClientOptions, DataStoreTO { private Date created; private boolean enableRRS; private boolean multipartEnabled; + private long maxSingleUploadSizeInBytes; public S3TO() { @@ -51,7 +52,7 @@ public final class S3TO implements S3Utils.ClientOptions, DataStoreTO { final String secretKey, final String endPoint, final String bucketName, final Boolean httpsFlag, final Integer connectionTimeout, final Integer maxErrorRetry, - final Integer socketTimeout, final Date created, final boolean enableRRS, final boolean multipart) { + final Integer socketTimeout, final Date created, final boolean enableRRS, final long maxUploadSize) { super(); @@ -67,7 +68,7 @@ public final class S3TO implements S3Utils.ClientOptions, DataStoreTO { this.socketTimeout = socketTimeout; this.created = created; this.enableRRS = enableRRS; - this.multipartEnabled = multipart; + this.maxSingleUploadSizeInBytes = maxUploadSize; } @@ -278,14 +279,28 @@ public final class S3TO implements S3Utils.ClientOptions, DataStoreTO { this.enableRRS = enableRRS; } - public boolean isMultipartEnabled() { - return multipartEnabled; + public long getMaxSingleUploadSizeInBytes() { + return maxSingleUploadSizeInBytes; } - public void setMultipartEnabled(boolean multipartEnabled) { - this.multipartEnabled = multipartEnabled; + public void setMaxSingleUploadSizeInBytes(long maxSingleUploadSizeInBytes) { + this.maxSingleUploadSizeInBytes = maxSingleUploadSizeInBytes; } - - + public boolean getSingleUpload(long objSize){ + if ( maxSingleUploadSizeInBytes < 0 ){ + // always use single part upload + return true; + } else if ( maxSingleUploadSizeInBytes == 0 ){ + // always use multi part upload + return false; + } else { + // check object size to set flag + if (objSize < maxSingleUploadSizeInBytes){ + return true; + } else{ + return false; + } + } + } } diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index a762606e9ad..c7e7a45cfdd 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -76,6 +76,7 @@ public class EventTypes { public static final String EVENT_VM_MIGRATE = "VM.MIGRATE"; public static final String EVENT_VM_MOVE = "VM.MOVE"; public static final String EVENT_VM_RESTORE = "VM.RESTORE"; + public static final String EVENT_VM_EXPUNGE = "VM.EXPUNGE"; // Domain Router public static final String EVENT_ROUTER_CREATE = "ROUTER.CREATE"; diff --git a/api/src/com/cloud/exception/ConcurrentOperationException.java b/api/src/com/cloud/exception/ConcurrentOperationException.java index cfe6ba3fa0a..018dba55f2e 100644 --- a/api/src/com/cloud/exception/ConcurrentOperationException.java +++ b/api/src/com/cloud/exception/ConcurrentOperationException.java @@ -17,8 +17,9 @@ package com.cloud.exception; import com.cloud.utils.SerialVersionUID; +import com.cloud.utils.exception.CloudRuntimeException; -public class ConcurrentOperationException extends CloudException { +public class ConcurrentOperationException extends CloudRuntimeException { private static final long serialVersionUID = SerialVersionUID.ConcurrentOperationException; diff --git a/api/src/com/cloud/network/element/RemoteAccessVPNServiceProvider.java b/api/src/com/cloud/network/element/RemoteAccessVPNServiceProvider.java index 4950ed92cab..b9233755249 100644 --- a/api/src/com/cloud/network/element/RemoteAccessVPNServiceProvider.java +++ b/api/src/com/cloud/network/element/RemoteAccessVPNServiceProvider.java @@ -19,7 +19,6 @@ package com.cloud.network.element; import java.util.List; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.network.Network; import com.cloud.network.RemoteAccessVpn; import com.cloud.network.VpnUser; import com.cloud.utils.component.Adapter; @@ -27,7 +26,7 @@ import com.cloud.utils.component.Adapter; public interface RemoteAccessVPNServiceProvider extends Adapter { String[] applyVpnUsers(RemoteAccessVpn vpn, List users) throws ResourceUnavailableException; - boolean startVpn(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException; + boolean startVpn(RemoteAccessVpn vpn) throws ResourceUnavailableException; - boolean stopVpn(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException; + boolean stopVpn(RemoteAccessVpn vpn) throws ResourceUnavailableException; } diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java index 6c5573e0368..749dae32fc9 100644 --- a/api/src/com/cloud/offering/NetworkOffering.java +++ b/api/src/com/cloud/offering/NetworkOffering.java @@ -130,4 +130,6 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity, boolean getEgressDefaultPolicy(); Integer getConcurrentConnections(); + + boolean isKeepAliveEnabled(); } diff --git a/api/src/com/cloud/server/ResourceMetaDataService.java b/api/src/com/cloud/server/ResourceMetaDataService.java index 556f97453a1..1a12b6af66e 100644 --- a/api/src/com/cloud/server/ResourceMetaDataService.java +++ b/api/src/com/cloud/server/ResourceMetaDataService.java @@ -16,22 +16,19 @@ // under the License.package com.cloud.server; package com.cloud.server; -import java.util.List; import java.util.Map; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; public interface ResourceMetaDataService { - TaggedResourceType getResourceType (String resourceTypeStr); - /** * @param resourceId TODO * @param resourceType * @param details * @return */ - boolean addResourceMetaData(String resourceId, TaggedResourceType resourceType, Map details); + boolean addResourceMetaData(String resourceId, ResourceObjectType resourceType, Map details); /** @@ -41,7 +38,7 @@ public interface ResourceMetaDataService { * @param key * @return */ - public boolean deleteResourceMetaData(String resourceId, TaggedResourceType resourceType, String key); + public boolean deleteResourceMetaData(String resourceId, ResourceObjectType resourceType, String key); } diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java index 9e166ab8c99..f2bcd18f90b 100644 --- a/api/src/com/cloud/server/ResourceTag.java +++ b/api/src/com/cloud/server/ResourceTag.java @@ -22,27 +22,44 @@ import org.apache.cloudstack.api.InternalIdentity; public interface ResourceTag extends ControlledEntity, Identity, InternalIdentity { - public enum TaggedResourceType { - UserVm, - Template, - ISO, - Volume, - Snapshot, - Network, - Nic, - LoadBalancer, - PortForwardingRule, - FirewallRule, - SecurityGroup, - PublicIpAddress, - Project, - Vpc, - NetworkACL, - StaticRoute, - VMSnapshot, - RemoteAccessVpn, - Zone, - ServiceOffering + //FIXME - extract enum to another interface as its used both by resourceTags and resourceMetaData code + public enum ResourceObjectType { + UserVm (true, true), + Template (true, true), + ISO (true, false), + Volume (true, true), + Snapshot (true, false), + Network (true, true), + Nic (false, true), + LoadBalancer (true, false), + PortForwardingRule (true, false), + FirewallRule (true, false), + SecurityGroup (true, false), + PublicIpAddress (true, false), + Project (true, false), + Vpc (true, false), + NetworkACL (true, false), + StaticRoute (true, false), + VMSnapshot (true, false), + RemoteAccessVpn (true, false), + Zone (false, true), + ServiceOffering (false, true); + + ResourceObjectType(boolean resourceTagsSupport, boolean resourceMetadataSupport) { + this.resourceTagsSupport = resourceTagsSupport; + this.metadataSupport = resourceMetadataSupport; + } + + private final boolean resourceTagsSupport; + private final boolean metadataSupport; + + public boolean resourceTagsSupport() { + return this.resourceTagsSupport; + } + + public boolean resourceMetadataSupport() { + return this.metadataSupport; + } } /** @@ -63,7 +80,7 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit /** * @return */ - TaggedResourceType getResourceType(); + ResourceObjectType getResourceType(); /** * @return diff --git a/api/src/com/cloud/server/TaggedResourceService.java b/api/src/com/cloud/server/TaggedResourceService.java index 46b185480bb..97046ac3950 100644 --- a/api/src/com/cloud/server/TaggedResourceService.java +++ b/api/src/com/cloud/server/TaggedResourceService.java @@ -19,12 +19,10 @@ package com.cloud.server; import java.util.List; import java.util.Map; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; public interface TaggedResourceService { - TaggedResourceType getResourceType (String resourceTypeStr); - /** * @param resourceIds TODO * @param resourceType @@ -32,14 +30,7 @@ public interface TaggedResourceService { * @param customer TODO * @return */ - List createTags(List resourceIds, TaggedResourceType resourceType, Map tags, String customer); - - /** - * @param resourceId - * @param resourceType - * @return - */ - String getUuid(String resourceId, TaggedResourceType resourceType); + List createTags(List resourceIds, ResourceObjectType resourceType, Map tags, String customer); /** @@ -48,10 +39,19 @@ public interface TaggedResourceService { * @param tags * @return */ - boolean deleteTags(List resourceIds, TaggedResourceType resourceType, Map tags); + boolean deleteTags(List resourceIds, ResourceObjectType resourceType, Map tags); - List listByResourceTypeAndId(TaggedResourceType type, long resourceId); + List listByResourceTypeAndId(ResourceObjectType type, long resourceId); - public Long getResourceId(String resourceId, TaggedResourceType resourceType); + //FIXME - the methods below should be extracted to its separate manager/service responsible just for retrieving object details + ResourceObjectType getResourceType (String resourceTypeStr); - } + /** + * @param resourceId + * @param resourceType + * @return + */ + String getUuid(String resourceId, ResourceObjectType resourceType); + + public long getResourceId(String resourceId, ResourceObjectType resourceType); +} diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/com/cloud/vm/UserVmService.java index 7d459b99a9e..0b142e83b72 100755 --- a/api/src/com/cloud/vm/UserVmService.java +++ b/api/src/com/cloud/vm/UserVmService.java @@ -23,6 +23,7 @@ import javax.naming.InsufficientResourcesException; import org.apache.cloudstack.api.BaseCmd.HTTPMethod; import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd; +import org.apache.cloudstack.api.command.admin.vm.ExpungeVMCmd; import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd; import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd; import org.apache.cloudstack.api.command.user.vm.DeployVMCmd; @@ -463,4 +464,8 @@ public interface UserVmService { UserVm upgradeVirtualMachine(ScaleVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException; + UserVm expungeVm(ExpungeVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException; + + UserVm expungeVm(long vmId) throws ResourceUnavailableException, ConcurrentOperationException; + } diff --git a/api/src/com/cloud/vm/VmDetailConstants.java b/api/src/com/cloud/vm/VmDetailConstants.java index 5ff3ce02fe4..87f4b5dc5de 100644 --- a/api/src/com/cloud/vm/VmDetailConstants.java +++ b/api/src/com/cloud/vm/VmDetailConstants.java @@ -21,4 +21,5 @@ public interface VmDetailConstants { public static final String NIC_ADAPTER = "nicAdapter"; public static final String ROOK_DISK_CONTROLLER = "rootDiskController"; public static final String NESTED_VIRTUALIZATION_FLAG = "nestedVirtualizationFlag"; + public static final String HYPERVISOR_TOOLS_VERSION = "hypervisortoolsversion"; } diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 62eed0908d4..61eeb958429 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -34,6 +34,7 @@ public class ApiConstants { public static final String BYTES_READ_RATE = "bytesreadrate"; public static final String BYTES_WRITE_RATE = "byteswriterate"; public static final String CATEGORY = "category"; + public static final String CAN_REVERT = "canrevert"; public static final String CERTIFICATE = "certificate"; public static final String PRIVATE_KEY = "privatekey"; public static final String DOMAIN_SUFFIX = "domainsuffix"; @@ -142,6 +143,7 @@ public class ApiConstants { public static final String MAX_SNAPS = "maxsnaps"; public static final String MEMORY = "memory"; public static final String MODE = "mode"; + public static final String KEEPALIVE_ENABLED = "keepaliveenabled"; public static final String NAME = "name"; public static final String METHOD_NAME = "methodname"; public static final String NETWORK_DOMAIN = "networkdomain"; @@ -186,6 +188,7 @@ public class ApiConstants { public static final String REQUIRES_HVM = "requireshvm"; public static final String RESOURCE_TYPE = "resourcetype"; public static final String RESPONSE = "response"; + public static final String REVERTABLE = "revertable"; public static final String QUERY_FILTER = "queryfilter"; public static final String SCHEDULE = "schedule"; public static final String SCOPE = "scope"; @@ -248,7 +251,7 @@ public class ApiConstants { public static final String IS_VOLATILE = "isvolatile"; public static final String VOLUME_ID = "volumeid"; public static final String ZONE_ID = "zoneid"; - public static final String ZONE_NAME = "zonename"; + public static final String ZONE_NAME = "zonename"; public static final String NETWORK_TYPE = "networktype"; public static final String PAGE = "page"; public static final String PAGE_SIZE = "pagesize"; @@ -518,7 +521,9 @@ public class ApiConstants { public static final String ROUTING = "isrouting"; public static final String MAX_CONNECTIONS = "maxconnections"; public static final String SERVICE_STATE = "servicestate"; - public static final String RESOURCE_TAG = "resourcetag"; + public static final String RESOURCE_DETAIL = "resourcedetail"; + public static final String EXPUNGE = "expunge"; + public enum HostDetails { all, capacity, events, stats, min; } diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java index bdad904c1dd..7296d5315d8 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java @@ -96,12 +96,15 @@ public class CreateNetworkOfferingCmd extends BaseCmd { private Boolean isPersistent; @Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, since="4.2.0", description="Network offering details in key/value pairs." + - " Supported keys are internallbprovider/publiclbprovider with service provider as a value") + " Supported keys are internallbprovider/publiclbprovider with service provider as a value") protected Map details; @Parameter(name=ApiConstants.EGRESS_DEFAULT_POLICY, type=CommandType.BOOLEAN, description="true if default guest network egress policy is allow; false if default egress policy is deny") private Boolean egressDefaultPolicy; + @Parameter(name=ApiConstants.KEEPALIVE_ENABLED, type=CommandType.BOOLEAN, required=false, description="if true keepalive will be turned on in the loadbalancer. At the time of writing this has only an effect on haproxy; the mode http and httpclose options are unset in the haproxy conf file.") + private Boolean keepAliveEnabled; + @Parameter(name=ApiConstants.MAX_CONNECTIONS, type=CommandType.INTEGER, description="maximum number of concurrent connections supported by the network offering") private Integer maxConnections; @@ -175,6 +178,10 @@ public class CreateNetworkOfferingCmd extends BaseCmd { return egressDefaultPolicy; } + public Boolean getKeepAliveEnabled() { + return keepAliveEnabled; + } + public Integer getMaxconnections() { return maxConnections; } diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java index c9c4c8ad3b4..f9bdadb4547 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java @@ -57,6 +57,9 @@ public class UpdateNetworkOfferingCmd extends BaseCmd { @Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="update state for the network offering") private String state; + @Parameter(name=ApiConstants.KEEPALIVE_ENABLED, type=CommandType.BOOLEAN, required=false, description="if true keepalive will be turned on in the loadbalancer. At the time of writing this has only an effect on haproxy; the mode http and httpclose options are unset in the haproxy conf file.") + private Boolean keepAliveEnabled; + @Parameter(name=ApiConstants.MAX_CONNECTIONS, type=CommandType.INTEGER, description="maximum number of concurrent connections supported by the network offering") private Integer maxConnections; @@ -91,6 +94,10 @@ public class UpdateNetworkOfferingCmd extends BaseCmd { public Integer getMaxconnections() { return maxConnections; } + + public Boolean getKeepAliveEnabled() { + return keepAliveEnabled; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/ExpungeVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vm/ExpungeVMCmd.java new file mode 100644 index 00000000000..387a0e986b2 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/vm/ExpungeVMCmd.java @@ -0,0 +1,116 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command.admin.vm; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiCommandJobType; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.api.response.UserVmResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.log4j.Logger; + +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.user.Account; +import com.cloud.uservm.UserVm; +import com.cloud.utils.exception.CloudRuntimeException; + +@APICommand(name = "expungeVirtualMachine", description="Expunge a virtual machine. Once expunged, it cannot be recoverd.", responseObject=SuccessResponse.class) +public class ExpungeVMCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(ExpungeVMCmd.class.getName()); + + private static final String s_name = "expungevirtualmachineresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class, + required=true, description="The ID of the virtual machine") + private Long id; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + UserVm vm = _responseGenerator.findUserVmById(getId()); + if (vm != null) { + return vm.getAccountId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + + @Override + public String getEventType() { + return EventTypes.EVENT_VM_EXPUNGE; + } + + @Override + public String getEventDescription() { + return "Expunging vm: " + getId(); + } + + public ApiCommandJobType getInstanceType() { + return ApiCommandJobType.VirtualMachine; + } + + public Long getInstanceId() { + return getId(); + } + + @Override + public void execute() throws ResourceUnavailableException, ConcurrentOperationException{ + CallContext.current().setEventDetails("Vm Id: "+getId()); + try { + UserVm result = _userVmService.expungeVm(this); + + if (result != null) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to expunge vm"); + } + } catch (InvalidParameterValueException ipve) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ipve.getMessage()); + } catch (CloudRuntimeException cre) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, cre.getMessage()); + } + } +} diff --git a/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkCmd.java index e0cd7133e11..a44b76828fb 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkCmd.java @@ -153,9 +153,7 @@ public class UpdateNetworkCmd extends BaseAsyncCmd { @Override public String getEventDescription() { - - - StringBuffer eventMsg = new StringBuffer("Updating network: " + getId()); + StringBuilder eventMsg = new StringBuilder("Updating network: " + getId()); if (getNetworkOfferingId() != null) { Network network = _networkService.getNetwork(getId()); if (network == null) { diff --git a/api/src/org/apache/cloudstack/api/command/user/offering/ListServiceOfferingsCmd.java b/api/src/org/apache/cloudstack/api/command/user/offering/ListServiceOfferingsCmd.java index 06aad9d4732..60eb438050f 100644 --- a/api/src/org/apache/cloudstack/api/command/user/offering/ListServiceOfferingsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/offering/ListServiceOfferingsCmd.java @@ -25,12 +25,10 @@ import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListCmd; import org.apache.cloudstack.api.Parameter; -import org.apache.cloudstack.api.BaseCmd.CommandType; import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.ServiceOfferingResponse; import org.apache.cloudstack.api.response.UserVmResponse; - import org.apache.log4j.Logger; import com.cloud.exception.InvalidParameterValueException; @@ -65,9 +63,6 @@ public class ListServiceOfferingsCmd extends BaseListCmd { @Parameter(name=ApiConstants.SYSTEM_VM_TYPE, type=CommandType.STRING, description="the system VM type. Possible types are \"consoleproxy\", \"secondarystoragevm\" or \"domainrouter\".") private String systemVmType; - - @Parameter(name = ApiConstants.RESOURCE_TAG, type = CommandType.MAP, description = "List service offerings by resource tags (key/value pairs)", since="4.3") - private Map resourceTag; ///////////////////////////////////////////////////// @@ -97,25 +92,6 @@ public class ListServiceOfferingsCmd extends BaseListCmd { public String getSystemVmType(){ return systemVmType; } - - public Map getResourceTags() { - Map tagsMap = null; - if (resourceTag != null && !resourceTag.isEmpty()) { - tagsMap = new HashMap(); - Collection servicesCollection = resourceTag.values(); - Iterator iter = servicesCollection.iterator(); - while (iter.hasNext()) { - HashMap services = (HashMap) iter.next(); - String key = services.get("key"); - String value = services.get("value"); - if (value == null) { - throw new InvalidParameterValueException("No value is passed in for key " + key); - } - tagsMap.put(key, value); - } - } - return tagsMap; - } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/ssh/CreateSSHKeyPairCmd.java b/api/src/org/apache/cloudstack/api/command/user/ssh/CreateSSHKeyPairCmd.java index 6f1a081da12..e36bd73263b 100644 --- a/api/src/org/apache/cloudstack/api/command/user/ssh/CreateSSHKeyPairCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/ssh/CreateSSHKeyPairCmd.java @@ -20,16 +20,16 @@ import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.response.CreateSSHKeyPairResponse; import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.ProjectResponse; -import org.apache.cloudstack.api.response.SSHKeyPairResponse; import org.apache.cloudstack.context.CallContext; import org.apache.log4j.Logger; import com.cloud.user.SSHKeyPair; -@APICommand(name = "createSSHKeyPair", description="Create a new keypair and returns the private key", responseObject=SSHKeyPairResponse.class) +@APICommand(name = "createSSHKeyPair", description="Create a new keypair and returns the private key", responseObject=CreateSSHKeyPairResponse.class) public class CreateSSHKeyPairCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(CreateSSHKeyPairCmd.class.getName()); private static final String s_name = "createsshkeypairresponse"; @@ -91,7 +91,7 @@ public class CreateSSHKeyPairCmd extends BaseCmd { @Override public void execute() { SSHKeyPair r = _mgr.createSSHKeyPair(this); - SSHKeyPairResponse response = new SSHKeyPairResponse(r.getName(), r.getFingerprint(), r.getPrivateKey()); + CreateSSHKeyPairResponse response = new CreateSSHKeyPairResponse(r.getName(), r.getFingerprint(), r.getPrivateKey()); response.setResponseName(getCommandName()); response.setObjectName("keypair"); this.setResponseObject(response); diff --git a/api/src/org/apache/cloudstack/api/command/user/tag/CreateTagsCmd.java b/api/src/org/apache/cloudstack/api/command/user/tag/CreateTagsCmd.java index a01bac39a4b..84226d7cc99 100644 --- a/api/src/org/apache/cloudstack/api/command/user/tag/CreateTagsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/tag/CreateTagsCmd.java @@ -34,7 +34,7 @@ import org.apache.log4j.Logger; import com.cloud.event.EventTypes; import com.cloud.server.ResourceTag; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; @APICommand(name = "createTags", description = "Creates resource tag(s)", responseObject = SuccessResponse.class, since = "4.0.0") public class CreateTagsCmd extends BaseAsyncCmd{ public static final Logger s_logger = Logger.getLogger(CreateTagsCmd.class.getName()); @@ -64,7 +64,7 @@ public class CreateTagsCmd extends BaseAsyncCmd{ ///////////////////////////////////////////////////// - public TaggedResourceType getResourceType(){ + public ResourceObjectType getResourceType(){ return _taggedResourceService.getResourceType(resourceType); } diff --git a/api/src/org/apache/cloudstack/api/command/user/tag/DeleteTagsCmd.java b/api/src/org/apache/cloudstack/api/command/user/tag/DeleteTagsCmd.java index a6ba0da82b7..5ce2e3795d1 100644 --- a/api/src/org/apache/cloudstack/api/command/user/tag/DeleteTagsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/tag/DeleteTagsCmd.java @@ -33,7 +33,7 @@ import org.apache.cloudstack.api.response.SuccessResponse; import org.apache.log4j.Logger; import com.cloud.event.EventTypes; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; @APICommand(name = "deleteTags", description = "Deleting resource tag(s)", responseObject = SuccessResponse.class, since = "4.0.0") public class DeleteTagsCmd extends BaseAsyncCmd{ public static final Logger s_logger = Logger.getLogger(DeleteTagsCmd.class.getName()); @@ -59,7 +59,7 @@ public class DeleteTagsCmd extends BaseAsyncCmd{ ///////////////////////////////////////////////////// - public TaggedResourceType getResourceType(){ + public ResourceObjectType getResourceType(){ return _taggedResourceService.getResourceType(resourceType); } diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java index 06959c15e75..b3e8d1f83fe 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java @@ -16,6 +16,8 @@ // under the License. package org.apache.cloudstack.api.command.user.vm; +import java.util.List; + import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -25,13 +27,11 @@ import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.cloudstack.context.CallContext; - import org.apache.log4j.Logger; import com.cloud.event.EventTypes; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.user.Account; import com.cloud.uservm.UserVm; @@ -48,7 +48,12 @@ public class DestroyVMCmd extends BaseAsyncCmd { @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class, required=true, description="The ID of the virtual machine") private Long id; - + + + @Parameter(name=ApiConstants.EXPUNGE, type=CommandType.BOOLEAN, + description="If true is passed, the vm is expunged immediately. False by default. Parameter can be passed to the call by ROOT/Domain admin only", since="4.2.1") + private Boolean expunge; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -56,6 +61,13 @@ public class DestroyVMCmd extends BaseAsyncCmd { public Long getId() { return id; } + + public boolean getExpunge() { + if (expunge == null) { + return false; + } + return expunge; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// @@ -97,11 +109,14 @@ public class DestroyVMCmd extends BaseAsyncCmd { @Override public void execute() throws ResourceUnavailableException, ConcurrentOperationException{ CallContext.current().setEventDetails("Vm Id: "+getId()); - UserVm result; - result = _userVmService.destroyVm(this); + UserVm result = _userVmService.destroyVm(this); + UserVmResponse response = new UserVmResponse(); if (result != null) { - UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0); + List responses = _responseGenerator.createUserVmResponse("virtualmachine", result); + if (responses != null && !responses.isEmpty()) { + response = responses.get(0); + } response.setResponseName("virtualmachine"); this.setResponseObject(response); } else { diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/AddResourceDetailCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/AddResourceDetailCmd.java index a3b92478d1e..1384b58b2d0 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/AddResourceDetailCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/AddResourceDetailCmd.java @@ -71,7 +71,7 @@ public class AddResourceDetailCmd extends BaseAsyncCmd { return detailsMap; } - public ResourceTag.TaggedResourceType getResourceType() { + public ResourceTag.ResourceObjectType getResourceType() { return _taggedResourceService.getResourceType(resourceType); } diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/ListResourceDetailsCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/ListResourceDetailsCmd.java index c02d4b4c6ef..4c2856b6a7a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/ListResourceDetailsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/ListResourceDetailsCmd.java @@ -55,7 +55,7 @@ public class ListResourceDetailsCmd extends BaseListProjectAndAccountResourcesCm this.setResponseObject(response); } - public ResourceTag.TaggedResourceType getResourceType() { + public ResourceTag.ResourceObjectType getResourceType() { return _taggedResourceService.getResourceType(resourceType); } diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/RemoveResourceDetailCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/RemoveResourceDetailCmd.java index 8be70f348d0..5f2e131f514 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/RemoveResourceDetailCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/RemoveResourceDetailCmd.java @@ -16,32 +16,21 @@ // under the License. package org.apache.cloudstack.api.command.user.volume; -import com.cloud.server.ResourceTag; - import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.api.BaseAsyncCmd; import org.apache.cloudstack.api.Parameter; -import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.SuccessResponse; -import org.apache.cloudstack.api.response.UserVmResponse; -import org.apache.cloudstack.api.response.VolumeResponse; -import org.apache.cloudstack.context.CallContext; - import org.apache.log4j.Logger; import com.cloud.event.EventTypes; -import com.cloud.storage.Volume; -import com.cloud.user.Account; - -import java.util.*; +import com.cloud.server.ResourceTag; @APICommand(name = "removeResourceDetail", description="Removes detail for the Resource.", responseObject=SuccessResponse.class) public class RemoveResourceDetailCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RemoveResourceDetailCmd.class.getName()); - private static final String s_name = "RemoveResourceDetailresponse"; + private static final String s_name = "removeresourcedetailresponse"; ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -62,7 +51,7 @@ public class RemoveResourceDetailCmd extends BaseAsyncCmd { ///////////////////////////////////////////////////// - public ResourceTag.TaggedResourceType getResourceType(){ + public ResourceTag.ResourceObjectType getResourceType(){ return _taggedResourceService.getResourceType(resourceType); } diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java index b247e0f4528..d4e3a6c1643 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java @@ -114,8 +114,8 @@ public class UpdateVolumeCmd extends BaseAsyncCmd { @Override public String getEventDescription() { - StringBuffer desc = new StringBuffer(); - desc.append(" with"); + StringBuilder desc = new StringBuilder("Updating volume: "); + desc.append(getId()).append(" with"); if (getPath() != null) { desc.append(" path " + getPath()); } @@ -126,7 +126,7 @@ public class UpdateVolumeCmd extends BaseAsyncCmd { if (getState() != null) { desc.append(", state " + getState()); } - return "Updating volume: " + getId() + desc.toString(); + return desc.toString(); } @Override diff --git a/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java b/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java index 4cf3b58a0a8..2a98cfbe928 100644 --- a/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java @@ -16,21 +16,21 @@ // under the License. package org.apache.cloudstack.api.command.user.zone; -import java.util.ArrayList; -import java.util.List; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListCmd; import org.apache.cloudstack.api.Parameter; -import org.apache.cloudstack.api.BaseCmd.CommandType; import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.ListResponse; -import org.apache.cloudstack.api.response.ServiceOfferingResponse; import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.log4j.Logger; -import com.cloud.dc.DataCenter; +import com.cloud.exception.InvalidParameterValueException; @APICommand(name = "listZones", description="Lists zones", responseObject=ZoneResponse.class) public class ListZonesByCmd extends BaseListCmd { @@ -62,6 +62,9 @@ public class ListZonesByCmd extends BaseListCmd { @Parameter(name=ApiConstants.SHOW_CAPACITIES, type=CommandType.BOOLEAN, description="flag to display the capacity of the zones") private Boolean showCapacities; + + @Parameter(name = ApiConstants.TAGS, type = CommandType.MAP, description = "List zones by resource tags (key/value pairs)", since="4.3") + private Map tags; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -90,6 +93,25 @@ public class ListZonesByCmd extends BaseListCmd { public Boolean getShowCapacities() { return showCapacities; } + + public Map getTags() { + Map tagsMap = null; + if (tags != null && !tags.isEmpty()) { + tagsMap = new HashMap(); + Collection servicesCollection = tags.values(); + Iterator iter = servicesCollection.iterator(); + while (iter.hasNext()) { + HashMap services = (HashMap) iter.next(); + String key = services.get("key"); + String value = services.get("value"); + if (value == null) { + throw new InvalidParameterValueException("No value is passed in for key " + key); + } + tagsMap.put(key, value); + } + } + return tagsMap; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// diff --git a/api/src/org/apache/cloudstack/api/response/CreateSSHKeyPairResponse.java b/api/src/org/apache/cloudstack/api/response/CreateSSHKeyPairResponse.java new file mode 100644 index 00000000000..e247fb4dcbc --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/CreateSSHKeyPairResponse.java @@ -0,0 +1,41 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.response; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +public class CreateSSHKeyPairResponse extends SSHKeyPairResponse { + + @SerializedName("privatekey") @Param(description="Private key") + private String privateKey; + + public CreateSSHKeyPairResponse() {} + + public CreateSSHKeyPairResponse(String name, String fingerprint, String privateKey) { + super(name, fingerprint); + this.privateKey = privateKey; + } + + public String getPrivateKey() { + return privateKey; + } + + public void setPrivateKey(String privateKey) { + this.privateKey = privateKey; + } +} diff --git a/api/src/org/apache/cloudstack/api/response/SSHKeyPairResponse.java b/api/src/org/apache/cloudstack/api/response/SSHKeyPairResponse.java index 2791853d4a2..e102bab0394 100644 --- a/api/src/org/apache/cloudstack/api/response/SSHKeyPairResponse.java +++ b/api/src/org/apache/cloudstack/api/response/SSHKeyPairResponse.java @@ -30,19 +30,11 @@ public class SSHKeyPairResponse extends BaseResponse { @SerializedName("fingerprint") @Param(description="Fingerprint of the public key") private String fingerprint; - @SerializedName("privatekey") @Param(description="Private key") - private String privateKey; - public SSHKeyPairResponse() {} public SSHKeyPairResponse(String name, String fingerprint) { - this(name, fingerprint, null); - } - - public SSHKeyPairResponse(String name, String fingerprint, String privateKey) { this.name = name; this.fingerprint = fingerprint; - this.privateKey = privateKey; } public String getName() { @@ -61,12 +53,4 @@ public class SSHKeyPairResponse extends BaseResponse { this.fingerprint = fingerprint; } - public String getPrivateKey() { - return privateKey; - } - - public void setPrivateKey(String privateKey) { - this.privateKey = privateKey; - } - } diff --git a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java index d6838402b3c..e305ee95e70 100644 --- a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java @@ -17,9 +17,7 @@ package org.apache.cloudstack.api.response; import java.util.Date; -import java.util.LinkedHashSet; import java.util.Map; -import java.util.Set; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; @@ -107,13 +105,8 @@ public class ServiceOfferingResponse extends BaseResponse { @Param(description = "additional key/value details tied with this service offering", since = "4.2.0") private Map details; - @SerializedName(ApiConstants.RESOURCE_TAG) @Param(description="the list of resource tags associated with service offering." + - " The resource tags are not used for Volume/VM placement on the specific host.", - responseObject = ResourceTagResponse.class, since="4.3") - private Set resourceTags; public ServiceOfferingResponse(){ - resourceTags = new LinkedHashSet(); } public String getId() { @@ -295,7 +288,4 @@ public class ServiceOfferingResponse extends BaseResponse { this.details = details; } - public void addTag(ResourceTagResponse tag){ - this.resourceTags.add(tag); - } } diff --git a/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java b/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java index e9cb109bf31..7c2b4a99770 100644 --- a/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java +++ b/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java @@ -26,18 +26,8 @@ import org.apache.cloudstack.api.EntityReference; import com.cloud.serializer.Param; import com.cloud.storage.Snapshot; import com.google.gson.annotations.SerializedName; -import com.cloud.serializer.Param; -import com.cloud.storage.Snapshot; -import com.google.gson.annotations.SerializedName; -import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.api.BaseResponse; -import org.apache.cloudstack.api.EntityReference; - -import java.util.Date; -import java.util.List; @EntityReference(value=Snapshot.class) -@SuppressWarnings("unused") public class SnapshotResponse extends BaseResponse implements ControlledEntityResponse { @SerializedName(ApiConstants.ID) @Param(description = "ID of the snapshot") @@ -100,6 +90,9 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with snapshot", responseObject = ResourceTagResponse.class) private List tags; + @SerializedName(ApiConstants.REVERTABLE) + @Param(description="indicates whether the underlying storage supports reverting the volume to this snapshot") + private boolean revertable; @Override public String getObjectId() { @@ -118,6 +111,7 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe return accountName; } + @Override public void setAccountName(String accountName) { this.accountName = accountName; } @@ -131,6 +125,7 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe this.domainId = domainId; } + @Override public void setDomainName(String domainName) { this.domainName = domainName; } @@ -180,8 +175,16 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe public void setZoneId(String zoneId) { this.zoneId = zoneId; } - + public void setTags(List tags) { this.tags = tags; } + + public boolean isRevertable() { + return revertable; + } + + public void setRevertable(boolean revertable) { + this.revertable = revertable; + } } diff --git a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java index d9bb2a976ee..9a7f91c70f6 100644 --- a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java +++ b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java @@ -18,6 +18,7 @@ package org.apache.cloudstack.api.response; import java.util.Date; import java.util.LinkedHashSet; +import java.util.Map; import java.util.Set; import org.apache.cloudstack.affinity.AffinityGroupResponse; @@ -177,6 +178,9 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with vm", responseObject = ResourceTagResponse.class) private Set tags; + + @SerializedName(ApiConstants.DETAILS) @Param(description="Template details in key/value pairs.", since="4.2.1") + private Map details; @SerializedName(ApiConstants.SSH_KEYPAIR) @Param(description="ssh key-pair") private String keyPairName; @@ -653,5 +657,8 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp public void setServiceState(String state) { this.serviceState = state; } - + + public void setDetails(Map details) { + this.details = details; + } } diff --git a/api/src/org/apache/cloudstack/api/response/ZoneResponse.java b/api/src/org/apache/cloudstack/api/response/ZoneResponse.java index 2ebb15a1ecf..85f9ecfe474 100644 --- a/api/src/org/apache/cloudstack/api/response/ZoneResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ZoneResponse.java @@ -16,7 +16,9 @@ // under the License. package org.apache.cloudstack.api.response; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; @@ -98,6 +100,15 @@ public class ZoneResponse extends BaseResponse { @SerializedName(ApiConstants.LOCAL_STORAGE_ENABLED) @Param(description="true if local storage offering enabled, false otherwise") private boolean localStorageEnabled; + + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with zone.", + responseObject = ResourceTagResponse.class, since="4.3") + private Set tags; + + + public ZoneResponse(){ + tags = new LinkedHashSet(); + } public void setId(String id) { this.id = id; @@ -198,4 +209,8 @@ public class ZoneResponse extends BaseResponse { public void setIp6Dns2(String ip6Dns2) { this.ip6Dns2 = ip6Dns2; } + + public void addTag(ResourceTagResponse tag){ + this.tags.add(tag); + } } diff --git a/api/src/org/apache/cloudstack/context/CallContext.java b/api/src/org/apache/cloudstack/context/CallContext.java index a9867d3bb70..5439aee7062 100644 --- a/api/src/org/apache/cloudstack/context/CallContext.java +++ b/api/src/org/apache/cloudstack/context/CallContext.java @@ -50,14 +50,16 @@ public class CallContext { private String contextId; private Account account; + private long accountId; private long startEventId = 0; private String eventDescription; private String eventDetails; private String eventType; private User user; + private long userId; private final Map context = new HashMap(); - private static EntityManager s_entityMgr; + static EntityManager s_entityMgr; public static void init(EntityManager entityMgr) { s_entityMgr = entityMgr; @@ -66,9 +68,17 @@ public class CallContext { protected CallContext() { } + protected CallContext(long userId, long accountId, String contextId) { + this.userId = userId; + this.accountId = accountId; + this.contextId = contextId; + } + protected CallContext(User user, Account account, String contextId) { this.user = user; + this.userId = user.getId(); this.account = account; + this.accountId = account.getId(); this.contextId = contextId; } @@ -81,10 +91,13 @@ public class CallContext { } public long getCallingUserId() { - return user.getId(); + return userId; } public User getCallingUser() { + if (user == null) { + user = s_entityMgr.findById(User.class, userId); + } return user; } @@ -93,6 +106,9 @@ public class CallContext { } public Account getCallingAccount() { + if (account == null) { + account = s_entityMgr.findById(Account.class, accountId); + } return account; } @@ -110,6 +126,10 @@ public class CallContext { * @return CallContext */ public static CallContext register(User callingUser, Account callingAccount, String contextId) { + return register(callingUser, callingAccount, null, null, contextId); + } + + protected static CallContext register(User callingUser, Account callingAccount, Long userId, Long accountId, String contextId) { /* Unit tests will have multiple times of setup/tear-down call to this, remove assertions to all unit test to run @@ -118,7 +138,12 @@ public class CallContext { throw new CloudRuntimeException("There's a context already so what does this new register context mean? " + s_currentContext.get().toString()); } */ - CallContext callingContext = new CallContext(callingUser, callingAccount, contextId); + CallContext callingContext = null; + if (userId == null || accountId == null) { + callingContext = new CallContext(callingUser, callingAccount, contextId); + } else { + callingContext = new CallContext(userId, accountId, contextId); + } s_currentContext.set(callingContext); NDC.push("ctx-" + UuidUtils.first(contextId)); if (s_logger.isTraceEnabled()) { @@ -138,14 +163,13 @@ public class CallContext { try { CallContext context = s_currentContext.get(); if (context == null) { - return register(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM); + return register(null, null, User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, UUID.randomUUID().toString()); } assert context.getCallingUserId() == User.UID_SYSTEM : "You are calling a very specific method that registers a one time system context. This method is meant for background threads that does processing."; return context; } catch (Exception e) { - s_logger.fatal("Exiting the system because we're unable to register the system call context.", e); - System.exit(1); - throw new CloudRuntimeException("Should never hit this"); + s_logger.error("Failed to register the system call context.", e); + throw new CloudRuntimeException("Failed to register system call context", e); } } @@ -220,15 +244,15 @@ public class CallContext { } public long getCallingAccountId() { - return account.getId(); + return accountId; } public String getCallingAccountUuid() { - return account.getUuid(); + return getCallingAccount().getUuid(); } public String getCallingUserUuid() { - return user.getUuid(); + return getCallingUser().getUuid(); } public void setEventDetails(String eventDetails) { @@ -265,8 +289,8 @@ public class CallContext { @Override public String toString() { - return new StringBuffer("CCtxt[acct=").append(account.getId()) - .append("; user=").append(user.getId()) + return new StringBuilder("CCtxt[acct=").append(getCallingAccountId()) + .append("; user=").append(getCallingUserId()) .append("; id=").append(contextId) .append("]").toString(); } diff --git a/awsapi/src/com/cloud/bridge/persist/dao/BucketPolicyDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/BucketPolicyDaoImpl.java index dd354a39ffb..00486cbaceb 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/BucketPolicyDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/BucketPolicyDaoImpl.java @@ -26,7 +26,7 @@ import com.cloud.bridge.model.BucketPolicyVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={BucketPolicyDao.class}) @@ -42,7 +42,7 @@ public class BucketPolicyDaoImpl extends GenericDaoBase im public BucketPolicyVO getByName( String bucketName ) { SearchBuilder searchByBucket = createSearchBuilder(); searchByBucket.and("BucketName", searchByBucket.entity().getBucketName(), SearchCriteria.Op.EQ); - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); try { txn.start(); SearchCriteria sc = searchByBucket.create(); @@ -59,7 +59,7 @@ public class BucketPolicyDaoImpl extends GenericDaoBase im public void deletePolicy( String bucketName ) { SearchBuilder deleteByBucket = createSearchBuilder(); deleteByBucket.and("BucketName", deleteByBucket.entity().getBucketName(), SearchCriteria.Op.EQ); - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); try { txn.start(); SearchCriteria sc = deleteByBucket.create(); diff --git a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackAccountDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackAccountDaoImpl.java index 8fbc7c8e3af..75a693e4955 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackAccountDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackAccountDaoImpl.java @@ -25,6 +25,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={CloudStackAccountDao.class}) @@ -34,7 +35,7 @@ public class CloudStackAccountDaoImpl extends GenericDaoBase SearchByUUID = createSearchBuilder(); - Transaction txn = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); try { txn.start(); SearchByUUID.and("uuid", SearchByUUID.entity().getUuid(), diff --git a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDaoImpl.java index bc77ea1d886..644dcdcef37 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDaoImpl.java @@ -27,6 +27,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={CloudStackConfigurationDao.class}) @@ -42,7 +43,7 @@ public class CloudStackConfigurationDaoImpl extends GenericDaoBase sc = NameSearch.create(); diff --git a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackSvcOfferingDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackSvcOfferingDaoImpl.java index 8021eb618e9..cb8d129f528 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackSvcOfferingDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackSvcOfferingDaoImpl.java @@ -29,6 +29,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={CloudStackSvcOfferingDao.class}) @@ -42,7 +43,7 @@ public class CloudStackSvcOfferingDaoImpl extends GenericDaoBase searchByName = createSearchBuilder(); searchByName.and("name", searchByName.entity().getName(), SearchCriteria.Op.EQ); searchByName.done(); - Transaction txn = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); try { txn.start(); SearchCriteria sc = searchByName.create(); @@ -61,7 +62,7 @@ public class CloudStackSvcOfferingDaoImpl extends GenericDaoBase searchByID = createSearchBuilder(); searchByID.and("uuid", searchByID.entity().getUuid(), SearchCriteria.Op.EQ); searchByID.done(); - Transaction txn = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); try { txn.start(); SearchCriteria sc = searchByID.create(); diff --git a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackUserDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackUserDaoImpl.java index f7e1da65dc6..7fe1dabee4d 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackUserDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackUserDaoImpl.java @@ -26,6 +26,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.crypt.DBEncryptionUtil; @Component @@ -43,7 +44,7 @@ public class CloudStackUserDaoImpl extends GenericDaoBase searchByAccessKey = createSearchBuilder(); searchByAccessKey.and("apiKey", searchByAccessKey.entity().getApiKey(), SearchCriteria.Op.EQ); searchByAccessKey.done(); - Transaction txn = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); try { txn.start(); SearchCriteria sc = searchByAccessKey.create(); diff --git a/awsapi/src/com/cloud/bridge/persist/dao/MHostDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/MHostDaoImpl.java index 222325498b9..b52fcaf221b 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/MHostDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/MHostDaoImpl.java @@ -25,6 +25,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={MHostDao.class}) @@ -38,7 +39,7 @@ public class MHostDaoImpl extends GenericDaoBase implements MHost @Override public MHostVO getByHostKey(String hostKey) { NameSearch.and("MHostKey", NameSearch.entity().getHostKey(), SearchCriteria.Op.EQ); - Transaction txn = Transaction.open("cloudbridge", Transaction.AWSAPI_DB, true); + TransactionLegacy txn = TransactionLegacy.open("cloudbridge", TransactionLegacy.AWSAPI_DB, true); try { txn.start(); SearchCriteria sc = NameSearch.create(); @@ -52,7 +53,7 @@ public class MHostDaoImpl extends GenericDaoBase implements MHost @Override public void updateHeartBeat(MHostVO mhost) { - Transaction txn = Transaction.open("cloudbridge", Transaction.AWSAPI_DB, true); + TransactionLegacy txn = TransactionLegacy.open("cloudbridge", TransactionLegacy.AWSAPI_DB, true); try { txn.start(); update(mhost.getId(), mhost); diff --git a/awsapi/src/com/cloud/bridge/persist/dao/MHostMountDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/MHostMountDaoImpl.java index 8b99f487911..8a7153a9b85 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/MHostMountDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/MHostMountDaoImpl.java @@ -25,6 +25,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={MHostMountDao.class}) @@ -37,7 +38,7 @@ public class MHostMountDaoImpl extends GenericDaoBase implem public MHostMountVO getHostMount(long mHostId, long sHostId) { SearchByMHostID.and("MHostID", SearchByMHostID.entity().getmHostID(), SearchCriteria.Op.EQ); SearchByMHostID.and("SHostID", SearchByMHostID.entity().getsHostID(), SearchCriteria.Op.EQ); - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); try { txn.start(); SearchCriteria sc = SearchByMHostID.create(); diff --git a/awsapi/src/com/cloud/bridge/persist/dao/MultiPartPartsDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/MultiPartPartsDaoImpl.java index 6f314951697..f1472e675aa 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/MultiPartPartsDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/MultiPartPartsDaoImpl.java @@ -28,6 +28,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={MultiPartPartsDao.class}) @@ -42,7 +43,7 @@ public class MultiPartPartsDaoImpl extends GenericDaoBase sc = ByUploadID.create(); @@ -61,7 +62,7 @@ public class MultiPartPartsDaoImpl extends GenericDaoBase byUploadID = createSearchBuilder(); byUploadID.and("UploadID", byUploadID.entity().getUploadid(), SearchCriteria.Op.EQ); byUploadID.and("partNumber", byUploadID.entity().getPartNumber(), SearchCriteria.Op.GT); - Transaction txn = Transaction.currentTxn(); // Transaction.open("cloudbridge", Transaction.AWSAPI_DB, true); + TransactionLegacy txn = TransactionLegacy.currentTxn(); // Transaction.open("cloudbridge", Transaction.AWSAPI_DB, true); try { txn.start(); SearchCriteria sc = byUploadID.create(); @@ -82,7 +83,7 @@ public class MultiPartPartsDaoImpl extends GenericDaoBase byUploadID = createSearchBuilder(); byUploadID.and("UploadID", byUploadID.entity().getUploadid(), SearchCriteria.Op.EQ); byUploadID.and("partNumber", byUploadID.entity().getPartNumber(), SearchCriteria.Op.EQ); - Transaction txn = Transaction.currentTxn(); // Transaction.open("cloudbridge", Transaction.AWSAPI_DB, true); + TransactionLegacy txn = TransactionLegacy.currentTxn(); // Transaction.open("cloudbridge", Transaction.AWSAPI_DB, true); try { txn.start(); SearchCriteria sc = byUploadID.create(); @@ -102,7 +103,7 @@ public class MultiPartPartsDaoImpl extends GenericDaoBase byUploadID = createSearchBuilder(); byUploadID.and("UploadID", byUploadID.entity().getUploadid(), SearchCriteria.Op.EQ); byUploadID.and("partNumber", byUploadID.entity().getPartNumber(), SearchCriteria.Op.EQ); - Transaction txn = Transaction.currentTxn(); // Transaction.open("cloudbridge", Transaction.AWSAPI_DB, true); + TransactionLegacy txn = TransactionLegacy.currentTxn(); // Transaction.open("cloudbridge", Transaction.AWSAPI_DB, true); try { txn.start(); SearchCriteria sc = byUploadID.create(); diff --git a/awsapi/src/com/cloud/bridge/persist/dao/MultiPartUploadsDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/MultiPartUploadsDaoImpl.java index 0f76e80a952..41133a06e92 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/MultiPartUploadsDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/MultiPartUploadsDaoImpl.java @@ -33,6 +33,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={MultiPartUploadsDao.class}) @@ -42,9 +43,9 @@ public class MultiPartUploadsDaoImpl extends GenericDaoBase multipartExits( int uploadId ) { MultiPartUploadsVO uploadvo = null; - Transaction txn = null; + TransactionLegacy txn = null; try { - txn = Transaction.open(Transaction.AWSAPI_DB); + txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); uploadvo = findById(new Long(uploadId)); if (null != uploadvo) return new OrderedPair(uploadvo.getAccessKey(), uploadvo.getNameKey()); @@ -58,9 +59,9 @@ public class MultiPartUploadsDaoImpl extends GenericDaoBase sc = byBucket.create(); diff --git a/awsapi/src/com/cloud/bridge/persist/dao/MultipartLoadDao.java b/awsapi/src/com/cloud/bridge/persist/dao/MultipartLoadDao.java index c1a69dc5e47..4e6ff3d1b25 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/MultipartLoadDao.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/MultipartLoadDao.java @@ -34,6 +34,7 @@ import com.cloud.bridge.service.core.s3.S3MultipartPart; import com.cloud.bridge.service.core.s3.S3MultipartUpload; import com.cloud.bridge.util.OrderedPair; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; public class MultipartLoadDao { public static final Logger logger = Logger.getLogger(MultipartLoadDao.class); @@ -94,9 +95,9 @@ public class MultipartLoadDao { */ public int initiateUpload( String accessKey, String bucketName, String key, String cannedAccess, S3MetaDataEntry[] meta ) { int uploadId = -1; - Transaction txn = null; + TransactionLegacy txn = null; try { - txn = Transaction.open(Transaction.AWSAPI_DB); + txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); Date tod = new Date(); MultiPartUploadsVO uploadVO = new MultiPartUploadsVO(accessKey, bucketName, key, cannedAccess, tod); @@ -315,9 +316,9 @@ public class MultipartLoadDao { private void saveMultipartMeta( int uploadId, S3MetaDataEntry[] meta ) { if (null == meta) return; - Transaction txn = null; + TransactionLegacy txn = null; try { - txn = Transaction.open(Transaction.AWSAPI_DB); + txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); for( int i=0; i < meta.length; i++ ) { S3MetaDataEntry entry = meta[i]; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/MultipartMetaDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/MultipartMetaDaoImpl.java index 7ab93599d22..fec0a2c1280 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/MultipartMetaDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/MultipartMetaDaoImpl.java @@ -27,6 +27,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={MultipartMetaDao.class}) @@ -37,7 +38,7 @@ public class MultipartMetaDaoImpl extends GenericDaoBase SearchBuilder searchByUID = createSearchBuilder(); searchByUID.and("UploadID", searchByUID.entity().getUploadID(), SearchCriteria.Op.EQ); searchByUID.done(); - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); try { txn.start(); SearchCriteria sc = searchByUID.create(); diff --git a/awsapi/src/com/cloud/bridge/persist/dao/OfferingDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/OfferingDaoImpl.java index ea7d264f80c..963f1084134 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/OfferingDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/OfferingDaoImpl.java @@ -29,6 +29,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={OfferingDao.class}) @@ -39,7 +40,7 @@ public class OfferingDaoImpl extends GenericDaoBase impl @Override public int getOfferingCount() { - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); try { txn.start(); return listAll().size(); @@ -56,7 +57,7 @@ public class OfferingDaoImpl extends GenericDaoBase impl SearchBuilder searchByAmazon = createSearchBuilder(); searchByAmazon.and("AmazonEC2Offering", searchByAmazon.entity().getAmazonOffering() , SearchCriteria.Op.EQ); searchByAmazon.done(); - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); try { txn.start(); SearchCriteria sc = searchByAmazon.create(); @@ -74,7 +75,7 @@ public class OfferingDaoImpl extends GenericDaoBase impl SearchBuilder searchByAmazon = createSearchBuilder(); searchByAmazon.and("CloudStackOffering", searchByAmazon.entity().getAmazonOffering() , SearchCriteria.Op.EQ); searchByAmazon.done(); - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); try { txn.start(); SearchCriteria sc = searchByAmazon.create(); @@ -93,7 +94,7 @@ public class OfferingDaoImpl extends GenericDaoBase impl searchByAmazon.and("CloudStackOffering", searchByAmazon.entity().getAmazonOffering() , SearchCriteria.Op.EQ); searchByAmazon.and("AmazonEC2Offering", searchByAmazon.entity().getCloudstackOffering() , SearchCriteria.Op.EQ); searchByAmazon.done(); - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); OfferingBundleVO offering = null; try { txn.start(); @@ -122,7 +123,7 @@ public class OfferingDaoImpl extends GenericDaoBase impl SearchBuilder searchByAmazon = createSearchBuilder(); searchByAmazon.and("AmazonEC2Offering", searchByAmazon.entity().getAmazonOffering() , SearchCriteria.Op.EQ); searchByAmazon.done(); - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); try { txn.start(); SearchCriteria sc = searchByAmazon.create(); diff --git a/awsapi/src/com/cloud/bridge/persist/dao/SAclDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/SAclDaoImpl.java index d88660e05c9..d4b4c90fedc 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/SAclDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/SAclDaoImpl.java @@ -32,6 +32,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={SAclDao.class}) @@ -46,7 +47,7 @@ public class SAclDaoImpl extends GenericDaoBase implements SAclDao SearchByTarget.and("TargetID", SearchByTarget.entity().getTargetId(), SearchCriteria.Op.EQ); SearchByTarget.done(); Filter filter = new Filter(SAclVO.class, "grantOrder", Boolean.TRUE, null, null); - Transaction txn = Transaction.open( Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open( TransactionLegacy.AWSAPI_DB); try { txn.start(); SearchCriteria sc = SearchByTarget.create(); @@ -66,7 +67,7 @@ public class SAclDaoImpl extends GenericDaoBase implements SAclDao SearchByAcl.and("TargetID", SearchByAcl.entity().getTargetId(), SearchCriteria.Op.EQ); SearchByAcl.and("GranteeCanonicalID", SearchByAcl.entity().getGranteeCanonicalId(), SearchCriteria.Op.EQ); Filter filter = new Filter(SAclVO.class, "grantOrder", Boolean.TRUE, null, null); - Transaction txn = Transaction.open( Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open( TransactionLegacy.AWSAPI_DB); try { txn.start(); SearchCriteria sc = SearchByAcl.create(); @@ -85,7 +86,7 @@ public class SAclDaoImpl extends GenericDaoBase implements SAclDao SearchByTarget.and("Target", SearchByTarget.entity().getTarget(), SearchCriteria.Op.EQ); SearchByTarget.and("TargetID", SearchByTarget.entity().getTargetId(), SearchCriteria.Op.EQ); - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); try { txn.start(); SearchCriteria sc = SearchByTarget.create(); diff --git a/awsapi/src/com/cloud/bridge/persist/dao/SBucketDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/SBucketDaoImpl.java index 817c682a946..552281d8b85 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/SBucketDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/SBucketDaoImpl.java @@ -29,6 +29,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={SBucketDao.class}) @@ -42,7 +43,7 @@ public class SBucketDaoImpl extends GenericDaoBase implements S SearchBuilder SearchByName = createSearchBuilder(); SearchByName.and("Name", SearchByName.entity().getName(), SearchCriteria.Op.EQ); //Transaction txn = Transaction.open(Transaction.AWSAPI_DB); - Transaction txn = Transaction.open("cloudbridge", Transaction.AWSAPI_DB, true); + TransactionLegacy txn = TransactionLegacy.open("cloudbridge", TransactionLegacy.AWSAPI_DB, true); try { txn.start(); SearchCriteria sc = SearchByName.create(); @@ -59,7 +60,7 @@ public class SBucketDaoImpl extends GenericDaoBase implements S SearchBuilder ByCanonicalID = createSearchBuilder(); ByCanonicalID.and("OwnerCanonicalID", ByCanonicalID.entity().getOwnerCanonicalId(), SearchCriteria.Op.EQ); Filter filter = new Filter(SBucketVO.class, "createTime", Boolean.TRUE, null, null); - Transaction txn = Transaction.currentTxn(); // Transaction.open("cloudbridge", Transaction.AWSAPI_DB, true); + TransactionLegacy txn = TransactionLegacy.currentTxn(); // Transaction.open("cloudbridge", Transaction.AWSAPI_DB, true); try { txn.start(); SearchCriteria sc = ByCanonicalID.create(); diff --git a/awsapi/src/com/cloud/bridge/persist/dao/SHostDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/SHostDaoImpl.java index 9b6b5359759..5d2e9b901b3 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/SHostDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/SHostDaoImpl.java @@ -25,6 +25,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={SHostDao.class}) @@ -36,7 +37,7 @@ public class SHostDaoImpl extends GenericDaoBase implements SHost SearchBuilder HostSearch = createSearchBuilder(); HostSearch.and("Host", HostSearch.entity().getHost(), SearchCriteria.Op.EQ); HostSearch.done(); - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); try { txn.start(); SearchCriteria sc = HostSearch.create(); @@ -55,7 +56,7 @@ public class SHostDaoImpl extends GenericDaoBase implements SHost LocalStorageHostSearch.and("MHostID", LocalStorageHostSearch.entity().getMhostid(), SearchCriteria.Op.EQ); LocalStorageHostSearch.and("ExportRoot", LocalStorageHostSearch.entity().getExportRoot(), SearchCriteria.Op.EQ); LocalStorageHostSearch.done(); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { txn.start(); SearchCriteria sc = LocalStorageHostSearch.create(); diff --git a/awsapi/src/com/cloud/bridge/persist/dao/SMetaDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/SMetaDaoImpl.java index 8fdc9493d82..95355b92689 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/SMetaDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/SMetaDaoImpl.java @@ -28,6 +28,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={SMetaDao.class}) @@ -41,7 +42,7 @@ public class SMetaDaoImpl extends GenericDaoBase implements SMeta SearchByTarget.and("Target", SearchByTarget.entity().getTarget(), SearchCriteria.Op.EQ); SearchByTarget.and("TargetID", SearchByTarget.entity().getTargetId(), SearchCriteria.Op.EQ); SearchByTarget.done(); - Transaction txn = Transaction.open( Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open( TransactionLegacy.AWSAPI_DB); try { txn.start(); SearchCriteria sc = SearchByTarget.create(); @@ -71,7 +72,7 @@ public class SMetaDaoImpl extends GenericDaoBase implements SMeta SearchBuilder SearchByTarget = createSearchBuilder(); SearchByTarget.and("Target", SearchByTarget.entity().getTarget(), SearchCriteria.Op.EQ); SearchByTarget.and("TargetID", SearchByTarget.entity().getTargetId(), SearchCriteria.Op.EQ); - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); try { txn.start(); SearchCriteria sc = SearchByTarget.create(); diff --git a/awsapi/src/com/cloud/bridge/persist/dao/SObjectDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/SObjectDaoImpl.java index 6d23757b8b5..e6370feca1b 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/SObjectDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/SObjectDaoImpl.java @@ -33,6 +33,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={SObjectDao.class}) @@ -47,7 +48,7 @@ public class SObjectDaoImpl extends GenericDaoBase implements S SearchBuilder SearchByName = createSearchBuilder(); SearchByName.and("SBucketID", SearchByName.entity().getBucketID() , SearchCriteria.Op.EQ); SearchByName.and("NameKey", SearchByName.entity().getNameKey() , SearchCriteria.Op.EQ); - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); try { txn.start(); SearchCriteria sc = SearchByName.create(); @@ -76,7 +77,7 @@ public class SObjectDaoImpl extends GenericDaoBase implements S SearchByBucket.and("SBucketID", SearchByBucket.entity().getBucketID(), SearchCriteria.Op.EQ); SearchByBucket.and("DeletionMark", SearchByBucket.entity().getDeletionMark(), SearchCriteria.Op.NULL); - Transaction txn = Transaction.currentTxn(); // Transaction.open("cloudbridge", Transaction.AWSAPI_DB, true); + TransactionLegacy txn = TransactionLegacy.currentTxn(); // Transaction.open("cloudbridge", Transaction.AWSAPI_DB, true); try { txn.start(); SearchCriteria sc = SearchByBucket.create(); @@ -100,7 +101,7 @@ public class SObjectDaoImpl extends GenericDaoBase implements S List objects = new ArrayList(); getAllBuckets.and("SBucketID", getAllBuckets.entity().getBucketID(), SearchCriteria.Op.EQ); - Transaction txn = Transaction.currentTxn(); // Transaction.open("cloudbridge", Transaction.AWSAPI_DB, true); + TransactionLegacy txn = TransactionLegacy.currentTxn(); // Transaction.open("cloudbridge", Transaction.AWSAPI_DB, true); try { txn.start(); SearchCriteria sc = getAllBuckets.create(); diff --git a/awsapi/src/com/cloud/bridge/persist/dao/SObjectItemDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/SObjectItemDaoImpl.java index 57140c49072..294b32d4d4f 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/SObjectItemDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/SObjectItemDaoImpl.java @@ -27,6 +27,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={SObjectItemDao.class}) @@ -39,7 +40,7 @@ public class SObjectItemDaoImpl extends GenericDaoBase impl @Override public SObjectItemVO getByObjectIdNullVersion(long id) { - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); SearchBuilder SearchByID = createSearchBuilder(); SearchByID.and("ID", SearchByID.entity().getId(), SearchCriteria.Op.EQ); @@ -56,7 +57,7 @@ public class SObjectItemDaoImpl extends GenericDaoBase impl @Override public List getItems(long sobjectID) { - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); SearchBuilder SearchBySobjectID = createSearchBuilder(); SearchBySobjectID.and("SObjectID", SearchBySobjectID.entity().getId(), SearchCriteria.Op.EQ); diff --git a/awsapi/src/com/cloud/bridge/persist/dao/UserCredentialsDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/UserCredentialsDaoImpl.java index c45886f794c..b60a717a3ee 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/UserCredentialsDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/UserCredentialsDaoImpl.java @@ -29,6 +29,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={UserCredentialsDao.class}) @@ -41,7 +42,7 @@ public class UserCredentialsDaoImpl extends GenericDaoBase SearchByAccessKey = createSearchBuilder(); - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); try { txn.start(); SearchByAccessKey.and("AccessKey", SearchByAccessKey.entity() @@ -60,7 +61,7 @@ public class UserCredentialsDaoImpl extends GenericDaoBase SearchByCertID = createSearchBuilder(); SearchByCertID.and("CertUniqueId", SearchByCertID.entity().getCertUniqueId(), SearchCriteria.Op.EQ); - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); try { txn.start(); SearchCriteria sc = SearchByCertID.create(); diff --git a/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java b/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java index 50ac26f2901..1ef04a4aebd 100644 --- a/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java +++ b/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java @@ -161,6 +161,7 @@ import com.cloud.bridge.util.ConfigurationHelper; import com.cloud.bridge.util.EC2RestAuth; import com.cloud.stack.models.CloudStackAccount; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component("EC2RestServlet") public class EC2RestServlet extends HttpServlet { @@ -377,7 +378,7 @@ public class EC2RestServlet extends HttpServlet { private void setUserKeys( HttpServletRequest request, HttpServletResponse response ) { String[] accessKey = null; String[] secretKey = null; - Transaction txn = null; + TransactionLegacy txn = null; try { // -> all these parameters are required accessKey = request.getParameterValues( "accesskey" ); @@ -398,7 +399,7 @@ public class EC2RestServlet extends HttpServlet { return; } try { - txn = Transaction.open(Transaction.AWSAPI_DB); + txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); txn.start(); // -> use the keys to see if the account actually exists ServiceProvider.getInstance().getEC2Engine().validateAccount( accessKey[0], secretKey[0] ); @@ -434,7 +435,7 @@ public class EC2RestServlet extends HttpServlet { */ private void setCertificate( HttpServletRequest request, HttpServletResponse response ) throws Exception { - Transaction txn = null; + TransactionLegacy txn = null; try { // [A] Pull the cert and cloud AccessKey from the request String[] certificate = request.getParameterValues( "cert" ); @@ -470,7 +471,7 @@ public class EC2RestServlet extends HttpServlet { // [C] Associate the cert's uniqueId with the Cloud API keys String uniqueId = AuthenticationUtils.X509CertUniqueId( userCert ); logger.debug( "SetCertificate, uniqueId: " + uniqueId ); - txn = Transaction.open(Transaction.AWSAPI_DB); + txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); txn.start(); UserCredentialsVO user = ucDao.getByAccessKey(accessKey[0]); user.setCertUniqueId(uniqueId); @@ -505,7 +506,7 @@ public class EC2RestServlet extends HttpServlet { */ private void deleteCertificate( HttpServletRequest request, HttpServletResponse response ) throws Exception { - Transaction txn = null; + TransactionLegacy txn = null; try { String [] accessKey = request.getParameterValues( "AWSAccessKeyId" ); if ( null == accessKey || 0 == accessKey.length ) { @@ -527,7 +528,7 @@ public class EC2RestServlet extends HttpServlet { /* UserCredentialsDao credentialDao = new UserCredentialsDao(); credentialDao.setCertificateId( accessKey[0], null ); - */ txn = Transaction.open(Transaction.AWSAPI_DB); + */ txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); UserCredentialsVO user = ucDao.getByAccessKey(accessKey[0]); user.setCertUniqueId(null); ucDao.update(user.getId(), user); diff --git a/awsapi/src/com/cloud/bridge/service/S3RestServlet.java b/awsapi/src/com/cloud/bridge/service/S3RestServlet.java index 7e69fd65087..192e1a28e51 100644 --- a/awsapi/src/com/cloud/bridge/service/S3RestServlet.java +++ b/awsapi/src/com/cloud/bridge/service/S3RestServlet.java @@ -67,6 +67,7 @@ import com.cloud.bridge.util.RestAuth; import com.cloud.bridge.util.S3SoapAuth; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; public class S3RestServlet extends HttpServlet { private static final long serialVersionUID = -6168996266762804877L; public static final String ENABLE_S3_API="enable.s3.api"; @@ -139,7 +140,7 @@ public class S3RestServlet extends HttpServlet { */ private void processRequest( HttpServletRequest request, HttpServletResponse response, String method ) { - Transaction txn = Transaction.open("cloudbridge", Transaction.AWSAPI_DB, true); + TransactionLegacy txn = TransactionLegacy.open("cloudbridge", TransactionLegacy.AWSAPI_DB, true); try { logRequest(request); @@ -274,7 +275,7 @@ public class S3RestServlet extends HttpServlet { // -> use the keys to see if the account actually exists //ServiceProvider.getInstance().getEC2Engine().validateAccount( accessKey[0], secretKey[0] ); //UserCredentialsDaoImpl credentialDao = new UserCredentialsDao(); - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); txn.start(); UserCredentialsVO user = new UserCredentialsVO(accessKey[0], secretKey[0]); user = ucDao.persist(user); diff --git a/awsapi/src/com/cloud/bridge/service/controller/s3/S3BucketAction.java b/awsapi/src/com/cloud/bridge/service/controller/s3/S3BucketAction.java index c98de34a698..4d7c41a75b3 100644 --- a/awsapi/src/com/cloud/bridge/service/controller/s3/S3BucketAction.java +++ b/awsapi/src/com/cloud/bridge/service/controller/s3/S3BucketAction.java @@ -94,6 +94,7 @@ import com.cloud.bridge.util.XSerializer; import com.cloud.bridge.util.XSerializerXmlAdapter; import com.cloud.bridge.util.XmlHelper; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; public class S3BucketAction implements ServletAction { @@ -371,7 +372,7 @@ public class S3BucketAction implements ServletAction { response.setStatus(403); return; } - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); // [B] Place the policy into the database over writting an existing policy try { // -> first make sure that the policy is valid by parsing it diff --git a/awsapi/src/com/cloud/bridge/service/controller/s3/ServiceProvider.java b/awsapi/src/com/cloud/bridge/service/controller/s3/ServiceProvider.java index 2623efe1f61..0854741699f 100644 --- a/awsapi/src/com/cloud/bridge/service/controller/s3/ServiceProvider.java +++ b/awsapi/src/com/cloud/bridge/service/controller/s3/ServiceProvider.java @@ -62,6 +62,7 @@ import com.cloud.bridge.util.OrderedPair; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component public class ServiceProvider extends ManagerBase { @@ -90,7 +91,7 @@ public class ServiceProvider extends ManagerBase { protected ServiceProvider() throws IOException { // register service implementation object - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); txn.close(); } @@ -183,7 +184,7 @@ public class ServiceProvider extends ManagerBase { public UserInfo getUserInfo(String accessKey) { UserInfo info = new UserInfo(); - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); try { txn.start(); UserCredentialsVO cloudKeys = ucDao.getByAccessKey( accessKey ); @@ -253,7 +254,7 @@ public class ServiceProvider extends ManagerBase { multipartDir = properties.getProperty("storage.multipartDir"); - Transaction txn1 = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn1 = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); timer.schedule(getHeartbeatTask(), HEARTBEAT_INTERVAL, HEARTBEAT_INTERVAL); txn1.close(); diff --git a/awsapi/src/com/cloud/bridge/service/core/s3/S3Engine.java b/awsapi/src/com/cloud/bridge/service/core/s3/S3Engine.java index 7beb012d4b7..05e87d788db 100644 --- a/awsapi/src/com/cloud/bridge/service/core/s3/S3Engine.java +++ b/awsapi/src/com/cloud/bridge/service/core/s3/S3Engine.java @@ -86,6 +86,7 @@ import com.cloud.bridge.util.StringHelper; import com.cloud.bridge.util.Triple; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; /** * The CRUD control actions to be invoked from S3BucketAction or S3ObjectAction. @@ -195,7 +196,7 @@ public class S3Engine { String cannedAccessPolicy = request.getCannedAccess(); String bucketName = request.getBucketName(); response.setBucketName( bucketName ); - Transaction txn= null; + TransactionLegacy txn= null; verifyBucketName( bucketName, false ); S3PolicyContext context = new S3PolicyContext( PolicyActions.CreateBucket, bucketName ); @@ -205,7 +206,7 @@ public class S3Engine { OrderedPair shost_storagelocation_pair = null; boolean success = false; try { - txn = Transaction.open(Transaction.AWSAPI_DB); + txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); if (bucketDao.getByName(request.getBucketName()) != null) throw new ObjectAlreadyExistsException("Bucket already exists"); @@ -257,10 +258,10 @@ public class S3Engine { String bucketName = request.getBucketName(); SBucketVO sbucket = bucketDao.getByName(bucketName); - Transaction txn = null; + TransactionLegacy txn = null; if ( sbucket != null ) { - txn = Transaction.open(Transaction.AWSAPI_DB); + txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); txn.start(); S3PolicyContext context = new S3PolicyContext( PolicyActions.DeleteBucket, bucketName ); switch( verifyPolicy( context )) @@ -699,7 +700,7 @@ public class S3Engine { if (null != version) httpResp.addHeader("x-amz-version-id", version); httpResp.flushBuffer(); - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); // [C] Re-assemble the object from its uploaded file parts try { // explicit transaction control to avoid holding transaction during @@ -752,11 +753,11 @@ public class S3Engine { S3BucketAdapter bucketAdapter = getStorageHostBucketAdapter(host_storagelocation_pair.getFirst()); String itemFileName = object_objectitem_pair.getSecond().getStoredPath(); InputStream is = null; - Transaction txn = null; + TransactionLegacy txn = null; try { // explicit transaction control to avoid holding transaction during file-copy process - txn = Transaction.open(Transaction.AWSAPI_DB); + txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); txn.start(); is = request.getDataInputStream(); String md5Checksum = bucketAdapter.saveObject(is, host_storagelocation_pair.getSecond(), bucket.getName(), itemFileName); @@ -813,11 +814,11 @@ public class S3Engine { S3BucketAdapter bucketAdapter = getStorageHostBucketAdapter(host_storagelocation_pair.getFirst()); String itemFileName = object_objectitem_pair.getSecond().getStoredPath(); InputStream is = null; - Transaction txn = null; + TransactionLegacy txn = null; try { // explicit transaction control to avoid holding transaction during file-copy process - txn = Transaction.open(Transaction.AWSAPI_DB); + txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); txn.start(); is = request.getInputStream(); @@ -1505,7 +1506,7 @@ public class S3Engine { context.setEvalParam( ConditionKeys.Acl, cannedAccessPolicy); verifyAccess( context, "SBucket", bucket.getId(), SAcl.PERMISSION_WRITE ); // TODO - check this validates plain POSTs - Transaction txn = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); txn.start(); // [B] If versioning is off them we over write a null object item @@ -1554,7 +1555,7 @@ public class S3Engine { } else { - Transaction txn1 = Transaction.open(Transaction.AWSAPI_DB); + TransactionLegacy txn1 = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); txn1.start(); // -> there is no object nor an object item object = new SObjectVO(); diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index 161d9484883..5536b0749ae 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -18,6 +18,7 @@ message.select.compute.offering=Please select a compute offering to associate wi message.select.disk.offering=(Optional) Select an additional disk offering to attach to this instance. label.home=Home label.use.default.language=Use default language +label.root.disk.size=Root disk size label.s3.nfs.server=S3 NFS Server label.s3.nfs.path=S3 NFS Path label.delete.events=Delete events @@ -206,6 +207,8 @@ label.action.enable.user.processing=Enabling User.... label.action.enable.user=Enable User label.action.enable.zone.processing=Enabling Zone.... label.action.enable.zone=Enable Zone +label.action.expunge.instance=Expunge Instance +label.action.expunge.instance.processing=Expunging Instance.... label.action.force.reconnect.processing=Reconnecting.... label.action.force.reconnect=Force Reconnect label.action.generate.keys.processing=Generate Keys.... @@ -566,6 +569,7 @@ label.ESP.lifetime=ESP Lifetime (second) label.ESP.policy=ESP policy label.esx.host=ESX/ESXi Host label.example=Example +label.expunge=Expunge label.external.link=External link label.f5=F5 label.failed=Failed @@ -814,6 +818,7 @@ label.network.domain.text=Network domain label.network.domain=Network Domain label.network.id=Network ID label.network.label.display.for.blank.value=Use default gateway +label.network.limits=Network limits label.network.name=Network Name label.network.offering.display.text=Network Offering Display Text label.network.offering.id=Network Offering ID @@ -1283,6 +1288,7 @@ message.action.enable.nexusVswitch=Please confirm that you want to enable this n message.action.enable.physical.network=Please confirm that you want to enable this physical network. message.action.enable.pod=Please confirm that you want to enable this pod. message.action.enable.zone=Please confirm that you want to enable this zone. +message.action.expunge.instance=Please confirm that you want to expunge this instance. message.action.force.reconnect=Your host has been successfully forced to reconnect. This process can take up to several minutes. message.action.host.enable.maintenance.mode=Enabling maintenance mode will cause a live migration of all running instances on this host to any available host. message.action.instance.reset.password=Please confirm that you want to change the ROOT password for this virtual machine. diff --git a/client/WEB-INF/web.xml b/client/WEB-INF/web.xml index e5c05d3fd20..1af38e14535 100644 --- a/client/WEB-INF/web.xml +++ b/client/WEB-INF/web.xml @@ -29,11 +29,11 @@ - org.springframework.web.context.ContextLoaderListener + org.apache.cloudstack.spring.module.web.CloudStackContextLoaderListener - + contextConfigLocation - classpath:applicationContext.xml, classpath:componentContext.xml + classpath:META-INF/cloudstack/webApplicationContext.xml diff --git a/client/pom.xml b/client/pom.xml index fd1f13a173e..3e08a9a9fb5 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -20,6 +20,16 @@ 4.3.0-SNAPSHOT + + org.apache.cloudstack + cloud-framework-spring-module + ${project.version} + + + org.apache.cloudstack + cloud-framework-spring-lifecycle + ${project.version} + org.apache.cloudstack cloud-plugin-storage-volume-solidfire @@ -467,21 +477,6 @@ - - process-simulator-context - process-resources - - run - - - - test - - - - process-noredist-spring-context process-resources @@ -502,22 +497,6 @@ - - process-quickcloud-spring-context - process-resources - - run - - - - quickcloud - - - - @@ -730,5 +709,20 @@ + + quickcloud + + + quickcloud + + + + + org.apache.cloudstack + cloud-quickcloud + ${project.version} + + + diff --git a/client/resources/META-INF/cloudstack/webApplicationContext.xml b/client/resources/META-INF/cloudstack/webApplicationContext.xml new file mode 100644 index 00000000000..fea2709747b --- /dev/null +++ b/client/resources/META-INF/cloudstack/webApplicationContext.xml @@ -0,0 +1,32 @@ + + + + + + diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in deleted file mode 100644 index 2a3520be9b2..00000000000 --- a/client/tomcatconf/applicationContext.xml.in +++ /dev/null @@ -1,956 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.apache.cloudstack.framework - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 96e841a4c7d..3fe046386df 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -71,6 +71,7 @@ assignVirtualMachine=7 migrateVirtualMachine=1 migrateVirtualMachineWithVolume=1 recoverVirtualMachine=7 +expungeVirtualMachine=1 #### snapshot commands createSnapshot=15 @@ -493,7 +494,7 @@ listVirtualRouterElements=7 #### usage commands generateUsageRecords=1 -listUsageRecords=1 +listUsageRecords=7 listUsageTypes=1 #### traffic monitor commands diff --git a/client/tomcatconf/componentContext.xml.in b/client/tomcatconf/componentContext.xml.in deleted file mode 100644 index df5b002f39b..00000000000 --- a/client/tomcatconf/componentContext.xml.in +++ /dev/null @@ -1,324 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/client/tomcatconf/log4j-cloud.xml.in b/client/tomcatconf/log4j-cloud.xml.in index d439b771f4f..08021f2077b 100755 --- a/client/tomcatconf/log4j-cloud.xml.in +++ b/client/tomcatconf/log4j-cloud.xml.in @@ -152,6 +152,14 @@ under the License. + + + + + + + + diff --git a/client/tomcatconf/nonossComponentContext.xml.in b/client/tomcatconf/nonossComponentContext.xml.in deleted file mode 100644 index 0502bbc8088..00000000000 --- a/client/tomcatconf/nonossComponentContext.xml.in +++ /dev/null @@ -1,421 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/client/tomcatconf/simulatorComponentContext.xml.in b/client/tomcatconf/simulatorComponentContext.xml.in deleted file mode 100644 index bc3599f797c..00000000000 --- a/client/tomcatconf/simulatorComponentContext.xml.in +++ /dev/null @@ -1,284 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.apache.cloudstack.framework - - - - - - - - - - - - - - - - - - - - - diff --git a/client/tomcatconf/tomcat6-nonssl.conf.in b/client/tomcatconf/tomcat6-nonssl.conf.in index 4a9a70f619e..5ce724c73b7 100644 --- a/client/tomcatconf/tomcat6-nonssl.conf.in +++ b/client/tomcatconf/tomcat6-nonssl.conf.in @@ -41,7 +41,7 @@ CATALINA_TMPDIR="@MSENVIRON@/temp" # Use JAVA_OPTS to set java.library.path for libtcnative.so #JAVA_OPTS="-Djava.library.path=/usr/lib64" -JAVA_OPTS="-Djava.awt.headless=true -Dcom.sun.management.jmxremote.port=45219 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Xmx2g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=@MSLOGDIR@ -XX:PermSize=512M -XX:MaxPermSize=800m" +JAVA_OPTS="-Djava.awt.headless=true -Dcom.sun.management.jmxremote=false -Xmx2g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=@MSLOGDIR@ -XX:PermSize=512M -XX:MaxPermSize=800m" # What user should run tomcat TOMCAT_USER="@MSUSER@" diff --git a/client/tomcatconf/tomcat6-ssl.conf.in b/client/tomcatconf/tomcat6-ssl.conf.in index 0d2650871b6..c967a98be98 100644 --- a/client/tomcatconf/tomcat6-ssl.conf.in +++ b/client/tomcatconf/tomcat6-ssl.conf.in @@ -40,7 +40,7 @@ CATALINA_TMPDIR="@MSENVIRON@/temp" # Use JAVA_OPTS to set java.library.path for libtcnative.so #JAVA_OPTS="-Djava.library.path=/usr/lib64" -JAVA_OPTS="-Djava.awt.headless=true -Djavax.net.ssl.trustStore=/etc/cloudstack/management/cloudmanagementserver.keystore -Djavax.net.ssl.trustStorePassword=vmops.com -Dcom.sun.management.jmxremote.port=45219 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Xmx2g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=@MSLOGDIR@ -XX:MaxPermSize=800m -XX:PermSize=512M" +JAVA_OPTS="-Djava.awt.headless=true -Dcom.sun.management.jmxremote=false -Djavax.net.ssl.trustStore=/etc/cloudstack/management/cloudmanagementserver.keystore -Djavax.net.ssl.trustStorePassword=vmops.com -Xmx2g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=@MSLOGDIR@ -XX:MaxPermSize=800m -XX:PermSize=512M" # What user should run tomcat TOMCAT_USER="@MSUSER@" diff --git a/core/resources/META-INF/cloudstack/allocator/module.properties b/core/resources/META-INF/cloudstack/allocator/module.properties new file mode 100644 index 00000000000..7866be06f30 --- /dev/null +++ b/core/resources/META-INF/cloudstack/allocator/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=allocator +parent=core diff --git a/core/resources/META-INF/cloudstack/allocator/spring-core-allocator-context.xml b/core/resources/META-INF/cloudstack/allocator/spring-core-allocator-context.xml new file mode 100644 index 00000000000..65ebc704400 --- /dev/null +++ b/core/resources/META-INF/cloudstack/allocator/spring-core-allocator-context.xml @@ -0,0 +1,32 @@ + + + + + + \ No newline at end of file diff --git a/core/resources/META-INF/cloudstack/allocator/spring-core-lifecycle-allocator-context-inheritable.xml b/core/resources/META-INF/cloudstack/allocator/spring-core-lifecycle-allocator-context-inheritable.xml new file mode 100644 index 00000000000..ad00de8be2c --- /dev/null +++ b/core/resources/META-INF/cloudstack/allocator/spring-core-lifecycle-allocator-context-inheritable.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core/resources/META-INF/cloudstack/api/module.properties b/core/resources/META-INF/cloudstack/api/module.properties new file mode 100644 index 00000000000..cc66a099a6c --- /dev/null +++ b/core/resources/META-INF/cloudstack/api/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=api +parent=core diff --git a/core/resources/META-INF/cloudstack/api/spring-core-lifecycle-api-context-inheritable.xml b/core/resources/META-INF/cloudstack/api/spring-core-lifecycle-api-context-inheritable.xml new file mode 100644 index 00000000000..b0ed228c0da --- /dev/null +++ b/core/resources/META-INF/cloudstack/api/spring-core-lifecycle-api-context-inheritable.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/resources/META-INF/cloudstack/backend/module.properties b/core/resources/META-INF/cloudstack/backend/module.properties new file mode 100644 index 00000000000..ab18ad18837 --- /dev/null +++ b/core/resources/META-INF/cloudstack/backend/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=backend +parent=core diff --git a/core/resources/META-INF/cloudstack/bootstrap/module.properties b/core/resources/META-INF/cloudstack/bootstrap/module.properties new file mode 100644 index 00000000000..716bd002d47 --- /dev/null +++ b/core/resources/META-INF/cloudstack/bootstrap/module.properties @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=bootstrap diff --git a/core/resources/META-INF/cloudstack/bootstrap/spring-bootstrap-context-inheritable.xml b/core/resources/META-INF/cloudstack/bootstrap/spring-bootstrap-context-inheritable.xml new file mode 100644 index 00000000000..adee3ed28e0 --- /dev/null +++ b/core/resources/META-INF/cloudstack/bootstrap/spring-bootstrap-context-inheritable.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + diff --git a/core/resources/META-INF/cloudstack/bootstrap/spring-bootstrap-context.xml b/core/resources/META-INF/cloudstack/bootstrap/spring-bootstrap-context.xml new file mode 100644 index 00000000000..40fcc71c14e --- /dev/null +++ b/core/resources/META-INF/cloudstack/bootstrap/spring-bootstrap-context.xml @@ -0,0 +1,32 @@ + + + + + + diff --git a/core/resources/META-INF/cloudstack/compute/module.properties b/core/resources/META-INF/cloudstack/compute/module.properties new file mode 100644 index 00000000000..0a12aae7c19 --- /dev/null +++ b/core/resources/META-INF/cloudstack/compute/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=compute +parent=backend diff --git a/core/resources/META-INF/cloudstack/compute/spring-core-lifecycle-compute-context-inheritable.xml b/core/resources/META-INF/cloudstack/compute/spring-core-lifecycle-compute-context-inheritable.xml new file mode 100644 index 00000000000..b57f52fc2ef --- /dev/null +++ b/core/resources/META-INF/cloudstack/compute/spring-core-lifecycle-compute-context-inheritable.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + diff --git a/core/resources/META-INF/cloudstack/core/module.properties b/core/resources/META-INF/cloudstack/core/module.properties new file mode 100644 index 00000000000..fd5ecb7bf15 --- /dev/null +++ b/core/resources/META-INF/cloudstack/core/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=core +parent=system diff --git a/core/resources/META-INF/cloudstack/core/spring-core-context.xml b/core/resources/META-INF/cloudstack/core/spring-core-context.xml new file mode 100644 index 00000000000..6cd00a40103 --- /dev/null +++ b/core/resources/META-INF/cloudstack/core/spring-core-context.xml @@ -0,0 +1,36 @@ + + + + + + + + + + diff --git a/core/resources/META-INF/cloudstack/core/spring-core-lifecycle-core-context-inheritable.xml b/core/resources/META-INF/cloudstack/core/spring-core-lifecycle-core-context-inheritable.xml new file mode 100644 index 00000000000..06b9f5e0748 --- /dev/null +++ b/core/resources/META-INF/cloudstack/core/spring-core-lifecycle-core-context-inheritable.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml b/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml new file mode 100644 index 00000000000..1de9a04fc6b --- /dev/null +++ b/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core/resources/META-INF/cloudstack/discoverer/module.properties b/core/resources/META-INF/cloudstack/discoverer/module.properties new file mode 100644 index 00000000000..e511fb5e37d --- /dev/null +++ b/core/resources/META-INF/cloudstack/discoverer/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=discoverer +parent=core diff --git a/core/resources/META-INF/cloudstack/discoverer/spring-core-lifecycle-discoverer-context-inheritable.xml b/core/resources/META-INF/cloudstack/discoverer/spring-core-lifecycle-discoverer-context-inheritable.xml new file mode 100644 index 00000000000..2c83a104b32 --- /dev/null +++ b/core/resources/META-INF/cloudstack/discoverer/spring-core-lifecycle-discoverer-context-inheritable.xml @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/core/resources/META-INF/cloudstack/network/module.properties b/core/resources/META-INF/cloudstack/network/module.properties new file mode 100644 index 00000000000..1a15fb01131 --- /dev/null +++ b/core/resources/META-INF/cloudstack/network/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=network +parent=backend diff --git a/core/resources/META-INF/cloudstack/network/spring-core-lifecycle-network-context-inheritable.xml b/core/resources/META-INF/cloudstack/network/spring-core-lifecycle-network-context-inheritable.xml new file mode 100644 index 00000000000..b2660fc7caf --- /dev/null +++ b/core/resources/META-INF/cloudstack/network/spring-core-lifecycle-network-context-inheritable.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core/resources/META-INF/cloudstack/planner/module.properties b/core/resources/META-INF/cloudstack/planner/module.properties new file mode 100644 index 00000000000..96359fbe6e3 --- /dev/null +++ b/core/resources/META-INF/cloudstack/planner/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=planner +parent=allocator \ No newline at end of file diff --git a/core/resources/META-INF/cloudstack/planner/spring-core-lifecycle-planner-context-inheritable.xml b/core/resources/META-INF/cloudstack/planner/spring-core-lifecycle-planner-context-inheritable.xml new file mode 100644 index 00000000000..715f86d9c28 --- /dev/null +++ b/core/resources/META-INF/cloudstack/planner/spring-core-lifecycle-planner-context-inheritable.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + diff --git a/core/resources/META-INF/cloudstack/storage/module.properties b/core/resources/META-INF/cloudstack/storage/module.properties new file mode 100644 index 00000000000..564e85e116e --- /dev/null +++ b/core/resources/META-INF/cloudstack/storage/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=storage +parent=backend diff --git a/core/resources/META-INF/cloudstack/storage/spring-lifecycle-storage-context-inheritable.xml b/core/resources/META-INF/cloudstack/storage/spring-lifecycle-storage-context-inheritable.xml new file mode 100644 index 00000000000..b6eed7d342b --- /dev/null +++ b/core/resources/META-INF/cloudstack/storage/spring-lifecycle-storage-context-inheritable.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/resources/META-INF/cloudstack/system/module.properties b/core/resources/META-INF/cloudstack/system/module.properties new file mode 100644 index 00000000000..0b07ebeb478 --- /dev/null +++ b/core/resources/META-INF/cloudstack/system/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=system +parent=bootstrap diff --git a/core/resources/META-INF/cloudstack/system/spring-core-system-context-inheritable.xml b/core/resources/META-INF/cloudstack/system/spring-core-system-context-inheritable.xml new file mode 100644 index 00000000000..80c5da744bb --- /dev/null +++ b/core/resources/META-INF/cloudstack/system/spring-core-system-context-inheritable.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/core/resources/META-INF/cloudstack/system/spring-core-system-context.xml b/core/resources/META-INF/cloudstack/system/spring-core-system-context.xml new file mode 100644 index 00000000000..c2d540ca102 --- /dev/null +++ b/core/resources/META-INF/cloudstack/system/spring-core-system-context.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + diff --git a/core/src/com/cloud/agent/api/ClusterSyncAnswer.java b/core/src/com/cloud/agent/api/ClusterSyncAnswer.java index 99fee2a9dd1..e5ea1f15aca 100644 --- a/core/src/com/cloud/agent/api/ClusterSyncAnswer.java +++ b/core/src/com/cloud/agent/api/ClusterSyncAnswer.java @@ -18,12 +18,12 @@ package com.cloud.agent.api; import java.util.HashMap; -import com.cloud.utils.Pair; +import com.cloud.utils.Ternary; import com.cloud.vm.VirtualMachine.State; public class ClusterSyncAnswer extends Answer { private long _clusterId; - private HashMap> _newStates; + private HashMap> _newStates; private boolean _isExecuted=false; // this is here because a cron command answer is being sent twice @@ -38,7 +38,7 @@ public class ClusterSyncAnswer extends Answer { } - public ClusterSyncAnswer(long clusterId, HashMap> newStates){ + public ClusterSyncAnswer(long clusterId, HashMap> newStates){ _clusterId = clusterId; _newStates = newStates; result = true; @@ -48,7 +48,7 @@ public class ClusterSyncAnswer extends Answer { return _clusterId; } - public HashMap> getNewStates() { + public HashMap> getNewStates() { return _newStates; } diff --git a/core/src/com/cloud/agent/api/StartupRoutingCommand.java b/core/src/com/cloud/agent/api/StartupRoutingCommand.java index 5961ab0017e..d52666b7d9d 100755 --- a/core/src/com/cloud/agent/api/StartupRoutingCommand.java +++ b/core/src/com/cloud/agent/api/StartupRoutingCommand.java @@ -22,7 +22,7 @@ import java.util.Map; import com.cloud.host.Host; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Networks.RouterPrivateIpStrategy; -import com.cloud.utils.Pair; +import com.cloud.utils.Ternary; import com.cloud.vm.VirtualMachine.State; public class StartupRoutingCommand extends StartupCommand { @@ -48,7 +48,7 @@ public class StartupRoutingCommand extends StartupCommand { long dom0MinMemory; boolean poolSync; Map vms; - HashMap> _clusterVMStates; + HashMap> _clusterVMStates; String caps; String pool; HypervisorType hypervisorType; @@ -129,7 +129,7 @@ getHostDetails().put(RouterPrivateIpStrategy.class.getCanonicalName(), privIpStr } } - public void setClusterVMStateChanges(HashMap> allStates){ + public void setClusterVMStateChanges(HashMap> allStates){ _clusterVMStates = allStates; } @@ -157,7 +157,7 @@ getHostDetails().put(RouterPrivateIpStrategy.class.getCanonicalName(), privIpStr return vms; } - public HashMap> getClusterVMStateChanges() { + public HashMap> getClusterVMStateChanges() { return _clusterVMStates; } diff --git a/core/src/com/cloud/agent/api/StopAnswer.java b/core/src/com/cloud/agent/api/StopAnswer.java index 0af23853da5..614835e2a37 100755 --- a/core/src/com/cloud/agent/api/StopAnswer.java +++ b/core/src/com/cloud/agent/api/StopAnswer.java @@ -17,37 +17,34 @@ package com.cloud.agent.api; public class StopAnswer extends RebootAnswer { - Integer vncPort; + + private String hypervisortoolsversion; Integer timeOffset; protected StopAnswer() { } - public StopAnswer(StopCommand cmd, String details, Integer vncPort, Integer timeOffset, boolean success) { + public StopAnswer(StopCommand cmd, String details, String hypervisortoolsversion, Integer timeOffset, boolean success) { super(cmd, details, success); - this.vncPort = vncPort; + this.hypervisortoolsversion = hypervisortoolsversion; this.timeOffset = timeOffset; } - public StopAnswer(StopCommand cmd, String details, Integer vncPort, boolean success) { + public StopAnswer(StopCommand cmd, String details, boolean success) { super(cmd, details, success); - this.vncPort = vncPort; + this.hypervisortoolsversion = null; this.timeOffset = null; } - public StopAnswer(StopCommand cmd, String details, boolean success) { - super(cmd, details, success); - vncPort = null; - timeOffset = null; - } public StopAnswer(StopCommand cmd, Exception e) { super(cmd, e); + this.hypervisortoolsversion = null; + this.timeOffset = null; } - @Override - public Integer getVncPort() { - return vncPort; + public String getHypervisorToolsVersion() { + return hypervisortoolsversion; } public Integer getTimeOffset() { diff --git a/core/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java b/core/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java index ee29290b720..3a51e8ad6be 100644 --- a/core/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java +++ b/core/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java @@ -33,6 +33,7 @@ public class LoadBalancerConfigCommand extends NetworkElementCommand { public String lbStatsAuth = "admin1:AdMiN123"; public String lbStatsUri = "/admin?stats"; public String maxconn =""; + public boolean keepAliveEnabled = false; NicTO nic; Long vpcId; @@ -44,7 +45,7 @@ public class LoadBalancerConfigCommand extends NetworkElementCommand { this.vpcId = vpcId; } - public LoadBalancerConfigCommand(LoadBalancerTO[] loadBalancers,String PublicIp,String GuestIp,String PrivateIp, NicTO nic, Long vpcId, String maxconn) { + public LoadBalancerConfigCommand(LoadBalancerTO[] loadBalancers,String PublicIp,String GuestIp,String PrivateIp, NicTO nic, Long vpcId, String maxconn, boolean keepAliveEnabled) { this.loadBalancers = loadBalancers; this.lbStatsPublicIP = PublicIp; this.lbStatsPrivateIP = PrivateIp; @@ -52,6 +53,7 @@ public class LoadBalancerConfigCommand extends NetworkElementCommand { this.nic = nic; this.vpcId = vpcId; this.maxconn=maxconn; + this.keepAliveEnabled = keepAliveEnabled; } public NicTO getNic() { diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index 479640a32b8..f18caaa9266 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -103,7 +103,6 @@ import com.cloud.utils.ssh.SshHelper; @Local(value = {VirtualRoutingResource.class}) public class VirtualRoutingResource implements Manager { private static final Logger s_logger = Logger.getLogger(VirtualRoutingResource.class); - private String _savepasswordPath; // This script saves a random password to the DomR file system private String _publicIpAddress; private String _firewallPath; private String _loadbPath; @@ -548,13 +547,14 @@ public class VirtualRoutingResource implements Manager { final String vmIpAddress = cmd.getVmIpAddress(); final String local = vmName; - // Run save_password_to_domr.sh - final String result = savePassword(routerPrivateIPAddress, vmIpAddress, password, local); + String args = "-v " + vmIpAddress; + args += " -p " + password; + + String result = routerProxy("savepassword.sh", routerPrivateIPAddress, args); if (result != null) { return new Answer(cmd, false, "Unable to save password to DomR."); - } else { - return new Answer(cmd); } + return new Answer(cmd); } protected Answer execute(final DhcpEntryCommand cmd) { @@ -813,16 +813,6 @@ public class VirtualRoutingResource implements Manager { return new ConsoleProxyLoadAnswer(cmd, proxyVmId, proxyVmName, success, result); } - public String savePassword(final String privateIpAddress, final String vmIpAddress, final String password, final String localPath) { - final Script command = new Script(_savepasswordPath, _startTimeout, s_logger); - command.add("-r", privateIpAddress); - command.add("-v", vmIpAddress); - command.add("-p", password); - command.add(localPath); - - return command.execute(); - } - public String assignGuestNetwork(final String dev, final String routerIP, final String routerGIP, final String gateway, final String cidr, final String netmask, final String dns, final String domainName) { @@ -1128,11 +1118,6 @@ public class VirtualRoutingResource implements Manager { throw new ConfigurationException("Unable to find the call_loadbalancer.sh"); } - _savepasswordPath = findScript("save_password_to_domr.sh"); - if (_savepasswordPath == null) { - throw new ConfigurationException("Unable to find save_password_to_domr.sh"); - } - _dhcpEntryPath = findScript("dhcp_entry.sh"); if (_dhcpEntryPath == null) { throw new ConfigurationException("Unable to find dhcp_entry.sh"); diff --git a/core/src/com/cloud/network/HAProxyConfigurator.java b/core/src/com/cloud/network/HAProxyConfigurator.java index 230912595cf..ae49a2e236f 100644 --- a/core/src/com/cloud/network/HAProxyConfigurator.java +++ b/core/src/com/cloud/network/HAProxyConfigurator.java @@ -44,6 +44,7 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { private static String[] globalSection = { "global", "\tlog 127.0.0.1:3914 local0 warning", "\tmaxconn 4096", + "\tmaxpipes 1024", "\tchroot /var/lib/haproxy", "\tuser haproxy", "\tgroup haproxy", @@ -122,7 +123,9 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { sb = new StringBuilder(); // FIXME sb.append("\t").append("balance ").append(algorithm); result.add(sb.toString()); - if (publicPort.equals(NetUtils.HTTP_PORT)) { + if (publicPort.equals(NetUtils.HTTP_PORT) + // && global option httpclose set (or maybe not in this spot???) + ) { sb = new StringBuilder(); sb.append("\t").append("mode http"); result.add(sb.toString()); @@ -434,7 +437,7 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { return sb.toString(); } - private List getRulesForPool(LoadBalancerTO lbTO) { + private List getRulesForPool(LoadBalancerTO lbTO, boolean keepAliveEnabled) { StringBuilder sb = new StringBuilder(); String poolName = sb.append(lbTO.getSrcIp().replace(".", "_")) .append('-').append(lbTO.getSrcPort()).toString(); @@ -498,7 +501,9 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { if ((stickinessSubRule != null) && !destsAvailable) { s_logger.warn("Haproxy stickiness policy for lb rule: " + lbTO.getSrcIp() + ":" + lbTO.getSrcPort() +": Not Applied, cause: backends are unavailable"); } - if ((publicPort.equals(NetUtils.HTTP_PORT)) || (httpbasedStickiness) ) { + if ((publicPort.equals(NetUtils.HTTP_PORT) + && !keepAliveEnabled + ) || (httpbasedStickiness) ) { sb = new StringBuilder(); sb.append("\t").append("mode http"); result.add(sb.toString()); @@ -516,23 +521,58 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { StringBuilder rule = new StringBuilder("\nlisten ").append(ruleName) .append(" ").append(statsIp).append(":") .append(lbCmd.lbStatsPort); + // TODO DH: write test for this in both cases + if(!lbCmd.keepAliveEnabled) { + s_logger.info("Haproxy mode http enabled"); + rule.append("\n\tmode http\n\toption httpclose"); + } rule.append( - "\n\tmode http\n\toption httpclose\n\tstats enable\n\tstats uri ") + "\n\tstats enable\n\tstats uri ") .append(lbCmd.lbStatsUri) .append("\n\tstats realm Haproxy\\ Statistics\n\tstats auth ") .append(lbCmd.lbStatsAuth); rule.append("\n"); - return rule.toString(); + String result = rule.toString(); + if(s_logger.isDebugEnabled()) { + s_logger.debug("Haproxystats rule: " + result); + } + return result; } @Override public String[] generateConfiguration(LoadBalancerConfigCommand lbCmd) { List result = new ArrayList(); List gSection = Arrays.asList(globalSection); +// note that this is overwritten on the String in the static ArrayList gSection.set(2,"\tmaxconn " + lbCmd.maxconn); + // TODO DH: write test for this function + String pipesLine = "\tmaxpipes " + Long.toString(Long.parseLong(lbCmd.maxconn)/4); + gSection.set(3,pipesLine); + if(s_logger.isDebugEnabled()) { + for(String s : gSection) { + s_logger.debug("global section: " + s); + } + } result.addAll(gSection); + // TODO decide under what circumstances these options are needed +// result.add("\tnokqueue"); +// result.add("\tnopoll"); + result.add(blankLine); - result.addAll(Arrays.asList(defaultsSection)); + List dSection = Arrays.asList(defaultsSection); + if(lbCmd.keepAliveEnabled) { + dSection.set(6, "\t#no option set here :<"); + dSection.set(7, "\tno option forceclose"); + } else { + dSection.set(6, "\toption forwardfor"); + dSection.set(7, "\toption forceclose"); + } + if(s_logger.isDebugEnabled()) { + for(String s : dSection) { + s_logger.debug("default section: " + s); + } + } + result.addAll(dSection); if (!lbCmd.lbStatsVisibility.equals("disabled")) { /* new rule : listen admin_page guestip/link-local:8081 */ if (lbCmd.lbStatsVisibility.equals("global")) { @@ -571,7 +611,7 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { if ( lbTO.isRevoked() ) { continue; } - List poolRules = getRulesForPool(lbTO); + List poolRules = getRulesForPool(lbTO, lbCmd.keepAliveEnabled); result.addAll(poolRules); has_listener = true; } diff --git a/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java index 002143f460e..b43722a6418 100644 --- a/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java +++ b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java @@ -34,7 +34,6 @@ import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.DiskTO; -import com.cloud.agent.api.to.NfsTO; import com.cloud.storage.DataStoreRole; import com.cloud.storage.Volume; @@ -68,7 +67,7 @@ public class StorageSubsystemCommandHandlerBase implements StorageSubsystemComma DataStoreTO srcDataStore = srcData.getDataStore(); DataStoreTO destDataStore = destData.getDataStore(); - if ((srcData.getObjectType() == DataObjectType.TEMPLATE) && (destData.getObjectType() == DataObjectType.TEMPLATE && destData.getDataStore().getRole() == DataStoreRole.Primary)) { + if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcData.getDataStore().getRole() == DataStoreRole.Image && destData.getDataStore().getRole() == DataStoreRole.Primary) { //copy template to primary storage return processor.copyTemplateToPrimaryStorage(cmd); } else if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcDataStore.getRole() == DataStoreRole.Primary && destDataStore.getRole() == DataStoreRole.Primary) { @@ -84,7 +83,7 @@ public class StorageSubsystemCommandHandlerBase implements StorageSubsystemComma return processor.createTemplateFromVolume(cmd); } } else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.SNAPSHOT && - destData.getDataStore().getRole() == DataStoreRole.Primary) { + srcData.getDataStore().getRole() == DataStoreRole.Primary) { return processor.backupSnapshot(cmd); } else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.VOLUME) { return processor.createVolumeFromSnapshot(cmd); diff --git a/core/src/com/cloud/storage/template/S3TemplateDownloader.java b/core/src/com/cloud/storage/template/S3TemplateDownloader.java index 462b21b700b..9dacbd31282 100644 --- a/core/src/com/cloud/storage/template/S3TemplateDownloader.java +++ b/core/src/com/cloud/storage/template/S3TemplateDownloader.java @@ -258,7 +258,8 @@ public class S3TemplateDownloader extends ManagedContextRunnable implements Temp }); - if ( s3.isMultipartEnabled()){ + + if ( !s3.getSingleUpload(remoteSize) ){ // use TransferManager to do multipart upload S3Utils.mputObject(s3, putObjectRequest); } else{ diff --git a/core/test/com/cloud/network/HAProxyConfiguratorTest.java b/core/test/com/cloud/network/HAProxyConfiguratorTest.java new file mode 100644 index 00000000000..d854231f985 --- /dev/null +++ b/core/test/com/cloud/network/HAProxyConfiguratorTest.java @@ -0,0 +1,97 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.network; + +import static org.junit.Assert.*; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.Mockito; + +import com.cloud.agent.api.routing.LoadBalancerConfigCommand; +import com.cloud.agent.api.to.LoadBalancerTO; + +/** + * @author dhoogland + * + */ +public class HAProxyConfiguratorTest { + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception { + } + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception { + } + + /** + * Test method for {@link com.cloud.network.HAProxyConfigurator#generateConfiguration(com.cloud.agent.api.routing.LoadBalancerConfigCommand)}. + */ + @Test + public void testGenerateConfigurationLoadBalancerConfigCommand() { + LoadBalancerTO lb = new LoadBalancerTO("1", "10.2.0.1", 80, "http", "bla", false, false, false, null); + LoadBalancerTO[] lba = new LoadBalancerTO[1]; + lba[0] = lb; + HAProxyConfigurator hpg = new HAProxyConfigurator(); + LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lba, "10.0.0.1", "10.1.0.1", "10.1.1.1", null, 1L, "12", false); + String result = genConfig(hpg, cmd); + assertTrue("keepalive disabled should result in 'mode http' in the resulting haproxy config", result.contains("mode http")); + + cmd = new LoadBalancerConfigCommand(lba, "10.0.0.1", "10.1.0.1", "10.1.1.1", null, 1L, "4", true); + result = genConfig(hpg, cmd); + assertTrue("keepalive enabled should not result in 'mode http' in the resulting haproxy config",! result.contains("mode http")); + // TODO + // create lb command + // setup tests for + // maxconn (test for maxpipes as well) + // httpmode + } + + private String genConfig(HAProxyConfigurator hpg, LoadBalancerConfigCommand cmd) { + String [] sa = hpg.generateConfiguration(cmd); + StringBuilder sb = new StringBuilder(); + for(String s: sa) { + sb.append(s).append('\n'); + } + return sb.toString(); + } + +} diff --git a/debian/cloudstack-management.install b/debian/cloudstack-management.install index a1325cdb2b5..f06ab86dda1 100644 --- a/debian/cloudstack-management.install +++ b/debian/cloudstack-management.install @@ -21,8 +21,6 @@ /etc/cloudstack/management/logging.properties /etc/cloudstack/management/commands.properties /etc/cloudstack/management/ehcache.xml -/etc/cloudstack/management/componentContext.xml -/etc/cloudstack/management/applicationContext.xml /etc/cloudstack/management/server-ssl.xml /etc/cloudstack/management/server-nonssl.xml /etc/cloudstack/management/server.xml @@ -33,7 +31,6 @@ /etc/cloudstack/management/tomcat6.conf /etc/cloudstack/management/web.xml /etc/cloudstack/management/environment.properties -/etc/cloudstack/management/nonossComponentContext.xml /etc/cloudstack/management/log4j-cloud.xml /etc/cloudstack/management/tomcat-users.xml /etc/cloudstack/management/context.xml diff --git a/debian/control b/debian/control index b20743da0a9..c756dcd0d8e 100644 --- a/debian/control +++ b/debian/control @@ -22,7 +22,7 @@ Description: CloudStack server library Package: cloudstack-agent Architecture: all -Depends: openjdk-6-jre | openjdk-7-jre, cloudstack-common (= ${source:Version}), lsb-base (>= 3.2), libcommons-daemon-java, openssh-client, libvirt0, sysvinit-utils, qemu-kvm, libvirt-bin, uuid-runtime, rsync, grep, iproute, perl-base, perl-modules, ebtables, vlan, wget, jsvc, ipset, python-libvirt +Depends: openjdk-6-jre | openjdk-7-jre, cloudstack-common (= ${source:Version}), lsb-base (>= 3.2), libcommons-daemon-java, openssh-client, libvirt0, sysvinit-utils, qemu-kvm, libvirt-bin, uuid-runtime, rsync, grep, iproute, perl-base, perl-modules, ebtables, vlan, wget, jsvc, ipset, python-libvirt, ethtool, iptables Conflicts: cloud-agent, cloud-agent-libs, cloud-agent-deps, cloud-agent-scripts Description: CloudStack agent The CloudStack agent is in charge of managing shared computing resources in diff --git a/engine/api/resources/META-INF/cloudstack/core/spring-engine-api-core-context.xml b/engine/api/resources/META-INF/cloudstack/core/spring-engine-api-core-context.xml new file mode 100644 index 00000000000..1cb8829839d --- /dev/null +++ b/engine/api/resources/META-INF/cloudstack/core/spring-engine-api-core-context.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java index 950f9e23758..85fbf73cb3b 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java @@ -26,9 +26,9 @@ import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.host.Host; public interface DataMotionStrategy { - StrategyPriority.Priority canHandle(DataObject srcData, DataObject destData); + StrategyPriority canHandle(DataObject srcData, DataObject destData); - StrategyPriority.Priority canHandle(Map volumeMap, Host srcHost, Host destHost); + StrategyPriority canHandle(Map volumeMap, Host srcHost, Host destHost); Void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java index 8d6b76010fe..a0ef7dd1273 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java @@ -32,4 +32,6 @@ public interface SnapshotInfo extends DataObject, Snapshot { Long getDataCenterId(); ObjectInDataStoreStateMachine.State getStatus(); + + boolean isRevertable(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java index e4cecb6b156..cf30f5912ea 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java @@ -19,6 +19,13 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import com.cloud.storage.Snapshot; public interface SnapshotStrategy { + enum SnapshotOperation { + TAKE, + BACKUP, + DELETE, + REVERT + } + SnapshotInfo takeSnapshot(SnapshotInfo snapshot); SnapshotInfo backupSnapshot(SnapshotInfo snapshot); @@ -27,5 +34,5 @@ public interface SnapshotStrategy { boolean revertSnapshot(Long snapshotId); - StrategyPriority.Priority canHandle(Snapshot snapshot); + StrategyPriority canHandle(Snapshot snapshot, SnapshotOperation op); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageStrategyFactory.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageStrategyFactory.java new file mode 100644 index 00000000000..ac1e311201a --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageStrategyFactory.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.engine.subsystem.api.storage; + +import java.util.Map; + +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy.SnapshotOperation; + +import com.cloud.host.Host; +import com.cloud.storage.Snapshot; + +public interface StorageStrategyFactory { + + DataMotionStrategy getDataMotionStrategy(DataObject srcData, DataObject destData); + + DataMotionStrategy getDataMotionStrategy(Map volumeMap, Host srcHost, Host destHost); + + SnapshotStrategy getSnapshotStrategy(Snapshot snapshot, SnapshotOperation op); + +} diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriority.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriority.java index 81034b1663f..12f2a6a4970 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriority.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriority.java @@ -16,84 +16,10 @@ // under the License. package org.apache.cloudstack.engine.subsystem.api.storage; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Map; - -import com.cloud.host.Host; -import com.cloud.storage.Snapshot; - -public class StrategyPriority { - public enum Priority { - CANT_HANDLE, - DEFAULT, - HYPERVISOR, - PLUGIN, - HIGHEST - } - - public static void sortStrategies(List strategies, Snapshot snapshot) { - Collections.sort(strategies, new SnapshotStrategyComparator(snapshot)); - } - - public static void sortStrategies(List strategies, DataObject srcData, DataObject destData) { - Collections.sort(strategies, new DataMotionStrategyComparator(srcData, destData)); - } - - public static void sortStrategies(List strategies, Map volumeMap, Host srcHost, Host destHost) { - Collections.sort(strategies, new DataMotionStrategyHostComparator(volumeMap, srcHost, destHost)); - } - - static class SnapshotStrategyComparator implements Comparator { - - Snapshot snapshot; - - public SnapshotStrategyComparator(Snapshot snapshot) { - this.snapshot = snapshot; - } - - @Override - public int compare(SnapshotStrategy o1, SnapshotStrategy o2) { - int i1 = o1.canHandle(snapshot).ordinal(); - int i2 = o2.canHandle(snapshot).ordinal(); - return new Integer(i2).compareTo(new Integer(i1)); - } - } - - static class DataMotionStrategyComparator implements Comparator { - - DataObject srcData, destData; - - public DataMotionStrategyComparator(DataObject srcData, DataObject destData) { - this.srcData = srcData; - this.destData = destData; - } - - @Override - public int compare(DataMotionStrategy o1, DataMotionStrategy o2) { - int i1 = o1.canHandle(srcData, destData).ordinal(); - int i2 = o2.canHandle(srcData, destData).ordinal(); - return new Integer(i2).compareTo(new Integer(i1)); - } - } - - static class DataMotionStrategyHostComparator implements Comparator { - - Host srcHost, destHost; - Map volumeMap; - - public DataMotionStrategyHostComparator(Map volumeMap, Host srcHost, Host destHost) { - this.volumeMap = volumeMap; - this.srcHost = srcHost; - this.destHost = destHost; - } - - @Override - public int compare(DataMotionStrategy o1, DataMotionStrategy o2) { - int i1 = o1.canHandle(volumeMap, srcHost, destHost).ordinal(); - int i2 = o2.canHandle(volumeMap, srcHost, destHost).ordinal(); - return new Integer(i2).compareTo(new Integer(i1)); - } - } +public enum StrategyPriority { + CANT_HANDLE, + DEFAULT, + HYPERVISOR, + PLUGIN, + HIGHEST } diff --git a/engine/api/test/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriorityTest.java b/engine/api/test/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriorityTest.java deleted file mode 100644 index 3d7527903b6..00000000000 --- a/engine/api/test/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriorityTest.java +++ /dev/null @@ -1,116 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package org.apache.cloudstack.engine.subsystem.api.storage; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority.Priority; -import org.junit.Test; - -import com.cloud.host.Host; -import com.cloud.storage.Snapshot; - -import static org.junit.Assert.assertEquals; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -public class StrategyPriorityTest { - - @Test - public void testSortSnapshotStrategies() { - SnapshotStrategy cantHandleStrategy = mock(SnapshotStrategy.class); - SnapshotStrategy defaultStrategy = mock(SnapshotStrategy.class); - SnapshotStrategy hyperStrategy = mock(SnapshotStrategy.class); - SnapshotStrategy pluginStrategy = mock(SnapshotStrategy.class); - SnapshotStrategy highestStrategy = mock(SnapshotStrategy.class); - - doReturn(Priority.CANT_HANDLE).when(cantHandleStrategy).canHandle(any(Snapshot.class)); - doReturn(Priority.DEFAULT).when(defaultStrategy).canHandle(any(Snapshot.class)); - doReturn(Priority.HYPERVISOR).when(hyperStrategy).canHandle(any(Snapshot.class)); - doReturn(Priority.PLUGIN).when(pluginStrategy).canHandle(any(Snapshot.class)); - doReturn(Priority.HIGHEST).when(highestStrategy).canHandle(any(Snapshot.class)); - - List strategies = new ArrayList(5); - strategies.addAll(Arrays.asList(defaultStrategy, pluginStrategy, hyperStrategy, cantHandleStrategy, highestStrategy)); - - StrategyPriority.sortStrategies(strategies, mock(Snapshot.class)); - - assertEquals("Highest was not 1st.", highestStrategy, strategies.get(0)); - assertEquals("Plugin was not 2nd.", pluginStrategy, strategies.get(1)); - assertEquals("Hypervisor was not 3rd.", hyperStrategy, strategies.get(2)); - assertEquals("Default was not 4th.", defaultStrategy, strategies.get(3)); - assertEquals("Can't Handle was not 5th.", cantHandleStrategy, strategies.get(4)); - } - - @Test - public void testSortDataMotionStrategies() { - DataMotionStrategy cantHandleStrategy = mock(DataMotionStrategy.class); - DataMotionStrategy defaultStrategy = mock(DataMotionStrategy.class); - DataMotionStrategy hyperStrategy = mock(DataMotionStrategy.class); - DataMotionStrategy pluginStrategy = mock(DataMotionStrategy.class); - DataMotionStrategy highestStrategy = mock(DataMotionStrategy.class); - - doReturn(Priority.CANT_HANDLE).when(cantHandleStrategy).canHandle(any(DataObject.class), any(DataObject.class)); - doReturn(Priority.DEFAULT).when(defaultStrategy).canHandle(any(DataObject.class), any(DataObject.class)); - doReturn(Priority.HYPERVISOR).when(hyperStrategy).canHandle(any(DataObject.class), any(DataObject.class)); - doReturn(Priority.PLUGIN).when(pluginStrategy).canHandle(any(DataObject.class), any(DataObject.class)); - doReturn(Priority.HIGHEST).when(highestStrategy).canHandle(any(DataObject.class), any(DataObject.class)); - - List strategies = new ArrayList(5); - strategies.addAll(Arrays.asList(defaultStrategy, pluginStrategy, hyperStrategy, cantHandleStrategy, highestStrategy)); - - StrategyPriority.sortStrategies(strategies, mock(DataObject.class), mock(DataObject.class)); - - assertEquals("Highest was not 1st.", highestStrategy, strategies.get(0)); - assertEquals("Plugin was not 2nd.", pluginStrategy, strategies.get(1)); - assertEquals("Hypervisor was not 3rd.", hyperStrategy, strategies.get(2)); - assertEquals("Default was not 4th.", defaultStrategy, strategies.get(3)); - assertEquals("Can't Handle was not 5th.", cantHandleStrategy, strategies.get(4)); - } - - @Test - @SuppressWarnings("unchecked") - public void testSortDataMotionStrategies2() { - DataMotionStrategy cantHandleStrategy = mock(DataMotionStrategy.class); - DataMotionStrategy defaultStrategy = mock(DataMotionStrategy.class); - DataMotionStrategy hyperStrategy = mock(DataMotionStrategy.class); - DataMotionStrategy pluginStrategy = mock(DataMotionStrategy.class); - DataMotionStrategy highestStrategy = mock(DataMotionStrategy.class); - - doReturn(Priority.CANT_HANDLE).when(cantHandleStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class)); - doReturn(Priority.DEFAULT).when(defaultStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class)); - doReturn(Priority.HYPERVISOR).when(hyperStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class)); - doReturn(Priority.PLUGIN).when(pluginStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class)); - doReturn(Priority.HIGHEST).when(highestStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class)); - - List strategies = new ArrayList(5); - strategies.addAll(Arrays.asList(defaultStrategy, pluginStrategy, hyperStrategy, cantHandleStrategy, highestStrategy)); - - StrategyPriority.sortStrategies(strategies, mock(Map.class), mock(Host.class), mock(Host.class)); - - assertEquals("Highest was not 1st.", highestStrategy, strategies.get(0)); - assertEquals("Plugin was not 2nd.", pluginStrategy, strategies.get(1)); - assertEquals("Hypervisor was not 3rd.", hyperStrategy, strategies.get(2)); - assertEquals("Default was not 4th.", defaultStrategy, strategies.get(3)); - assertEquals("Can't Handle was not 5th.", cantHandleStrategy, strategies.get(4)); - } -} diff --git a/engine/components-api/resources/META-INF/cloudstack/core/spring-engine-components-api-core-context.xml b/engine/components-api/resources/META-INF/cloudstack/core/spring-engine-components-api-core-context.xml new file mode 100644 index 00000000000..fd7f96752f9 --- /dev/null +++ b/engine/components-api/resources/META-INF/cloudstack/core/spring-engine-components-api-core-context.xml @@ -0,0 +1,30 @@ + + + + diff --git a/engine/components-api/src/com/cloud/configuration/ConfigurationManager.java b/engine/components-api/src/com/cloud/configuration/ConfigurationManager.java index 5e1b9b58902..03a549f1a35 100755 --- a/engine/components-api/src/com/cloud/configuration/ConfigurationManager.java +++ b/engine/components-api/src/com/cloud/configuration/ConfigurationManager.java @@ -210,7 +210,7 @@ public interface ConfigurationManager { NetworkOfferingVO createNetworkOffering(String name, String displayText, TrafficType trafficType, String tags, boolean specifyVlan, Availability availability, Integer networkRate, Map> serviceProviderMap, boolean isDefault, Network.GuestType type, boolean systemOnly, Long serviceOfferingId, boolean conserveMode, Map> serviceCapabilityMap, - boolean specifyIpRanges, boolean isPersistent, Map details, boolean egressDefaultPolicy, Integer maxconn); + boolean specifyIpRanges, boolean isPersistent, Map details, boolean egressDefaultPolicy, Integer maxconn, boolean enableKeepAlive); Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, Long podId, String startIP, String endIP, String vlanGateway, String vlanNetmask, String vlanId, Account vlanOwner, String startIPv6, String endIPv6, String vlanIp6Gateway, String vlanIp6Cidr) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException; diff --git a/engine/orchestration/resources/META-INF/cloudstack/core/spring-engine-orchestration-core-context.xml b/engine/orchestration/resources/META-INF/cloudstack/core/spring-engine-orchestration-core-context.xml new file mode 100644 index 00000000000..b5c4254abaa --- /dev/null +++ b/engine/orchestration/resources/META-INF/cloudstack/core/spring-engine-orchestration-core-context.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java b/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java index 6804dc1ef68..3e684cc9fd4 100755 --- a/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -97,6 +97,7 @@ import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; import com.cloud.utils.db.EntityManager; import com.cloud.utils.db.QueryBuilder; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; @@ -355,7 +356,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl @DB protected boolean noDbTxn() { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); return !txn.dbTxnStarted(); } @@ -1252,7 +1253,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl @Override protected void doTask(final Task task) throws Exception { - Transaction txn = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); try { final Type type = task.getType(); if (type == Task.Type.DATA) { diff --git a/engine/orchestration/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java b/engine/orchestration/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java index 07fa73caae0..8681263347e 100755 --- a/engine/orchestration/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java +++ b/engine/orchestration/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java @@ -85,8 +85,8 @@ import com.cloud.serializer.GsonHelper; import com.cloud.utils.DateUtil; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.QueryBuilder; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.nio.Link; import com.cloud.utils.nio.Task; @@ -591,7 +591,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust @Override protected void doTask(final Task task) throws Exception { - Transaction txn = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); try { if (task.getType() != Task.Type.DATA) { super.doTask(task); diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index 8bf419f1a65..ce078c94422 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -36,7 +36,6 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; - import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -50,8 +49,8 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; -import org.apache.cloudstack.utils.identity.ManagementServerNode; import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.cloudstack.utils.identity.ManagementServerNode; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -86,7 +85,6 @@ import com.cloud.agent.api.UnPlugNicCommand; import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; -import com.cloud.agent.api.to.VolumeTO; import com.cloud.agent.manager.Commands; import com.cloud.agent.manager.allocator.HostAllocator; import com.cloud.alert.AlertManager; @@ -165,6 +163,11 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.EntityManager; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionCallbackWithException; +import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.ExecutionException; import com.cloud.utils.fsm.NoTransitionException; @@ -283,20 +286,20 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac static final ConfigKey StartRetry = new ConfigKey(Integer.class, "start.retry", "Advanced", "10", "Number of times to retry create and start commands", true); static final ConfigKey VmOpWaitInterval = new ConfigKey("Advanced", Integer.class, "vm.op.wait.interval", "120", - "Time (in seconds) to wait before checking if a previous operation has succeeded", true); + "Time (in seconds) to wait before checking if a previous operation has succeeded", true); static final ConfigKey VmOpLockStateRetry = new ConfigKey("Advanced", Integer.class, "vm.op.lock.state.retry", "5", - "Times to retry locking the state of a VM for operations, -1 means forever", true); + "Times to retry locking the state of a VM for operations, -1 means forever", true); static final ConfigKey VmOpCleanupInterval = new ConfigKey("Advanced", Long.class, "vm.op.cleanup.interval", "86400", - "Interval to run the thread that cleans up the vm operations (in seconds)", false); + "Interval to run the thread that cleans up the vm operations (in seconds)", false); static final ConfigKey VmOpCleanupWait = new ConfigKey("Advanced", Long.class, "vm.op.cleanup.wait", "3600", - "Time (in seconds) to wait before cleanuping up any vm work items", true); + "Time (in seconds) to wait before cleanuping up any vm work items", true); static final ConfigKey VmOpCancelInterval = new ConfigKey("Advanced", Long.class, "vm.op.cancel.interval", "3600", - "Time (in seconds) to wait before cancelling a operation", false); + "Time (in seconds) to wait before cancelling a operation", false); static final ConfigKey VmDestroyForcestop = new ConfigKey("Advanced", Boolean.class, "vm.destroy.forcestop", "false", - "On destroy, force-stop takes this value ", true); + "On destroy, force-stop takes this value ", true); static final ConfigKey ClusterDeltaSyncInterval = new ConfigKey("Advanced", Integer.class, "sync.interval", "60", "Cluster Delta sync interval in seconds", - false); + false); ScheduledExecutorService _executor = null; @@ -311,12 +314,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Override @DB - public void allocate(String vmInstanceName, VirtualMachineTemplate template, ServiceOffering serviceOffering, Pair rootDiskOffering, - LinkedHashMap dataDiskOfferings, LinkedHashMap auxiliaryNetworks, DeploymentPlan plan, + public void allocate(String vmInstanceName, final VirtualMachineTemplate template, ServiceOffering serviceOffering, final Pair rootDiskOffering, + LinkedHashMap dataDiskOfferings, final LinkedHashMap auxiliaryNetworks, DeploymentPlan plan, HypervisorType hyperType) throws InsufficientCapacityException { VMInstanceVO vm = _vmDao.findVMByInstanceName(vmInstanceName); - Account owner = _entityMgr.findById(Account.class, vm.getAccountId()); + final Account owner = _entityMgr.findById(Account.class, vm.getAccountId()); if (s_logger.isDebugEnabled()) { s_logger.debug("Allocating entries for VM: " + vm); @@ -327,52 +330,52 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac vm.setPodId(plan.getPodId()); } assert (plan.getClusterId() == null && plan.getPoolId() == null) : "We currently don't support cluster and pool preset yet"; - vm = _vmDao.persist(vm); + final VMInstanceVO vmFinal = _vmDao.persist(vm); + final LinkedHashMap dataDiskOfferingsFinal = dataDiskOfferings == null ? + new LinkedHashMap() : dataDiskOfferings; - VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, serviceOffering, null, null); - Transaction txn = Transaction.currentTxn(); - txn.start(); + final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmFinal, template, serviceOffering, null, null); + + Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientCapacityException { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Allocating nics for " + vmFinal); + } + + try { + _networkMgr.allocate(vmProfile, auxiliaryNetworks); + } catch (ConcurrentOperationException e) { + throw new CloudRuntimeException("Concurrent operation while trying to allocate resources for the VM", e); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Allocating disks for " + vmFinal); + } + + if (template.getFormat() == ImageFormat.ISO) { + volumeMgr.allocateRawVolume(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOffering.first(), rootDiskOffering.second(), vmFinal, template, owner); + } else if (template.getFormat() == ImageFormat.BAREMETAL) { + // Do nothing + } else { + volumeMgr.allocateTemplatedVolume(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOffering.first(), template, vmFinal, owner); + } + + for (Map.Entry offering : dataDiskOfferingsFinal.entrySet()) { + volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vmFinal.getId(), offering.getKey(), offering.getValue(), vmFinal, template, owner); + } + } + }); if (s_logger.isDebugEnabled()) { - s_logger.debug("Allocating nics for " + vm); - } - - try { - _networkMgr.allocate(vmProfile, auxiliaryNetworks); - } catch (ConcurrentOperationException e) { - throw new CloudRuntimeException("Concurrent operation while trying to allocate resources for the VM", e); - } - - if (dataDiskOfferings == null) { - dataDiskOfferings = new LinkedHashMap(0); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Allocating disks for " + vm); - } - - if (template.getFormat() == ImageFormat.ISO) { - volumeMgr.allocateRawVolume(Type.ROOT, "ROOT-" + vm.getId(), rootDiskOffering.first(), rootDiskOffering.second(), vm, template, owner); - } else if (template.getFormat() == ImageFormat.BAREMETAL) { - // Do nothing - } else { - volumeMgr.allocateTemplatedVolume(Type.ROOT, "ROOT-" + vm.getId(), rootDiskOffering.first(), template, vm, owner); - } - - for (Map.Entry offering : dataDiskOfferings.entrySet()) { - volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vm.getId(), offering.getKey(), offering.getValue(), vm, template, owner); - } - - txn.commit(); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Allocation completed for VM: " + vm); + s_logger.debug("Allocation completed for VM: " + vmFinal); } } @Override public void allocate(String vmInstanceName, VirtualMachineTemplate template, ServiceOffering serviceOffering, LinkedHashMap networks, - DeploymentPlan plan, HypervisorType hyperType) throws InsufficientCapacityException { + DeploymentPlan plan, HypervisorType hyperType) throws InsufficientCapacityException { allocate(vmInstanceName, template, serviceOffering, new Pair(serviceOffering, null), null, networks, plan, hyperType); } @@ -551,37 +554,41 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } @DB - protected Ternary changeToStartState(VirtualMachineGuru vmGuru, VMInstanceVO vm, User caller, Account account) + protected Ternary changeToStartState(VirtualMachineGuru vmGuru, final VMInstanceVO vm, final User caller, final Account account) throws ConcurrentOperationException { long vmId = vm.getId(); ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Starting, vm.getType(), vm.getId()); int retry = VmOpLockStateRetry.value(); while (retry-- != 0) { - Transaction txn = Transaction.currentTxn(); - Ternary result = null; - txn.start(); try { - Journal journal = new Journal.LogJournal("Creating " + vm, s_logger); - work = _workDao.persist(work); - ReservationContextImpl context = new ReservationContextImpl(work.getId(), journal, caller, account); + final ItWorkVO workFinal = work; + Ternary result = + Transaction.execute(new TransactionCallbackWithException, NoTransitionException>() { + @Override + public Ternary doInTransaction(TransactionStatus status) throws NoTransitionException { + Journal journal = new Journal.LogJournal("Creating " + vm, s_logger); + ItWorkVO work = _workDao.persist(workFinal); + ReservationContextImpl context = new ReservationContextImpl(work.getId(), journal, caller, account); - if (stateTransitTo(vm, Event.StartRequested, null, work.getId())) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Successfully transitioned to start state for " + vm + " reservation id = " + work.getId()); + if (stateTransitTo(vm, Event.StartRequested, null, work.getId())) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Successfully transitioned to start state for " + vm + " reservation id = " + work.getId()); + } + return new Ternary(vm, context, work); + } + + return new Ternary(null, null, work); } - result = new Ternary(vm, context, work); - txn.commit(); + }); + + work = result.third(); + if (result.first() != null) return result; - } } catch (NoTransitionException e) { if (s_logger.isDebugEnabled()) { s_logger.debug("Unable to transition into Starting state due to " + e.getMessage()); } - } finally { - if (result == null) { - txn.rollback(); - } } VMInstanceVO instance = _vmDao.findById(vmId); @@ -645,13 +652,13 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Override public void advanceStart(String vmUuid, Map params) throws InsufficientCapacityException, ConcurrentOperationException, - ResourceUnavailableException { + ResourceUnavailableException { advanceStart(vmUuid, params, null); } @Override public void advanceStart(String vmUuid, Map params, DeploymentPlan planToDeploy) throws InsufficientCapacityException, - ConcurrentOperationException, ResourceUnavailableException { + ConcurrentOperationException, ResourceUnavailableException { CallContext cctxt = CallContext.current(); Account account = cctxt.getCallingAccount(); User caller = cctxt.getCallingUser(); @@ -680,10 +687,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (planToDeploy != null && planToDeploy.getDataCenterId() != 0) { if (s_logger.isDebugEnabled()) { s_logger.debug("advanceStart: DeploymentPlan is provided, using dcId:" + planToDeploy.getDataCenterId() + ", podId: " + planToDeploy.getPodId() + ", clusterId: " + - planToDeploy.getClusterId() + ", hostId: " + planToDeploy.getHostId() + ", poolId: " + planToDeploy.getPoolId()); + planToDeploy.getClusterId() + ", hostId: " + planToDeploy.getHostId() + ", poolId: " + planToDeploy.getPoolId()); } plan = new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), - planToDeploy.getPoolId(), planToDeploy.getPhysicalNetworkId(), ctx); + planToDeploy.getPoolId(), planToDeploy.getPhysicalNetworkId(), ctx); } HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); @@ -741,20 +748,20 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // planner if (s_logger.isDebugEnabled()) { s_logger.debug("Cannot satisfy the deployment plan passed in since the ready Root volume is in different cluster. volume's cluster: " + - rootVolClusterId + ", cluster specified: " + clusterIdSpecified); + rootVolClusterId + ", cluster specified: " + clusterIdSpecified); } throw new ResourceUnavailableException( - "Root volume is ready in different cluster, Deployment plan provided cannot be satisfied, unable to create a deployment for " + vm, - Cluster.class, clusterIdSpecified); + "Root volume is ready in different cluster, Deployment plan provided cannot be satisfied, unable to create a deployment for " + vm, + Cluster.class, clusterIdSpecified); } } plan = new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), - vol.getPoolId(), null, ctx); + vol.getPoolId(), null, ctx); } else { plan = new DataCenterDeployment(rootVolDcId, rootVolPodId, rootVolClusterId, null, vol.getPoolId(), null, ctx); if (s_logger.isDebugEnabled()) { s_logger.debug(vol + " is READY, changing deployment plan to use this pool's dcId: " + rootVolDcId + " , podId: " + rootVolPodId + - " , and clusterId: " + rootVolClusterId); + " , and clusterId: " + rootVolClusterId); } planChangedByVolume = true; } @@ -781,7 +788,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac continue; } throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId(), - areAffinityGroupsAssociated(vmProfile)); + areAffinityGroupsAssociated(vmProfile)); } if (dest != null) { @@ -796,7 +803,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac ClusterDetailsVO cluster_detail_ram = _clusterDetailsDao.findDetail(cluster_id, "memoryOvercommitRatio"); //storing the value of overcommit in the vm_details table for doing a capacity check in case the cluster overcommit ratio is changed. if (_uservmDetailsDao.findDetail(vm.getId(), "cpuOvercommitRatio") == null && - ((Float.parseFloat(cluster_detail_cpu.getValue()) > 1f || Float.parseFloat(cluster_detail_ram.getValue()) > 1f))) { + ((Float.parseFloat(cluster_detail_cpu.getValue()) > 1f || Float.parseFloat(cluster_detail_ram.getValue()) > 1f))) { UserVmDetailVO vmDetail_cpu = new UserVmDetailVO(vm.getId(), "cpuOvercommitRatio", cluster_detail_cpu.getValue()); UserVmDetailVO vmDetail_ram = new UserVmDetailVO(vm.getId(), "memoryOvercommitRatio", cluster_detail_ram.getValue()); _uservmDetailsDao.persist(vmDetail_cpu); @@ -867,7 +874,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } if (vmGuru.finalizeStart(vmProfile, destHostId, cmds, ctx)) { syncDiskChainChange(startAnswer); - + if (!changeState(vm, Event.OperationSucceeded, destHostId, work, Step.Done)) { throw new ConcurrentOperationException("Unable to transition to a new state."); } @@ -884,6 +891,18 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac StopCommand cmd = new StopCommand(vm, getExecuteInSequence()); StopAnswer answer = (StopAnswer)_agentMgr.easySend(destHostId, cmd); + if ( answer != null ) { + String hypervisortoolsversion = answer.getHypervisorToolsVersion(); + if (hypervisortoolsversion != null) { + if (vm.getType() == VirtualMachine.Type.User) { + UserVmVO userVm = _userVmDao.findById(vm.getId()); + _userVmDao.loadDetails(userVm); + userVm.setDetail("hypervisortoolsversion", hypervisortoolsversion); + _userVmDao.saveDetails(userVm); + } + } + } + if (answer == null || !answer.getResult()) { s_logger.warn("Unable to stop " + vm + " due to " + (answer != null ? answer.getDetails() : "no answers")); _haMgr.scheduleStop(vm, destHostId, WorkType.ForceStop); @@ -957,17 +976,17 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac throw new CloudRuntimeException("Unable to start instance '" + vm.getHostName() + "' (" + vm.getUuid() + "), see management server log for details"); } } - + private void syncDiskChainChange(StartAnswer answer) { - VirtualMachineTO vmSpec = answer.getVirtualMachine(); - - for(DiskTO disk : vmSpec.getDisks()) { - if(disk.getType() != Volume.Type.ISO) { - VolumeObjectTO vol = (VolumeObjectTO)disk.getData(); - - volumeMgr.updateVolumeDiskChain(vol.getId(), vol.getPath(), vol.getChainInfo()); - } - } + VirtualMachineTO vmSpec = answer.getVirtualMachine(); + + for(DiskTO disk : vmSpec.getDisks()) { + if(disk.getType() != Volume.Type.ISO) { + VolumeObjectTO vol = (VolumeObjectTO)disk.getData(); + + volumeMgr.updateVolumeDiskChain(vol.getId(), vol.getPath(), vol.getChainInfo()); + } + } } @Override @@ -989,7 +1008,18 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac VirtualMachine vm = profile.getVirtualMachine(); StopCommand stop = new StopCommand(vm, getExecuteInSequence()); try { - Answer answer = _agentMgr.send(vm.getHostId(), stop); + StopAnswer answer = (StopAnswer) _agentMgr.send(vm.getHostId(), stop); + if ( answer != null ) { + String hypervisortoolsversion = answer.getHypervisorToolsVersion(); + if (hypervisortoolsversion != null) { + if (vm.getType() == VirtualMachine.Type.User) { + UserVmVO userVm = _userVmDao.findById(vm.getId()); + _userVmDao.loadDetails(userVm); + userVm.setDetail("hypervisortoolsversion", hypervisortoolsversion); + _userVmDao.saveDetails(userVm); + } + } + } if (!answer.getResult()) { s_logger.debug("Unable to stop VM due to " + answer.getDetails()); return false; @@ -1185,6 +1215,18 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac StopAnswer answer = null; try { answer = (StopAnswer)_agentMgr.send(vm.getHostId(), stop); + + if ( answer != null ) { + String hypervisortoolsversion = answer.getHypervisorToolsVersion(); + if (hypervisortoolsversion != null) { + if (vm.getType() == VirtualMachine.Type.User) { + UserVmVO userVm = _userVmDao.findById(vm.getId()); + _userVmDao.loadDetails(userVm); + userVm.setDetail("hypervisortoolsversion", hypervisortoolsversion); + _userVmDao.saveDetails(userVm); + } + } + } stopped = answer.getResult(); if (!stopped) { throw new CloudRuntimeException("Unable to stop the virtual machine due to " + answer.getDetails()); @@ -1528,8 +1570,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _networkMgr.rollbackNicForMigration(vmSrc, profile); _alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), "Unable to migrate vm " + vm.getInstanceName() + " from host " + - fromHost.getName() + " in zone " + dest.getDataCenter().getName() + " and pod " + - dest.getPod().getName(), "Migrate Command failed. Please check logs."); + fromHost.getName() + " in zone " + dest.getDataCenter().getName() + " and pod " + + dest.getPod().getName(), "Migrate Command failed. Please check logs."); try { _agentMgr.send(dstHostId, new Commands(cleanup(vm)), null); } catch (AgentUnavailableException ae) { @@ -1562,8 +1604,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (_poolHostDao.findByPoolHost(pool.getId(), host.getId()) == null || pool.isLocal() != diskOffering.getUseLocalStorage()) { // Cannot find a pool for the volume. Throw an exception. throw new CloudRuntimeException("Cannot migrate volume " + volume + " to storage pool " + pool + " while migrating vm to host " + host + - ". Either the pool is not accessible from the " + - "host or because of the offering with which the volume is created it cannot be placed on " + "the given pool."); + ". Either the pool is not accessible from the " + + "host or because of the offering with which the volume is created it cannot be placed on " + "the given pool."); } else if (pool.getId() == currentPool.getId()) { // If the pool to migrate too is the same as current pool, remove the volume from the list of // volumes to be migrated. @@ -1595,7 +1637,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (!currentPoolAvailable && !volumeToPool.containsKey(volume)) { // Cannot find a pool for the volume. Throw an exception. throw new CloudRuntimeException("Cannot find a storage pool which is available for volume " + volume + " while migrating virtual machine " + - profile.getVirtualMachine() + " to host " + host); + profile.getVirtualMachine() + " to host " + host); } } } @@ -1631,7 +1673,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Override public void migrateWithStorage(String vmUuid, long srcHostId, long destHostId, Map volumeToPool) throws ResourceUnavailableException, - ConcurrentOperationException { + ConcurrentOperationException { VMInstanceVO vm = _vmDao.findByUuid(vmUuid); HostVO srcHost = _hostDao.findById(srcHostId); @@ -1651,7 +1693,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // a vm and not migrating a vm with storage. if (volumeToPool.isEmpty()) { throw new InvalidParameterValueException("Migration of the vm " + vm + "from host " + srcHost + " to destination host " + destHost + - " doesn't involve migrating the volumes."); + " doesn't involve migrating the volumes."); } short alertType = AlertManager.ALERT_TYPE_USERVM_MIGRATE; @@ -1704,8 +1746,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (!migrated) { s_logger.info("Migration was unsuccessful. Cleaning up: " + vm); _alertMgr.sendAlert(alertType, srcHost.getDataCenterId(), srcHost.getPodId(), "Unable to migrate vm " + vm.getInstanceName() + " from host " + srcHost.getName() + - " in zone " + dc.getName() + " and pod " + dc.getName(), - "Migrate Command failed. Please check logs."); + " in zone " + dc.getName() + " and pod " + dc.getName(), + "Migrate Command failed. Please check logs."); try { _agentMgr.send(destHostId, new Commands(cleanup(vm.getInstanceName())), null); stateTransitTo(vm, Event.OperationFailed, srcHostId); @@ -1873,7 +1915,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Override public void advanceReboot(String vmUuid, Map params) throws InsufficientCapacityException, ConcurrentOperationException, - ResourceUnavailableException { + ResourceUnavailableException { VMInstanceVO vm = _vmDao.findByUuid(vmUuid); DataCenter dc = _entityMgr.findById(DataCenter.class, vm.getDataCenterId()); @@ -1922,7 +1964,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // sync VM Snapshots related transient states List vmSnapshotsInTrasientStates = _vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging, VMSnapshot.State.Reverting, - VMSnapshot.State.Creating); + VMSnapshot.State.Creating); if (vmSnapshotsInTrasientStates.size() > 1) { s_logger.info("Found vm " + vm.getInstanceName() + " with VM snapshots in transient states, needs to sync VM snapshot state"); if (!_vmSnapshotMgr.syncVMSnapshot(vm, hostId)) { @@ -1997,7 +2039,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac return commands; } - public void deltaSync(Map> newStates) { + + + public void deltaSync(Map> newStates) { Map states = convertToInfos(newStates); for (Map.Entry entry : states.entrySet()) { @@ -2032,8 +2076,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } } - public void fullSync(final long clusterId, Map> newStates) { - if (newStates == null) + public void fullSync(final long clusterId, Map> newStates) { + if (newStates==null) return; Map infos = convertToInfos(newStates); Set set_vms = Collections.synchronizedSet(new HashSet()); @@ -2045,7 +2089,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // sync VM Snapshots related transient states List vmSnapshotsInExpungingStates = _vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging, VMSnapshot.State.Creating, - VMSnapshot.State.Reverting); + VMSnapshot.State.Reverting); if (vmSnapshotsInExpungingStates.size() > 0) { s_logger.info("Found vm " + vm.getInstanceName() + " in state. " + vm.getState() + ", needs to sync VM snapshot state"); Long hostId = null; @@ -2063,9 +2107,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } if ((info == null && (vm.getState() == State.Running || vm.getState() == State.Starting)) || - (info != null && (info.state == State.Running && vm.getState() == State.Starting))) { + (info != null && (info.state == State.Running && vm.getState() == State.Starting))) { s_logger.info("Found vm " + vm.getInstanceName() + " in inconsistent state. " + vm.getState() + " on CS while " + (info == null ? "Stopped" : "Running") + - " on agent"); + " on agent"); info = new AgentVmInfo(vm.getInstanceName(), vm, State.Stopped); // Bug 13850- grab outstanding work item if any for this VM state so that we mark it as DONE after we change VM state, else it will remain pending @@ -2102,7 +2146,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac e.printStackTrace(); } } else if (info != null && - (vm.getState() == State.Stopped || vm.getState() == State.Stopping || vm.isRemoved() || vm.getState() == State.Destroyed || vm.getState() == State.Expunging)) { + (vm.getState() == State.Stopped || vm.getState() == State.Stopping || vm.isRemoved() || vm.getState() == State.Destroyed || vm.getState() == State.Expunging)) { Host host = _hostDao.findByGuid(info.getHostUuid()); if (host != null) { s_logger.warn("Stopping a VM which is stopped/stopping/destroyed/expunging " + info.name); @@ -2121,19 +2165,19 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } } } else - // host id can change - if (info != null && vm.getState() == State.Running) { - // check for host id changes - Host host = _hostDao.findByGuid(info.getHostUuid()); - if (host != null && (vm.getHostId() == null || host.getId() != vm.getHostId())) { - s_logger.info("Found vm " + vm.getInstanceName() + " with inconsistent host in db, new host is " + host.getId()); - try { - stateTransitTo(vm, VirtualMachine.Event.AgentReportMigrated, host.getId()); - } catch (NoTransitionException e) { - s_logger.warn(e.getMessage()); + // host id can change + if (info != null && vm.getState() == State.Running) { + // check for host id changes + Host host = _hostDao.findByGuid(info.getHostUuid()); + if (host != null && (vm.getHostId() == null || host.getId() != vm.getHostId())) { + s_logger.info("Found vm " + vm.getInstanceName() + " with inconsistent host in db, new host is " + host.getId()); + try { + stateTransitTo(vm, VirtualMachine.Event.AgentReportMigrated, host.getId()); + } catch (NoTransitionException e) { + s_logger.warn(e.getMessage()); + } } } - } /* else if(info == null && vm.getState() == State.Stopping) { //Handling CS-13376 s_logger.warn("Marking the VM as Stopped as it was still stopping on the CS" +vm.getName()); vm.setState(State.Stopped); // Setting the VM as stopped on the DB and clearing it from the host @@ -2162,24 +2206,27 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } - protected Map convertToInfos(final Map> newStates) { + + protected Map convertToInfos(final Map> newStates) { final HashMap map = new HashMap(); if (newStates == null) { return map; } boolean is_alien_vm = true; long alien_vm_count = -1; - for (Map.Entry> entry : newStates.entrySet()) { + for (Map.Entry> entry : newStates.entrySet()) { is_alien_vm = true; String name = entry.getKey(); VMInstanceVO vm = _vmDao.findVMByInstanceName(name); if (vm != null) { - map.put(vm.getId(), new AgentVmInfo(entry.getKey(), vm, entry.getValue().second(), entry.getValue().first())); + map.put(vm.getId(), new AgentVmInfo(entry.getKey(), vm, entry.getValue().second(), + entry.getValue().first(), entry.getValue().third())); is_alien_vm = false; } // alien VMs if (is_alien_vm) { - map.put(alien_vm_count--, new AgentVmInfo(entry.getKey(), null, entry.getValue().second(), entry.getValue().first())); + map.put(alien_vm_count--, new AgentVmInfo(entry.getKey(), null, entry.getValue().second(), + entry.getValue().first(), entry.getValue().third())); s_logger.warn("Found an alien VM " + entry.getKey()); } } @@ -2257,15 +2304,33 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac String hostDesc = "name: " + hostVO.getName() + " (id:" + hostVO.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName(); _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "VM (name: " + vm.getInstanceName() + ", id: " + vm.getId() + ") stopped on host " + - hostDesc + " due to storage failure", - "Virtual Machine " + vm.getInstanceName() + " (id: " + vm.getId() + ") running on host [" + vm.getHostId() + "] stopped due to storage failure."); + hostDesc + " due to storage failure", + "Virtual Machine " + vm.getInstanceName() + " (id: " + vm.getId() + ") running on host [" + vm.getHostId() + "] stopped due to storage failure."); + } + // track hypervsion tools version + if( info.hvtoolsversion != null && !info.hvtoolsversion.isEmpty() ) { + if (vm.getType() == VirtualMachine.Type.User) { + UserVmVO userVm = _userVmDao.findById(vm.getId()); + _userVmDao.loadDetails(userVm); + userVm.setDetail("hypervisortoolsversion", info.hvtoolsversion); + _userVmDao.saveDetails(userVm); + } + } + // track hypervsion tools version + if( info.hvtoolsversion != null && !info.hvtoolsversion.isEmpty() ) { + if (vm.getType() == VirtualMachine.Type.User) { + UserVmVO userVm = _userVmDao.findById(vm.getId()); + _userVmDao.loadDetails(userVm); + userVm.setDetail("hypervisortoolsversion", info.hvtoolsversion); + _userVmDao.saveDetails(userVm); + } } if (trackExternalChange) { if (serverState == State.Starting) { if (vm.getHostId() != null && vm.getHostId() != hostId) { s_logger.info("CloudStack is starting VM on host " + vm.getHostId() + ", but status report comes from a different host " + hostId + - ", skip status sync for vm: " + vm.getInstanceName()); + ", skip status sync for vm: " + vm.getInstanceName()); return null; } } @@ -2290,7 +2355,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (serverState == State.Starting) { if (vm.getHostId() != null && vm.getHostId() != hostId) { s_logger.info("CloudStack is starting VM on host " + vm.getHostId() + ", but status report comes from a different host " + hostId + - ", skip status sync for vm: " + vm.getInstanceName()); + ", skip status sync for vm: " + vm.getInstanceName()); return null; } } @@ -2306,7 +2371,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (vm.getHostId() == null || hostId != vm.getHostId()) { if (s_logger.isDebugEnabled()) { s_logger.debug("detected host change when VM " + vm + " is at running state, VM could be live-migrated externally from host " + vm.getHostId() + - " to host " + hostId); + " to host " + hostId); } stateTransitTo(vm, VirtualMachine.Event.AgentReportMigrated, hostId); @@ -2404,7 +2469,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } private void ensureVmRunningContext(long hostId, VMInstanceVO vm, Event cause) throws OperationTimedoutException, ResourceUnavailableException, NoTransitionException, - InsufficientAddressCapacityException { + InsufficientAddressCapacityException { VirtualMachineGuru vmGuru = getVmGuru(vm); s_logger.debug("VM state is starting on full sync so updating it to running"); @@ -2433,7 +2498,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac for (NicVO nic : nics) { Network network = _networkModel.getNetwork(nic.getNetworkId()); NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, _networkModel.isSecurityGroupSupportedInNetwork(network), - _networkModel.getNetworkTag(profile.getHypervisorType(), network)); + _networkModel.getNetworkTag(profile.getHypervisorType(), network)); profile.addNic(nicProfile); } @@ -2544,9 +2609,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac long agentId = agent.getId(); if (agent.getHypervisorType() == HypervisorType.XenServer) { // only for Xen - StartupRoutingCommand startup = (StartupRoutingCommand)cmd; - HashMap> allStates = startup.getClusterVMStateChanges(); - if (allStates != null) { + StartupRoutingCommand startup = (StartupRoutingCommand) cmd; + HashMap> allStates = startup.getClusterVMStateChanges(); + if (allStates != null){ fullSync(clusterId, allStates); } @@ -2625,22 +2690,35 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac public String name; public State state; public String hostUuid; + public String hvtoolsversion; public VMInstanceVO vm; - public AgentVmInfo(String name, VMInstanceVO vm, State state, String host) { + + @SuppressWarnings("unchecked") + public AgentVmInfo(String name, VMInstanceVO vm, State state, String host, String hvtoolsversion) { this.name = name; this.state = state; this.vm = vm; - hostUuid = host; + this.hostUuid = host; + this.hvtoolsversion= hvtoolsversion; + + } + + public AgentVmInfo(String name, VMInstanceVO vm, State state, String host) { + this(name, vm, state, host, null); } public AgentVmInfo(String name, VMInstanceVO vm, State state) { - this(name, vm, state, null); + this(name, vm, state, null, null); } public String getHostUuid() { return hostUuid; } + + public String getHvtoolsversion() { + return hvtoolsversion; + } } @Override @@ -2659,7 +2737,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (!(vmInstance.getState().equals(State.Stopped) || vmInstance.getState().equals(State.Running))) { s_logger.warn("Unable to upgrade virtual machine " + vmInstance.toString() + " in state " + vmInstance.getState()); throw new InvalidParameterValueException("Unable to upgrade virtual machine " + vmInstance.toString() + " " + " in state " + vmInstance.getState() + - "; make sure the virtual machine is stopped/running"); + "; make sure the virtual machine is stopped/running"); } // Check if the service offering being upgraded to is what the VM is already running with @@ -2669,7 +2747,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } throw new InvalidParameterValueException("Not upgrading vm " + vmInstance.toString() + " since it already " + "has the requested service offering (" + - newServiceOffering.getName() + ")"); + newServiceOffering.getName() + ")"); } ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getServiceOfferingId()); @@ -2687,8 +2765,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // offering if (currentServiceOffering.getUseLocalStorage() != newServiceOffering.getUseLocalStorage()) { throw new InvalidParameterValueException("Unable to upgrade virtual machine " + vmInstance.toString() + - ", cannot switch between local storage and shared storage service offerings. Current offering " + "useLocalStorage=" + - currentServiceOffering.getUseLocalStorage() + ", target offering useLocalStorage=" + newServiceOffering.getUseLocalStorage()); + ", cannot switch between local storage and shared storage service offerings. Current offering " + "useLocalStorage=" + + currentServiceOffering.getUseLocalStorage() + ", target offering useLocalStorage=" + newServiceOffering.getUseLocalStorage()); } // if vm is a system vm, check if it is a system service offering, if yes return with error as it cannot be used for user vms @@ -2699,7 +2777,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // Check that there are enough resources to upgrade the service offering if (!isVirtualMachineUpgradable(vmInstance, newServiceOffering)) { throw new InvalidParameterValueException("Unable to upgrade virtual machine, not enough resources available " + "for an offering of " + newServiceOffering.getCpu() + - " cpu(s) at " + newServiceOffering.getSpeed() + " Mhz, and " + newServiceOffering.getRamSize() + " MB of memory"); + " cpu(s) at " + newServiceOffering.getSpeed() + " Mhz, and " + newServiceOffering.getRamSize() + " MB of memory"); } // Check that the service offering being upgraded to has all the tags of the current service offering @@ -2707,8 +2785,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac List newTags = StringUtils.csvTagsToList(newServiceOffering.getTags()); if (!newTags.containsAll(currentTags)) { throw new InvalidParameterValueException("Unable to upgrade virtual machine; the new service offering " + "does not have all the tags of the " + - "current service offering. Current service offering tags: " + currentTags + "; " + "new service " + "offering tags: " + - newTags); + "current service offering. Current service offering tags: " + currentTags + "; " + "new service " + "offering tags: " + + newTags); } } @@ -2725,7 +2803,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Override public NicProfile addVmToNetwork(VirtualMachine vm, Network network, NicProfile requested) throws ConcurrentOperationException, ResourceUnavailableException, - InsufficientCapacityException { + InsufficientCapacityException { CallContext cctx = CallContext.current(); s_logger.debug("Adding vm " + vm + " to network " + network + "; requested nic profile " + requested); @@ -2761,7 +2839,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac long isDefault = (nic.isDefaultNic()) ? 1 : 0; // insert nic's Id into DB as resource_name UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vmVO.getAccountId(), vmVO.getDataCenterId(), vmVO.getId(), - Long.toString(nic.getId()), network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vmVO.getUuid()); + Long.toString(nic.getId()), network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vmVO.getUuid()); return nic; } else { s_logger.warn("Failed to plug nic to the vm " + vm + " in network " + network); @@ -2817,7 +2895,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), _networkModel.getNetworkRate(network.getId(), vm.getId()), - _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network)); + _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network)); //1) Unplug the nic if (vm.getState() == State.Running) { @@ -2828,7 +2906,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac s_logger.debug("Nic is unplugged successfully for vm " + vm + " in network " + network); long isDefault = (nic.isDefaultNic()) ? 1 : 0; UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), Long.toString(nic.getId()), - network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vm.getUuid()); + network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vm.getUuid()); } else { s_logger.warn("Failed to unplug nic for the vm " + vm + " from network " + network); return false; @@ -2900,7 +2978,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac try { NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), _networkModel.getNetworkRate(network.getId(), vm.getId()), - _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network)); + _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network)); //1) Unplug the nic if (vm.getState() == State.Running) { @@ -2937,7 +3015,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Override public void findHostAndMigrate(String vmUuid, Long newSvcOfferingId, ExcludeList excludes) throws InsufficientCapacityException, ConcurrentOperationException, - ResourceUnavailableException { + ResourceUnavailableException { VMInstanceVO vm = _vmDao.findByUuid(vmUuid); if (vm == null) { @@ -3122,8 +3200,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac s_logger.info("Migration was unsuccessful. Cleaning up: " + vm); _alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), "Unable to migrate vm " + vm.getInstanceName() + " from host " + - fromHost.getName() + " in zone " + dest.getDataCenter().getName() + " and pod " + - dest.getPod().getName(), "Migrate Command failed. Please check logs."); + fromHost.getName() + " in zone " + dest.getDataCenter().getName() + " and pod " + + dest.getPod().getName(), "Migrate Command failed. Please check logs."); try { _agentMgr.send(dstHostId, new Commands(cleanup(vm.getInstanceName())), null); } catch (AgentUnavailableException ae) { @@ -3143,7 +3221,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, - ResourceUnavailableException, InsufficientCapacityException { + ResourceUnavailableException, InsufficientCapacityException { boolean result = true; VMInstanceVO router = _vmDao.findById(vm.getId()); @@ -3166,14 +3244,14 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac s_logger.warn("Unable to apply PlugNic, vm " + router + " is not in the right state " + router.getState()); throw new ResourceUnavailableException("Unable to apply PlugNic on the backend," + " vm " + vm + " is not in the right state", DataCenter.class, - router.getDataCenterId()); + router.getDataCenterId()); } return result; } public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, - ResourceUnavailableException { + ResourceUnavailableException { boolean result = true; VMInstanceVO router = _vmDao.findById(vm.getId()); @@ -3199,7 +3277,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac s_logger.warn("Unable to apply unplug nic, Vm " + router + " is not in the right state " + router.getState()); throw new ResourceUnavailableException("Unable to apply unplug nic on the backend," + " vm " + router + " is not in the right state", DataCenter.class, - router.getDataCenterId()); + router.getDataCenterId()); } return result; @@ -3207,7 +3285,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Override public VMInstanceVO reConfigureVm(String vmUuid, ServiceOffering oldServiceOffering, boolean reconfiguringOnExistingHost) throws ResourceUnavailableException, - ConcurrentOperationException { + ConcurrentOperationException { VMInstanceVO vm = _vmDao.findByUuid(vmUuid); long newServiceofferingId = vm.getServiceOfferingId(); @@ -3218,7 +3296,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac Float cpuOvercommitRatio = CapacityManager.CpuOverprovisioningFactor.valueIn(hostVo.getClusterId()); long minMemory = (long)(newServiceOffering.getRamSize() / memoryOvercommitRatio); ScaleVmCommand reconfigureCmd = new ScaleVmCommand(vm.getInstanceName(), newServiceOffering.getCpu(), (int)(newServiceOffering.getSpeed() / cpuOvercommitRatio), - newServiceOffering.getSpeed(), minMemory * 1024L * 1024L, newServiceOffering.getRamSize() * 1024L * 1024L, newServiceOffering.getLimitCpuUse()); + newServiceOffering.getSpeed(), minMemory * 1024L * 1024L, newServiceOffering.getRamSize() * 1024L * 1024L, newServiceOffering.getLimitCpuUse()); Long dstHostId = vm.getHostId(); ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Running, vm.getType(), vm.getId()); diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/DcDetailsDaoImpl.java b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/DcDetailsDaoImpl.java index 2ace8a0fbcb..43385488d12 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/DcDetailsDaoImpl.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/DcDetailsDaoImpl.java @@ -29,7 +29,7 @@ import org.springframework.stereotype.Component; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component(value="EngineDcDetailsDao") @Local(value=DcDetailsDao.class) @@ -83,7 +83,7 @@ public class DcDetailsDaoImpl extends GenericDaoBase implement @Override public void persist(long dcId, Map details) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SearchCriteria sc = DcSearch.create(); sc.setParameters("dcId", dcId); diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineClusterDaoImpl.java b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineClusterDaoImpl.java index e7eea6c42c3..4251baf06c6 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineClusterDaoImpl.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineClusterDaoImpl.java @@ -45,7 +45,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.db.UpdateBuilder; import com.cloud.utils.exception.CloudRuntimeException; @@ -162,7 +162,7 @@ public class EngineClusterDaoImpl extends GenericDaoBase @Override public Map> getPodClusterIdMap(List clusterIds){ - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; Map> result = new HashMap>(); @@ -243,7 +243,7 @@ public class EngineClusterDaoImpl extends GenericDaoBase @Override public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); EngineClusterVO cluster = createForUpdate(); cluster.setName(null); diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineDataCenterDaoImpl.java b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineDataCenterDaoImpl.java index 5d8ef8d3243..de710532d98 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineDataCenterDaoImpl.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineDataCenterDaoImpl.java @@ -40,7 +40,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SequenceFetcher; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.db.UpdateBuilder; import com.cloud.utils.net.NetUtils; @@ -216,7 +216,7 @@ public class EngineDataCenterDaoImpl extends GenericDaoBase implem @Override @DB public List findAndUpdateDirectAgentToLoad(long lastPingSecondsAfter, Long limit, long managementServerId) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SearchCriteria sc = UnmanagedDirectConnectSearch.create(); sc.setParameters("lastPinged", lastPingSecondsAfter); @@ -356,7 +356,7 @@ public class EngineHostDaoImpl extends GenericDaoBase implem @Override @DB public List findAndUpdateApplianceToLoad(long lastPingSecondsAfter, long managementServerId) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SearchCriteria sc = UnmanagedApplianceSearch.create(); @@ -495,7 +495,7 @@ public class EngineHostDaoImpl extends GenericDaoBase implem @DB @Override public List findLostHosts(long timeout) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); ResultSet rs = null; @@ -546,7 +546,7 @@ public class EngineHostDaoImpl extends GenericDaoBase implem public EngineHostVO persist(EngineHostVO host) { final String InsertSequenceSql = "INSERT INTO op_host(id) VALUES(?)"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); EngineHostVO dbHost = super.persist(host); @@ -572,7 +572,7 @@ public class EngineHostDaoImpl extends GenericDaoBase implem @Override @DB public boolean update(Long hostId, EngineHostVO host) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); boolean persisted = super.update(hostId, host); @@ -598,7 +598,7 @@ public class EngineHostDaoImpl extends GenericDaoBase implem ArrayList l = new ArrayList(); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); ; PreparedStatement pstmt = null; try { diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostPodDaoImpl.java b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostPodDaoImpl.java index 7bf85d530e5..2bcfdd148f9 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostPodDaoImpl.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostPodDaoImpl.java @@ -41,7 +41,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.UpdateBuilder; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component(value="EngineHostPodDao") @Local(value={EngineHostPodDao.class}) @@ -97,7 +97,7 @@ public class EngineHostPodDaoImpl extends GenericDaoBase HashMap> currentPodCidrSubnets = new HashMap>(); String selectSql = "SELECT id, cidr_address, cidr_size FROM host_pod_ref WHERE data_center_id=" + zoneId +" and removed IS NULL"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql); ResultSet rs = stmt.executeQuery(); @@ -123,7 +123,7 @@ public class EngineHostPodDaoImpl extends GenericDaoBase @Override public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); EngineHostPodVO pod = createForUpdate(); pod.setName(null); diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDetailsDaoImpl.java b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDetailsDaoImpl.java index e0ae778911c..e0a6dceac31 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDetailsDaoImpl.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDetailsDaoImpl.java @@ -31,7 +31,7 @@ import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component(value="EngineHostDetailsDao") @@ -96,7 +96,7 @@ public class HostDetailsDaoImpl extends GenericDaoBase implement public void persist(long hostId, Map details) { final String InsertOrUpdateSql = "INSERT INTO `cloud`.`host_details` (host_id, name, value) VALUES (?,?,?) ON DUPLICATE KEY UPDATE value=?"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); for (Map.Entry detail : details.entrySet()) { diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostTagsDaoImpl.java b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostTagsDaoImpl.java index a70b7d1b234..17d6f811a61 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostTagsDaoImpl.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostTagsDaoImpl.java @@ -27,7 +27,7 @@ import com.cloud.host.HostTagVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component(value="EngineHostTagsDao") @Local(value=HostTagsDao.class) @@ -56,7 +56,7 @@ public class HostTagsDaoImpl extends GenericDaoBase implements @Override public void persist(long hostId, List hostTags) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SearchCriteria sc = HostSearch.create(); diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index 3c4b1ed5e72..5636e0783b4 100755 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -167,6 +167,10 @@ import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; import com.cloud.utils.db.EntityManager; import com.cloud.utils.db.GlobalLock; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.db.JoinBuilder.JoinType; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria.Op; @@ -346,7 +350,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra @DB public boolean configure(final String name, final Map params) throws ConfigurationException { // populate providers - Map> defaultSharedNetworkOfferingProviders = new HashMap>(); + final Map> defaultSharedNetworkOfferingProviders = new HashMap>(); Set defaultProviders = new HashSet(); defaultProviders.add(Network.Provider.VirtualRouter); @@ -354,7 +358,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra defaultSharedNetworkOfferingProviders.put(Service.Dns, defaultProviders); defaultSharedNetworkOfferingProviders.put(Service.UserData, defaultProviders); - Map> defaultIsolatedNetworkOfferingProviders = defaultSharedNetworkOfferingProviders; + final Map> defaultIsolatedNetworkOfferingProviders = defaultSharedNetworkOfferingProviders; defaultIsolatedNetworkOfferingProviders.put(Service.Dhcp, defaultProviders); defaultIsolatedNetworkOfferingProviders.put(Service.Dns, defaultProviders); defaultIsolatedNetworkOfferingProviders.put(Service.UserData, defaultProviders); @@ -365,7 +369,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra defaultIsolatedNetworkOfferingProviders.put(Service.PortForwarding, defaultProviders); defaultIsolatedNetworkOfferingProviders.put(Service.Vpn, defaultProviders); - Map> defaultSharedSGEnabledNetworkOfferingProviders = new HashMap>(); + final Map> defaultSharedSGEnabledNetworkOfferingProviders = new HashMap>(); defaultSharedSGEnabledNetworkOfferingProviders.put(Service.Dhcp, defaultProviders); defaultSharedSGEnabledNetworkOfferingProviders.put(Service.Dns, defaultProviders); defaultSharedSGEnabledNetworkOfferingProviders.put(Service.UserData, defaultProviders); @@ -373,7 +377,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra sgProviders.add(Provider.SecurityGroupProvider); defaultSharedSGEnabledNetworkOfferingProviders.put(Service.SecurityGroup, sgProviders); - Map> defaultIsolatedSourceNatEnabledNetworkOfferingProviders = new HashMap>(); + final Map> defaultIsolatedSourceNatEnabledNetworkOfferingProviders = new HashMap>(); defaultProviders.clear(); defaultProviders.add(Network.Provider.VirtualRouter); defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dhcp, defaultProviders); @@ -387,7 +391,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.PortForwarding, defaultProviders); defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Vpn, defaultProviders); - Map> defaultVPCOffProviders = new HashMap>(); + final Map> defaultVPCOffProviders = new HashMap>(); defaultProviders.clear(); defaultProviders.add(Network.Provider.VPCVirtualRouter); defaultVPCOffProviders.put(Service.Dhcp, defaultProviders); @@ -401,133 +405,134 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra defaultVPCOffProviders.put(Service.PortForwarding, defaultProviders); defaultVPCOffProviders.put(Service.Vpn, defaultProviders); - Transaction txn = Transaction.currentTxn(); - txn.start(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + NetworkOfferingVO offering = null; + //#1 - quick cloud network offering + if (_networkOfferingDao.findByUniqueName(NetworkOffering.QuickCloudNoServices) == null) { + offering = _configMgr.createNetworkOffering(NetworkOffering.QuickCloudNoServices, "Offering for QuickCloud with no services", TrafficType.Guest, null, true, + Availability.Optional, null, new HashMap>(), true, Network.GuestType.Shared, false, null, true, null, true, false, null, + false, null, true); + offering.setState(NetworkOffering.State.Enabled); + _networkOfferingDao.update(offering.getId(), offering); + } + + //#2 - SG enabled network offering + if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOfferingWithSGService) == null) { + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks", + TrafficType.Guest, null, true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true, + false, null, false, null, true); + offering.setState(NetworkOffering.State.Enabled); + _networkOfferingDao.update(offering.getId(), offering); + } + + //#3 - shared network offering with no SG service + if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOffering) == null) { + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, null, true, + Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true, false, null, false, null, true); + offering.setState(NetworkOffering.State.Enabled); + _networkOfferingDao.update(offering.getId(), offering); + } + + //#4 - default isolated offering with Source nat service + if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService) == null) { + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService, + "Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest, null, false, Availability.Required, null, + defaultIsolatedSourceNatEnabledNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null, true, null, false, false, null, false, null, true); + + offering.setState(NetworkOffering.State.Enabled); + _networkOfferingDao.update(offering.getId(), offering); + } + + //#5 - default vpc offering with LB service + if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks) == null) { + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks, + "Offering for Isolated VPC networks with Source Nat service enabled", TrafficType.Guest, null, false, Availability.Optional, null, defaultVPCOffProviders, true, + Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true); + offering.setState(NetworkOffering.State.Enabled); + _networkOfferingDao.update(offering.getId(), offering); + } + + //#6 - default vpc offering with no LB service + if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB) == null) { + //remove LB service + defaultVPCOffProviders.remove(Service.Lb); + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB, + "Offering for Isolated VPC networks with Source Nat service enabled and LB service disabled", TrafficType.Guest, null, false, Availability.Optional, null, + defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true); + offering.setState(NetworkOffering.State.Enabled); + _networkOfferingDao.update(offering.getId(), offering); + } + + //#7 - isolated offering with source nat disabled + if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOffering) == null) { + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOffering, "Offering for Isolated networks with no Source Nat service", + TrafficType.Guest, null, true, Availability.Optional, null, defaultIsolatedNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null, true, null, + true, false, null, false, null, true); + offering.setState(NetworkOffering.State.Enabled); + _networkOfferingDao.update(offering.getId(), offering); + } + + //#8 - network offering with internal lb service + Map> internalLbOffProviders = new HashMap>(); + Set defaultVpcProvider = new HashSet(); + defaultVpcProvider.add(Network.Provider.VPCVirtualRouter); + + Set defaultInternalLbProvider = new HashSet(); + defaultInternalLbProvider.add(Network.Provider.InternalLbVm); + + internalLbOffProviders.put(Service.Dhcp, defaultVpcProvider); + internalLbOffProviders.put(Service.Dns, defaultVpcProvider); + internalLbOffProviders.put(Service.UserData, defaultVpcProvider); + internalLbOffProviders.put(Service.NetworkACL, defaultVpcProvider); + internalLbOffProviders.put(Service.Gateway, defaultVpcProvider); + internalLbOffProviders.put(Service.Lb, defaultInternalLbProvider); + internalLbOffProviders.put(Service.SourceNat, defaultVpcProvider); + + if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB) == null) { + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB, + "Offering for Isolated VPC networks with Internal Lb support", TrafficType.Guest, null, false, Availability.Optional, null, internalLbOffProviders, true, + Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true); + offering.setState(NetworkOffering.State.Enabled); + offering.setInternalLb(true); + offering.setPublicLb(false); + _networkOfferingDao.update(offering.getId(), offering); + } + + Map> netscalerServiceProviders = new HashMap>(); + Set vrProvider = new HashSet(); + vrProvider.add(Provider.VirtualRouter); + Set sgProvider = new HashSet(); + sgProvider.add(Provider.SecurityGroupProvider); + Set nsProvider = new HashSet(); + nsProvider.add(Provider.Netscaler); + netscalerServiceProviders.put(Service.Dhcp, vrProvider); + netscalerServiceProviders.put(Service.Dns, vrProvider); + netscalerServiceProviders.put(Service.UserData, vrProvider); + netscalerServiceProviders.put(Service.SecurityGroup, sgProvider); + netscalerServiceProviders.put(Service.StaticNat, nsProvider); + netscalerServiceProviders.put(Service.Lb, nsProvider); + + Map> serviceCapabilityMap = new HashMap>(); + Map elb = new HashMap(); + elb.put(Capability.ElasticLb, "true"); + Map eip = new HashMap(); + eip.put(Capability.ElasticIp, "true"); + serviceCapabilityMap.put(Service.Lb, elb); + serviceCapabilityMap.put(Service.StaticNat, eip); + + if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedEIPandELBNetworkOffering) == null) { + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedEIPandELBNetworkOffering, + "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, null, true, Availability.Optional, null, netscalerServiceProviders, + true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, false, null, false, null, true); + offering.setState(NetworkOffering.State.Enabled); + offering.setDedicatedLB(false); + _networkOfferingDao.update(offering.getId(), offering); + } + } + }); - NetworkOfferingVO offering = null; - //#1 - quick cloud network offering - if (_networkOfferingDao.findByUniqueName(NetworkOffering.QuickCloudNoServices) == null) { - offering = _configMgr.createNetworkOffering(NetworkOffering.QuickCloudNoServices, "Offering for QuickCloud with no services", TrafficType.Guest, null, true, - Availability.Optional, null, new HashMap>(), true, Network.GuestType.Shared, false, null, true, null, true, false, null, - false, null); - offering.setState(NetworkOffering.State.Enabled); - _networkOfferingDao.update(offering.getId(), offering); - } - - //#2 - SG enabled network offering - if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOfferingWithSGService) == null) { - offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks", - TrafficType.Guest, null, true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true, - false, null, false, null); - offering.setState(NetworkOffering.State.Enabled); - _networkOfferingDao.update(offering.getId(), offering); - } - - //#3 - shared network offering with no SG service - if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOffering) == null) { - offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, null, true, - Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true, false, null, false, null); - offering.setState(NetworkOffering.State.Enabled); - _networkOfferingDao.update(offering.getId(), offering); - } - - //#4 - default isolated offering with Source nat service - if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService) == null) { - offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService, - "Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest, null, false, Availability.Required, null, - defaultIsolatedSourceNatEnabledNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null, true, null, false, false, null, false, null); - - offering.setState(NetworkOffering.State.Enabled); - _networkOfferingDao.update(offering.getId(), offering); - } - - //#5 - default vpc offering with LB service - if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks) == null) { - offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks, - "Offering for Isolated VPC networks with Source Nat service enabled", TrafficType.Guest, null, false, Availability.Optional, null, defaultVPCOffProviders, true, - Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null); - offering.setState(NetworkOffering.State.Enabled); - _networkOfferingDao.update(offering.getId(), offering); - } - - //#6 - default vpc offering with no LB service - if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB) == null) { - //remove LB service - defaultVPCOffProviders.remove(Service.Lb); - offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB, - "Offering for Isolated VPC networks with Source Nat service enabled and LB service disabled", TrafficType.Guest, null, false, Availability.Optional, null, - defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null); - offering.setState(NetworkOffering.State.Enabled); - _networkOfferingDao.update(offering.getId(), offering); - } - - //#7 - isolated offering with source nat disabled - if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOffering) == null) { - offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOffering, "Offering for Isolated networks with no Source Nat service", - TrafficType.Guest, null, true, Availability.Optional, null, defaultIsolatedNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null, true, null, - true, false, null, false, null); - offering.setState(NetworkOffering.State.Enabled); - _networkOfferingDao.update(offering.getId(), offering); - } - - //#8 - network offering with internal lb service - Map> internalLbOffProviders = new HashMap>(); - Set defaultVpcProvider = new HashSet(); - defaultVpcProvider.add(Network.Provider.VPCVirtualRouter); - - Set defaultInternalLbProvider = new HashSet(); - defaultInternalLbProvider.add(Network.Provider.InternalLbVm); - - internalLbOffProviders.put(Service.Dhcp, defaultVpcProvider); - internalLbOffProviders.put(Service.Dns, defaultVpcProvider); - internalLbOffProviders.put(Service.UserData, defaultVpcProvider); - internalLbOffProviders.put(Service.NetworkACL, defaultVpcProvider); - internalLbOffProviders.put(Service.Gateway, defaultVpcProvider); - internalLbOffProviders.put(Service.Lb, defaultInternalLbProvider); - internalLbOffProviders.put(Service.SourceNat, defaultVpcProvider); - - if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB) == null) { - offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB, - "Offering for Isolated VPC networks with Internal Lb support", TrafficType.Guest, null, false, Availability.Optional, null, internalLbOffProviders, true, - Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null); - offering.setState(NetworkOffering.State.Enabled); - offering.setInternalLb(true); - offering.setPublicLb(false); - _networkOfferingDao.update(offering.getId(), offering); - } - - Map> netscalerServiceProviders = new HashMap>(); - Set vrProvider = new HashSet(); - vrProvider.add(Provider.VirtualRouter); - Set sgProvider = new HashSet(); - sgProvider.add(Provider.SecurityGroupProvider); - Set nsProvider = new HashSet(); - nsProvider.add(Provider.Netscaler); - netscalerServiceProviders.put(Service.Dhcp, vrProvider); - netscalerServiceProviders.put(Service.Dns, vrProvider); - netscalerServiceProviders.put(Service.UserData, vrProvider); - netscalerServiceProviders.put(Service.SecurityGroup, sgProvider); - netscalerServiceProviders.put(Service.StaticNat, nsProvider); - netscalerServiceProviders.put(Service.Lb, nsProvider); - - Map> serviceCapabilityMap = new HashMap>(); - Map elb = new HashMap(); - elb.put(Capability.ElasticLb, "true"); - Map eip = new HashMap(); - eip.put(Capability.ElasticIp, "true"); - serviceCapabilityMap.put(Service.Lb, elb); - serviceCapabilityMap.put(Service.StaticNat, eip); - - if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedEIPandELBNetworkOffering) == null) { - offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedEIPandELBNetworkOffering, - "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, null, true, Availability.Optional, null, netscalerServiceProviders, - true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, false, null, false, null); - offering.setState(NetworkOffering.State.Enabled); - offering.setDedicatedLB(false); - _networkOfferingDao.update(offering.getId(), offering); - } - - txn.commit(); AssignIpAddressSearch = _ipAddressDao.createSearchBuilder(); AssignIpAddressSearch.and("dc", AssignIpAddressSearch.entity().getDataCenterId(), Op.EQ); @@ -590,8 +595,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra @Override @DB - public List setupNetwork(Account owner, NetworkOffering offering, Network predefined, DeploymentPlan plan, String name, String displayText, - boolean errorIfAlreadySetup, Long domainId, ACLType aclType, Boolean subdomainAccess, Long vpcId, Boolean isDisplayNetworkEnabled) throws ConcurrentOperationException { + public List setupNetwork(final Account owner, final NetworkOffering offering, final Network predefined, final DeploymentPlan plan, final String name, final String displayText, + boolean errorIfAlreadySetup, final Long domainId, final ACLType aclType, final Boolean subdomainAccess, final Long vpcId, final Boolean isDisplayNetworkEnabled) throws ConcurrentOperationException { Account locked = _accountDao.acquireInLockTable(owner.getId()); if (locked == null) { @@ -622,12 +627,12 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra } } - List networks = new ArrayList(); + final List networks = new ArrayList(); long related = -1; - for (NetworkGuru guru : _networkGurus) { - Network network = guru.design(offering, plan, predefined, owner); + for (final NetworkGuru guru : _networkGurus) { + final Network network = guru.design(offering, plan, predefined, owner); if (network == null) { continue; } @@ -641,28 +646,26 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra continue; } - long id = _networksDao.getNextInSequence(Long.class, "id"); + final long id = _networksDao.getNextInSequence(Long.class, "id"); if (related == -1) { related = id; } - Transaction txn = Transaction.currentTxn(); - txn.start(); - - NetworkVO vo = new NetworkVO(id, network, offering.getId(), guru.getName(), owner.getDomainId(), owner.getId(), related, name, displayText, - predefined.getNetworkDomain(), offering.getGuestType(), plan.getDataCenterId(), plan.getPhysicalNetworkId(), aclType, offering.getSpecifyIpRanges(), vpcId); - vo.setDisplayNetwork(isDisplayNetworkEnabled == null ? true : isDisplayNetworkEnabled); - networks.add(_networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated, - finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId()))); - - if (domainId != null && aclType == ACLType.Domain) { - if (subdomainAccess == null) { - subdomainAccess = true; + final long relatedFile = related; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + NetworkVO vo = new NetworkVO(id, network, offering.getId(), guru.getName(), owner.getDomainId(), owner.getId(), relatedFile, name, displayText, + predefined.getNetworkDomain(), offering.getGuestType(), plan.getDataCenterId(), plan.getPhysicalNetworkId(), aclType, offering.getSpecifyIpRanges(), vpcId); + vo.setDisplayNetwork(isDisplayNetworkEnabled == null ? true : isDisplayNetworkEnabled); + networks.add(_networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated, + finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId()))); + + if (domainId != null && aclType == ACLType.Domain) { + _networksDao.addDomainToNetwork(id, domainId, subdomainAccess == null ? true : subdomainAccess); + } } - _networksDao.addDomainToNetwork(id, domainId, subdomainAccess); - } - - txn.commit(); + }); } if (networks.size() < 1) { @@ -681,73 +684,74 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra @Override @DB - public void allocate(VirtualMachineProfile vm, LinkedHashMap networks) throws InsufficientCapacityException, + public void allocate(final VirtualMachineProfile vm, final LinkedHashMap networks) throws InsufficientCapacityException, ConcurrentOperationException { - Transaction txn = Transaction.currentTxn(); - txn.start(); - int deviceId = 0; - - boolean[] deviceIds = new boolean[networks.size()]; - Arrays.fill(deviceIds, false); - - List nics = new ArrayList(networks.size()); - NicProfile defaultNic = null; - - for (Map.Entry network : networks.entrySet()) { - Network config = network.getKey(); - NicProfile requested = network.getValue(); - - Boolean isDefaultNic = false; - if (vm != null && (requested != null && requested.isDefaultNic())) { - isDefaultNic = true; - } - - while (deviceIds[deviceId] && deviceId < deviceIds.length) { - deviceId++; - } - - Pair vmNicPair = allocateNic(requested, config, isDefaultNic, deviceId, vm); - - NicProfile vmNic = vmNicPair.first(); - if (vmNic == null) { - continue; - } - - deviceId = vmNicPair.second(); - - int devId = vmNic.getDeviceId(); - if (devId > deviceIds.length) { - throw new IllegalArgumentException("Device id for nic is too large: " + vmNic); - } - if (deviceIds[devId]) { - throw new IllegalArgumentException("Conflicting device id for two different nics: " + vmNic); - } - - deviceIds[devId] = true; - - if (vmNic.isDefaultNic()) { - if (defaultNic != null) { - throw new IllegalArgumentException("You cannot specify two nics as default nics: nic 1 = " + defaultNic + "; nic 2 = " + vmNic); + Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientCapacityException { + int deviceId = 0; + + boolean[] deviceIds = new boolean[networks.size()]; + Arrays.fill(deviceIds, false); + + List nics = new ArrayList(networks.size()); + NicProfile defaultNic = null; + + for (Map.Entry network : networks.entrySet()) { + Network config = network.getKey(); + NicProfile requested = network.getValue(); + + Boolean isDefaultNic = false; + if (vm != null && (requested != null && requested.isDefaultNic())) { + isDefaultNic = true; + } + + while (deviceIds[deviceId] && deviceId < deviceIds.length) { + deviceId++; + } + + Pair vmNicPair = allocateNic(requested, config, isDefaultNic, deviceId, vm); + + NicProfile vmNic = vmNicPair.first(); + if (vmNic == null) { + continue; + } + + deviceId = vmNicPair.second(); + + int devId = vmNic.getDeviceId(); + if (devId > deviceIds.length) { + throw new IllegalArgumentException("Device id for nic is too large: " + vmNic); + } + if (deviceIds[devId]) { + throw new IllegalArgumentException("Conflicting device id for two different nics: " + vmNic); + } + + deviceIds[devId] = true; + + if (vmNic.isDefaultNic()) { + if (defaultNic != null) { + throw new IllegalArgumentException("You cannot specify two nics as default nics: nic 1 = " + defaultNic + "; nic 2 = " + vmNic); + } + defaultNic = vmNic; + } + + nics.add(vmNic); + vm.addNic(vmNic); + + } + + if (nics.size() != networks.size()) { + s_logger.warn("Number of nics " + nics.size() + " doesn't match number of requested networks " + networks.size()); + throw new CloudRuntimeException("Number of nics " + nics.size() + " doesn't match number of requested networks " + networks.size()); + } + + if (nics.size() == 1) { + nics.get(0).setDefaultNic(true); } - defaultNic = vmNic; } - - nics.add(vmNic); - vm.addNic(vmNic); - - } - - if (nics.size() != networks.size()) { - s_logger.warn("Number of nics " + nics.size() + " doesn't match number of requested networks " + networks.size()); - throw new CloudRuntimeException("Number of nics " + nics.size() + " doesn't match number of requested networks " + networks.size()); - } - - if (nics.size() == 1) { - nics.get(0).setDefaultNic(true); - } - - txn.commit(); + }); } @DB @@ -900,7 +904,6 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra @DB public Pair implementNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { - Transaction.currentTxn(); Pair implemented = new Pair(null, null); NetworkVO network = _networksDao.findById(networkId); @@ -1176,22 +1179,23 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra } @DB - protected void updateNic(NicVO nic, long networkId, int count) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - _nicDao.update(nic.getId(), nic); - - if (nic.getVmType() == VirtualMachine.Type.User) { - s_logger.debug("Changing active number of nics for network id=" + networkId + " on " + count); - _networksDao.changeActiveNicsBy(networkId, count); - } - - if (nic.getVmType() == VirtualMachine.Type.User || - (nic.getVmType() == VirtualMachine.Type.DomainRouter && _networksDao.findById(networkId).getTrafficType() == TrafficType.Guest)) { - _networksDao.setCheckForGc(networkId); - } - - txn.commit(); + protected void updateNic(final NicVO nic, final long networkId, final int count) { + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + _nicDao.update(nic.getId(), nic); + + if (nic.getVmType() == VirtualMachine.Type.User) { + s_logger.debug("Changing active number of nics for network id=" + networkId + " on " + count); + _networksDao.changeActiveNicsBy(networkId, count); + } + + if (nic.getVmType() == VirtualMachine.Type.User || + (nic.getVmType() == VirtualMachine.Type.DomainRouter && _networksDao.findById(networkId).getTrafficType() == TrafficType.Guest)) { + _networksDao.setCheckForGc(networkId); + } + } + }); } @Override @@ -1414,59 +1418,63 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra } @DB - protected void releaseNic(VirtualMachineProfile vmProfile, long nicId) throws ConcurrentOperationException, ResourceUnavailableException { - //lock the nic - Transaction txn = Transaction.currentTxn(); - txn.start(); + protected void releaseNic(final VirtualMachineProfile vmProfile, final long nicId) throws ConcurrentOperationException, ResourceUnavailableException { + Pair networkToRelease = Transaction.execute(new TransactionCallback>() { + @Override + public Pair doInTransaction(TransactionStatus status) { + NicVO nic = _nicDao.lockRow(nicId, true); + if (nic == null) { + throw new ConcurrentOperationException("Unable to acquire lock on nic " + nic); + } - NicVO nic = _nicDao.lockRow(nicId, true); - if (nic == null) { - throw new ConcurrentOperationException("Unable to acquire lock on nic " + nic); - } + Nic.State originalState = nic.getState(); + NetworkVO network = _networksDao.findById(nic.getNetworkId()); - Nic.State originalState = nic.getState(); - NetworkVO network = _networksDao.findById(nic.getNetworkId()); - - if (originalState == Nic.State.Reserved || originalState == Nic.State.Reserving) { - if (nic.getReservationStrategy() == Nic.ReservationStrategy.Start) { - NetworkGuru guru = AdapterBase.getAdapterByName(_networkGurus, network.getGuruName()); - nic.setState(Nic.State.Releasing); - _nicDao.update(nic.getId(), nic); - NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, _networkModel.isSecurityGroupSupportedInNetwork(network), - _networkModel.getNetworkTag(vmProfile.getHypervisorType(), network)); - if (guru.release(profile, vmProfile, nic.getReservationId())) { - applyProfileToNicForRelease(nic, profile); - nic.setState(Nic.State.Allocated); - if (originalState == Nic.State.Reserved) { - updateNic(nic, network.getId(), -1); - } else { + if (originalState == Nic.State.Reserved || originalState == Nic.State.Reserving) { + if (nic.getReservationStrategy() == Nic.ReservationStrategy.Start) { + NetworkGuru guru = AdapterBase.getAdapterByName(_networkGurus, network.getGuruName()); + nic.setState(Nic.State.Releasing); _nicDao.update(nic.getId(), nic); - } - } - //commit the transaction before proceeding releasing nic profile on the network elements - txn.commit(); - - // Perform release on network elements - List providersToImplement = getNetworkProviders(network.getId()); - for (NetworkElement element : _networkElements) { - if (providersToImplement.contains(element.getProvider())) { - if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) { - throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + - " either doesn't exist or is not enabled in physical network id: " + network.getPhysicalNetworkId()); + NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, _networkModel.isSecurityGroupSupportedInNetwork(network), + _networkModel.getNetworkTag(vmProfile.getHypervisorType(), network)); + if (guru.release(profile, vmProfile, nic.getReservationId())) { + applyProfileToNicForRelease(nic, profile); + nic.setState(Nic.State.Allocated); + if (originalState == Nic.State.Reserved) { + updateNic(nic, network.getId(), -1); + } else { + _nicDao.update(nic.getId(), nic); + } } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Asking " + element.getName() + " to release " + nic); - } - //NOTE: Context appear to never be used in release method - //implementations. Consider removing it from interface Element - element.release(network, profile, vmProfile, null); + // Perform release on network elements + return new Pair(network, profile); + } else { + nic.setState(Nic.State.Allocated); + updateNic(nic, network.getId(), -1); } } - } else { - nic.setState(Nic.State.Allocated); - updateNic(nic, network.getId(), -1); - txn.commit(); + return null; + } + }); + + if (networkToRelease != null) { + Network network = networkToRelease.first(); + NicProfile profile = networkToRelease.second(); + List providersToImplement = getNetworkProviders(network.getId()); + for (NetworkElement element : _networkElements) { + if (providersToImplement.contains(element.getProvider())) { + if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) { + throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + + " either doesn't exist or is not enabled in physical network id: " + network.getPhysicalNetworkId()); + } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Asking " + element.getName() + " to release " + profile); + } + //NOTE: Context appear to never be used in release method + //implementations. Consider removing it from interface Element + element.release(network, profile, vmProfile, null); + } } } } @@ -1563,15 +1571,17 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra Network network = _networksDao.findById(nic.getNetworkId()); DhcpServiceProvider dhcpServiceProvider = getDhcpServiceProvider(network); try { - NicIpAliasVO ipAlias = _nicIpAliasDao.findByGatewayAndNetworkIdAndState(nic.getGateway(), network.getId(), NicIpAlias.state.active); + final NicIpAliasVO ipAlias = _nicIpAliasDao.findByGatewayAndNetworkIdAndState(nic.getGateway(), network.getId(), NicIpAlias.state.active); if (ipAlias != null) { ipAlias.setState(NicIpAlias.state.revoked); - Transaction txn = Transaction.currentTxn(); - txn.start(); - _nicIpAliasDao.update(ipAlias.getId(), ipAlias); - IPAddressVO aliasIpaddressVo = _publicIpAddressDao.findByIpAndSourceNetworkId(ipAlias.getNetworkId(), ipAlias.getIp4Address()); - _publicIpAddressDao.unassignIpAddress(aliasIpaddressVo.getId()); - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + _nicIpAliasDao.update(ipAlias.getId(), ipAlias); + IPAddressVO aliasIpaddressVo = _publicIpAddressDao.findByIpAndSourceNetworkId(ipAlias.getNetworkId(), ipAlias.getIp4Address()); + _publicIpAddressDao.unassignIpAddress(aliasIpaddressVo.getId()); + } + }); if (!dhcpServiceProvider.removeDhcpSupportForSubnet(network)) { s_logger.warn("Failed to remove the ip alias on the router, marking it as removed in db and freed the allocated ip " + ipAlias.getIp4Address()); } @@ -1593,18 +1603,18 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra @Override @DB - public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, - Long domainId, PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr, - Boolean isDisplayNetworkEnabled, String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { + public Network createGuestNetwork(long networkOfferingId, final String name, final String displayText, final String gateway, final String cidr, String vlanId, String networkDomain, final Account owner, + final Long domainId, final PhysicalNetwork pNtwk, final long zoneId, final ACLType aclType, Boolean subdomainAccess, final Long vpcId, final String ip6Gateway, final String ip6Cidr, + final Boolean isDisplayNetworkEnabled, final String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { - NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId); + final NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId); // this method supports only guest network creation if (ntwkOff.getTrafficType() != TrafficType.Guest) { s_logger.warn("Only guest networks can be created using this method"); return null; } - boolean updateResourceCount = resourceCountNeedsUpdate(ntwkOff, aclType); + final boolean updateResourceCount = resourceCountNeedsUpdate(ntwkOff, aclType); //check resource limits if (updateResourceCount) { _resourceLimitMgr.checkResourceLimit(owner, ResourceType.network); @@ -1632,7 +1642,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra ipv6 = true; } // Validate zone - DataCenterVO zone = _dcDao.findById(zoneId); + final DataCenterVO zone = _dcDao.findById(zoneId); if (zone.getNetworkType() == NetworkType.Basic) { if (ipv6) { throw new InvalidParameterValueException("IPv6 is not supported in Basic zone"); @@ -1819,79 +1829,84 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra } } - Transaction txn = Transaction.currentTxn(); - txn.start(); - - Long physicalNetworkId = null; - if (pNtwk != null) { - physicalNetworkId = pNtwk.getId(); - } - DataCenterDeployment plan = new DataCenterDeployment(zoneId, null, null, null, null, physicalNetworkId); - NetworkVO userNetwork = new NetworkVO(); - userNetwork.setNetworkDomain(networkDomain); - - if (cidr != null && gateway != null) { - userNetwork.setCidr(cidr); - userNetwork.setGateway(gateway); - } - - if (ip6Cidr != null && ip6Gateway != null) { - userNetwork.setIp6Cidr(ip6Cidr); - userNetwork.setIp6Gateway(ip6Gateway); - } - - if (vlanId != null) { - if (isolatedPvlan == null) { - URI uri = BroadcastDomainType.fromString(vlanId); - userNetwork.setBroadcastUri(uri); - if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) { - userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan); - } else { - userNetwork.setBroadcastDomainType(BroadcastDomainType.Native); - } - } else { - if (vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) { - throw new InvalidParameterValueException("Cannot support pvlan with untagged primary vlan!"); - } - userNetwork.setBroadcastUri(NetUtils.generateUriForPvlan(vlanId, isolatedPvlan)); - userNetwork.setBroadcastDomainType(BroadcastDomainType.Pvlan); - } - } + final String networkDomainFinal = networkDomain; + final String vlanIdFinal = vlanId; + final Boolean subdomainAccessFinal = subdomainAccess; + Network network = Transaction.execute(new TransactionCallback() { + @Override + public Network doInTransaction(TransactionStatus status) { + Long physicalNetworkId = null; + if (pNtwk != null) { + physicalNetworkId = pNtwk.getId(); + } + DataCenterDeployment plan = new DataCenterDeployment(zoneId, null, null, null, null, physicalNetworkId); + NetworkVO userNetwork = new NetworkVO(); + userNetwork.setNetworkDomain(networkDomainFinal); - List networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId, aclType, subdomainAccess, vpcId, - isDisplayNetworkEnabled); - - Network network = null; - if (networks == null || networks.isEmpty()) { - throw new CloudRuntimeException("Fail to create a network"); - } else { - if (networks.size() > 0 && networks.get(0).getGuestType() == Network.GuestType.Isolated && networks.get(0).getTrafficType() == TrafficType.Guest) { - Network defaultGuestNetwork = networks.get(0); - for (Network nw : networks) { - if (nw.getCidr() != null && nw.getCidr().equals(zone.getGuestNetworkCidr())) { - defaultGuestNetwork = nw; + if (cidr != null && gateway != null) { + userNetwork.setCidr(cidr); + userNetwork.setGateway(gateway); + } + + if (ip6Cidr != null && ip6Gateway != null) { + userNetwork.setIp6Cidr(ip6Cidr); + userNetwork.setIp6Gateway(ip6Gateway); + } + + if (vlanIdFinal != null) { + if (isolatedPvlan == null) { + URI uri = BroadcastDomainType.fromString(vlanIdFinal); + userNetwork.setBroadcastUri(uri); + if (!vlanIdFinal.equalsIgnoreCase(Vlan.UNTAGGED)) { + userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan); + } else { + userNetwork.setBroadcastDomainType(BroadcastDomainType.Native); + } + } else { + if (vlanIdFinal.equalsIgnoreCase(Vlan.UNTAGGED)) { + throw new InvalidParameterValueException("Cannot support pvlan with untagged primary vlan!"); + } + userNetwork.setBroadcastUri(NetUtils.generateUriForPvlan(vlanIdFinal, isolatedPvlan)); + userNetwork.setBroadcastDomainType(BroadcastDomainType.Pvlan); + } + } + + List networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId, aclType, subdomainAccessFinal, vpcId, + isDisplayNetworkEnabled); + + Network network = null; + if (networks == null || networks.isEmpty()) { + throw new CloudRuntimeException("Fail to create a network"); + } else { + if (networks.size() > 0 && networks.get(0).getGuestType() == Network.GuestType.Isolated && networks.get(0).getTrafficType() == TrafficType.Guest) { + Network defaultGuestNetwork = networks.get(0); + for (Network nw : networks) { + if (nw.getCidr() != null && nw.getCidr().equals(zone.getGuestNetworkCidr())) { + defaultGuestNetwork = nw; + } + } + network = defaultGuestNetwork; + } else { + // For shared network + network = networks.get(0); } } - network = defaultGuestNetwork; - } else { - // For shared network - network = networks.get(0); + + if (updateResourceCount) { + _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.network); + } + + return network; } - } + }); - if (updateResourceCount) { - _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.network); - } - - txn.commit(); CallContext.current().setEventDetails("Network Id: " + network.getId()); return network; } @Override @DB - public boolean shutdownNetwork(long networkId, ReservationContext context, boolean cleanupElements) { - boolean result = false; + public boolean shutdownNetwork(final long networkId, ReservationContext context, boolean cleanupElements) { NetworkVO network = _networksDao.findById(networkId); if (network.getState() == Network.State.Allocated) { s_logger.debug("Network is already shutdown: " + network); @@ -1936,43 +1951,51 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra } } - boolean success = shutdownNetworkElementsAndResources(context, cleanupElements, network); + final boolean success = shutdownNetworkElementsAndResources(context, cleanupElements, network); - Transaction txn = Transaction.currentTxn(); - txn.start(); - if (success) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Network id=" + networkId + " is shutdown successfully, cleaning up corresponding resources now."); - } - NetworkGuru guru = AdapterBase.getAdapterByName(_networkGurus, network.getGuruName()); - NetworkProfile profile = convertNetworkToNetworkProfile(network.getId()); - guru.shutdown(profile, _networkOfferingDao.findById(network.getNetworkOfferingId())); + final NetworkVO networkFinal = network; + boolean result = Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + boolean result = false; - applyProfileToNetwork(network, profile); - DataCenterVO zone = _dcDao.findById(network.getDataCenterId()); - if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId()) && (zone.getNetworkType() == NetworkType.Advanced)) { - network.setState(Network.State.Setup); - } else { - try { - stateTransitTo(network, Event.OperationSucceeded); - } catch (NoTransitionException e) { - network.setState(Network.State.Allocated); - network.setRestartRequired(false); + if (success) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Network id=" + networkId + " is shutdown successfully, cleaning up corresponding resources now."); + } + NetworkGuru guru = AdapterBase.getAdapterByName(_networkGurus, networkFinal.getGuruName()); + NetworkProfile profile = convertNetworkToNetworkProfile(networkFinal.getId()); + guru.shutdown(profile, _networkOfferingDao.findById(networkFinal.getNetworkOfferingId())); + + applyProfileToNetwork(networkFinal, profile); + DataCenterVO zone = _dcDao.findById(networkFinal.getDataCenterId()); + if (isSharedNetworkOfferingWithServices(networkFinal.getNetworkOfferingId()) && (zone.getNetworkType() == NetworkType.Advanced)) { + networkFinal.setState(Network.State.Setup); + } else { + try { + stateTransitTo(networkFinal, Event.OperationSucceeded); + } catch (NoTransitionException e) { + networkFinal.setState(Network.State.Allocated); + networkFinal.setRestartRequired(false); + } + } + _networksDao.update(networkFinal.getId(), networkFinal); + _networksDao.clearCheckForGc(networkId); + result = true; + } else { + try { + stateTransitTo(networkFinal, Event.OperationFailed); + } catch (NoTransitionException e) { + networkFinal.setState(Network.State.Implemented); + _networksDao.update(networkFinal.getId(), networkFinal); + } + result = false; } + + return result; } - _networksDao.update(network.getId(), network); - _networksDao.clearCheckForGc(networkId); - result = true; - } else { - try { - stateTransitTo(network, Event.OperationFailed); - } catch (NoTransitionException e) { - network.setState(Network.State.Implemented); - _networksDao.update(network.getId(), network); - } - result = false; - } - txn.commit(); + }); + return result; } finally { if (network != null) { @@ -2036,8 +2059,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra @Override @DB - public boolean destroyNetwork(long networkId, ReservationContext context) { - Account callerAccount = context.getAccount(); + public boolean destroyNetwork(long networkId, final ReservationContext context) { + final Account callerAccount = context.getAccount(); NetworkVO network = _networksDao.findById(networkId); if (network == null) { @@ -2126,38 +2149,48 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra if (s_logger.isDebugEnabled()) { s_logger.debug("Network id=" + networkId + " is destroyed successfully, cleaning up corresponding resources now."); } - NetworkGuru guru = AdapterBase.getAdapterByName(_networkGurus, network.getGuruName()); - Transaction txn = Transaction.currentTxn(); - txn.start(); - guru.trash(network, _networkOfferingDao.findById(network.getNetworkOfferingId())); - - if (!deleteVlansInNetwork(network.getId(), context.getCaller().getId(), callerAccount)) { - success = false; - s_logger.warn("Failed to delete network " + network + "; was unable to cleanup corresponding ip ranges"); - } else { - // commit transaction only when ips and vlans for the network are released successfully - try { - stateTransitTo(network, Event.DestroyNetwork); - } catch (NoTransitionException e) { - s_logger.debug(e.getMessage()); - } - if (_networksDao.remove(network.getId())) { - NetworkDomainVO networkDomain = _networkDomainDao.getDomainNetworkMapByNetworkId(network.getId()); - if (networkDomain != null) - _networkDomainDao.remove(networkDomain.getId()); - - NetworkAccountVO networkAccount = _networkAccountDao.getAccountNetworkMapByNetworkId(network.getId()); - if (networkAccount != null) - _networkAccountDao.remove(networkAccount.getId()); - } - - NetworkOffering ntwkOff = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId()); - boolean updateResourceCount = resourceCountNeedsUpdate(ntwkOff, network.getAclType()); - if (updateResourceCount) { - _resourceLimitMgr.decrementResourceCount(network.getAccountId(), ResourceType.network); - } - txn.commit(); + final NetworkVO networkFinal = network; + try { + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + NetworkGuru guru = AdapterBase.getAdapterByName(_networkGurus, networkFinal.getGuruName()); + + guru.trash(networkFinal, _networkOfferingDao.findById(networkFinal.getNetworkOfferingId())); + + if (!deleteVlansInNetwork(networkFinal.getId(), context.getCaller().getId(), callerAccount)) { + s_logger.warn("Failed to delete network " + networkFinal + "; was unable to cleanup corresponding ip ranges"); + throw new CloudRuntimeException("Failed to delete network " + networkFinal + "; was unable to cleanup corresponding ip ranges"); + } else { + // commit transaction only when ips and vlans for the network are released successfully + try { + stateTransitTo(networkFinal, Event.DestroyNetwork); + } catch (NoTransitionException e) { + s_logger.debug(e.getMessage()); + } + if (_networksDao.remove(networkFinal.getId())) { + NetworkDomainVO networkDomain = _networkDomainDao.getDomainNetworkMapByNetworkId(networkFinal.getId()); + if (networkDomain != null) + _networkDomainDao.remove(networkDomain.getId()); + + NetworkAccountVO networkAccount = _networkAccountDao.getAccountNetworkMapByNetworkId(networkFinal.getId()); + if (networkAccount != null) + _networkAccountDao.remove(networkAccount.getId()); + } + + NetworkOffering ntwkOff = _entityMgr.findById(NetworkOffering.class, networkFinal.getNetworkOfferingId()); + boolean updateResourceCount = resourceCountNeedsUpdate(ntwkOff, networkFinal.getAclType()); + if (updateResourceCount) { + _resourceLimitMgr.decrementResourceCount(networkFinal.getAccountId(), ResourceType.network); + } + } + } + }); + return false; + } catch ( CloudRuntimeException e ) { + s_logger.error("Failed to delete network", e); + return false; } } @@ -2426,24 +2459,22 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra @DB @Override - public boolean reallocate(VirtualMachineProfile vm, DataCenterDeployment dest) throws InsufficientCapacityException, ConcurrentOperationException { + public boolean reallocate(final VirtualMachineProfile vm, DataCenterDeployment dest) throws InsufficientCapacityException, ConcurrentOperationException { VMInstanceVO vmInstance = _vmDao.findById(vm.getId()); DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterId()); if (dc.getNetworkType() == NetworkType.Basic) { List nics = _nicDao.listByVmId(vmInstance.getId()); NetworkVO network = _networksDao.findById(nics.get(0).getNetworkId()); - LinkedHashMap profiles = new LinkedHashMap(); + final LinkedHashMap profiles = new LinkedHashMap(); profiles.put(network, null); - Transaction txn = Transaction.currentTxn(); - txn.start(); - - try { - cleanupNics(vm); - allocate(vm, profiles); - } finally { - txn.commit(); - } + Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientCapacityException { + cleanupNics(vm); + allocate(vm, profiles); + } + }); } return true; } @@ -3050,17 +3081,20 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra return nic.getSecondaryIp(); } - private boolean removeVmSecondaryIpsOfNic(long nicId) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - List ipList = _nicSecondaryIpDao.listByNicId(nicId); - if (ipList != null) { - for (NicSecondaryIpVO ip : ipList) { - _nicSecondaryIpDao.remove(ip.getId()); + private boolean removeVmSecondaryIpsOfNic(final long nicId) { + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + List ipList = _nicSecondaryIpDao.listByNicId(nicId); + if (ipList != null) { + for (NicSecondaryIpVO ip : ipList) { + _nicSecondaryIpDao.remove(ip.getId()); + } + s_logger.debug("Revoving nic secondary ip entry ..."); + } } - s_logger.debug("Revoving nic secondary ip entry ..."); - } - txn.commit(); + }); + return true; } diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java index 0817393ab9c..7d812325cf5 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java @@ -31,7 +31,6 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; - import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; @@ -97,6 +96,9 @@ import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.EntityManager; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.utils.fsm.StateMachine2; @@ -681,9 +683,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati } @DB - protected VolumeVO switchVolume(VolumeVO existingVolume, VirtualMachineProfile vm) throws StorageUnavailableException { - Transaction txn = Transaction.currentTxn(); - + protected VolumeVO switchVolume(final VolumeVO existingVolume, final VirtualMachineProfile vm) throws StorageUnavailableException { Long templateIdToUse = null; Long volTemplateId = existingVolume.getTemplateId(); long vmTemplateId = vm.getTemplateId(); @@ -695,22 +695,26 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati templateIdToUse = vmTemplateId; } - txn.start(); - VolumeVO newVolume = allocateDuplicateVolumeVO(existingVolume, templateIdToUse); - // In case of Vmware if vm reference is not removed then during root - // disk cleanup - // the vm also gets deleted, so remove the reference - if (vm.getHypervisorType() == HypervisorType.VMware) { - _volsDao.detachVolume(existingVolume.getId()); - } - try { - stateTransitTo(existingVolume, Volume.Event.DestroyRequested); - } catch (NoTransitionException e) { - s_logger.debug("Unable to destroy existing volume: " + e.toString()); - } - txn.commit(); - return newVolume; - + final Long templateIdToUseFinal = templateIdToUse; + return Transaction.execute(new TransactionCallback() { + @Override + public VolumeVO doInTransaction(TransactionStatus status) { + VolumeVO newVolume = allocateDuplicateVolumeVO(existingVolume, templateIdToUseFinal); + // In case of Vmware if vm reference is not removed then during root + // disk cleanup + // the vm also gets deleted, so remove the reference + if (vm.getHypervisorType() == HypervisorType.VMware) { + _volsDao.detachVolume(existingVolume.getId()); + } + try { + stateTransitTo(existingVolume, Volume.Event.DestroyRequested); + } catch (NoTransitionException e) { + s_logger.debug("Unable to destroy existing volume: " + e.toString()); + } + + return newVolume; + } + }); } @Override @@ -724,28 +728,32 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati if (s_logger.isDebugEnabled()) { s_logger.debug("Cleaning storage for vm: " + vmId); } - List volumesForVm = _volsDao.findByInstance(vmId); - List toBeExpunged = new ArrayList(); - Transaction txn = Transaction.currentTxn(); - txn.start(); - for (VolumeVO vol : volumesForVm) { - if (vol.getVolumeType().equals(Type.ROOT)) { - // Destroy volume if not already destroyed - boolean volumeAlreadyDestroyed = (vol.getState() == Volume.State.Destroy || vol.getState() == Volume.State.Expunged || vol.getState() == Volume.State.Expunging); - if (!volumeAlreadyDestroyed) { - volService.destroyVolume(vol.getId()); - } else { - s_logger.debug("Skipping destroy for the volume " + vol + " as its in state " + vol.getState().toString()); + final List volumesForVm = _volsDao.findByInstance(vmId); + final List toBeExpunged = new ArrayList(); + + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + for (VolumeVO vol : volumesForVm) { + if (vol.getVolumeType().equals(Type.ROOT)) { + // Destroy volume if not already destroyed + boolean volumeAlreadyDestroyed = (vol.getState() == Volume.State.Destroy || vol.getState() == Volume.State.Expunged || vol.getState() == Volume.State.Expunging); + if (!volumeAlreadyDestroyed) { + volService.destroyVolume(vol.getId()); + } else { + s_logger.debug("Skipping destroy for the volume " + vol + " as its in state " + vol.getState().toString()); + } + toBeExpunged.add(vol); + } else { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Detaching " + vol); + } + _volsDao.detachVolume(vol.getId()); + } } - toBeExpunged.add(vol); - } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Detaching " + vol); - } - _volsDao.detachVolume(vol.getId()); } - } - txn.commit(); + }); + AsyncCallFuture future = null; for (VolumeVO expunge : toBeExpunged) { future = volService.expungeVolumeAsync(volFactory.getVolume(expunge.getId())); diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml new file mode 100644 index 00000000000..f4bbb23c819 --- /dev/null +++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -0,0 +1,322 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/engine/schema/resources/META-INF/cloudstack/system/spring-engine-schema-system-checkers-context.xml b/engine/schema/resources/META-INF/cloudstack/system/spring-engine-schema-system-checkers-context.xml new file mode 100644 index 00000000000..2a308873f6a --- /dev/null +++ b/engine/schema/resources/META-INF/cloudstack/system/spring-engine-schema-system-checkers-context.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/engine/schema/src/com/cloud/alert/dao/AlertDaoImpl.java b/engine/schema/src/com/cloud/alert/dao/AlertDaoImpl.java index 7c0a56224f3..57102cbb50b 100755 --- a/engine/schema/src/com/cloud/alert/dao/AlertDaoImpl.java +++ b/engine/schema/src/com/cloud/alert/dao/AlertDaoImpl.java @@ -29,7 +29,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value = { AlertDao.class }) @@ -116,7 +116,7 @@ public class AlertDaoImpl extends GenericDaoBase implements Alert return result; } if (alerts != null && !alerts.isEmpty()) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); for (AlertVO alert : alerts) { alert = lockRow(alert.getId(), true); diff --git a/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java b/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java index 88a2b2b7ab7..c642504df1d 100755 --- a/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java +++ b/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java @@ -46,7 +46,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -186,7 +186,7 @@ public class CapacityDaoImpl extends GenericDaoBase implements @Override public List listClustersCrossingThreshold(short capacityType, Long zoneId, String configName, long compute_requested){ - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); StringBuilder sql = new StringBuilder(LIST_CLUSTERS_CROSSING_THRESHOLD); @@ -241,7 +241,7 @@ public class CapacityDaoImpl extends GenericDaoBase implements @Override public List findCapacityBy(Integer capacityType, Long zoneId, Long podId, Long clusterId, String resource_state){ - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); @@ -291,7 +291,7 @@ public class CapacityDaoImpl extends GenericDaoBase implements public List listCapacitiesGroupedByLevelAndType(Integer capacityType, Long zoneId, Long podId, Long clusterId, int level, Long limit){ StringBuilder finalQuery = new StringBuilder(); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); @@ -360,7 +360,7 @@ public class CapacityDaoImpl extends GenericDaoBase implements if(level == 3 && rs.getLong(7) != 0) capacityClusterId = rs.getLong(7); - SummedCapacity summedCapacity = new SummedCapacity( rs.getLong(1), rs.getLong(3), rs.getFloat(4), + SummedCapacity summedCapacity = new SummedCapacity( rs.getLong(1), rs.getLong(2), rs.getLong(3), rs.getFloat(4), (short)rs.getLong(5), rs.getLong(6), capacityPodId, capacityClusterId); @@ -378,7 +378,7 @@ public class CapacityDaoImpl extends GenericDaoBase implements @Override public List findCapacityBy(Integer capacityType, Long zoneId, Long podId, Long clusterId){ - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); @@ -425,7 +425,7 @@ public class CapacityDaoImpl extends GenericDaoBase implements } public void updateAllocated(Long hostId, long allocatedAmount, short capacityType, boolean add) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { txn.start(); @@ -458,7 +458,7 @@ public class CapacityDaoImpl extends GenericDaoBase implements @Override public List listClustersInZoneOrPodByHostCapacities(long id, int requiredCpu, long requiredRam, short capacityTypeForOrdering, boolean isZone){ - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); @@ -503,7 +503,7 @@ public class CapacityDaoImpl extends GenericDaoBase implements @Override public List listHostsWithEnoughCapacity(int requiredCpu, long requiredRam, Long clusterId, String hostType){ - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); @@ -565,6 +565,11 @@ public class CapacityDaoImpl extends GenericDaoBase implements this.dcId = zoneId; } + public SummedCapacity(long sumUsed, long sumReserved, long sumTotal, float percentUsed, short capacityType, Long zoneId, Long podId, Long clusterId) { + this(sumUsed, sumTotal, percentUsed, capacityType, zoneId, podId, clusterId); + this.sumReserved = sumReserved; + } + public Short getCapacityType() { return capacityType; } @@ -594,7 +599,7 @@ public class CapacityDaoImpl extends GenericDaoBase implements @Override public List findByClusterPodZone(Long zoneId, Long podId, Long clusterId){ - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); @@ -706,7 +711,7 @@ public class CapacityDaoImpl extends GenericDaoBase implements @Override public Pair, Map> orderClustersByAggregateCapacity(long id, short capacityTypeForOrdering, boolean isZone){ - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); Map clusterCapacityMap = new HashMap(); @@ -759,7 +764,7 @@ public class CapacityDaoImpl extends GenericDaoBase implements @Override public List listPodsByHostCapacities(long zoneId, int requiredCpu, long requiredRam, short capacityType) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); @@ -793,7 +798,7 @@ public class CapacityDaoImpl extends GenericDaoBase implements @Override public Pair, Map> orderPodsByAggregateCapacity(long zoneId, short capacityTypeForOrdering) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); Map podCapacityMap = new HashMap(); @@ -835,7 +840,7 @@ public class CapacityDaoImpl extends GenericDaoBase implements @Override public void updateCapacityState(Long dcId, Long podId, Long clusterId, Long hostId, String capacityState) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); StringBuilder sql = new StringBuilder(UPDATE_CAPACITY_STATE); List resourceIdList = new ArrayList(); diff --git a/engine/schema/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java b/engine/schema/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java index 9070ff912b3..0d99d30f11b 100644 --- a/engine/schema/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java +++ b/engine/schema/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java @@ -40,7 +40,7 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={ResourceCountDao.class}) @@ -158,7 +158,7 @@ public class ResourceCountDaoImpl extends GenericDaoBase @Override @DB public void createResourceCounts(long ownerId, ResourceLimit.ResourceOwnerType ownerType){ - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); ResourceType[] resourceTypes = Resource.ResourceType.values(); diff --git a/engine/schema/src/com/cloud/dc/ClusterDetailsDaoImpl.java b/engine/schema/src/com/cloud/dc/ClusterDetailsDaoImpl.java index f7f0f11ba07..72ac400ba72 100755 --- a/engine/schema/src/com/cloud/dc/ClusterDetailsDaoImpl.java +++ b/engine/schema/src/com/cloud/dc/ClusterDetailsDaoImpl.java @@ -30,7 +30,7 @@ import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Local(value=ClusterDetailsDao.class) public class ClusterDetailsDaoImpl extends GenericDaoBase implements ClusterDetailsDao, ScopedConfigStorage { @@ -100,7 +100,7 @@ public class ClusterDetailsDaoImpl extends GenericDaoBase details) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SearchCriteria sc = ClusterSearch.create(); sc.setParameters("clusterId", clusterId); @@ -119,7 +119,7 @@ public class ClusterDetailsDaoImpl extends GenericDaoBase sc = DetailSearch.create(); sc.setParameters("clusterId", clusterId); diff --git a/engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java index d115ce9e973..bd45ecd93fa 100644 --- a/engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java +++ b/engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java @@ -40,7 +40,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -156,7 +156,7 @@ public class ClusterDaoImpl extends GenericDaoBase implements C @Override public Map> getPodClusterIdMap(List clusterIds){ - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; Map> result = new HashMap>(); @@ -243,7 +243,7 @@ public class ClusterDaoImpl extends GenericDaoBase implements C @Override public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); ClusterVO cluster = createForUpdate(); cluster.setName(null); diff --git a/engine/schema/src/com/cloud/dc/dao/ClusterVSMMapDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/ClusterVSMMapDaoImpl.java index c3d3f2a9352..a01af0656a6 100644 --- a/engine/schema/src/com/cloud/dc/dao/ClusterVSMMapDaoImpl.java +++ b/engine/schema/src/com/cloud/dc/dao/ClusterVSMMapDaoImpl.java @@ -26,7 +26,7 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value=ClusterVSMMapDao.class) @@ -79,7 +79,7 @@ public class ClusterVSMMapDaoImpl extends GenericDaoBase } public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); ClusterVSMMapVO cluster = createForUpdate(); //cluster.setClusterId(null); diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java index 47b5522326a..e3b70a2f9af 100755 --- a/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java +++ b/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java @@ -44,7 +44,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SequenceFetcher; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.net.NetUtils; /** @@ -343,7 +343,7 @@ public class DataCenterDaoImpl extends GenericDaoBase implem @Override @DB public boolean update(Long zoneId, DataCenterVO zone) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); boolean persisted = super.update(zoneId, zone); if (!persisted) { @@ -408,7 +408,7 @@ public class DataCenterDaoImpl extends GenericDaoBase implem @Override public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); DataCenterVO zone = createForUpdate(); zone.setName(null); diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java index 0ec2bb50c7b..c2ed551a668 100755 --- a/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java +++ b/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java @@ -33,7 +33,7 @@ import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; @@ -52,7 +52,7 @@ public class DataCenterIpAddressDaoImpl extends GenericDaoBase { public List listAllocatedVnets(long physicalNetworkId); @@ -33,7 +34,7 @@ public interface DataCenterVnetDao extends GenericDao { public void delete(long physicalNetworkId); - public void deleteVnets(Transaction txn, long dcId, long physicalNetworkId, List vnets); + public void deleteVnets(TransactionLegacy txn, long dcId, long physicalNetworkId, List vnets); public void lockRange(long dcId, long physicalNetworkId, Integer start, Integer end); diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java index c052026eb2d..4e2aabf117f 100755 --- a/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java +++ b/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java @@ -38,7 +38,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; /** @@ -121,7 +121,7 @@ public class DataCenterVnetDaoImpl extends GenericDaoBase vnets) { String insertVnet = "INSERT INTO `cloud`.`op_dc_vnet_alloc` (vnet, data_center_id, physical_network_id) VALUES ( ?, ?, ?)"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { txn.start(); PreparedStatement stmt = txn.prepareAutoCloseStatement(insertVnet); @@ -139,7 +139,7 @@ public class DataCenterVnetDaoImpl extends GenericDaoBase argument each string is a vlan. not a vlanRange. - public void deleteVnets(Transaction txn, long dcId, long physicalNetworkId, List vnets) { + public void deleteVnets(TransactionLegacy txn, long dcId, long physicalNetworkId, List vnets) { String deleteVnet = "DELETE FROM `cloud`.`op_dc_vnet_alloc` WHERE data_center_id=? AND physical_network_id=? AND taken IS NULL AND vnet=?"; try { PreparedStatement stmt = txn.prepareAutoCloseStatement(deleteVnet); @@ -171,7 +171,7 @@ public class DataCenterVnetDaoImpl extends GenericDaoBase implements DcDetailsDao, ScopedConfigStorage { @@ -106,7 +106,7 @@ public class DcDetailsDaoImpl extends GenericDaoBase implement @Override public void persist(long dcId, Map details) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SearchCriteria sc = DcSearch.create(); sc.setParameters("dcId", dcId); diff --git a/engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java index f77dedae1b7..384fa00350f 100644 --- a/engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java +++ b/engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java @@ -35,7 +35,7 @@ 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; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={HostPodDao.class}) @@ -85,7 +85,7 @@ public class HostPodDaoImpl extends GenericDaoBase implements H HashMap> currentPodCidrSubnets = new HashMap>(); String selectSql = "SELECT id, cidr_address, cidr_size FROM host_pod_ref WHERE data_center_id=" + zoneId +" and removed IS NULL"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql); ResultSet rs = stmt.executeQuery(); @@ -111,7 +111,7 @@ public class HostPodDaoImpl extends GenericDaoBase implements H @Override public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); HostPodVO pod = createForUpdate(); pod.setName(null); diff --git a/engine/schema/src/com/cloud/dc/dao/PodVlanDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/PodVlanDaoImpl.java index 413f9ed6c18..9e9a0e77d18 100755 --- a/engine/schema/src/com/cloud/dc/dao/PodVlanDaoImpl.java +++ b/engine/schema/src/com/cloud/dc/dao/PodVlanDaoImpl.java @@ -28,7 +28,7 @@ import com.cloud.utils.db.GenericDao; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; /** @@ -49,7 +49,7 @@ public class PodVlanDaoImpl extends GenericDaoBase implements P public void add(long podId, int start, int end) { String insertVnet = "INSERT INTO `cloud`.`op_pod_vlan_alloc` (vlan, pod_id) VALUES ( ?, ?)"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { txn.start(); PreparedStatement stmt = txn.prepareAutoCloseStatement(insertVnet); @@ -68,7 +68,7 @@ public class PodVlanDaoImpl extends GenericDaoBase implements P public void delete(long podId) { String deleteVnet = "DELETE FROM `cloud`.`op_pod_vlan_alloc` WHERE pod_id = ?"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(deleteVnet); stmt.setLong(1, podId); @@ -82,7 +82,7 @@ public class PodVlanDaoImpl extends GenericDaoBase implements P SearchCriteria sc = FreeVlanSearch.create(); sc.setParameters("podId", podId); Date now = new Date(); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { txn.start(); PodVlanVO vo = lockOneRandomRow(sc, true); diff --git a/engine/schema/src/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java index a7bb9c1c005..d6a38794ba5 100755 --- a/engine/schema/src/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java +++ b/engine/schema/src/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java @@ -30,10 +30,10 @@ import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.GenericQueryBuilder; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={StorageNetworkIpAddressDao.class}) @@ -87,7 +87,7 @@ public class StorageNetworkIpAddressDaoImpl extends GenericDaoBase sc = untakenIp.create(); sc.setParameters("rangeId", rangeId); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); StorageNetworkIpAddressVO ip = lockOneRandomRow(sc, true); if (ip == null) { diff --git a/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java index 6f5a01f1476..6ec819d17f1 100755 --- a/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java +++ b/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java @@ -28,7 +28,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; import org.springframework.stereotype.Component; @@ -301,7 +301,7 @@ public class VlanDaoImpl extends GenericDaoBase implements VlanDao StringBuilder sql = new StringBuilder(FindZoneWideVlans); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(sql.toString()); diff --git a/engine/schema/src/com/cloud/domain/dao/DomainDaoImpl.java b/engine/schema/src/com/cloud/domain/dao/DomainDaoImpl.java index 3d0588e8da6..3fd1d582302 100644 --- a/engine/schema/src/com/cloud/domain/dao/DomainDaoImpl.java +++ b/engine/schema/src/com/cloud/domain/dao/DomainDaoImpl.java @@ -35,7 +35,7 @@ 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.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={DomainDao.class}) @@ -117,7 +117,7 @@ public class DomainDaoImpl extends GenericDaoBase implements Dom return null; } - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { txn.start(); @@ -168,7 +168,7 @@ public class DomainDaoImpl extends GenericDaoBase implements Dom String sql1 = "SELECT * from domain where parent = " + id + " and removed is null"; boolean success = false; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { txn.start(); DomainVO parentDomain = super.lockRow(domain.getParent(), true); @@ -224,7 +224,7 @@ public class DomainDaoImpl extends GenericDaoBase implements Dom @Override public List findAllChildren(String path, Long parentId){ SearchCriteria sc = FindAllChildrenSearch.create(); - sc.setParameters("path", "%"+path+"%"); + sc.setParameters("path", path+"%"); sc.setParameters("id", parentId); return listBy(sc); } diff --git a/engine/schema/src/com/cloud/event/dao/EventDaoImpl.java b/engine/schema/src/com/cloud/event/dao/EventDaoImpl.java index e5615db3433..f3a11c601e3 100644 --- a/engine/schema/src/com/cloud/event/dao/EventDaoImpl.java +++ b/engine/schema/src/com/cloud/event/dao/EventDaoImpl.java @@ -30,7 +30,7 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.db.SearchCriteria.Op; @Component @@ -104,7 +104,7 @@ public class EventDaoImpl extends GenericDaoBase implements Event @Override public void archiveEvents(List events) { if (events != null && !events.isEmpty()) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); for (EventVO event : events) { event = lockRow(event.getId(), true); diff --git a/engine/schema/src/com/cloud/event/dao/UsageEventDaoImpl.java b/engine/schema/src/com/cloud/event/dao/UsageEventDaoImpl.java index 4f05bbe8fcd..43339038c53 100644 --- a/engine/schema/src/com/cloud/event/dao/UsageEventDaoImpl.java +++ b/engine/schema/src/com/cloud/event/dao/UsageEventDaoImpl.java @@ -36,7 +36,7 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -90,7 +90,7 @@ public class UsageEventDaoImpl extends GenericDaoBase implem public synchronized List getRecentEvents(Date endDate) { long recentEventId = getMostRecentEventId(); long maxEventId = getMaxEventId(endDate); - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); String sql = COPY_EVENTS; if (recentEventId == 0) { if (s_logger.isDebugEnabled()) { @@ -120,7 +120,7 @@ public class UsageEventDaoImpl extends GenericDaoBase implem @DB private long getMostRecentEventId() { - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); try { List latestEvents = getLatestEvent(); @@ -140,7 +140,7 @@ public class UsageEventDaoImpl extends GenericDaoBase implem } private List findRecentEvents(Date endDate) { - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); try { return listLatestEvents(endDate); } catch (Exception ex) { @@ -152,7 +152,7 @@ public class UsageEventDaoImpl extends GenericDaoBase implem } private long getMaxEventId(Date endDate) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { String sql = MAX_EVENT; diff --git a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java index caf7c014bd0..c51e2c7ff60 100755 --- a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java +++ b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java @@ -59,7 +59,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.db.UpdateBuilder; import com.cloud.utils.exception.CloudRuntimeException; @@ -490,7 +490,7 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao @Override @DB public List findAndUpdateDirectAgentToLoad(long lastPingSecondsAfter, Long limit, long managementServerId) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); if (s_logger.isDebugEnabled()) { @@ -589,7 +589,7 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao @Override @DB public List findAndUpdateApplianceToLoad(long lastPingSecondsAfter, long managementServerId) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SearchCriteria sc = UnmanagedApplianceSearch.create(); @@ -728,7 +728,7 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao @DB @Override public List findLostHosts(long timeout) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); ResultSet rs = null; @@ -779,7 +779,7 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao public HostVO persist(HostVO host) { final String InsertSequenceSql = "INSERT INTO op_host(id) VALUES(?)"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); HostVO dbHost = super.persist(host); @@ -805,7 +805,7 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao @Override @DB public boolean update(Long hostId, HostVO host) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); boolean persisted = super.update(hostId, host); @@ -831,7 +831,7 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao ArrayList l = new ArrayList(); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); ; PreparedStatement pstmt = null; try { diff --git a/engine/schema/src/com/cloud/host/dao/HostDetailsDaoImpl.java b/engine/schema/src/com/cloud/host/dao/HostDetailsDaoImpl.java index 47cdeb30633..7b7267cccf5 100644 --- a/engine/schema/src/com/cloud/host/dao/HostDetailsDaoImpl.java +++ b/engine/schema/src/com/cloud/host/dao/HostDetailsDaoImpl.java @@ -31,7 +31,7 @@ import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -96,7 +96,7 @@ public class HostDetailsDaoImpl extends GenericDaoBase implement public void persist(long hostId, Map details) { final String InsertOrUpdateSql = "INSERT INTO `cloud`.`host_details` (host_id, name, value) VALUES (?,?,?) ON DUPLICATE KEY UPDATE value=?"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); for (Map.Entry detail : details.entrySet()) { diff --git a/engine/schema/src/com/cloud/host/dao/HostTagsDaoImpl.java b/engine/schema/src/com/cloud/host/dao/HostTagsDaoImpl.java index 0e93275d360..b12fd7e1ac1 100644 --- a/engine/schema/src/com/cloud/host/dao/HostTagsDaoImpl.java +++ b/engine/schema/src/com/cloud/host/dao/HostTagsDaoImpl.java @@ -27,7 +27,7 @@ import com.cloud.host.HostTagVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value=HostTagsDao.class) @@ -56,7 +56,7 @@ public class HostTagsDaoImpl extends GenericDaoBase implements @Override public void persist(long hostId, List hostTags) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SearchCriteria sc = HostSearch.create(); diff --git a/engine/schema/src/com/cloud/keystore/KeystoreDaoImpl.java b/engine/schema/src/com/cloud/keystore/KeystoreDaoImpl.java index f53f228e6b3..370f874ecd9 100644 --- a/engine/schema/src/com/cloud/keystore/KeystoreDaoImpl.java +++ b/engine/schema/src/com/cloud/keystore/KeystoreDaoImpl.java @@ -30,7 +30,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -74,7 +74,7 @@ public class KeystoreDaoImpl extends GenericDaoBase implements @Override @DB public void save(String name, String certificate, String key, String domainSuffix) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { txn.start(); diff --git a/engine/schema/src/com/cloud/network/dao/FirewallRulesCidrsDaoImpl.java b/engine/schema/src/com/cloud/network/dao/FirewallRulesCidrsDaoImpl.java index b007e19e779..26f399d1246 100644 --- a/engine/schema/src/com/cloud/network/dao/FirewallRulesCidrsDaoImpl.java +++ b/engine/schema/src/com/cloud/network/dao/FirewallRulesCidrsDaoImpl.java @@ -28,7 +28,7 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value=FirewallRulesCidrsDao.class) @@ -58,7 +58,7 @@ public class FirewallRulesCidrsDaoImpl extends GenericDaoBase sourceCidrs) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); for (String tag : sourceCidrs) { diff --git a/engine/schema/src/com/cloud/network/dao/FirewallRulesDaoImpl.java b/engine/schema/src/com/cloud/network/dao/FirewallRulesDaoImpl.java index cd7878f08c8..daac54a1709 100644 --- a/engine/schema/src/com/cloud/network/dao/FirewallRulesDaoImpl.java +++ b/engine/schema/src/com/cloud/network/dao/FirewallRulesDaoImpl.java @@ -29,7 +29,7 @@ import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.FirewallRule.State; import com.cloud.network.rules.FirewallRule.TrafficType; import com.cloud.network.rules.FirewallRuleVO; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; @@ -39,7 +39,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value = FirewallRulesDao.class) @@ -220,7 +220,7 @@ public class FirewallRulesDaoImpl extends GenericDaoBase i @Override @DB public FirewallRuleVO persist(FirewallRuleVO firewallRule) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); FirewallRuleVO dbfirewallRule = super.persist(firewallRule); @@ -309,18 +309,18 @@ public class FirewallRulesDaoImpl extends GenericDaoBase i @Override @DB public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); FirewallRuleVO entry = findById(id); if (entry != null) { if (entry.getPurpose() == Purpose.LoadBalancing) { - _tagsDao.removeByIdAndType(id, TaggedResourceType.LoadBalancer); + _tagsDao.removeByIdAndType(id, ResourceObjectType.LoadBalancer); } else if (entry.getPurpose() == Purpose.PortForwarding) { - _tagsDao.removeByIdAndType(id, TaggedResourceType.PortForwardingRule); + _tagsDao.removeByIdAndType(id, ResourceObjectType.PortForwardingRule); } else if (entry.getPurpose() == Purpose.Firewall) { - _tagsDao.removeByIdAndType(id, TaggedResourceType.FirewallRule); + _tagsDao.removeByIdAndType(id, ResourceObjectType.FirewallRule); } else if (entry.getPurpose() == Purpose.NetworkACL) { - _tagsDao.removeByIdAndType(id, TaggedResourceType.NetworkACL); + _tagsDao.removeByIdAndType(id, ResourceObjectType.NetworkACL); } } boolean result = super.remove(id); diff --git a/engine/schema/src/com/cloud/network/dao/IPAddressDaoImpl.java b/engine/schema/src/com/cloud/network/dao/IPAddressDaoImpl.java index 9f5f403631b..08bff891968 100755 --- a/engine/schema/src/com/cloud/network/dao/IPAddressDaoImpl.java +++ b/engine/schema/src/com/cloud/network/dao/IPAddressDaoImpl.java @@ -21,7 +21,7 @@ import com.cloud.dc.Vlan.VlanType; import com.cloud.dc.VlanVO; import com.cloud.dc.dao.VlanDao; import com.cloud.network.IpAddress.State; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; @@ -31,7 +31,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.net.Ip; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -285,7 +285,7 @@ public class IPAddressDaoImpl extends GenericDaoBase implemen @Override @DB public int countIPs(long dcId, Long accountId, String vlanId, String vlanGateway, String vlanNetmask) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); int ipCount = 0; try { String sql = "SELECT count(*) FROM user_ip_address u INNER JOIN vlan v on (u.vlan_db_id = v.id AND v.data_center_id = ? AND v.vlan_id = ? AND v.vlan_gateway = ? AND v.vlan_netmask = ? AND u.account_id = ?)"; @@ -390,11 +390,11 @@ public class IPAddressDaoImpl extends GenericDaoBase implemen @Override @DB public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); IPAddressVO entry = findById(id); if (entry != null) { - _tagsDao.removeByIdAndType(id, TaggedResourceType.SecurityGroup); + _tagsDao.removeByIdAndType(id, ResourceObjectType.SecurityGroup); } boolean result = super.remove(id); txn.commit(); diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java b/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java index 72b357d659c..90ba4a32828 100644 --- a/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java +++ b/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java @@ -40,7 +40,7 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.offering.NetworkOffering; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.utils.db.*; import com.cloud.utils.db.JoinBuilder.JoinType; @@ -289,7 +289,7 @@ public class NetworkDaoImpl extends GenericDaoBase implements N @Override @DB public NetworkVO persist(NetworkVO network, boolean gc, Map serviceProviderMap) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); // 1) create network @@ -309,7 +309,7 @@ public class NetworkDaoImpl extends GenericDaoBase implements N @Override @DB public boolean update(Long networkId, NetworkVO network, Map serviceProviderMap) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); super.update(networkId, network); @@ -325,7 +325,7 @@ public class NetworkDaoImpl extends GenericDaoBase implements N @Override @DB public void persistNetworkServiceProviders(long networkId, Map serviceProviderMap) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); for (String service : serviceProviderMap.keySet()) { NetworkServiceMapVO serviceMap = new NetworkServiceMapVO(networkId, Service.getService(service), Provider.getProvider(serviceProviderMap.get(service))); @@ -576,11 +576,11 @@ public class NetworkDaoImpl extends GenericDaoBase implements N @Override @DB public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); NetworkVO entry = findById(id); if (entry != null) { - _tagsDao.removeByIdAndType(id, TaggedResourceType.Network); + _tagsDao.removeByIdAndType(id, ResourceObjectType.Network); } boolean result = super.remove(id); txn.commit(); @@ -599,7 +599,7 @@ public class NetworkDaoImpl extends GenericDaoBase implements N @Override public boolean updateState(State currentState, Event event, State nextState, Network vo, Object data) { // TODO: ensure this update is correct - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); NetworkVO networkVo = (NetworkVO) vo; diff --git a/engine/schema/src/com/cloud/network/dao/PortProfileDaoImpl.java b/engine/schema/src/com/cloud/network/dao/PortProfileDaoImpl.java index 2325c4a9705..64a846c6d5b 100644 --- a/engine/schema/src/com/cloud/network/dao/PortProfileDaoImpl.java +++ b/engine/schema/src/com/cloud/network/dao/PortProfileDaoImpl.java @@ -29,7 +29,7 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.exception.CloudRuntimeException; @@ -66,7 +66,7 @@ public class PortProfileDaoImpl extends GenericDaoBase impl String condition = "(trunk_low_vlan_id BETWEEN " + lowVlanId + " AND " + highVlanId + ")" + " OR (trunk_high_vlan_id BETWEEN " + lowVlanId + " AND " + highVlanId + ")"; String selectSql = "SELECT * FROM `" + dbName + "`.`" + tableName + "` WHERE " + condition; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql); ResultSet rs = stmt.executeQuery(); diff --git a/engine/schema/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java b/engine/schema/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java index d82cc4a79b5..31131b8bd3d 100644 --- a/engine/schema/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java +++ b/engine/schema/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java @@ -24,7 +24,7 @@ import javax.inject.Inject; import org.springframework.stereotype.Component; import com.cloud.network.security.SecurityGroupVO; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.tags.dao.ResourceTagsDaoImpl; @@ -32,7 +32,7 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={SecurityGroupDao.class}) @@ -109,11 +109,11 @@ public class SecurityGroupDaoImpl extends GenericDaoBase @Override @DB public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SecurityGroupVO entry = findById(id); if (entry != null) { - _tagsDao.removeByIdAndType(id, TaggedResourceType.SecurityGroup); + _tagsDao.removeByIdAndType(id, ResourceObjectType.SecurityGroup); } boolean result = super.remove(id); txn.commit(); @@ -123,11 +123,11 @@ public class SecurityGroupDaoImpl extends GenericDaoBase @Override @DB public boolean expunge(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SecurityGroupVO entry = findById(id); if (entry != null) { - _tagsDao.removeByIdAndType(id, TaggedResourceType.SecurityGroup); + _tagsDao.removeByIdAndType(id, ResourceObjectType.SecurityGroup); } boolean result = super.expunge(id); txn.commit(); diff --git a/engine/schema/src/com/cloud/network/security/dao/SecurityGroupWorkDaoImpl.java b/engine/schema/src/com/cloud/network/security/dao/SecurityGroupWorkDaoImpl.java index 3154ffeb873..98cc0d3fc65 100644 --- a/engine/schema/src/com/cloud/network/security/dao/SecurityGroupWorkDaoImpl.java +++ b/engine/schema/src/com/cloud/network/security/dao/SecurityGroupWorkDaoImpl.java @@ -33,7 +33,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -100,7 +100,7 @@ public class SecurityGroupWorkDaoImpl extends GenericDaoBase sc = UntakenWorkSearch.create(); sc.setParameters("step", Step.Scheduled); @@ -149,7 +149,7 @@ public class SecurityGroupWorkDaoImpl extends GenericDaoBase sc = VmIdSeqNumSearch.create(); sc.setParameters("vmId", vmId); @@ -180,7 +180,7 @@ public class SecurityGroupWorkDaoImpl extends GenericDaoBase im return createOrUpdateUsingMultiInsert(workItems); } - private int executeWithRetryOnDeadlock(Transaction txn, String pstmt, List vmIds) throws SQLException { + private int executeWithRetryOnDeadlock(TransactionLegacy txn, String pstmt, List vmIds) throws SQLException { int numUpdated = 0; final int maxTries = 3; @@ -120,7 +120,7 @@ public class VmRulesetLogDaoImpl extends GenericDaoBase im } protected int createOrUpdateUsingMultiInsert(Set workItems) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); int size = workItems.size(); int count = 0; @@ -156,7 +156,7 @@ public class VmRulesetLogDaoImpl extends GenericDaoBase im } protected int createOrUpdateUsingBatch(Set workItems) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement stmtInsert = null; int [] queryResult = null; int count=0; diff --git a/engine/schema/src/com/cloud/network/vpc/dao/PrivateIpDaoImpl.java b/engine/schema/src/com/cloud/network/vpc/dao/PrivateIpDaoImpl.java index 5ed7fb2f757..7511657c0ea 100644 --- a/engine/schema/src/com/cloud/network/vpc/dao/PrivateIpDaoImpl.java +++ b/engine/schema/src/com/cloud/network/vpc/dao/PrivateIpDaoImpl.java @@ -32,7 +32,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value = PrivateIpDao.class) @@ -78,7 +78,7 @@ public class PrivateIpDaoImpl extends GenericDaoBase implemen sc.setParameters("ipAddress", requestedIp); } - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); PrivateIpVO vo = lockOneRandomRow(sc, true); if (vo == null) { diff --git a/engine/schema/src/com/cloud/network/vpc/dao/StaticRouteDaoImpl.java b/engine/schema/src/com/cloud/network/vpc/dao/StaticRouteDaoImpl.java index e7e006e852e..a85b907f89c 100644 --- a/engine/schema/src/com/cloud/network/vpc/dao/StaticRouteDaoImpl.java +++ b/engine/schema/src/com/cloud/network/vpc/dao/StaticRouteDaoImpl.java @@ -25,7 +25,7 @@ import org.springframework.stereotype.Component; import com.cloud.network.vpc.StaticRoute; import com.cloud.network.vpc.StaticRouteVO; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.tags.dao.ResourceTagsDaoImpl; @@ -36,7 +36,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value = StaticRouteDao.class) @@ -106,11 +106,11 @@ public class StaticRouteDaoImpl extends GenericDaoBase impl @Override @DB public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); StaticRouteVO entry = findById(id); if (entry != null) { - _tagsDao.removeByIdAndType(id, TaggedResourceType.StaticRoute); + _tagsDao.removeByIdAndType(id, ResourceObjectType.StaticRoute); } boolean result = super.remove(id); txn.commit(); diff --git a/engine/schema/src/com/cloud/network/vpc/dao/VpcDaoImpl.java b/engine/schema/src/com/cloud/network/vpc/dao/VpcDaoImpl.java index 289b896899a..ba030e9a44a 100644 --- a/engine/schema/src/com/cloud/network/vpc/dao/VpcDaoImpl.java +++ b/engine/schema/src/com/cloud/network/vpc/dao/VpcDaoImpl.java @@ -28,7 +28,7 @@ import org.springframework.stereotype.Component; import com.cloud.network.vpc.Vpc; import com.cloud.network.vpc.VpcVO; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.utils.db.DB; @@ -38,7 +38,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value = VpcDao.class) @@ -107,11 +107,11 @@ public class VpcDaoImpl extends GenericDaoBase implements VpcDao{ @Override @DB public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); VpcVO entry = findById(id); if (entry != null) { - _tagsDao.removeByIdAndType(id, TaggedResourceType.Vpc); + _tagsDao.removeByIdAndType(id, ResourceObjectType.Vpc); } boolean result = super.remove(id); txn.commit(); @@ -129,7 +129,7 @@ public class VpcDaoImpl extends GenericDaoBase implements VpcDao{ @Override @DB public VpcVO persist(VpcVO vpc, Map> serviceProviderMap) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); VpcVO newVpc = super.persist(vpc); persistVpcServiceProviders(vpc.getId(), serviceProviderMap); @@ -140,7 +140,7 @@ public class VpcDaoImpl extends GenericDaoBase implements VpcDao{ @Override @DB public void persistVpcServiceProviders(long vpcId, Map> serviceProviderMap) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); for (String service : serviceProviderMap.keySet()) { for (String provider : serviceProviderMap.get(service)) { diff --git a/engine/schema/src/com/cloud/network/vpc/dao/VpcOfferingDaoImpl.java b/engine/schema/src/com/cloud/network/vpc/dao/VpcOfferingDaoImpl.java index b5a7e4dd7bf..3453da04483 100644 --- a/engine/schema/src/com/cloud/network/vpc/dao/VpcOfferingDaoImpl.java +++ b/engine/schema/src/com/cloud/network/vpc/dao/VpcOfferingDaoImpl.java @@ -26,7 +26,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value = VpcOfferingDao.class) @@ -51,7 +51,7 @@ public class VpcOfferingDaoImpl extends GenericDaoBase impl @Override @DB public boolean remove(Long vpcOffId) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); VpcOfferingVO offering = findById(vpcOffId); offering.setUniqueName(null); diff --git a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java index eefdc9442c8..d9fb54399f9 100755 --- a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java +++ b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java @@ -136,6 +136,8 @@ public class NetworkOfferingVO implements NetworkOffering { @Column(name = "concurrent_connections") Integer concurrentConnections; + @Column(name = "keep_alive_enabled") + boolean keepAliveEnabled = false; @Override public String getDisplayText() { @@ -148,6 +150,15 @@ public class NetworkOfferingVO implements NetworkOffering { @Column(name = "public_lb") boolean publicLb; + @Override + public boolean isKeepAliveEnabled() { + return keepAliveEnabled; + } + + public void setKeepAliveEnabled(boolean keepAliveEnabled) { + this.keepAliveEnabled = keepAliveEnabled; + } + @Override public long getId() { return id; @@ -430,6 +441,7 @@ public class NetworkOfferingVO implements NetworkOffering { this.internalLb = internalLb; } + @Override public Integer getConcurrentConnections() { return this.concurrentConnections; } diff --git a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java index 1c0a1d74743..19290a60693 100644 --- a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java +++ b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java @@ -38,7 +38,7 @@ 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; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value = NetworkOfferingDao.class) @@ -129,7 +129,7 @@ public class NetworkOfferingDaoImpl extends GenericDaoBase details) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); //1) persist the offering NetworkOfferingVO vo = super.persist(off); diff --git a/engine/schema/src/com/cloud/projects/dao/ProjectDaoImpl.java b/engine/schema/src/com/cloud/projects/dao/ProjectDaoImpl.java index ecf40dacaff..63a21c4614f 100644 --- a/engine/schema/src/com/cloud/projects/dao/ProjectDaoImpl.java +++ b/engine/schema/src/com/cloud/projects/dao/ProjectDaoImpl.java @@ -26,7 +26,7 @@ import org.springframework.stereotype.Component; import com.cloud.projects.Project; import com.cloud.projects.ProjectVO; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.tags.dao.ResourceTagsDaoImpl; @@ -36,7 +36,7 @@ import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value = { ProjectDao.class }) @@ -75,7 +75,7 @@ public class ProjectDaoImpl extends GenericDaoBase implements P @DB public boolean remove(Long projectId) { boolean result = false; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); ProjectVO projectToRemove = findById(projectId); projectToRemove.setName(null); @@ -84,7 +84,7 @@ public class ProjectDaoImpl extends GenericDaoBase implements P return false; } - _tagsDao.removeByIdAndType(projectId, TaggedResourceType.Project); + _tagsDao.removeByIdAndType(projectId, ResourceObjectType.Project); result = super.remove(projectId); txn.commit(); diff --git a/engine/schema/src/com/cloud/service/dao/ServiceOfferingDetailsDaoImpl.java b/engine/schema/src/com/cloud/service/dao/ServiceOfferingDetailsDaoImpl.java index 91d736a38c4..70fd5701507 100644 --- a/engine/schema/src/com/cloud/service/dao/ServiceOfferingDetailsDaoImpl.java +++ b/engine/schema/src/com/cloud/service/dao/ServiceOfferingDetailsDaoImpl.java @@ -28,7 +28,7 @@ import com.cloud.service.ServiceOfferingDetailsVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value=ServiceOfferingDetailsDao.class) @@ -82,7 +82,7 @@ public class ServiceOfferingDetailsDaoImpl extends GenericDaoBase details) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SearchCriteria sc = ServiceOfferingSearch.create(); sc.setParameters("serviceOfferingId", serviceOfferingId); diff --git a/engine/schema/src/com/cloud/storage/VMTemplateStoragePoolVO.java b/engine/schema/src/com/cloud/storage/VMTemplateStoragePoolVO.java index 8ee0c4a5955..b9886e08237 100644 --- a/engine/schema/src/com/cloud/storage/VMTemplateStoragePoolVO.java +++ b/engine/schema/src/com/cloud/storage/VMTemplateStoragePoolVO.java @@ -257,7 +257,7 @@ public class VMTemplateStoragePoolVO implements VMTemplateStorageResourceAssoc, @Override public String toString() { - return new StringBuilder("TmplPool[").append(id).append("-").append(templateId).append("-").append("poolId") + return new StringBuilder("TmplPool[").append(id).append("-").append(templateId).append("-").append(poolId) .append("-").append(installPath).append("]").toString(); } diff --git a/engine/schema/src/com/cloud/storage/dao/LaunchPermissionDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/LaunchPermissionDaoImpl.java index 3e32f1a9529..60c87af0fcc 100644 --- a/engine/schema/src/com/cloud/storage/dao/LaunchPermissionDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/LaunchPermissionDaoImpl.java @@ -35,7 +35,7 @@ import com.cloud.utils.DateUtil; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -69,7 +69,7 @@ public class LaunchPermissionDaoImpl extends GenericDaoBase accountIds) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { txn.start(); @@ -106,7 +106,7 @@ public class LaunchPermissionDaoImpl extends GenericDaoBase listPermittedTemplates(long accountId) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); List permittedTemplates = new ArrayList(); PreparedStatement pstmt = null; try { diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java index f5319ea120a..c56a3cf43b8 100644 --- a/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java @@ -27,7 +27,7 @@ import javax.inject.Inject; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.storage.DataStoreRole; import com.cloud.storage.Snapshot; import com.cloud.storage.Snapshot.Event; @@ -47,7 +47,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.dao.VMInstanceDao; @@ -204,7 +204,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements @Override public Long getSecHostId(long volumeId) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; String sql = GET_SECHOST_ID; try { @@ -221,7 +221,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements @Override public long getLastSnapshot(long volumeId, DataStoreRole role) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; String sql = GET_LAST_SNAPSHOT; try { @@ -240,7 +240,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements @Override public long updateSnapshotVersion(long volumeId, String from, String to) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; String sql = UPDATE_SNAPSHOT_VERSION; try { @@ -258,7 +258,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements @Override public long updateSnapshotSecHost(long dcId, long secHostId) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; String sql = UPDATE_SECHOST_ID; try { @@ -304,11 +304,11 @@ public class SnapshotDaoImpl extends GenericDaoBase implements @Override @DB public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SnapshotVO entry = findById(id); if (entry != null) { - _tagsDao.removeByIdAndType(id, TaggedResourceType.Snapshot); + _tagsDao.removeByIdAndType(id, ResourceObjectType.Snapshot); } boolean result = super.remove(id); txn.commit(); @@ -324,7 +324,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements @Override public boolean updateState(State currentState, Event event, State nextState, SnapshotVO snapshot, Object data) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SnapshotVO snapshotVO = (SnapshotVO) snapshot; snapshotVO.setState(nextState); diff --git a/engine/schema/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java index f60ea176f52..7859ca796b0 100644 --- a/engine/schema/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java @@ -31,7 +31,7 @@ import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Local(value = StoragePoolDetailsDao.class) public class StoragePoolDetailsDaoImpl extends GenericDaoBase implements StoragePoolDetailsDao, ScopedConfigStorage { @@ -48,7 +48,7 @@ public class StoragePoolDetailsDaoImpl extends GenericDaoBase details) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); SearchCriteria sc = PoolSearch.create(); sc.setParameters("pool", poolId); diff --git a/engine/schema/src/com/cloud/storage/dao/StoragePoolHostDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/StoragePoolHostDaoImpl.java index 730216b82b0..ba0c48daf09 100644 --- a/engine/schema/src/com/cloud/storage/dao/StoragePoolHostDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/StoragePoolHostDaoImpl.java @@ -33,7 +33,7 @@ import com.cloud.utils.Pair; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value = { StoragePoolHostDao.class }) @@ -104,7 +104,7 @@ public class StoragePoolHostDaoImpl extends GenericDaoBase listByHostStatus(long poolId, Status hostStatus) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); ResultSet rs = null; @@ -142,7 +142,7 @@ public class StoragePoolHostDaoImpl extends GenericDaoBase> getDatacenterStoragePoolHostInfo(long dcId, boolean sharedOnly) { ArrayList> l = new ArrayList>(); String sql = sharedOnly ? SHARED_STORAGE_POOL_HOST_INFO : STORAGE_POOL_HOST_INFO; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); ; PreparedStatement pstmt = null; try { @@ -169,7 +169,7 @@ public class StoragePoolHostDaoImpl extends GenericDaoBase sc = HostSearch.create(); sc.setParameters("host_id", hostId); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); remove(sc); txn.commit(); @@ -180,7 +180,7 @@ public class StoragePoolHostDaoImpl extends GenericDaoBase sc = PoolHostSearch.create(); sc.setParameters("host_id", hostId); sc.setParameters("pool_id", poolId); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); remove(sc); txn.commit(); diff --git a/engine/schema/src/com/cloud/storage/dao/StoragePoolWorkDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/StoragePoolWorkDaoImpl.java index aa3e0df04ea..df0b6f2312b 100644 --- a/engine/schema/src/com/cloud/storage/dao/StoragePoolWorkDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/StoragePoolWorkDaoImpl.java @@ -31,7 +31,7 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -125,7 +125,7 @@ public class StoragePoolWorkDaoImpl extends GenericDaoBase { List findTemplatesToSyncToS3(); + void loadDetails(VMTemplateVO tmpl); + + void saveDetails(VMTemplateVO tmpl); } diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java index a96524cdd9f..71ec6c72264 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -40,7 +40,7 @@ import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.storage.Storage; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; @@ -57,7 +57,7 @@ import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -175,7 +175,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem if (tags != null && !tags.isEmpty()) { int count = 0; - sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.ISO.toString()); + sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.ISO.toString()); for (String key : tags.keySet()) { sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); @@ -220,7 +220,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem List l = new ArrayList(); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { @@ -402,6 +402,23 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem return routerTmpltName; } + + @Override + public void loadDetails(VMTemplateVO tmpl) { + Map details = _templateDetailsDao.findDetails(tmpl.getId()); + tmpl.setDetails(details); + } + + @Override + public void saveDetails(VMTemplateVO tmpl) { + Map details = tmpl.getDetails(); + if (details == null) { + return; + } + _templateDetailsDao.persist(tmpl.getId(), details); + } + + /* * @Override public Set> searchSwiftTemplates(String name, * String keyword, TemplateFilter templateFilter, boolean isIso, @@ -421,7 +438,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * permittedAccountsStr = permittedAccountsStr.substring(0, * permittedAccountsStr.length() - 1); } * - * Transaction txn = Transaction.currentTxn(); txn.start(); + * TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); * * Set> templateZonePairList = new HashSet>(); PreparedStatement pstmt = null; ResultSet rs = null; String sql @@ -505,7 +522,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * permittedAccountsStr = permittedAccountsStr.substring(0, * permittedAccountsStr.length()-1); } * - * Transaction txn = Transaction.currentTxn(); txn.start(); + * TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); * * // Use LinkedHashSet here to guarantee iteration order Set> templateZonePairList = new LinkedHashSet>(); @@ -720,7 +737,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem @Override @DB public long addTemplateToZone(VMTemplateVO tmplt, long zoneId) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); VMTemplateVO tmplt2 = findById(tmplt.getId()); if (tmplt2 == null) { @@ -855,7 +872,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem @Override @DB public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); VMTemplateVO template = createForUpdate(); template.setRemoved(new Date()); @@ -863,9 +880,9 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem VMTemplateVO vo = findById(id); if (vo != null) { if (vo.getFormat() == ImageFormat.ISO) { - _tagsDao.removeByIdAndType(id, TaggedResourceType.ISO); + _tagsDao.removeByIdAndType(id, ResourceObjectType.ISO); } else { - _tagsDao.removeByIdAndType(id, TaggedResourceType.Template); + _tagsDao.removeByIdAndType(id, ResourceObjectType.Template); } } @@ -890,7 +907,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * * final String permittedAccountsStr = join(",", permittedAccounts); * - * final Transaction txn = Transaction.currentTxn(); txn.start(); + * final TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); * * Set> templateZonePairList = new HashSet>(); PreparedStatement pstmt = null; ResultSet rs = null; try { diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDetailsDao.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDetailsDao.java index 552f8f00a86..3021b8f956f 100644 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDetailsDao.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDetailsDao.java @@ -29,4 +29,8 @@ public interface VMTemplateDetailsDao extends GenericDao details) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SearchCriteria sc = TemplateSearch.create(); sc.setParameters("templateId", templateId); @@ -96,4 +96,28 @@ public class VMTemplateDetailsDaoImpl extends GenericDaoBase listByTemplateStatus(long templateId, long datacenterId, VMTemplateHostVO.Status downloadState) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); try { @@ -267,7 +267,7 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase listByTemplateStatus(long templateId, long datacenterId, long podId, VMTemplateHostVO.Status downloadState) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); ResultSet rs = null; diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java index ba8135b5f32..b121297437a 100644 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java @@ -38,7 +38,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.db.UpdateBuilder; @Component @@ -150,7 +150,7 @@ public class VMTemplatePoolDaoImpl extends GenericDaoBase listByTemplateStatus(long templateId, long datacenterId, VMTemplateStoragePoolVO.Status downloadState) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); try { @@ -173,7 +173,7 @@ public class VMTemplatePoolDaoImpl extends GenericDaoBase listByTemplateStatus(long templateId, long datacenterId, long podId, VMTemplateStoragePoolVO.Status downloadState) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); ResultSet rs = null; @@ -210,7 +210,7 @@ public class VMTemplatePoolDaoImpl extends GenericDaoBase listByHostTemplate(long hostId, long templateId) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); ResultSet rs = null; diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java index c4a4dc7230a..a56959d32ab 100644 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java @@ -27,7 +27,7 @@ import com.cloud.storage.VMTemplateZoneVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value = { VMTemplateZoneDao.class }) @@ -89,7 +89,7 @@ public class VMTemplateZoneDaoImpl extends GenericDaoBase sc = TemplateSearch.create(); sc.setParameters("template_id", templateId); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); remove(sc); txn.commit(); diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java index 2b796649551..54b6465642e 100755 --- a/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java @@ -31,7 +31,7 @@ import org.springframework.stereotype.Component; import com.cloud.exception.InvalidParameterValueException; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.storage.ScopeType; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Volume; @@ -48,7 +48,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.db.UpdateBuilder; import com.cloud.utils.exception.CloudRuntimeException; @@ -237,7 +237,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol @DB public HypervisorType getHypervisorType(long volumeId) { /* lookup from cluster of pool */ - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; String sql = null; try { @@ -458,7 +458,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol @Override public List listPoolIdsByVolumeCount(long dcId, Long podId, Long clusterId, long accountId) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); try { @@ -484,7 +484,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol @Override public List listZoneWidePoolIdsByVolumeCount(long dcId, long accountId) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); try { @@ -519,11 +519,11 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol @Override @DB public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); VolumeVO entry = findById(id); if (entry != null) { - _tagsDao.removeByIdAndType(id, TaggedResourceType.Volume); + _tagsDao.removeByIdAndType(id, ResourceObjectType.Volume); } boolean result = super.remove(id); txn.commit(); @@ -533,7 +533,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol @Override public ScopeType getVolumeStoragePoolScope(long volumeId) { // finding the storage scope where the volume is present - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeDetailsDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VolumeDetailsDaoImpl.java index 40af999032f..54158f5d9e2 100644 --- a/engine/schema/src/com/cloud/storage/dao/VolumeDetailsDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VolumeDetailsDaoImpl.java @@ -27,7 +27,7 @@ import org.springframework.stereotype.Component; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value=VolumeDetailsDao.class) @@ -98,7 +98,7 @@ public class VolumeDetailsDaoImpl extends GenericDaoBase i @Override public void persist(long volumeId, Map details) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SearchCriteria sc = VolumeSearch.create(); sc.setParameters("volumeId", volumeId); diff --git a/engine/schema/src/com/cloud/tags/ResourceTagVO.java b/engine/schema/src/com/cloud/tags/ResourceTagVO.java index 04ae757bf75..6130390aa4c 100644 --- a/engine/schema/src/com/cloud/tags/ResourceTagVO.java +++ b/engine/schema/src/com/cloud/tags/ResourceTagVO.java @@ -64,7 +64,7 @@ public class ResourceTagVO implements ResourceTag { @Column(name="resource_type") @Enumerated(value=EnumType.STRING) - private TaggedResourceType resourceType; + private ResourceObjectType resourceType; @Column(name="customer") String customer; @@ -85,7 +85,7 @@ public class ResourceTagVO implements ResourceTag { * @param resourceUuid TODO */ public ResourceTagVO(String key, String value, long accountId, long domainId, long resourceId, - TaggedResourceType resourceType, String customer, String resourceUuid) { + ResourceObjectType resourceType, String customer, String resourceUuid) { super(); this.key = key; this.value = value; @@ -139,7 +139,7 @@ public class ResourceTagVO implements ResourceTag { } @Override - public TaggedResourceType getResourceType() { + public ResourceObjectType getResourceType() { return resourceType; } diff --git a/engine/schema/src/com/cloud/tags/dao/ResourceTagDao.java b/engine/schema/src/com/cloud/tags/dao/ResourceTagDao.java index 335c748768c..395cf1b311c 100644 --- a/engine/schema/src/com/cloud/tags/dao/ResourceTagDao.java +++ b/engine/schema/src/com/cloud/tags/dao/ResourceTagDao.java @@ -19,7 +19,7 @@ package com.cloud.tags.dao; import java.util.List; import com.cloud.server.ResourceTag; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.ResourceTagVO; import com.cloud.utils.db.GenericDao; @@ -30,8 +30,8 @@ public interface ResourceTagDao extends GenericDao{ * @param resourceType * @return */ - boolean removeByIdAndType(long resourceId, TaggedResourceType resourceType); + boolean removeByIdAndType(long resourceId, ResourceObjectType resourceType); - List listBy(long resourceId, TaggedResourceType resourceType); + List listBy(long resourceId, ResourceObjectType resourceType); } diff --git a/engine/schema/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java b/engine/schema/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java index a8e1393d6da..2243fabaf5c 100644 --- a/engine/schema/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java +++ b/engine/schema/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java @@ -23,7 +23,7 @@ import javax.ejb.Local; import org.springframework.stereotype.Component; import com.cloud.server.ResourceTag; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.ResourceTagVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; @@ -44,7 +44,7 @@ public class ResourceTagsDaoImpl extends GenericDaoBase imp } @Override - public boolean removeByIdAndType(long resourceId, ResourceTag.TaggedResourceType resourceType) { + public boolean removeByIdAndType(long resourceId, ResourceTag.ResourceObjectType resourceType) { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("resourceId", resourceId); sc.setParameters("resourceType", resourceType); @@ -53,7 +53,7 @@ public class ResourceTagsDaoImpl extends GenericDaoBase imp } @Override - public List listBy(long resourceId, TaggedResourceType resourceType) { + public List listBy(long resourceId, ResourceObjectType resourceType) { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("resourceId", resourceId); sc.setParameters("resourceType", resourceType); diff --git a/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java b/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java index c97085b6e9e..8260aa125e5 100755 --- a/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java +++ b/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java @@ -30,11 +30,11 @@ import java.util.Properties; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.cloud.utils.PropertiesUtil; - import com.cloud.utils.component.ComponentContext; import com.cloud.utils.component.SystemIntegrityChecker; import com.cloud.utils.db.ScriptRunner; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; // Creates the CloudStack Database by using the 4.0 schema and apply // upgrade steps to it. @@ -172,7 +172,7 @@ public class DatabaseCreator { } try { - Transaction.initDataSource(dbPropsFile); + TransactionLegacy.initDataSource(dbPropsFile); } catch (NullPointerException e) { } initDB(dbPropsFile, rootPassword, databases, dryRun); @@ -187,7 +187,7 @@ public class DatabaseCreator { } System.out.println("========> Processing SQL file at " + sqlScript.getAbsolutePath()); - Connection conn = Transaction.getStandaloneConnection(); + Connection conn = TransactionLegacy.getStandaloneConnection(); try { FileReader reader = null; try { @@ -207,7 +207,7 @@ public class DatabaseCreator { } } - Transaction txn = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); try { // Process db upgrade classes for (String upgradeClass: upgradeClasses) { diff --git a/engine/schema/src/com/cloud/upgrade/DatabaseIntegrityChecker.java b/engine/schema/src/com/cloud/upgrade/DatabaseIntegrityChecker.java index 50eb47be027..b6e45ec8995 100755 --- a/engine/schema/src/com/cloud/upgrade/DatabaseIntegrityChecker.java +++ b/engine/schema/src/com/cloud/upgrade/DatabaseIntegrityChecker.java @@ -29,12 +29,11 @@ import org.springframework.stereotype.Component; import com.cloud.maint.Version; import com.cloud.upgrade.dao.VersionDao; - import com.cloud.utils.component.AdapterBase; import com.cloud.utils.component.ComponentLifecycle; import com.cloud.utils.component.SystemIntegrityChecker; import com.cloud.utils.db.GlobalLock; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -72,7 +71,7 @@ public class DatabaseIntegrityChecker extends AdapterBase implements SystemInteg } private Boolean checkDuplicateHostWithTheSameLocalStorage() { - Transaction txn = Transaction.open("Integrity"); + TransactionLegacy txn = TransactionLegacy.open("Integrity"); txn.start(); try { Connection conn; @@ -167,7 +166,7 @@ public class DatabaseIntegrityChecker extends AdapterBase implements SystemInteg } private boolean checkMissedPremiumUpgradeFor228() { - Transaction txn = Transaction.open("Integrity"); + TransactionLegacy txn = TransactionLegacy.open("Integrity"); txn.start(); try { String dbVersion = _dao.getCurrentVersion(); diff --git a/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java b/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java index 85e36a5afc1..b0beedfc6ed 100755 --- a/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java +++ b/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java @@ -31,6 +31,7 @@ import java.util.List; import java.util.TreeMap; import javax.ejb.Local; +import javax.inject.Inject; import org.apache.log4j.Logger; @@ -73,7 +74,7 @@ import com.cloud.upgrade.dao.VersionVO.Step; import com.cloud.utils.component.SystemIntegrityChecker; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.ScriptRunner; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Local(value = {SystemIntegrityChecker.class}) @@ -82,10 +83,12 @@ public class DatabaseUpgradeChecker implements SystemIntegrityChecker { protected HashMap _upgradeMap = new HashMap(); + @Inject VersionDao _dao; public DatabaseUpgradeChecker() { _dao = new VersionDaoImpl(); + _upgradeMap.put("2.1.7", new DbUpgrade[] {new Upgrade217to218(), new Upgrade218to22(), new Upgrade221to222(), new UpgradeSnapshot217to224(), new Upgrade222to224(), new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), @@ -269,7 +272,7 @@ public class DatabaseUpgradeChecker implements SystemIntegrityChecker { s_logger.debug("Running upgrade " + upgrade.getClass().getSimpleName() + " to upgrade from " + upgrade.getUpgradableVersionRange()[0] + "-" + upgrade.getUpgradableVersionRange()[1] + " to " + upgrade.getUpgradedVersion()); - Transaction txn = Transaction.open("Upgrade"); + TransactionLegacy txn = TransactionLegacy.open("Upgrade"); txn.start(); try { Connection conn; @@ -339,7 +342,7 @@ public class DatabaseUpgradeChecker implements SystemIntegrityChecker { VersionVO version = _dao.findByVersion(upgradedVersion, Step.Upgrade); s_logger.debug("Upgrading to version " + upgradedVersion + "..."); - Transaction txn = Transaction.open("Cleanup"); + TransactionLegacy txn = TransactionLegacy.open("Cleanup"); try { if (version != null) { for (DbUpgrade upgrade : versionUpgrades) { diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade307to410.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade307to410.java index 663105065c8..aeeb6d5863f 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade307to410.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade307to410.java @@ -29,7 +29,6 @@ import com.cloud.utils.PropertiesUtil; import com.cloud.utils.crypt.EncryptionSecretKeyChecker; import org.apache.log4j.Logger; -import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; import org.jasypt.encryption.pbe.StandardPBEStringEncryptor; diff --git a/engine/schema/src/com/cloud/upgrade/dao/VersionDaoImpl.java b/engine/schema/src/com/cloud/upgrade/dao/VersionDaoImpl.java index 8c92765e48b..12c99b2b6c8 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/VersionDaoImpl.java +++ b/engine/schema/src/com/cloud/upgrade/dao/VersionDaoImpl.java @@ -35,7 +35,7 @@ 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; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -79,7 +79,7 @@ public class VersionDaoImpl extends GenericDaoBase implements V try { s_logger.debug("Checking to see if the database is at a version before it was the version table is created"); - conn = Transaction.getStandaloneConnection(); + conn = TransactionLegacy.getStandaloneConnection(); PreparedStatement pstmt = conn.prepareStatement("SHOW TABLES LIKE 'version'"); ResultSet rs = pstmt.executeQuery(); diff --git a/engine/schema/src/com/cloud/usage/dao/UsageDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageDaoImpl.java index ce6d9e4a477..e1e843e9ed5 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageDaoImpl.java @@ -38,7 +38,7 @@ import com.cloud.utils.DateUtil; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -74,7 +74,7 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage @Override public void deleteRecordsForAccount(Long accountId) { String sql = ((accountId == null) ? DELETE_ALL : DELETE_ALL_BY_ACCOUNTID); - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); PreparedStatement pstmt = null; try { txn.start(); @@ -99,7 +99,7 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage @Override public void saveAccounts(List accounts) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { txn.start(); String sql = INSERT_ACCOUNT; @@ -133,7 +133,7 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage @Override public void updateAccounts(List accounts) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { txn.start(); String sql = UPDATE_ACCOUNT; @@ -163,7 +163,7 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage @Override public void saveUserStats(List userStats) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { txn.start(); String sql = INSERT_USER_STATS; @@ -204,7 +204,7 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage @Override public void updateUserStats(List userStats) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { txn.start(); String sql = UPDATE_USER_STATS; @@ -231,7 +231,7 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage @Override public Long getLastAccountId() { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; String sql = GET_LAST_ACCOUNT; try { @@ -248,7 +248,7 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage @Override public Long getLastUserStatsId() { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; String sql = GET_LAST_USER_STATS; try { @@ -265,7 +265,7 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage @Override public List listPublicTemplatesByAccount(long accountId) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; String sql = GET_PUBLIC_TEMPLATES_BY_ACCOUNTID; List templateList = new ArrayList(); @@ -284,7 +284,7 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage @Override public Long getLastVmDiskStatsId() { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; String sql = GET_LAST_VM_DISK_STATS; try { @@ -301,7 +301,7 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage @Override public void updateVmDiskStats(List vmDiskStats) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { txn.start(); String sql = UPDATE_VM_DISK_STATS; @@ -335,7 +335,7 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage @Override public void saveVmDiskStats(List vmDiskStats) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { txn.start(); String sql = INSERT_VM_DISK_STATS; @@ -381,7 +381,7 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage @Override public void saveUsageRecords(List usageRecords) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { txn.start(); String sql = INSERT_USGAE_RECORDS; diff --git a/engine/schema/src/com/cloud/usage/dao/UsageIPAddressDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageIPAddressDaoImpl.java index 9af4a267097..00145530a9c 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageIPAddressDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageIPAddressDaoImpl.java @@ -32,7 +32,7 @@ import com.cloud.usage.UsageIPAddressVO; import com.cloud.user.Account; import com.cloud.utils.DateUtil; import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={UsageIPAddressDao.class}) @@ -56,7 +56,7 @@ public class UsageIPAddressDaoImpl extends GenericDaoBase implements @Override public long getLastJobSuccessDateMillis() { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; String sql = GET_LAST_JOB_SUCCESS_DATE_MILLIS; try { @@ -61,7 +61,7 @@ public class UsageJobDaoImpl extends GenericDaoBase implements @Override public void updateJobSuccess(Long jobId, long startMillis, long endMillis, long execTime, boolean success) { - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); try { txn.start(); @@ -115,7 +115,7 @@ public class UsageJobDaoImpl extends GenericDaoBase implements @Override public UsageJobVO isOwner(String hostname, int pid) { - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); try { if ((hostname == null) || (pid <= 0)) { return null; diff --git a/engine/schema/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDaoImpl.java index fa632236b79..70b1764498b 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDaoImpl.java @@ -31,7 +31,7 @@ import org.springframework.stereotype.Component; import com.cloud.usage.UsageLoadBalancerPolicyVO; import com.cloud.utils.DateUtil; import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={UsageLoadBalancerPolicyDao.class}) @@ -56,7 +56,7 @@ public class UsageLoadBalancerPolicyDaoImpl extends GenericDaoBase im @Override public Map getRecentNetworkStats() { - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); String sql = SELECT_LATEST_STATS; PreparedStatement pstmt = null; try { @@ -85,7 +85,7 @@ public class UsageNetworkDaoImpl extends GenericDaoBase im @Override public void deleteOldStats(long maxEventTime) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); String sql = DELETE_OLD_STATS; PreparedStatement pstmt = null; try { @@ -102,7 +102,7 @@ public class UsageNetworkDaoImpl extends GenericDaoBase im @Override public void saveUsageNetworks (List usageNetworks) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { txn.start(); String sql = INSERT_USAGE_NETWORK; diff --git a/engine/schema/src/com/cloud/usage/dao/UsageNetworkOfferingDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageNetworkOfferingDaoImpl.java index 4ed7c27d491..6fb03e7252d 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageNetworkOfferingDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageNetworkOfferingDaoImpl.java @@ -31,7 +31,7 @@ import org.springframework.stereotype.Component; import com.cloud.usage.UsageNetworkOfferingVO; import com.cloud.utils.DateUtil; import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={UsageNetworkOfferingDao.class}) @@ -55,7 +55,7 @@ public class UsageNetworkOfferingDaoImpl extends GenericDaoBase im } public void removeBy(long accountId, long volId, int storage_type) { - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); PreparedStatement pstmt = null; try { txn.start(); @@ -113,7 +113,7 @@ public class UsageStorageDaoImpl extends GenericDaoBase im } public void update(UsageStorageVO usage) { - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); PreparedStatement pstmt = null; try { txn.start(); @@ -158,7 +158,7 @@ public class UsageStorageDaoImpl extends GenericDaoBase im sql += " LIMIT " + startIndex + ",500"; } - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); PreparedStatement pstmt = null; try { diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVMInstanceDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageVMInstanceDaoImpl.java index fc827548781..ef313904956 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageVMInstanceDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageVMInstanceDaoImpl.java @@ -31,7 +31,7 @@ import org.springframework.stereotype.Component; import com.cloud.usage.UsageVMInstanceVO; import com.cloud.utils.DateUtil; import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={UsageVMInstanceDao.class}) @@ -51,7 +51,7 @@ public class UsageVMInstanceDaoImpl extends GenericDaoBase getUsageRecords(long accountId, Date startDate, Date endDate) { - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); PreparedStatement pstmt = null; List usageInstances = new ArrayList(); try { diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVMSnapshotDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageVMSnapshotDaoImpl.java index 9f98bbf1be5..b9f5f8ce358 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageVMSnapshotDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageVMSnapshotDaoImpl.java @@ -20,7 +20,7 @@ package com.cloud.usage.dao; import com.cloud.usage.UsageVMSnapshotVO; import com.cloud.utils.DateUtil; import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -51,7 +51,7 @@ public class UsageVMSnapshotDaoImpl extends GenericDaoBase usageRecords = new ArrayList(); String sql = GET_USAGE_RECORDS_BY_ACCOUNT; - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); PreparedStatement pstmt = null; try { @@ -130,7 +130,7 @@ public class UsageVMSnapshotDaoImpl extends GenericDaoBase usageRecords = new ArrayList(); String sql = PREVIOUS_QUERY; - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); PreparedStatement pstmt = null; try { int i = 1; diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVPNUserDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageVPNUserDaoImpl.java index d6bf13b41bf..d8d14552cca 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageVPNUserDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageVPNUserDaoImpl.java @@ -31,7 +31,7 @@ import org.springframework.stereotype.Component; import com.cloud.usage.UsageVPNUserVO; import com.cloud.utils.DateUtil; import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={UsageVPNUserDao.class}) @@ -55,7 +55,7 @@ public class UsageVPNUserDaoImpl extends GenericDaoBase im public UsageVPNUserDaoImpl() {} public void update(UsageVPNUserVO usage) { - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); PreparedStatement pstmt = null; try { txn.start(); @@ -99,7 +99,7 @@ public class UsageVPNUserDaoImpl extends GenericDaoBase im sql += " LIMIT " + startIndex + ",500"; } - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); PreparedStatement pstmt = null; try { diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVmDiskDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageVmDiskDaoImpl.java index 8436c5955c8..d2cb6730854 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageVmDiskDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageVmDiskDaoImpl.java @@ -29,7 +29,7 @@ import org.springframework.stereotype.Component; import com.cloud.usage.UsageVmDiskVO; import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -51,7 +51,7 @@ public class UsageVmDiskDaoImpl extends GenericDaoBase impl @Override public Map getRecentVmDiskStats() { - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); String sql = SELECT_LATEST_STATS; PreparedStatement pstmt = null; try { @@ -89,7 +89,7 @@ public class UsageVmDiskDaoImpl extends GenericDaoBase impl @Override public void deleteOldStats(long maxEventTime) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); String sql = DELETE_OLD_STATS; PreparedStatement pstmt = null; try { @@ -106,7 +106,7 @@ public class UsageVmDiskDaoImpl extends GenericDaoBase impl @Override public void saveUsageVmDisks(List usageVmDisks) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { txn.start(); String sql = INSERT_USAGE_VM_DISK; diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java index 039d8f4be90..8bf95b63aa3 100644 --- a/engine/schema/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java @@ -31,7 +31,7 @@ import org.springframework.stereotype.Component; import com.cloud.usage.UsageVolumeVO; import com.cloud.utils.DateUtil; import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={UsageVolumeDao.class}) @@ -56,7 +56,7 @@ public class UsageVolumeDaoImpl extends GenericDaoBase impl public UsageVolumeDaoImpl() {} public void removeBy(long accountId, long volId) { - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); PreparedStatement pstmt = null; try { txn.start(); @@ -75,7 +75,7 @@ public class UsageVolumeDaoImpl extends GenericDaoBase impl } public void update(UsageVolumeVO usage) { - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); PreparedStatement pstmt = null; try { txn.start(); @@ -119,7 +119,7 @@ public class UsageVolumeDaoImpl extends GenericDaoBase impl sql += " LIMIT " + startIndex + ",500"; } - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); PreparedStatement pstmt = null; try { diff --git a/engine/schema/src/com/cloud/user/AccountDetailsDaoImpl.java b/engine/schema/src/com/cloud/user/AccountDetailsDaoImpl.java index 30bbe73a568..9bdaff60309 100755 --- a/engine/schema/src/com/cloud/user/AccountDetailsDaoImpl.java +++ b/engine/schema/src/com/cloud/user/AccountDetailsDaoImpl.java @@ -31,7 +31,7 @@ import com.cloud.utils.db.QueryBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Local(value = {AccountDetailsDao.class}) public class AccountDetailsDaoImpl extends GenericDaoBase implements AccountDetailsDao, ScopedConfigStorage { @@ -57,7 +57,7 @@ public class AccountDetailsDaoImpl extends GenericDaoBase @Override public void persist(long accountId, Map details) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SearchCriteria sc = accountSearch.create(); sc.setParameters("accountId", accountId); diff --git a/engine/schema/src/com/cloud/user/dao/AccountDaoImpl.java b/engine/schema/src/com/cloud/user/dao/AccountDaoImpl.java index 41f1f734732..91226e79846 100755 --- a/engine/schema/src/com/cloud/user/dao/AccountDaoImpl.java +++ b/engine/schema/src/com/cloud/user/dao/AccountDaoImpl.java @@ -39,7 +39,7 @@ 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; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={AccountDao.class}) @@ -124,7 +124,7 @@ public class AccountDaoImpl extends GenericDaoBase implements A @Override public Pair findUserAccountByApiKey(String apiKey) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; Pair userAcctPair = null; try { diff --git a/engine/schema/src/com/cloud/user/dao/UserStatisticsDaoImpl.java b/engine/schema/src/com/cloud/user/dao/UserStatisticsDaoImpl.java index 4a1a51c6d9f..ae21dfec16e 100644 --- a/engine/schema/src/com/cloud/user/dao/UserStatisticsDaoImpl.java +++ b/engine/schema/src/com/cloud/user/dao/UserStatisticsDaoImpl.java @@ -33,7 +33,7 @@ import com.cloud.utils.DateUtil; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={UserStatisticsDao.class}) @@ -100,7 +100,7 @@ public class UserStatisticsDaoImpl extends GenericDaoBase userStats = new ArrayList(); if (minRemovedDate == null) return userStats; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { String sql = ACTIVE_AND_RECENTLY_DELETED_SEARCH + " LIMIT " + startIndex + "," + limit; PreparedStatement pstmt = null; @@ -120,7 +120,7 @@ public class UserStatisticsDaoImpl extends GenericDaoBase listUpdatedStats() { List userStats = new ArrayList(); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement pstmt = null; pstmt = txn.prepareAutoCloseStatement(UPDATED_STATS_SEARCH); diff --git a/engine/schema/src/com/cloud/user/dao/VmDiskStatisticsDaoImpl.java b/engine/schema/src/com/cloud/user/dao/VmDiskStatisticsDaoImpl.java index 02f3406c497..2a3d132eeaa 100644 --- a/engine/schema/src/com/cloud/user/dao/VmDiskStatisticsDaoImpl.java +++ b/engine/schema/src/com/cloud/user/dao/VmDiskStatisticsDaoImpl.java @@ -33,7 +33,7 @@ import com.cloud.utils.DateUtil; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={VmDiskStatisticsDao.class}) @@ -97,7 +97,7 @@ public class VmDiskStatisticsDaoImpl extends GenericDaoBase vmDiskStats = new ArrayList(); if (minRemovedDate == null) return vmDiskStats; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { String sql = ACTIVE_AND_RECENTLY_DELETED_SEARCH + " LIMIT " + startIndex + "," + limit; PreparedStatement pstmt = null; @@ -117,7 +117,7 @@ public class VmDiskStatisticsDaoImpl extends GenericDaoBase listUpdatedStats() { List vmDiskStats = new ArrayList(); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement pstmt = null; pstmt = txn.prepareAutoCloseStatement(UPDATED_VM_NETWORK_STATS_SEARCH); diff --git a/engine/schema/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java index 9af371eb3c8..4238f6a38fd 100644 --- a/engine/schema/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java @@ -34,7 +34,7 @@ import com.cloud.utils.db.Attribute; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.db.UpdateBuilder; import com.cloud.vm.ConsoleProxyVO; import com.cloud.vm.VirtualMachine.State; @@ -162,7 +162,7 @@ public class ConsoleProxyDaoImpl extends GenericDaoBase im @Override public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); ConsoleProxyVO proxy = createForUpdate(); proxy.setPublicIpAddress(null); @@ -227,7 +227,7 @@ public class ConsoleProxyDaoImpl extends GenericDaoBase im public List> getProxyLoadMatrix() { ArrayList> l = new ArrayList>(); - Transaction txn = Transaction.currentTxn();; + TransactionLegacy txn = TransactionLegacy.currentTxn();; PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(PROXY_ASSIGNMENT_MATRIX); @@ -245,7 +245,7 @@ public class ConsoleProxyDaoImpl extends GenericDaoBase im public List> getDatacenterStoragePoolHostInfo(long dcId, boolean countAllPoolTypes) { ArrayList> l = new ArrayList>(); - Transaction txn = Transaction.currentTxn();; + TransactionLegacy txn = TransactionLegacy.currentTxn();; PreparedStatement pstmt = null; try { if(countAllPoolTypes) { @@ -267,7 +267,7 @@ public class ConsoleProxyDaoImpl extends GenericDaoBase im @Override public int getProxyStaticLoad(long proxyVmId) { - Transaction txn = Transaction.currentTxn();; + TransactionLegacy txn = TransactionLegacy.currentTxn();; PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(GET_PROXY_LOAD); @@ -285,7 +285,7 @@ public class ConsoleProxyDaoImpl extends GenericDaoBase im @Override public int getProxyActiveLoad(long proxyVmId) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(GET_PROXY_ACTIVE_LOAD); @@ -304,7 +304,7 @@ public class ConsoleProxyDaoImpl extends GenericDaoBase im private List getDatacenterLoadMatrix(String sql) { ArrayList l = new ArrayList(); - Transaction txn = Transaction.currentTxn();; + TransactionLegacy txn = TransactionLegacy.currentTxn();; PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(sql); @@ -325,7 +325,7 @@ public class ConsoleProxyDaoImpl extends GenericDaoBase im @Override public List getRunningProxyListByMsid(long msid) { List l = new ArrayList(); - Transaction txn = Transaction.currentTxn();; + TransactionLegacy txn = TransactionLegacy.currentTxn();; PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement( diff --git a/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java index 65b9d3b27c7..7676e2daf8d 100755 --- a/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java @@ -47,7 +47,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.db.UpdateBuilder; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.VirtualMachine; @@ -143,7 +143,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im @Override public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); DomainRouterVO router = createForUpdate(); router.setPublicIpAddress(null); @@ -307,7 +307,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im @Override @DB public DomainRouterVO persist(DomainRouterVO router, List guestNetworks) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); // 1) create network @@ -330,7 +330,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im if (_routerNetworkDao.findByRouterAndNetwork(router.getId(), guestNetwork.getId()) == null) { NetworkOffering off = _offDao.findById(guestNetwork.getNetworkOfferingId()); if (!(off.getName().equalsIgnoreCase(NetworkOffering.SystemPrivateGatewayNetworkOffering))) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); //1) add router to network RouterNetworkVO routerNtwkMap = new RouterNetworkVO(router.getId(), guestNetwork.getId(), guestNetwork.getGuestType()); diff --git a/engine/schema/src/com/cloud/vm/dao/NicDetailDao.java b/engine/schema/src/com/cloud/vm/dao/NicDetailDao.java index 38eb2f2a3b1..66bff167fbf 100644 --- a/engine/schema/src/com/cloud/vm/dao/NicDetailDao.java +++ b/engine/schema/src/com/cloud/vm/dao/NicDetailDao.java @@ -31,5 +31,5 @@ public interface NicDetailDao extends GenericDao { void deleteDetails(long nicId); - void removeDetails(Long id, String key); + void removeDetails(long nicId, String key); } diff --git a/engine/schema/src/com/cloud/vm/dao/NicDetailDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/NicDetailDaoImpl.java index 67bc0b5b871..4c1d59cbd5e 100644 --- a/engine/schema/src/com/cloud/vm/dao/NicDetailDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/NicDetailDaoImpl.java @@ -19,7 +19,7 @@ package com.cloud.vm.dao; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.vm.NicDetailVO; import org.springframework.stereotype.Component; @@ -75,7 +75,7 @@ public class NicDetailDaoImpl extends GenericDaoBase implemen @Override public void persist(long nicId, Map details) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SearchCriteria sc = NicSearch.create(); sc.setParameters("nicId", nicId); @@ -89,8 +89,7 @@ public class NicDetailDaoImpl extends GenericDaoBase implemen } @Override - public void removeDetails(Long nicId, String key) { - + public void removeDetails(long nicId, String key) { if(key != null){ NicDetailVO detail = findDetail(nicId, key); if(detail != null){ @@ -99,7 +98,6 @@ public class NicDetailDaoImpl extends GenericDaoBase implemen }else { deleteDetails(nicId); } - } } diff --git a/engine/schema/src/com/cloud/vm/dao/SecondaryStorageVmDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/SecondaryStorageVmDaoImpl.java index f802a90d39f..2fcc3e7809d 100644 --- a/engine/schema/src/com/cloud/vm/dao/SecondaryStorageVmDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/SecondaryStorageVmDaoImpl.java @@ -31,7 +31,7 @@ import com.cloud.utils.db.Attribute; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.db.UpdateBuilder; import com.cloud.vm.SecondaryStorageVm; import com.cloud.vm.SecondaryStorageVmVO; @@ -105,7 +105,7 @@ public class SecondaryStorageVmDaoImpl extends GenericDaoBase getRunningSecStorageVmListByMsid(SecondaryStorageVm.Role role, long msid) { List l = new ArrayList(); - Transaction txn = Transaction.currentTxn();; + TransactionLegacy txn = TransactionLegacy.currentTxn();; PreparedStatement pstmt = null; try { String sql; @@ -237,7 +237,7 @@ public class SecondaryStorageVmDaoImpl extends GenericDaoBase listRunningSecStorageOrderByLoad(SecondaryStorageVm.Role role, long zoneId) { List l = new ArrayList(); - Transaction txn = Transaction.currentTxn();; + TransactionLegacy txn = TransactionLegacy.currentTxn();; PreparedStatement pstmt = null; try { String sql; diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java index 8afce099394..70b04e3479e 100755 --- a/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java @@ -34,7 +34,7 @@ import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.configuration.Resource; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.user.Account; @@ -46,7 +46,7 @@ import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.NicVO; import com.cloud.vm.UserVmVO; @@ -350,7 +350,7 @@ public class UserVmDaoImpl extends GenericDaoBase implements Use @Override public List listPodIdsHavingVmsforAccount(long zoneId, long accountId){ - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); @@ -374,7 +374,7 @@ public class UserVmDaoImpl extends GenericDaoBase implements Use @Override public Hashtable listVmDetails(Hashtable userVmDataHash){ - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { @@ -575,9 +575,9 @@ public class UserVmDaoImpl extends GenericDaoBase implements Use @Override public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); - _tagsDao.removeByIdAndType(id, TaggedResourceType.UserVm); + _tagsDao.removeByIdAndType(id, ResourceObjectType.UserVm); boolean result = super.remove(id); txn.commit(); return result; diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmDetailsDao.java b/engine/schema/src/com/cloud/vm/dao/UserVmDetailsDao.java index e117f630594..ce36c0bd823 100644 --- a/engine/schema/src/com/cloud/vm/dao/UserVmDetailsDao.java +++ b/engine/schema/src/com/cloud/vm/dao/UserVmDetailsDao.java @@ -32,7 +32,8 @@ public interface UserVmDetailsDao extends GenericDao { UserVmDetailVO findDetail(long vmId, String name); void deleteDetails(long vmId); - - public void removeDetails(Long vmId, String key); - + + void addVmDetail(long vmId, String key, String value); + + void removeDetails(long vmId, String key); } diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmDetailsDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/UserVmDetailsDaoImpl.java index ce8dbd86225..67b7f81f5df 100644 --- a/engine/schema/src/com/cloud/vm/dao/UserVmDetailsDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/UserVmDetailsDaoImpl.java @@ -22,13 +22,12 @@ import java.util.Map; import javax.ejb.Local; -import com.cloud.vm.NicDetailVO; import org.springframework.stereotype.Component; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.vm.UserVmDetailVO; @Component @@ -93,7 +92,7 @@ public class UserVmDetailsDaoImpl extends GenericDaoBase i @Override public void persist(long vmId, Map details) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SearchCriteria sc = VmSearch.create(); sc.setParameters("vmId", vmId); @@ -107,7 +106,19 @@ public class UserVmDetailsDaoImpl extends GenericDaoBase i } @Override - public void removeDetails(Long vmId, String key) { + public void addVmDetail(long vmId, String key, String value) { + UserVmDetailVO detail = findDetail(vmId, key); + if (detail == null) { + UserVmDetailVO newEntry = new UserVmDetailVO(vmId, key, value); + persist(newEntry); + } else { + detail.setValue(value); + update(detail.getId(), detail); + } + } + + @Override + public void removeDetails(long vmId, String key) { if(key != null){ UserVmDetailVO detail = findDetail(vmId, key); if(detail != null){ @@ -116,8 +127,5 @@ public class UserVmDetailsDaoImpl extends GenericDaoBase i }else { deleteDetails(vmId); } - } - - } diff --git a/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index cf8e0a89c40..2c62376d642 100644 --- a/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -35,7 +35,7 @@ import org.springframework.stereotype.Component; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.utils.Pair; import com.cloud.utils.db.Attribute; @@ -48,7 +48,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.db.UpdateBuilder; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.NicVO; @@ -484,7 +484,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem @Override public Pair, Map> listClusterIdsInZoneByVmCount(long zoneId, long accountId) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); Map clusterVmCountMap = new HashMap(); @@ -513,7 +513,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem @Override public Pair, Map> listClusterIdsInPodByVmCount(long podId, long accountId) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); Map clusterVmCountMap = new HashMap(); @@ -543,7 +543,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem @Override public Pair, Map> listPodIdsInZoneByVmCount(long dataCenterId, long accountId) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); Map podVmCountMap = new HashMap(); @@ -569,7 +569,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem @Override public List listHostIdsByVmCount(long dcId, Long podId, Long clusterId, long accountId) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); try { @@ -654,11 +654,11 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem @Override @DB public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); VMInstanceVO vm = findById(id); if (vm != null && vm.getType() == Type.User) { - _tagsDao.removeByIdAndType(id, TaggedResourceType.UserVm); + _tagsDao.removeByIdAndType(id, ResourceObjectType.UserVm); } boolean result = super.remove(id); txn.commit(); diff --git a/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDaoImpl.java b/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDaoImpl.java index ad8f4f0a4ea..c2d48d42366 100644 --- a/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDaoImpl.java +++ b/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDaoImpl.java @@ -32,7 +32,7 @@ import com.cloud.utils.db.JoinBuilder.JoinType; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Local(value = { AffinityGroupVMMapDao.class }) public class AffinityGroupVMMapDaoImpl extends GenericDaoBase implements @@ -160,7 +160,7 @@ public class AffinityGroupVMMapDaoImpl extends GenericDaoBase affinityGroupIds) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SearchCriteria sc = createSearchCriteria(); diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMComputeTagDaoImpl.java b/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMComputeTagDaoImpl.java index 6f70b353176..54a557bfcb7 100644 --- a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMComputeTagDaoImpl.java +++ b/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMComputeTagDaoImpl.java @@ -31,7 +31,7 @@ import org.springframework.stereotype.Component; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value = { VMComputeTagDao.class }) @@ -52,7 +52,7 @@ public class VMComputeTagDaoImpl extends GenericDaoBase im @Override public void persist(long vmId, List computeTags) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SearchCriteria sc = VmIdSearch.create(); diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMEntityDaoImpl.java b/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMEntityDaoImpl.java index 3082d21c1ee..fa2ce81a657 100644 --- a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMEntityDaoImpl.java +++ b/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMEntityDaoImpl.java @@ -37,7 +37,7 @@ import com.cloud.network.dao.NetworkVO; import com.cloud.utils.Pair; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.vm.NicProfile; @@ -78,7 +78,7 @@ public class VMEntityDaoImpl extends GenericDaoBase implements @Override @DB public VMEntityVO persist(VMEntityVO vm) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); VMEntityVO dbVO = super.persist(vm); diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMNetworkMapDaoImpl.java b/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMNetworkMapDaoImpl.java index 0f2c4ccb77e..f86e788ea1a 100644 --- a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMNetworkMapDaoImpl.java +++ b/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMNetworkMapDaoImpl.java @@ -28,7 +28,7 @@ import com.cloud.network.dao.NetworkDao; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value = { VMNetworkMapDao.class }) @@ -52,7 +52,7 @@ public class VMNetworkMapDaoImpl extends GenericDaoBase im @Override public void persist(long vmId, List networks) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SearchCriteria sc = VmIdSearch.create(); diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMReservationDaoImpl.java b/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMReservationDaoImpl.java index 73b4dd2194c..31ed5b8650b 100644 --- a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMReservationDaoImpl.java +++ b/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMReservationDaoImpl.java @@ -35,7 +35,7 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value = { VMReservationDao.class }) @@ -80,7 +80,7 @@ public class VMReservationDaoImpl extends GenericDaoBase @Override @DB public VMReservationVO persist(VMReservationVO reservation) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); VMReservationVO dbVO = super.persist(reservation); diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMRootDiskTagDaoImpl.java b/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMRootDiskTagDaoImpl.java index be194bbfcaa..cd06b202b7b 100644 --- a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMRootDiskTagDaoImpl.java +++ b/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMRootDiskTagDaoImpl.java @@ -31,7 +31,7 @@ import org.springframework.stereotype.Component; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value = { VMRootDiskTagDao.class }) @@ -52,7 +52,7 @@ public class VMRootDiskTagDaoImpl extends GenericDaoBase @Override public void persist(long vmId, List rootDiskTags) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); SearchCriteria sc = VmIdSearch.create(); diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java index 9e2bb365518..8ed84ef8244 100644 --- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java +++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java @@ -40,7 +40,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Local(value = { PrimaryDataStoreDao.class }) @@ -226,7 +226,7 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase @Override @DB public StoragePoolVO persist(StoragePoolVO pool, Map details) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); pool = super.persist(pool); if (details != null) { @@ -254,7 +254,7 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase } sql.delete(sql.length() - 4, sql.length()); sql.append(DetailsSqlSuffix); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(sql.toString()); @@ -331,7 +331,7 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase } sql.delete(sql.length() - 4, sql.length()); sql.append(ZoneWideDetailsSqlSuffix); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(sql.toString()); @@ -357,7 +357,7 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase StringBuilder sql = new StringBuilder(FindPoolTagDetails); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(sql.toString()); diff --git a/engine/storage/cache/resources/META-INF/cloudstack/core/spring-engine-storage-cache-core-context.xml b/engine/storage/cache/resources/META-INF/cloudstack/core/spring-engine-storage-cache-core-context.xml new file mode 100644 index 00000000000..7b8e2a4ab2c --- /dev/null +++ b/engine/storage/cache/resources/META-INF/cloudstack/core/spring-engine-storage-cache-core-context.xml @@ -0,0 +1,38 @@ + + + + + + + + + diff --git a/engine/storage/datamotion/resources/META-INF/cloudstack/core/spring-engine-storage-datamotion-core-context.xml b/engine/storage/datamotion/resources/META-INF/cloudstack/core/spring-engine-storage-datamotion-core-context.xml new file mode 100644 index 00000000000..3bde7686848 --- /dev/null +++ b/engine/storage/datamotion/resources/META-INF/cloudstack/core/spring-engine-storage-datamotion-core-context.xml @@ -0,0 +1,34 @@ + + + + + + + diff --git a/engine/storage/datamotion/resources/META-INF/cloudstack/storage/spring-engine-storage-datamotion-storage-context.xml b/engine/storage/datamotion/resources/META-INF/cloudstack/storage/spring-engine-storage-datamotion-storage-context.xml new file mode 100644 index 00000000000..725f7d35be5 --- /dev/null +++ b/engine/storage/datamotion/resources/META-INF/cloudstack/storage/spring-engine-storage-datamotion-storage-context.xml @@ -0,0 +1,34 @@ + + + + + + diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java index 5f5f01e4e10..54e01f18e98 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -36,7 +36,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager; -import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority.Priority; +import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; @@ -124,13 +124,13 @@ AncientDataMotionStrategy implements DataMotionStrategy { ManagementService _mgmtServer; @Override - public Priority canHandle(DataObject srcData, DataObject destData) { - return Priority.DEFAULT; + public StrategyPriority canHandle(DataObject srcData, DataObject destData) { + return StrategyPriority.DEFAULT; } @Override - public Priority canHandle(Map volumeMap, Host srcHost, Host destHost) { - return Priority.CANT_HANDLE; + public StrategyPriority canHandle(Map volumeMap, Host srcHost, Host destHost) { + return StrategyPriority.CANT_HANDLE; } protected boolean needCacheStorage(DataObject srcData, DataObject destData) { diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java index 2d3132095e3..a1f05e1bb65 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java @@ -18,6 +18,7 @@ */ package org.apache.cloudstack.storage.motion; +import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -29,19 +30,21 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority; -import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority.Priority; +import org.apache.cloudstack.engine.subsystem.api.storage.StorageStrategyFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.springframework.stereotype.Component; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.host.Host; +import com.cloud.utils.StringUtils; import com.cloud.utils.exception.CloudRuntimeException; @Component public class DataMotionServiceImpl implements DataMotionService { @Inject - List strategies; + StorageStrategyFactory storageStrategyFactory; @Override public void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback) { @@ -57,33 +60,32 @@ public class DataMotionServiceImpl implements DataMotionService { return; } - StrategyPriority.sortStrategies(strategies, srcData, destData); - - for (DataMotionStrategy strategy : strategies) { - if (strategy.canHandle(srcData, destData) != Priority.CANT_HANDLE) { - strategy.copyAsync(srcData, destData, callback); - return; - } + DataMotionStrategy strategy = storageStrategyFactory.getDataMotionStrategy(srcData, destData); + if (strategy == null) { + throw new CloudRuntimeException("Can't find strategy to move data. "+ + "Source: "+srcData.getType().name()+" '"+srcData.getUuid()+ + ", Destination: "+destData.getType().name()+" '"+destData.getUuid()+"'"); } - throw new CloudRuntimeException("can't find strategy to move data"); + + strategy.copyAsync(srcData, destData, callback); } @Override public void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback) { - StrategyPriority.sortStrategies(strategies, volumeMap, srcHost, destHost); - - for (DataMotionStrategy strategy : strategies) { - if (strategy.canHandle(volumeMap, srcHost, destHost) != Priority.CANT_HANDLE) { - strategy.copyAsync(volumeMap, vmTo, srcHost, destHost, callback); - return; + DataMotionStrategy strategy = storageStrategyFactory.getDataMotionStrategy(volumeMap, srcHost, destHost); + if (strategy == null) { + List volumeIds = new LinkedList(); + for (final VolumeInfo volumeInfo : volumeMap.keySet()) { + volumeIds.add(volumeInfo.getUuid()); } - } - throw new CloudRuntimeException("can't find strategy to move data"); - } - public void setStrategies(List strategies) { - this.strategies = strategies; + throw new CloudRuntimeException("Can't find strategy to move data. "+ + "Source Host: "+srcHost.getName()+", Destination Host: "+destHost.getName()+ + ", Volume UUIDs: "+StringUtils.join(volumeIds, ",")); + } + + strategy.copyAsync(volumeMap, vmTo, srcHost, destHost, callback); } } diff --git a/engine/storage/image/resources/META-INF/cloudstack/core/spring-engine-storage-image-core-context.xml b/engine/storage/image/resources/META-INF/cloudstack/core/spring-engine-storage-image-core-context.xml new file mode 100644 index 00000000000..db517dbd863 --- /dev/null +++ b/engine/storage/image/resources/META-INF/cloudstack/core/spring-engine-storage-image-core-context.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java index be0ce4e6b99..a67f08f604c 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java @@ -70,8 +70,12 @@ public class TemplateDataFactoryImpl implements TemplateDataFactory { } } - if (!found) { - s_logger.debug("template " + templateId + " is not in store:" + store.getId() + ", type:" + store.getRole()); + if (s_logger.isDebugEnabled()) { + if (!found) { + s_logger.debug("template " + templateId + " is not in store:" + store.getId() + ", type:" + store.getRole()); + } else { + s_logger.debug("template " + templateId + " is already in store:" + store.getId() + ", type:" + store.getRole()); + } } TemplateObject tmpl = TemplateObject.getTemplate(templ, store); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/AopTestAdvice.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/AopTestAdvice.java index 902f5953eb1..e51155d9d13 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/AopTestAdvice.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/AopTestAdvice.java @@ -19,10 +19,11 @@ package org.apache.cloudstack.storage.test; import org.aspectj.lang.ProceedingJoinPoint; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; public class AopTestAdvice { public Object AopTestMethod(ProceedingJoinPoint call) throws Throwable { - Transaction txn = Transaction.open(call.getSignature().getName()); + TransactionLegacy txn = TransactionLegacy.open(call.getSignature().getName()); Object ret = null; try { ret = call.proceed(); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java index 26f4c5da0e9..c2b9466f90b 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java @@ -26,6 +26,7 @@ import org.testng.annotations.Test; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { private String hostGateway; @@ -39,7 +40,7 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { private String imageInstallPath; private String scriptPath; private HypervisorType hypervisor; - private Transaction txn; + private TransactionLegacy txn; private String s3AccessKey; private String s3SecretKey; @@ -54,7 +55,7 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { @BeforeMethod(alwaysRun = true) protected void injectDB(Method testMethod) throws Exception { - txn = Transaction.open(testMethod.getName()); + txn = TransactionLegacy.open(testMethod.getName()); } @Test diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakePrimaryDataStoreDriver.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakePrimaryDataStoreDriver.java index 810afd11577..de64b8f5ca2 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakePrimaryDataStoreDriver.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakePrimaryDataStoreDriver.java @@ -18,8 +18,8 @@ */ package org.apache.cloudstack.storage.test; -import com.cloud.agent.api.to.DataStoreTO; -import com.cloud.agent.api.to.DataTO; +import java.util.UUID; + import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; @@ -33,7 +33,8 @@ import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.to.SnapshotObjectTO; -import java.util.UUID; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; public class FakePrimaryDataStoreDriver implements PrimaryDataStoreDriver { boolean snapshotResult = true; diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java index 79ed61bc849..2e77ac33ed8 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java @@ -26,7 +26,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority.Priority; +import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CopyCmdAnswer; @@ -43,8 +43,8 @@ public class MockStorageMotionStrategy implements DataMotionStrategy { boolean success = true; @Override - public Priority canHandle(DataObject srcData, DataObject destData) { - return Priority.HIGHEST; + public StrategyPriority canHandle(DataObject srcData, DataObject destData) { + return StrategyPriority.HIGHEST; } public void makeBackupSnapshotSucceed(boolean success) { @@ -52,8 +52,8 @@ public class MockStorageMotionStrategy implements DataMotionStrategy { } @Override - public Priority canHandle(Map volumeMap, Host srcHost, Host destHost) { - return Priority.HIGHEST; + public StrategyPriority canHandle(Map volumeMap, Host srcHost, Host destHost) { + return StrategyPriority.HIGHEST; } @Override diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java index 81f77d62429..1407707c330 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java @@ -39,13 +39,16 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy.SnapshotOperation; +import org.apache.cloudstack.engine.subsystem.api.storage.StorageStrategyFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.LocalHostEndpoint; @@ -148,6 +151,8 @@ public class SnapshotTest extends CloudStackTestNGBase { @Inject SnapshotDataFactory snapshotFactory; @Inject + StorageStrategyFactory storageStrategyFactory; + @Inject List snapshotStrategies; @Inject SnapshotService snapshotSvr; @@ -281,7 +286,7 @@ public class SnapshotTest extends CloudStackTestNGBase { Mockito.when(epSelector.select(Matchers.any(DataObject.class))).thenReturn(remoteEp); Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(remoteEp); Mockito.when(hyGuruMgr.getGuruProcessedCommandTargetHost(Matchers.anyLong(), Matchers.any(Command.class))) - .thenReturn(this.host.getId()); + .thenReturn(this.host.getId()); } @@ -367,10 +372,10 @@ public class SnapshotTest extends CloudStackTestNGBase { result = future.get(); Assert.assertTrue(result.isSuccess()); return result.getVolume(); - + } - + private VMTemplateVO createTemplateInDb() { VMTemplateVO image = new VMTemplateVO(); @@ -401,13 +406,10 @@ public class SnapshotTest extends CloudStackTestNGBase { SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore()); boolean result = false; - StrategyPriority.sortStrategies(snapshotStrategies, snapshot); - - for (SnapshotStrategy strategy : this.snapshotStrategies) { - if (strategy.canHandle(snapshot) != Priority.CANT_HANDLE) { - snapshot = strategy.takeSnapshot(snapshot); - result = true; - } + SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE); + if (snapshotStrategy != null) { + snapshot = snapshotStrategy.takeSnapshot(snapshot); + result = true; } AssertJUnit.assertTrue(result); @@ -426,18 +428,15 @@ public class SnapshotTest extends CloudStackTestNGBase { SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore()); SnapshotInfo newSnapshot = null; - StrategyPriority.sortStrategies(snapshotStrategies, newSnapshot); - - for (SnapshotStrategy strategy : this.snapshotStrategies) { - if (strategy.canHandle(snapshot) != Priority.CANT_HANDLE) { - newSnapshot = strategy.takeSnapshot(snapshot); - } + SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE); + if (snapshotStrategy != null) { + newSnapshot = snapshotStrategy.takeSnapshot(snapshot); } AssertJUnit.assertNotNull(newSnapshot); // create another snapshot for (SnapshotStrategy strategy : this.snapshotStrategies) { - if (strategy.canHandle(snapshot) != Priority.CANT_HANDLE) { + if (strategy.canHandle(snapshot, SnapshotOperation.DELETE) != StrategyPriority.CANT_HANDLE) { strategy.deleteSnapshot(newSnapshot.getId()); } } @@ -451,13 +450,10 @@ public class SnapshotTest extends CloudStackTestNGBase { SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore()); boolean result = false; - StrategyPriority.sortStrategies(snapshotStrategies, snapshot); - - for (SnapshotStrategy strategy : this.snapshotStrategies) { - if (strategy.canHandle(snapshot) != Priority.CANT_HANDLE) { - snapshot = strategy.takeSnapshot(snapshot); - result = true; - } + SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE); + if (snapshotStrategy != null) { + snapshot = snapshotStrategy.takeSnapshot(snapshot); + result = true; } AssertJUnit.assertTrue(result); @@ -484,13 +480,11 @@ public class SnapshotTest extends CloudStackTestNGBase { SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore()); SnapshotInfo newSnapshot = null; - StrategyPriority.sortStrategies(snapshotStrategies, newSnapshot); - - for (SnapshotStrategy strategy : this.snapshotStrategies) { - if (strategy.canHandle(snapshot) != Priority.CANT_HANDLE) { - newSnapshot = strategy.takeSnapshot(snapshot); - } + SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE); + if (snapshotStrategy != null) { + newSnapshot = snapshotStrategy.takeSnapshot(snapshot); } + AssertJUnit.assertNotNull(newSnapshot); LocalHostEndpoint ep = new MockLocalHostEndPoint(); @@ -499,7 +493,7 @@ public class SnapshotTest extends CloudStackTestNGBase { try { for (SnapshotStrategy strategy : this.snapshotStrategies) { - if (strategy.canHandle(snapshot) != Priority.CANT_HANDLE) { + if (strategy.canHandle(snapshot, SnapshotOperation.DELETE) != StrategyPriority.CANT_HANDLE) { boolean res = strategy.deleteSnapshot(newSnapshot.getId()); Assert.assertTrue(res); } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNGAop.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNGAop.java index 515c5c80532..44ead367f64 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNGAop.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNGAop.java @@ -26,7 +26,7 @@ import org.testng.ITestNGMethod; import org.testng.internal.ConstructorOrMethod; import com.cloud.utils.db.DB; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; public class TestNGAop implements IMethodInterceptor { @@ -39,7 +39,7 @@ public class TestNGAop implements IMethodInterceptor { if (m != null) { DB db = m.getAnnotation(DB.class); if (db != null) { - Transaction txn = Transaction.open(m.getName()); + TransactionLegacy txn = TransactionLegacy.open(m.getName()); } } } diff --git a/engine/storage/integration-test/test/resources/storageContext.xml b/engine/storage/integration-test/test/resources/storageContext.xml index 664f1e3a290..e4b82741364 100644 --- a/engine/storage/integration-test/test/resources/storageContext.xml +++ b/engine/storage/integration-test/test/resources/storageContext.xml @@ -85,4 +85,5 @@ + diff --git a/engine/storage/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml b/engine/storage/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml new file mode 100644 index 00000000000..8a78fddb8ca --- /dev/null +++ b/engine/storage/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/engine/storage/resources/META-INF/cloudstack/storage-allocator/module.properties b/engine/storage/resources/META-INF/cloudstack/storage-allocator/module.properties new file mode 100644 index 00000000000..6c96e91a22d --- /dev/null +++ b/engine/storage/resources/META-INF/cloudstack/storage-allocator/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=storage-allocator +parent=storage \ No newline at end of file diff --git a/engine/storage/resources/META-INF/cloudstack/storage-allocator/spring-engine-storage-storage-allocator-context.xml b/engine/storage/resources/META-INF/cloudstack/storage-allocator/spring-engine-storage-storage-allocator-context.xml new file mode 100644 index 00000000000..e4e02aa210e --- /dev/null +++ b/engine/storage/resources/META-INF/cloudstack/storage-allocator/spring-engine-storage-storage-allocator-context.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + diff --git a/engine/storage/snapshot/resources/META-INF/cloudstack/core/spring-engine-storage-snapshot-core-context.xml b/engine/storage/snapshot/resources/META-INF/cloudstack/core/spring-engine-storage-snapshot-core-context.xml new file mode 100644 index 00000000000..308899280dc --- /dev/null +++ b/engine/storage/snapshot/resources/META-INF/cloudstack/core/spring-engine-storage-snapshot-core-context.xml @@ -0,0 +1,41 @@ + + + + + + + + + + \ No newline at end of file diff --git a/engine/storage/snapshot/resources/META-INF/cloudstack/storage/spring-engine-storage-snapshot-storage-context.xml b/engine/storage/snapshot/resources/META-INF/cloudstack/storage/spring-engine-storage-snapshot-storage-context.xml new file mode 100644 index 00000000000..3faa89482c6 --- /dev/null +++ b/engine/storage/snapshot/resources/META-INF/cloudstack/storage/spring-engine-storage-snapshot-storage-context.xml @@ -0,0 +1,33 @@ + + + + + + \ No newline at end of file diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java index 3f35e1dd5bc..daf6477be02 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java @@ -19,16 +19,19 @@ package org.apache.cloudstack.storage.snapshot; import java.util.Date; +import java.util.List; import javax.inject.Inject; -import org.apache.log4j.Logger; - import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy.SnapshotOperation; +import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority; +import org.apache.cloudstack.engine.subsystem.api.storage.StorageStrategyFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.storage.command.CopyCmdAnswer; @@ -37,6 +40,7 @@ import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; import org.apache.cloudstack.storage.to.SnapshotObjectTO; +import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; import com.cloud.agent.api.to.DataObjectType; @@ -72,6 +76,8 @@ public class SnapshotObject implements SnapshotInfo { ObjectInDataStoreManager objectInStoreMgr; @Inject SnapshotDataStoreDao snapshotStoreDao; + @Inject + StorageStrategyFactory storageStrategyFactory; public SnapshotObject() { @@ -122,6 +128,16 @@ public class SnapshotObject implements SnapshotInfo { return snapshotFactory.getSnapshot(vo.getId(), store); } + @Override + public boolean isRevertable() { + SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.REVERT); + if (snapshotStrategy != null) { + return true; + } + + return false; + } + @Override public VolumeInfo getBaseVolume() { return volFactory.getVolume(snapshot.getVolumeId()); @@ -268,18 +284,18 @@ public class SnapshotObject implements SnapshotInfo { snapshotStore.setParentSnapshotId(0L); } snapshotStoreDao.update(snapshotStore.getId(), snapshotStore); - + // update side-effect of snapshot operation if(snapshotTO.getVolume() != null && snapshotTO.getVolume().getPath() != null) { - VolumeVO vol = volumeDao.findByUuid(snapshotTO.getVolume().getUuid()); - if(vol != null) { - s_logger.info("Update volume path change due to snapshot operation, volume " + vol.getId() + " path: " - + vol.getPath() + "->" + snapshotTO.getVolume().getPath()); - vol.setPath(snapshotTO.getVolume().getPath()); - volumeDao.update(vol.getId(), vol); - } else { - s_logger.error("Cound't find the original volume with uuid: " + snapshotTO.getVolume().getUuid()); - } + VolumeVO vol = volumeDao.findByUuid(snapshotTO.getVolume().getUuid()); + if(vol != null) { + s_logger.info("Update volume path change due to snapshot operation, volume " + vol.getId() + " path: " + + vol.getPath() + "->" + snapshotTO.getVolume().getPath()); + vol.setPath(snapshotTO.getVolume().getPath()); + volumeDao.update(vol.getId(), vol); + } else { + s_logger.error("Cound't find the original volume with uuid: " + snapshotTO.getVolume().getUuid()); + } } } else { throw new CloudRuntimeException("Unknown answer: " + answer.getClass()); diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java index 6a874d67b8b..27dbd83e842 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java @@ -310,7 +310,11 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase { } @Override - public StrategyPriority.Priority canHandle(Snapshot snapshot) { - return StrategyPriority.Priority.DEFAULT; + public StrategyPriority canHandle(Snapshot snapshot, SnapshotOperation op) { + if (op == SnapshotOperation.REVERT) { + return StrategyPriority.CANT_HANDLE; + } + + return StrategyPriority.DEFAULT; } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java index 6b076d39f1a..d48edd6eb80 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java @@ -51,8 +51,13 @@ public class ClusterScopeStoragePoolAllocator extends AbstractStoragePoolAllocat @Override protected List select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { - s_logger.debug("ClusterScopeStoragePoolAllocator looking for storage pool"); + + if (dskCh.useLocalStorage()) { + // cluster wide allocator should bail out in case of local disk + return null; + } + List suitablePools = new ArrayList(); long dcId = plan.getDataCenterId(); @@ -84,9 +89,7 @@ public class ClusterScopeStoragePoolAllocator extends AbstractStoragePoolAllocat if (pools.size() == 0) { if (s_logger.isDebugEnabled()) { - String storageType = dskCh.useLocalStorage() ? ServiceOffering.StorageType.local.toString() - : ServiceOffering.StorageType.shared.toString(); - s_logger.debug("No storage pools available for " + storageType + " volume allocation, returning"); + s_logger.debug("No storage pools available for " + ServiceOffering.StorageType.shared.toString() + " volume allocation, returning"); } return suitablePools; } @@ -95,16 +98,16 @@ public class ClusterScopeStoragePoolAllocator extends AbstractStoragePoolAllocat if (suitablePools.size() == returnUpTo) { break; } - StoragePool pol = (StoragePool) dataStoreMgr.getPrimaryDataStore(pool.getId()); - if (filter(avoid, pol, dskCh, plan)) { - suitablePools.add(pol); + StoragePool storagePool = (StoragePool) dataStoreMgr.getPrimaryDataStore(pool.getId()); + if (filter(avoid, storagePool, dskCh, plan)) { + suitablePools.add(storagePool); } else { avoid.addPool(pool.getId()); } } if (s_logger.isDebugEnabled()) { - s_logger.debug("FirstFitStoragePoolAllocator returning " + suitablePools.size() + " suitable storage pools"); + s_logger.debug("ClusterScopeStoragePoolAllocator returning " + suitablePools.size() + " suitable storage pools"); } return suitablePools; diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java index 3ea2c462087..1f61e8b948d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java @@ -68,25 +68,24 @@ public class LocalStoragePoolAllocator extends AbstractStoragePoolAllocator { @Override protected List select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { - - List suitablePools = new ArrayList(); - s_logger.debug("LocalStoragePoolAllocator trying to find storage pool to fit the vm"); if (!dskCh.useLocalStorage()) { - return suitablePools; + return null; } + List suitablePools = new ArrayList(); + // data disk and host identified from deploying vm (attach volume case) if (dskCh.getType() == Volume.Type.DATADISK && plan.getHostId() != null) { List hostPools = _poolHostDao.listByHostId(plan.getHostId()); for (StoragePoolHostVO hostPool : hostPools) { StoragePoolVO pool = _storagePoolDao.findById(hostPool.getPoolId()); if (pool != null && pool.isLocal()) { - StoragePool pol = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(pool.getId()); - if (filter(avoid, pol, dskCh, plan)) { + StoragePool storagePool = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(pool.getId()); + if (filter(avoid, storagePool, dskCh, plan)) { s_logger.debug("Found suitable local storage pool " + pool.getId() + ", adding to list"); - suitablePools.add(pol); + suitablePools.add(storagePool); } else { avoid.addPool(pool.getId()); } @@ -107,9 +106,9 @@ public class LocalStoragePoolAllocator extends AbstractStoragePoolAllocator { if (suitablePools.size() == returnUpTo) { break; } - StoragePool pol = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(pool.getId()); - if (filter(avoid, pol, dskCh, plan)) { - suitablePools.add(pol); + StoragePool storagePool = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(pool.getId()); + if (filter(avoid, storagePool, dskCh, plan)) { + suitablePools.add(storagePool); } else { avoid.addPool(pool.getId()); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java index 38724fa8214..b58bcb53cb6 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java @@ -57,21 +57,25 @@ public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator { storageMgr.storagePoolHasEnoughSpace(requestVolumes, pool); } - @Override - protected List select(DiskProfile dskCh, - VirtualMachineProfile vmProfile, - DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { - s_logger.debug("ZoneWideStoragePoolAllocator to find storage pool"); - List suitablePools = new ArrayList(); + + @Override + protected List select(DiskProfile dskCh, + VirtualMachineProfile vmProfile, + DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { + s_logger.debug("ZoneWideStoragePoolAllocator to find storage pool"); + + if (dskCh.useLocalStorage()) { + return null; + } + + List suitablePools = new ArrayList(); List storagePools = _storagePoolDao.findZoneWideStoragePoolsByTags(plan.getDataCenterId(), dskCh.getTags()); - if (storagePools == null) { storagePools = new ArrayList(); } List anyHypervisorStoragePools = new ArrayList(); - for (StoragePoolVO storagePool : storagePools) { if (HypervisorType.Any.equals(storagePool.getHypervisor())) { anyHypervisorStoragePools.add(storagePool); @@ -79,9 +83,7 @@ public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator { } List storagePoolsByHypervisor = _storagePoolDao.findZoneWideStoragePoolsByHypervisor(plan.getDataCenterId(), dskCh.getHypervisorType()); - storagePools.retainAll(storagePoolsByHypervisor); - storagePools.addAll(anyHypervisorStoragePools); // add remaining pools in zone, that did not match tags, to avoid set @@ -95,15 +97,16 @@ public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator { if (suitablePools.size() == returnUpTo) { break; } - StoragePool pol = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(storage.getId()); - if (filter(avoid, pol, dskCh, plan)) { - suitablePools.add(pol); + StoragePool storagePool = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(storage.getId()); + if (filter(avoid, storagePool, dskCh, plan)) { + suitablePools.add(storagePool); } else { - avoid.addPool(pol.getId()); + avoid.addPool(storagePool.getId()); } } return suitablePools; } + @Override protected List reorderPoolsByNumberOfVolumes(DeploymentPlan plan, List pools, Account account) { diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java index 92b4e7a5479..e186bd82017 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java @@ -20,6 +20,8 @@ package org.apache.cloudstack.storage.datastore.provider; import com.cloud.exception.InvalidParameterValueException; import com.cloud.utils.component.ManagerBase; +import com.cloud.utils.component.Registry; + import org.apache.cloudstack.api.response.StorageProviderResponse; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider.DataStoreProviderType; @@ -33,18 +35,22 @@ import org.springframework.stereotype.Component; import javax.inject.Inject; import javax.naming.ConfigurationException; + import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; @Component -public class DataStoreProviderManagerImpl extends ManagerBase implements DataStoreProviderManager { +public class DataStoreProviderManagerImpl extends ManagerBase implements DataStoreProviderManager, Registry { private static final Logger s_logger = Logger.getLogger(DataStoreProviderManagerImpl.class); - @Inject + List providers; - protected Map providerMap = new HashMap(); + protected Map providerMap = new ConcurrentHashMap(); @Inject PrimaryDataStoreProviderManager primaryDataStoreProviderMgr; @Inject @@ -52,6 +58,9 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto @Override public DataStoreProvider getDataStoreProvider(String name) { + if (name == null) + return null; + return providerMap.get(name); } @@ -96,43 +105,54 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto @Override public boolean configure(String name, Map params) throws ConfigurationException { - Map copyParams = new HashMap(params); - for (DataStoreProvider provider : providers) { - String providerName = provider.getName(); - if (providerMap.get(providerName) != null) { - s_logger.debug("Failed to register data store provider, provider name: " + providerName - + " is not unique"); - return false; - } - - s_logger.debug("registering data store provider:" + provider.getName()); - - providerMap.put(providerName, provider); - try { - boolean registrationResult = provider.configure(copyParams); - if (!registrationResult) { - providerMap.remove(providerName); - s_logger.debug("Failed to register data store provider: " + providerName); - return false; - } - - Set types = provider.getTypes(); - if (types.contains(DataStoreProviderType.PRIMARY)) { - primaryDataStoreProviderMgr.registerDriver(provider.getName(), - (PrimaryDataStoreDriver) provider.getDataStoreDriver()); - primaryDataStoreProviderMgr.registerHostListener(provider.getName(), provider.getHostListener()); - } else if (types.contains(DataStoreProviderType.IMAGE)) { - imageStoreProviderMgr.registerDriver(provider.getName(), - (ImageStoreDriver) provider.getDataStoreDriver()); - } - } catch (Exception e) { - s_logger.debug("configure provider failed", e); - providerMap.remove(providerName); - return false; + if ( providers != null ) { + for (DataStoreProvider provider : providers) { + registerProvider(provider); } } + providers = new CopyOnWriteArrayList(providers); + + return true; + } + + protected boolean registerProvider(DataStoreProvider provider) { + Map copyParams = new HashMap(); + + String providerName = provider.getName(); + if (providerMap.get(providerName) != null) { + s_logger.debug("Did not register data store provider, provider name: " + providerName + + " is not unique"); + return false; + } + + s_logger.debug("registering data store provider:" + provider.getName()); + + providerMap.put(providerName, provider); + try { + boolean registrationResult = provider.configure(copyParams); + if (!registrationResult) { + providerMap.remove(providerName); + s_logger.debug("Failed to register data store provider: " + providerName); + return false; + } + + Set types = provider.getTypes(); + if (types.contains(DataStoreProviderType.PRIMARY)) { + primaryDataStoreProviderMgr.registerDriver(provider.getName(), + (PrimaryDataStoreDriver) provider.getDataStoreDriver()); + primaryDataStoreProviderMgr.registerHostListener(provider.getName(), provider.getHostListener()); + } else if (types.contains(DataStoreProviderType.IMAGE)) { + imageStoreProviderMgr.registerDriver(provider.getName(), + (ImageStoreDriver) provider.getDataStoreDriver()); + } + } catch (Exception e) { + s_logger.debug("configure provider failed", e); + providerMap.remove(providerName); + return false; + } + return true; } @@ -167,6 +187,27 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto } } + @Override + public boolean register(DataStoreProvider type) { + if ( registerProvider(type) ) { + providers.add(type); + return true; + } + + return false; + } + + @Override + public void unregister(DataStoreProvider type) { + /* Sorry, no unregister supported... */ + } + + @Override + public List getRegistered() { + return Collections.unmodifiableList(providers); + } + + @Inject public void setProviders(List providers) { this.providers = providers; } @@ -178,4 +219,9 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto public void setImageStoreProviderMgr(ImageStoreProviderManager imageDataStoreProviderMgr) { this.imageStoreProviderMgr = imageDataStoreProviderMgr; } + + public List getProviders() { + return providers; + } + } diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index e7c66279e06..196b08b2f42 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -47,6 +47,7 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.QueryBuilder; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -110,7 +111,7 @@ public class DefaultEndPointSelector implements EndPointSelector { PreparedStatement pstmt = null; ResultSet rs = null; HostVO host = null; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { pstmt = txn.prepareStatement(sql); diff --git a/engine/storage/src/org/apache/cloudstack/storage/helper/StorageStrategyFactoryImpl.java b/engine/storage/src/org/apache/cloudstack/storage/helper/StorageStrategyFactoryImpl.java new file mode 100644 index 00000000000..30812bf39f1 --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/helper/StorageStrategyFactoryImpl.java @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.helper; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy.SnapshotOperation; +import org.apache.cloudstack.engine.subsystem.api.storage.StorageStrategyFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; + +import com.cloud.host.Host; +import com.cloud.storage.Snapshot; + +public class StorageStrategyFactoryImpl implements StorageStrategyFactory { + + List snapshotStrategies; + List dataMotionStrategies; + + @Override + public DataMotionStrategy getDataMotionStrategy(final DataObject srcData, final DataObject destData) { + return bestMatch(dataMotionStrategies, new CanHandle() { + @Override + public StrategyPriority canHandle(DataMotionStrategy strategy) { + return strategy.canHandle(srcData, destData); + } + }); + } + + @Override + public DataMotionStrategy getDataMotionStrategy(final Map volumeMap, final Host srcHost, final Host destHost) { + return bestMatch(dataMotionStrategies, new CanHandle() { + @Override + public StrategyPriority canHandle(DataMotionStrategy strategy) { + return strategy.canHandle(volumeMap, srcHost, destHost); + } + }); + } + + @Override + public SnapshotStrategy getSnapshotStrategy(final Snapshot snapshot, final SnapshotOperation op) { + return bestMatch(snapshotStrategies, new CanHandle() { + @Override + public StrategyPriority canHandle(SnapshotStrategy strategy) { + return strategy.canHandle(snapshot, op); + } + }); + } + + private static T bestMatch(Collection collection, final CanHandle canHandle) { + if (collection.size() == 0) + return null; + + StrategyPriority highestPriority = StrategyPriority.CANT_HANDLE; + + T strategyToUse = null; + for (T strategy : collection) { + StrategyPriority priority = canHandle.canHandle(strategy); + if (priority.ordinal() > highestPriority.ordinal()) { + highestPriority = priority; + strategyToUse = strategy; + } + } + + return strategyToUse; + } + + private static interface CanHandle { + StrategyPriority canHandle(T strategy); + } + + public List getSnapshotStrategies() { + return snapshotStrategies; + } + + @Inject + public void setSnapshotStrategies(List snapshotStrategies) { + this.snapshotStrategies = snapshotStrategies; + } + + public List getDataMotionStrategies() { + return dataMotionStrategies; + } + + @Inject + public void setDataMotionStrategies(List dataMotionStrategies) { + this.dataMotionStrategies = dataMotionStrategies; + } + +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java index ad52042bc7c..3c766cf80c7 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java @@ -29,7 +29,7 @@ import org.springframework.stereotype.Component; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value = ImageStoreDetailsDao.class) @@ -46,7 +46,7 @@ public class ImageStoreDetailsDaoImpl extends GenericDaoBase details) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); SearchCriteria sc = storeSearch.create(); sc.setParameters("store", storeId); diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java index d8280851a38..48416a2d96c 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java @@ -40,7 +40,7 @@ import com.cloud.storage.DataStoreRole; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.UpdateBuilder; @@ -164,7 +164,7 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase sc = storeSearch.create(); sc.setParameters("store_id", id); sc.setParameters("store_role", role); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); remove(sc); txn.commit(); @@ -182,7 +182,7 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase sc = storeSearch.create(); sc.setParameters("store_id", id); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); remove(sc); txn.commit(); @@ -212,7 +212,7 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase sc = templateSearch.create(); sc.setParameters("template_id", templateId); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); expunge(sc); txn.commit(); diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java index 04f8b70e44b..2bacd03560a 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java @@ -33,7 +33,7 @@ import org.springframework.stereotype.Component; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.UpdateBuilder; @@ -143,7 +143,7 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase sc = storeSearch.create(); sc.setParameters("store_id", id); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); remove(sc); txn.commit(); diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java index 4ea4ceec555..90ad17aa6d8 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java @@ -43,7 +43,7 @@ import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePoolHostVO; import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.dao.StoragePoolHostDao; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -181,7 +181,7 @@ public class PrimaryDataStoreHelper { public boolean deletePrimaryDataStore(DataStore store) { List hostPoolRecords = this.storagePoolHostDao.listByPoolId(store.getId()); StoragePoolVO poolVO = this.dataStoreDao.findById(store.getId()); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); for (StoragePoolHostVO host : hostPoolRecords) { storagePoolHostDao.deleteStoragePoolHostDetails(host.getHostId(), host.getPoolId()); diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/db/PrimaryDataStoreDetailsDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/volume/db/PrimaryDataStoreDetailsDaoImpl.java index 9d174348c73..be741da3846 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/db/PrimaryDataStoreDetailsDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/db/PrimaryDataStoreDetailsDaoImpl.java @@ -27,7 +27,7 @@ import org.springframework.stereotype.Component; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component public class PrimaryDataStoreDetailsDaoImpl extends GenericDaoBase implements @@ -45,7 +45,7 @@ public class PrimaryDataStoreDetailsDaoImpl extends GenericDaoBase details) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); SearchCriteria sc = PoolSearch.create(); sc.setParameters("pool", poolId); diff --git a/engine/storage/test/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriorityTest.java b/engine/storage/test/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriorityTest.java new file mode 100644 index 00000000000..1c3ceb6653b --- /dev/null +++ b/engine/storage/test/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriorityTest.java @@ -0,0 +1,161 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.engine.subsystem.api.storage; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy.SnapshotOperation; +import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority; +import org.apache.cloudstack.storage.helper.StorageStrategyFactoryImpl; +import org.junit.Test; + +import com.cloud.host.Host; +import com.cloud.storage.Snapshot; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +public class StrategyPriorityTest { + + @Test + public void testSortSnapshotStrategies() { + SnapshotStrategy cantHandleStrategy = mock(SnapshotStrategy.class); + SnapshotStrategy defaultStrategy = mock(SnapshotStrategy.class); + SnapshotStrategy hyperStrategy = mock(SnapshotStrategy.class); + SnapshotStrategy pluginStrategy = mock(SnapshotStrategy.class); + SnapshotStrategy highestStrategy = mock(SnapshotStrategy.class); + + doReturn(StrategyPriority.CANT_HANDLE).when(cantHandleStrategy).canHandle(any(Snapshot.class), any(SnapshotOperation.class)); + doReturn(StrategyPriority.DEFAULT).when(defaultStrategy).canHandle(any(Snapshot.class), any(SnapshotOperation.class)); + doReturn(StrategyPriority.HYPERVISOR).when(hyperStrategy).canHandle(any(Snapshot.class), any(SnapshotOperation.class)); + doReturn(StrategyPriority.PLUGIN).when(pluginStrategy).canHandle(any(Snapshot.class), any(SnapshotOperation.class)); + doReturn(StrategyPriority.HIGHEST).when(highestStrategy).canHandle(any(Snapshot.class), any(SnapshotOperation.class)); + + List strategies = new ArrayList(5); + SnapshotStrategy strategy = null; + + StorageStrategyFactoryImpl factory = new StorageStrategyFactoryImpl(); + factory.setSnapshotStrategies(strategies); + + strategies.add(cantHandleStrategy); + strategy = factory.getSnapshotStrategy(mock(Snapshot.class), SnapshotOperation.TAKE); + assertEquals("A strategy was found when it shouldn't have been.", null, strategy); + + strategies.add(defaultStrategy); + strategy = factory.getSnapshotStrategy(mock(Snapshot.class), SnapshotOperation.TAKE); + assertEquals("Default strategy was not picked.", defaultStrategy, strategy); + + strategies.add(hyperStrategy); + strategy = factory.getSnapshotStrategy(mock(Snapshot.class), SnapshotOperation.TAKE); + assertEquals("Hypervisor strategy was not picked.", hyperStrategy, strategy); + + strategies.add(pluginStrategy); + strategy = factory.getSnapshotStrategy(mock(Snapshot.class), SnapshotOperation.TAKE); + assertEquals("Plugin strategy was not picked.", pluginStrategy, strategy); + + strategies.add(highestStrategy); + strategy = factory.getSnapshotStrategy(mock(Snapshot.class), SnapshotOperation.TAKE); + assertEquals("Highest strategy was not picked.", highestStrategy, strategy); + } + + @Test + public void testSortDataMotionStrategies() { + DataMotionStrategy cantHandleStrategy = mock(DataMotionStrategy.class); + DataMotionStrategy defaultStrategy = mock(DataMotionStrategy.class); + DataMotionStrategy hyperStrategy = mock(DataMotionStrategy.class); + DataMotionStrategy pluginStrategy = mock(DataMotionStrategy.class); + DataMotionStrategy highestStrategy = mock(DataMotionStrategy.class); + + doReturn(StrategyPriority.CANT_HANDLE).when(cantHandleStrategy).canHandle(any(DataObject.class), any(DataObject.class)); + doReturn(StrategyPriority.DEFAULT).when(defaultStrategy).canHandle(any(DataObject.class), any(DataObject.class)); + doReturn(StrategyPriority.HYPERVISOR).when(hyperStrategy).canHandle(any(DataObject.class), any(DataObject.class)); + doReturn(StrategyPriority.PLUGIN).when(pluginStrategy).canHandle(any(DataObject.class), any(DataObject.class)); + doReturn(StrategyPriority.HIGHEST).when(highestStrategy).canHandle(any(DataObject.class), any(DataObject.class)); + + List strategies = new ArrayList(5); + DataMotionStrategy strategy = null; + + StorageStrategyFactoryImpl factory = new StorageStrategyFactoryImpl(); + factory.setDataMotionStrategies(strategies); + + strategies.add(cantHandleStrategy); + strategy = factory.getDataMotionStrategy(mock(DataObject.class), mock(DataObject.class)); + assertEquals("A strategy was found when it shouldn't have been.", null, strategy); + + strategies.add(defaultStrategy); + strategy = factory.getDataMotionStrategy(mock(DataObject.class), mock(DataObject.class)); + assertEquals("Default strategy was not picked.", defaultStrategy, strategy); + + strategies.add(hyperStrategy); + strategy = factory.getDataMotionStrategy(mock(DataObject.class), mock(DataObject.class)); + assertEquals("Hypervisor strategy was not picked.", hyperStrategy, strategy); + + strategies.add(pluginStrategy); + strategy = factory.getDataMotionStrategy(mock(DataObject.class), mock(DataObject.class)); + assertEquals("Plugin strategy was not picked.", pluginStrategy, strategy); + + strategies.add(highestStrategy); + strategy = factory.getDataMotionStrategy(mock(DataObject.class), mock(DataObject.class)); + assertEquals("Highest strategy was not picked.", highestStrategy, strategy); + } + + @Test + @SuppressWarnings("unchecked") + public void testSortDataMotionStrategies2() { + DataMotionStrategy cantHandleStrategy = mock(DataMotionStrategy.class); + DataMotionStrategy defaultStrategy = mock(DataMotionStrategy.class); + DataMotionStrategy hyperStrategy = mock(DataMotionStrategy.class); + DataMotionStrategy pluginStrategy = mock(DataMotionStrategy.class); + DataMotionStrategy highestStrategy = mock(DataMotionStrategy.class); + + doReturn(StrategyPriority.CANT_HANDLE).when(cantHandleStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class)); + doReturn(StrategyPriority.DEFAULT).when(defaultStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class)); + doReturn(StrategyPriority.HYPERVISOR).when(hyperStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class)); + doReturn(StrategyPriority.PLUGIN).when(pluginStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class)); + doReturn(StrategyPriority.HIGHEST).when(highestStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class)); + + List strategies = new ArrayList(5); + DataMotionStrategy strategy = null; + + StorageStrategyFactoryImpl factory = new StorageStrategyFactoryImpl(); + factory.setDataMotionStrategies(strategies); + + strategies.add(cantHandleStrategy); + strategy = factory.getDataMotionStrategy(mock(Map.class), mock(Host.class), mock(Host.class)); + assertEquals("A strategy was found when it shouldn't have been.", null, strategy); + + strategies.add(defaultStrategy); + strategy = factory.getDataMotionStrategy(mock(Map.class), mock(Host.class), mock(Host.class)); + assertEquals("Default strategy was not picked.", defaultStrategy, strategy); + + strategies.add(hyperStrategy); + strategy = factory.getDataMotionStrategy(mock(Map.class), mock(Host.class), mock(Host.class)); + assertEquals("Hypervisor strategy was not picked.", hyperStrategy, strategy); + + strategies.add(pluginStrategy); + strategy = factory.getDataMotionStrategy(mock(Map.class), mock(Host.class), mock(Host.class)); + assertEquals("Plugin strategy was not picked.", pluginStrategy, strategy); + + strategies.add(highestStrategy); + strategy = factory.getDataMotionStrategy(mock(Map.class), mock(Host.class), mock(Host.class)); + assertEquals("Highest strategy was not picked.", highestStrategy, strategy); + } +} diff --git a/engine/storage/volume/resources/META-INF/cloudstack/core/spring-engine-storage-volume-core-context.xml b/engine/storage/volume/resources/META-INF/cloudstack/core/spring-engine-storage-volume-core-context.xml new file mode 100644 index 00000000000..ba9afb538ec --- /dev/null +++ b/engine/storage/volume/resources/META-INF/cloudstack/core/spring-engine-storage-volume-core-context.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java index 22ff2209b19..2d99c9b6b48 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java @@ -23,19 +23,20 @@ import java.util.List; import javax.inject.Inject; -import com.cloud.utils.db.GlobalLock; +import org.apache.log4j.Logger; + import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; @@ -44,14 +45,13 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; import org.apache.cloudstack.storage.volume.VolumeObject; -import org.apache.log4j.Logger; import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; +import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StoragePoolHostVO; import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.VMTemplateStoragePoolVO; @@ -60,6 +60,7 @@ import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.component.ComponentContext; +import com.cloud.utils.db.GlobalLock; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.storage.encoding.EncodingType; @@ -111,7 +112,7 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { @Override public List getVolumes() { - List volumes = volumeDao.findByPoolId(this.getId()); + List volumes = volumeDao.findByPoolId(getId()); List volumeInfos = new ArrayList(); for (VolumeVO volume : volumes) { volumeInfos.add(VolumeObject.getVolumeObject(this, volume)); @@ -121,7 +122,7 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { @Override public DataStoreDriver getDriver() { - return this.driver; + return driver; } @Override @@ -131,28 +132,28 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { @Override public long getId() { - return this.pdsv.getId(); + return pdsv.getId(); } @Override public String getUri() { - String path = this.pdsv.getPath(); + String path = pdsv.getPath(); path.replaceFirst("/*", ""); StringBuilder builder = new StringBuilder(); - builder.append(this.pdsv.getPoolType()); + builder.append(pdsv.getPoolType()); builder.append("://"); - builder.append(this.pdsv.getHostAddress()); + builder.append(pdsv.getHostAddress()); builder.append(File.separator); - builder.append(this.pdsv.getPath()); + builder.append(pdsv.getPath()); builder.append(File.separator); - builder.append("?" + EncodingType.ROLE + "=" + this.getRole()); - builder.append("&" + EncodingType.STOREUUID + "=" + this.pdsv.getUuid()); + builder.append("?" + EncodingType.ROLE + "=" + getRole()); + builder.append("&" + EncodingType.STOREUUID + "=" + pdsv.getUuid()); return builder.toString(); } @Override public Scope getScope() { - StoragePoolVO vo = dataStoreDao.findById(this.pdsv.getId()); + StoragePoolVO vo = dataStoreDao.findById(pdsv.getId()); if (vo.getScope() == ScopeType.CLUSTER) { return new ClusterScope(vo.getClusterId(), vo.getPodId(), vo.getDataCenterId()); } else if (vo.getScope() == ScopeType.ZONE) { @@ -184,7 +185,7 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { @Override public String getUuid() { - return this.pdsv.getUuid(); + return pdsv.getUuid(); } @Override @@ -195,7 +196,7 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { @Override public PrimaryDataStoreLifeCycle getLifeCycle() { - return this.lifeCycle; + return lifeCycle; } @Override @@ -205,7 +206,7 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { @Override public TemplateInfo getTemplate(long templateId) { - VMTemplateStoragePoolVO template = templatePoolDao.findByPoolTemplate(this.getId(), templateId); + VMTemplateStoragePoolVO template = templatePoolDao.findByPoolTemplate(getId(), templateId); if (template == null || template.getState() != ObjectInDataStoreStateMachine.State.Ready) { return null; } @@ -227,7 +228,7 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { // create template on primary storage if (obj.getType() == DataObjectType.TEMPLATE) { try{ - String templateIdPoolIdString = "templateId:" + obj.getId() + "poolId:" + this.getId(); + String templateIdPoolIdString = "templateId:" + obj.getId() + "poolId:" + getId(); VMTemplateStoragePoolVO templateStoragePoolRef; GlobalLock lock = GlobalLock.getInternLock(templateIdPoolIdString); if (!lock.lock(5)) { @@ -235,21 +236,21 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { return null; } try { - templateStoragePoolRef = templatePoolDao.findByPoolTemplate(this.getId(), + templateStoragePoolRef = templatePoolDao.findByPoolTemplate(getId(), obj.getId()); if (templateStoragePoolRef == null) { if (s_logger.isDebugEnabled()) { s_logger.debug("Not found (" + templateIdPoolIdString + ") in template_spool_ref, persisting it"); } - templateStoragePoolRef = new VMTemplateStoragePoolVO(this.getId(), obj.getId()); + templateStoragePoolRef = new VMTemplateStoragePoolVO(getId(), obj.getId()); templateStoragePoolRef = templatePoolDao.persist(templateStoragePoolRef); } } catch (Throwable t) { if (s_logger.isDebugEnabled()) { s_logger.debug("Failed to insert (" + templateIdPoolIdString + ") to template_spool_ref", t); } - templateStoragePoolRef = templatePoolDao.findByPoolTemplate(this.getId(), obj.getId()); + templateStoragePoolRef = templatePoolDao.findByPoolTemplate(getId(), obj.getId()); if (templateStoragePoolRef == null) { throw new CloudRuntimeException("Failed to create template storage pool entry"); } else { @@ -269,7 +270,7 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { } else if (obj.getType() == DataObjectType.VOLUME) { VolumeVO vol = volumeDao.findById(obj.getId()); if (vol != null) { - vol.setPoolId(this.getId()); + vol.setPoolId(getId()); volumeDao.update(vol.getId(), vol); } } @@ -286,96 +287,96 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { @Override public long getDataCenterId() { - return this.pdsv.getDataCenterId(); + return pdsv.getDataCenterId(); } @Override public String getPath() { - return this.pdsv.getPath(); + return pdsv.getPath(); } @Override public StoragePoolType getPoolType() { - return this.pdsv.getPoolType(); + return pdsv.getPoolType(); } @Override public Date getCreated() { - return this.pdsv.getCreated(); + return pdsv.getCreated(); } @Override public Date getUpdateTime() { - return this.pdsv.getUpdateTime(); + return pdsv.getUpdateTime(); } @Override public long getCapacityBytes() { - return this.pdsv.getCapacityBytes(); + return pdsv.getCapacityBytes(); } @Override public long getUsedBytes() { - return this.pdsv.getUsedBytes(); + return pdsv.getUsedBytes(); } @Override public Long getCapacityIops() { - return this.pdsv.getCapacityIops(); + return pdsv.getCapacityIops(); } @Override public Long getClusterId() { - return this.pdsv.getClusterId(); + return pdsv.getClusterId(); } @Override public String getHostAddress() { - return this.pdsv.getHostAddress(); + return pdsv.getHostAddress(); } @Override public String getUserInfo() { - return this.pdsv.getUserInfo(); + return pdsv.getUserInfo(); } @Override public boolean isShared() { - return this.pdsv.getScope() == ScopeType.HOST ? false : true; + return pdsv.getScope() == ScopeType.HOST ? false : true; } @Override public boolean isLocal() { - return !this.isShared(); + return !isShared(); } @Override public StoragePoolStatus getStatus() { - return this.pdsv.getStatus(); + return pdsv.getStatus(); } @Override public int getPort() { - return this.pdsv.getPort(); + return pdsv.getPort(); } @Override public Long getPodId() { - return this.pdsv.getPodId(); + return pdsv.getPodId(); } public Date getRemoved() { - return this.pdsv.getRemoved(); + return pdsv.getRemoved(); } @Override public boolean isInMaintenance() { - return this.getStatus() == StoragePoolStatus.PrepareForMaintenance || this.getStatus() == StoragePoolStatus.Maintenance || this.getStatus() == StoragePoolStatus.ErrorInMaintenance || this.getRemoved() != null; + return getStatus() == StoragePoolStatus.PrepareForMaintenance || getStatus() == StoragePoolStatus.Maintenance || getStatus() == StoragePoolStatus.ErrorInMaintenance || getRemoved() != null; } @Override public String getStorageProviderName() { - return this.pdsv.getStorageProviderName(); + return pdsv.getStorageProviderName(); } @Override diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 340d7037c19..b367deedadb 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -400,8 +400,12 @@ public class VolumeServiceImpl implements VolumeService { VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(dataStore.getId(), template.getId()); if (templatePoolRef == null) { - throw new CloudRuntimeException("Failed to find template " + template.getUniqueName() - + " in VMTemplateStoragePool"); + throw new CloudRuntimeException("Failed to find template " + template.getUniqueName() + " in storage pool " + dataStore.getId()); + } else { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Found template " + template.getUniqueName() + " in storage pool " + dataStore.getId() + " with VMTemplateStoragePool id: " + + templatePoolRef.getId()); + } } long templatePoolRefId = templatePoolRef.getId(); CreateBaseImageContext context = new CreateBaseImageContext(null, volume, @@ -411,9 +415,15 @@ public class VolumeServiceImpl implements VolumeService { int storagePoolMaxWaitSeconds = NumbersUtil.parseInt( configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Acquire lock on VMTemplateStoragePool " + templatePoolRefId + " with timeout " + storagePoolMaxWaitSeconds + " seconds"); + } templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolRefId, storagePoolMaxWaitSeconds); if (templatePoolRef == null) { + if (s_logger.isDebugEnabled()) { + s_logger.info("Unable to acquire lock on VMTemplateStoragePool " + templatePoolRefId); + } templatePoolRef = _tmpltPoolDao.findByPoolTemplate(dataStore.getId(), template.getId()); if (templatePoolRef.getState() == ObjectInDataStoreStateMachine.State.Ready ) { s_logger.info("Unable to acquire lock on VMTemplateStoragePool " + templatePoolRefId + ", But Template " + template.getUniqueName() + " is already copied to primary storage, skip copying"); @@ -423,17 +433,15 @@ public class VolumeServiceImpl implements VolumeService { throw new CloudRuntimeException("Unable to acquire lock on VMTemplateStoragePool: " + templatePoolRefId); } + if (s_logger.isDebugEnabled()) { + s_logger.info("lock is acquired for VMTemplateStoragePool " + templatePoolRefId); + } try { - // lock acquired if (templatePoolRef.getState() == ObjectInDataStoreStateMachine.State.Ready ) { s_logger.info("Template " + template.getUniqueName() + " is already copied to primary storage, skip copying"); createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, dataStore, future); return; } - // remove the leftover hanging entry - dataStore.delete(templateOnPrimaryStoreObj); - // create a new entry to restart copying process - templateOnPrimaryStoreObj = dataStore.create(template); templateOnPrimaryStoreObj.processEvent(Event.CreateOnlyRequested); motionSrv.copyAsync(template, templateOnPrimaryStoreObj, caller); } catch (Throwable e) { @@ -442,6 +450,10 @@ public class VolumeServiceImpl implements VolumeService { VolumeApiResult result = new VolumeApiResult(volume); result.setResult(e.toString()); future.complete(result); + } finally { + if (s_logger.isDebugEnabled()) { + s_logger.info("releasing lock for VMTemplateStoragePool " + templatePoolRefId); + } _tmpltPoolDao.releaseFromLockTable(templatePoolRefId); } return; @@ -713,7 +725,7 @@ public class VolumeServiceImpl implements VolumeService { srcVolume.processEvent(Event.OperationSuccessed); destVolume.processEvent(Event.OperationSuccessed, result.getAnswer()); - // srcVolume.getDataStore().delete(srcVolume); + srcVolume.getDataStore().delete(srcVolume); future.complete(res); } catch (Exception e) { res.setResult(e.toString()); diff --git a/framework/cluster/resources/META-INF/cloudstack/core/spring-framework-cluster-core-context.xml b/framework/cluster/resources/META-INF/cloudstack/core/spring-framework-cluster-core-context.xml new file mode 100644 index 00000000000..13353b0ead1 --- /dev/null +++ b/framework/cluster/resources/META-INF/cloudstack/core/spring-framework-cluster-core-context.xml @@ -0,0 +1,36 @@ + + + + + + + + + + diff --git a/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java b/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java index 56d405e98e9..35968ee015e 100644 --- a/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java +++ b/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java @@ -44,7 +44,6 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; - import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.Configurable; @@ -62,6 +61,9 @@ import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.ConnectionConcierge; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionLegacy; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.events.SubscriptionMgr; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.ExceptionUtil; @@ -532,7 +534,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C return new ManagedContextRunnable() { @Override protected void runInContext() { - Transaction txn = Transaction.open("ClusterHeartbeat"); + TransactionLegacy txn = TransactionLegacy.open("ClusterHeartbeat"); try { Profiler profiler = new Profiler(); Profiler profilerHeartbeatUpdate = new Profiler(); @@ -599,7 +601,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C invalidHeartbeatConnection(); } finally { - txn.transitToAutoManagedConnection(Transaction.CLOUD_DB); + txn.transitToAutoManagedConnection(TransactionLegacy.CLOUD_DB); txn.close("ClusterHeartbeat"); } } @@ -620,7 +622,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C private Connection getHeartbeatConnection() throws SQLException { if(_heartbeatConnection == null) { - Connection conn = Transaction.getStandaloneConnectionWithException(); + Connection conn = TransactionLegacy.getStandaloneConnectionWithException(); _heartbeatConnection = new ConnectionConcierge("ClusterManagerHeartbeat", conn, false); } @@ -629,9 +631,9 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C private void invalidHeartbeatConnection() { if(_heartbeatConnection != null) { - Connection conn = Transaction.getStandaloneConnection(); + Connection conn = TransactionLegacy.getStandaloneConnection(); if (conn != null) { - _heartbeatConnection.reset(Transaction.getStandaloneConnection()); + _heartbeatConnection.reset(TransactionLegacy.getStandaloneConnection()); } } } @@ -942,58 +944,54 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C s_logger.info("Starting cluster manager, msid : " + _msId); } - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); + ManagementServerHostVO mshost = Transaction.execute(new TransactionCallback() { + @Override + public ManagementServerHostVO doInTransaction(TransactionStatus status) { - final Class c = this.getClass(); - String version = c.getPackage().getImplementationVersion(); - - ManagementServerHostVO mshost = _mshostDao.findByMsid(_msId); - if (mshost == null) { - mshost = new ManagementServerHostVO(); - mshost.setMsid(_msId); - mshost.setRunid(getCurrentRunId()); - mshost.setName(NetUtils.getHostName()); - mshost.setVersion(version); - mshost.setServiceIP(_clusterNodeIP); - mshost.setServicePort(_currentServiceAdapter.getServicePort()); - mshost.setLastUpdateTime(DateUtil.currentGMTTime()); - mshost.setRemoved(null); - mshost.setAlertCount(0); - mshost.setState(ManagementServerHost.State.Up); - _mshostDao.persist(mshost); - - if (s_logger.isInfoEnabled()) { - s_logger.info("New instance of management server msid " + _msId + " is being started"); + final Class c = this.getClass(); + String version = c.getPackage().getImplementationVersion(); + + ManagementServerHostVO mshost = _mshostDao.findByMsid(_msId); + if (mshost == null) { + mshost = new ManagementServerHostVO(); + mshost.setMsid(_msId); + mshost.setRunid(getCurrentRunId()); + mshost.setName(NetUtils.getHostName()); + mshost.setVersion(version); + mshost.setServiceIP(_clusterNodeIP); + mshost.setServicePort(_currentServiceAdapter.getServicePort()); + mshost.setLastUpdateTime(DateUtil.currentGMTTime()); + mshost.setRemoved(null); + mshost.setAlertCount(0); + mshost.setState(ManagementServerHost.State.Up); + _mshostDao.persist(mshost); + + if (s_logger.isInfoEnabled()) { + s_logger.info("New instance of management server msid " + _msId + " is being started"); + } + } else { + if (s_logger.isInfoEnabled()) { + s_logger.info("Management server " + _msId + " is being started"); + } + + _mshostDao.update(mshost.getId(), getCurrentRunId(), NetUtils.getHostName(), version, _clusterNodeIP, _currentServiceAdapter.getServicePort(), DateUtil.currentGMTTime()); } - } else { - if (s_logger.isInfoEnabled()) { - s_logger.info("Management server " + _msId + " is being started"); - } - - _mshostDao.update(mshost.getId(), getCurrentRunId(), NetUtils.getHostName(), version, _clusterNodeIP, _currentServiceAdapter.getServicePort(), DateUtil.currentGMTTime()); + + return mshost; } + }); - txn.commit(); - - _mshostId = mshost.getId(); - if (s_logger.isInfoEnabled()) { - s_logger.info("Management server (host id : " + _mshostId + ") is being started at " + _clusterNodeIP + ":" + _currentServiceAdapter.getServicePort()); - } - - _mshostPeerDao.clearPeerInfo(_mshostId); - - // use seperate thread for heartbeat updates - _heartbeatScheduler.scheduleAtFixedRate(getHeartbeatTask(), HeartbeatInterval.value(), HeartbeatInterval.value(), TimeUnit.MILLISECONDS); - _notificationExecutor.submit(getNotificationTask()); - - } catch (Throwable e) { - s_logger.error("Unexpected exception : ", e); - txn.rollback(); - - throw new CloudRuntimeException("Unable to initialize cluster info into database"); + _mshostId = mshost.getId(); + if (s_logger.isInfoEnabled()) { + s_logger.info("Management server (host id : " + _mshostId + ") is being started at " + _clusterNodeIP + ":" + _currentServiceAdapter.getServicePort()); } + + _mshostPeerDao.clearPeerInfo(_mshostId); + + // use seperate thread for heartbeat updates + _heartbeatScheduler.scheduleAtFixedRate(getHeartbeatTask(), HeartbeatInterval.value(), HeartbeatInterval.value(), TimeUnit.MILLISECONDS); + _notificationExecutor.submit(getNotificationTask()); + if (s_logger.isInfoEnabled()) { s_logger.info("Cluster manager was started successfully"); diff --git a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java index 879c4ce3a27..246bfe6bcd4 100644 --- a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java +++ b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java @@ -38,7 +38,7 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Local(value={ManagementServerHostDao.class}) @@ -52,7 +52,7 @@ public class ManagementServerHostDaoImpl extends GenericDaoBase listOrphanMsids() { List orphanList = new ArrayList(); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement( diff --git a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java index 8ef2e82a943..f51076ceb47 100644 --- a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java +++ b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java @@ -28,7 +28,7 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Local(value={ManagementServerHostPeerDao.class}) public class ManagementServerHostPeerDaoImpl extends GenericDaoBase implements ManagementServerHostPeerDao { @@ -68,7 +68,7 @@ public class ManagementServerHostPeerDaoImpl extends GenericDaoBase + + + + + + + + + + + diff --git a/framework/config/resources/META-INF/cloudstack/system/spring-framework-config-system-context.xml b/framework/config/resources/META-INF/cloudstack/system/spring-framework-config-system-context.xml new file mode 100644 index 00000000000..8d75d27576e --- /dev/null +++ b/framework/config/resources/META-INF/cloudstack/system/spring-framework-config-system-context.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepotAdmin.java b/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepotAdmin.java index b4d3773356d..b7fe1253854 100644 --- a/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepotAdmin.java +++ b/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepotAdmin.java @@ -31,6 +31,8 @@ public interface ConfigDepotAdmin { * @see Configuration */ void populateConfigurations(); + + void populateConfiguration(Configurable configurable); List getComponentsInDepot(); } diff --git a/framework/config/src/org/apache/cloudstack/framework/config/dao/ConfigurationDao.java b/framework/config/src/org/apache/cloudstack/framework/config/dao/ConfigurationDao.java index 2f4b6e225ff..58e8a69b371 100644 --- a/framework/config/src/org/apache/cloudstack/framework/config/dao/ConfigurationDao.java +++ b/framework/config/src/org/apache/cloudstack/framework/config/dao/ConfigurationDao.java @@ -55,6 +55,8 @@ public interface ConfigurationDao extends GenericDao { public String getValueAndInitIfNotExist(String name, String category, String initValue); + public String getValueAndInitIfNotExist(String name, String category, String initValue, String desc); + /** * returns whether or not this is a premium configuration diff --git a/framework/config/src/org/apache/cloudstack/framework/config/dao/ConfigurationDaoImpl.java b/framework/config/src/org/apache/cloudstack/framework/config/dao/ConfigurationDaoImpl.java index e4029888007..8804740a7af 100644 --- a/framework/config/src/org/apache/cloudstack/framework/config/dao/ConfigurationDaoImpl.java +++ b/framework/config/src/org/apache/cloudstack/framework/config/dao/ConfigurationDaoImpl.java @@ -21,6 +21,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.annotation.PostConstruct; import javax.ejb.Local; import javax.naming.ConfigurationException; @@ -34,7 +35,7 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -128,11 +129,19 @@ public class ConfigurationDaoImpl extends GenericDaoBase _configurables; - @Inject List _scopedStorages; + Set _configured = Collections.synchronizedSet(new HashSet()); HashMap>> _allKeys = new HashMap>>(1007); @@ -85,52 +86,60 @@ public class ConfigDepotImpl implements ConfigDepot, ConfigDepotAdmin, SystemInt return value != null ? value.second() : null; } + @PostConstruct @Override public void populateConfigurations() { Date date = new Date(); for (Configurable configurable : _configurables) { - for (ConfigKey key : configurable.getConfigKeys()) { - ConfigurationVO vo = _configDao.findById(key.key()); - if (vo == null) { - vo = new ConfigurationVO(configurable.getConfigComponentName(), key); - vo.setUpdated(date); - _configDao.persist(vo); - } else { - if (vo.isDynamic() != key.isDynamic() || - !ObjectUtils.equals(vo.getDescription(), key.description()) || - !ObjectUtils.equals(vo.getDefaultValue(), key.defaultValue())) { - vo.setDynamic(key.isDynamic()); - vo.setDescription(key.description()); - vo.setDefaultValue(key.defaultValue()); - vo.setUpdated(date); - _configDao.persist(vo); - } - } - } + populateConfiguration(date, configurable); } } + protected void populateConfiguration(Date date, Configurable configurable) { + if ( _configured.contains(configurable) ) + return; + + s_logger.debug("Retrieving keys from " + configurable.getClass().getSimpleName()); + + for (ConfigKey key : configurable.getConfigKeys()) { + Pair> previous = _allKeys.get(key.key()); + if (previous != null && !previous.first().equals(configurable.getConfigComponentName())) { + throw new CloudRuntimeException("Configurable " + configurable.getConfigComponentName() + " is adding a key that has been added before by " + previous.first() + + ": " + key.toString()); + } + _allKeys.put(key.key(), new Pair>(configurable.getConfigComponentName(), key)); + + ConfigurationVO vo = _configDao.findById(key.key()); + if (vo == null) { + vo = new ConfigurationVO(configurable.getConfigComponentName(), key); + vo.setUpdated(date); + _configDao.persist(vo); + } else { + if (vo.isDynamic() != key.isDynamic() || + !ObjectUtils.equals(vo.getDescription(), key.description()) || + !ObjectUtils.equals(vo.getDefaultValue(), key.defaultValue())) { + vo.setDynamic(key.isDynamic()); + vo.setDescription(key.description()); + vo.setDefaultValue(key.defaultValue()); + vo.setUpdated(date); + _configDao.persist(vo); + } + } + } + + _configured.add(configurable); + } + + @Override + public void populateConfiguration(Configurable configurable) { + populateConfiguration(new Date(), configurable); + } + @Override public List getComponentsInDepot() { return new ArrayList(); } - @Override - @PostConstruct - public void check() { - for (Configurable configurable : _configurables) { - s_logger.debug("Retrieving keys from " + configurable.getClass().getSimpleName()); - for (ConfigKey key : configurable.getConfigKeys()) { - Pair> previous = _allKeys.get(key.key()); - if (previous != null && !previous.first().equals(configurable.getConfigComponentName())) { - throw new CloudRuntimeException("Configurable " + configurable.getConfigComponentName() + " is adding a key that has been added before by " + previous.first() + - ": " + key.toString()); - } - _allKeys.put(key.key(), new Pair>(configurable.getConfigComponentName(), key)); - } - } - } - public ConfigurationDao global() { return _configDao; } @@ -144,4 +153,23 @@ public class ConfigDepotImpl implements ConfigDepot, ConfigDepotAdmin, SystemInt throw new CloudRuntimeException("Unable to find config storage for this scope: " + config.scope() + " for " + config.key()); } + + public List getScopedStorages() { + return _scopedStorages; + } + + @Inject + public void setScopedStorages(List scopedStorages) { + this._scopedStorages = scopedStorages; + } + + public List getConfigurables() { + return _configurables; + } + + @Inject + public void setConfigurables(List configurables) { + this._configurables = configurables; + } + } diff --git a/framework/config/test/org/apache/cloudstack/framework/config/impl/ConfigDepotAdminTest.java b/framework/config/test/org/apache/cloudstack/framework/config/impl/ConfigDepotAdminTest.java index 1c5fbe5c807..5a7f1768e14 100644 --- a/framework/config/test/org/apache/cloudstack/framework/config/impl/ConfigDepotAdminTest.java +++ b/framework/config/test/org/apache/cloudstack/framework/config/impl/ConfigDepotAdminTest.java @@ -95,6 +95,7 @@ public class ConfigDepotAdminTest extends TestCase { verify(_configDao, times(1)).persist(any(ConfigurationVO.class)); when(_configDao.findById(DynamicIntCK.key())).thenReturn(dynamicIntCV); + _depotAdmin._configured.clear(); _depotAdmin.populateConfigurations(); // This is two because DynamicIntCK also returns null. verify(_configDao, times(2)).persist(any(ConfigurationVO.class)); diff --git a/framework/db/resources/META-INF/cloudstack/system/spring-framework-db-system-context.xml b/framework/db/resources/META-INF/cloudstack/system/spring-framework-db-system-context.xml new file mode 100644 index 00000000000..651b8742a33 --- /dev/null +++ b/framework/db/resources/META-INF/cloudstack/system/spring-framework-db-system-context.xml @@ -0,0 +1,32 @@ + + + + + + diff --git a/framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java b/framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java index 9b13eb8b155..b7246a95805 100755 --- a/framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java +++ b/framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java @@ -39,6 +39,7 @@ import org.jasypt.properties.EncryptableProperties; import com.cloud.utils.PropertiesUtil; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; import org.apache.commons.configuration.ConfigurationException; @@ -227,7 +228,7 @@ public class EncryptionSecretKeyChanger { initEncryptor(newEncryptor, newDBKey); System.out.println("Initialised Encryptors"); - Transaction txn = Transaction.open("Migrate"); + TransactionLegacy txn = TransactionLegacy.open("Migrate"); txn.start(); try { Connection conn; diff --git a/framework/db/src/com/cloud/utils/db/ConnectionConcierge.java b/framework/db/src/com/cloud/utils/db/ConnectionConcierge.java index c3c24f94766..acb9cc6851b 100644 --- a/framework/db/src/com/cloud/utils/db/ConnectionConcierge.java +++ b/framework/db/src/com/cloud/utils/db/ConnectionConcierge.java @@ -178,7 +178,7 @@ public class ConnectionConcierge { return "Not Found"; } - Connection conn = Transaction.getStandaloneConnection(); + Connection conn = TransactionLegacy.getStandaloneConnection(); if (conn == null) { return "Unable to get anotehr db connection"; } diff --git a/framework/db/src/com/cloud/utils/db/DbUtil.java b/framework/db/src/com/cloud/utils/db/DbUtil.java index da0efbbe8cb..25700933080 100755 --- a/framework/db/src/com/cloud/utils/db/DbUtil.java +++ b/framework/db/src/com/cloud/utils/db/DbUtil.java @@ -56,7 +56,7 @@ public class DbUtil { assert(false); } - Connection connection = Transaction.getStandaloneConnection(); + Connection connection = TransactionLegacy.getStandaloneConnection(); if(connection != null) { try { connection.setAutoCommit(true); diff --git a/framework/db/src/com/cloud/utils/db/GenericDaoBase.java b/framework/db/src/com/cloud/utils/db/GenericDaoBase.java index 574974e8368..ba5200ea65f 100755 --- a/framework/db/src/com/cloud/utils/db/GenericDaoBase.java +++ b/framework/db/src/com/cloud/utils/db/GenericDaoBase.java @@ -380,7 +380,7 @@ public abstract class GenericDaoBase extends Compone List groupByValues = addGroupBy(str, sc); addFilter(str, filter); - final Transaction txn = Transaction.currentTxn(); + final TransactionLegacy txn = TransactionLegacy.currentTxn(); if (lock != null) { assert (txn.dbTxnStarted() == true) : "As nice as I can here now....how do you lock when there's no DB transaction? Review your db 101 course from college."; str.append(lock ? FOR_UPDATE_CLAUSE : SHARE_MODE_CLAUSE); @@ -452,7 +452,7 @@ public abstract class GenericDaoBase extends Compone final String sql = str.toString(); - final Transaction txn = Transaction.currentTxn(); + final TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(sql); @@ -770,7 +770,7 @@ public abstract class GenericDaoBase extends Compone } SearchCriteria sc = createSearchCriteria(); sc.addAnd(_idAttributes.get(_table)[0], SearchCriteria.Op.EQ, id); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); try { @@ -791,7 +791,7 @@ public abstract class GenericDaoBase extends Compone public int update(UpdateBuilder ub, final SearchCriteria sc, Integer rows) { StringBuilder sql = null; PreparedStatement pstmt = null; - final Transaction txn = Transaction.currentTxn(); + final TransactionLegacy txn = TransactionLegacy.currentTxn(); try { final String searchClause = sc.getWhereClause(); @@ -971,7 +971,7 @@ public abstract class GenericDaoBase extends Compone if (lock != null) { sql.append(lock ? FOR_UPDATE_CLAUSE : SHARE_MODE_CLAUSE); } - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(sql.toString()); @@ -994,7 +994,7 @@ public abstract class GenericDaoBase extends Compone @Override public T acquireInLockTable(final ID id, int seconds) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); T t = null; boolean locked = false; try { @@ -1014,7 +1014,7 @@ public abstract class GenericDaoBase extends Compone @Override public boolean releaseFromLockTable(final ID id) { - final Transaction txn = Transaction.currentTxn(); + final TransactionLegacy txn = TransactionLegacy.currentTxn(); return txn.release(_table + id); } @@ -1025,13 +1025,13 @@ public abstract class GenericDaoBase extends Compone @Override public boolean lockInLockTable(final String id, int seconds) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); return txn.lock(_table + id, seconds); } @Override public boolean unlockFromLockTable(final String id) { - final Transaction txn = Transaction.currentTxn(); + final TransactionLegacy txn = TransactionLegacy.currentTxn(); return txn.release(_table + id); } @@ -1076,7 +1076,7 @@ public abstract class GenericDaoBase extends Compone } protected List executeList(final String sql, final Object... params) { - final Transaction txn = Transaction.currentTxn(); + final TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; final List result = new ArrayList(); try { @@ -1118,7 +1118,7 @@ public abstract class GenericDaoBase extends Compone @Override public boolean expunge(final ID id) { - final Transaction txn = Transaction.currentTxn(); + final TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; String sql = null; try { @@ -1158,7 +1158,7 @@ public abstract class GenericDaoBase extends Compone final String sql = str.toString(); - final Transaction txn = Transaction.currentTxn(); + final TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(sql); @@ -1296,7 +1296,7 @@ public abstract class GenericDaoBase extends Compone } ID id = null; - final Transaction txn = Transaction.currentTxn(); + final TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; String sql = null; try { @@ -1359,7 +1359,7 @@ public abstract class GenericDaoBase extends Compone } protected void insertElementCollection(T entity, Attribute idAttribute, ID id, Map ecAttributes) throws SQLException { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); for (Map.Entry entry : ecAttributes.entrySet()) { Attribute attr = entry.getKey(); @@ -1591,7 +1591,7 @@ public abstract class GenericDaoBase extends Compone protected void loadCollection(T entity, Attribute attr) { EcInfo ec = (EcInfo)attr.attache; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); ResultSet rs = null; PreparedStatement pstmt = null; try { @@ -1675,7 +1675,7 @@ public abstract class GenericDaoBase extends Compone } final StringBuilder sql = new StringBuilder("DELETE FROM "); sql.append(_table).append(" WHERE ").append(_removed.first()).append(" IS NOT NULL"); - final Transaction txn = Transaction.currentTxn(); + final TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { txn.start(); @@ -1708,7 +1708,7 @@ public abstract class GenericDaoBase extends Compone return expunge(id); } - final Transaction txn = Transaction.currentTxn(); + final TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { @@ -1817,7 +1817,7 @@ public abstract class GenericDaoBase extends Compone // we have to disable group by in getting count, since count for groupBy clause will be different. //List groupByValues = addGroupBy(str, sc); - final Transaction txn = Transaction.currentTxn(); + final TransactionLegacy txn = TransactionLegacy.currentTxn(); final String sql = str.toString(); PreparedStatement pstmt = null; diff --git a/framework/db/src/com/cloud/utils/db/Merovingian2.java b/framework/db/src/com/cloud/utils/db/Merovingian2.java index 0e0e8f250b1..8544aab0384 100644 --- a/framework/db/src/com/cloud/utils/db/Merovingian2.java +++ b/framework/db/src/com/cloud/utils/db/Merovingian2.java @@ -65,7 +65,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean { _msId = msId; Connection conn = null; try { - conn = Transaction.getStandaloneConnectionWithException(); + conn = TransactionLegacy.getStandaloneConnectionWithException(); conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); conn.setAutoCommit(true); _concierge = new ConnectionConcierge("LockMaster", conn, true); diff --git a/framework/db/src/com/cloud/utils/db/SequenceFetcher.java b/framework/db/src/com/cloud/utils/db/SequenceFetcher.java index 88235527fc2..bb45847a7bb 100644 --- a/framework/db/src/com/cloud/utils/db/SequenceFetcher.java +++ b/framework/db/src/com/cloud/utils/db/SequenceFetcher.java @@ -98,7 +98,7 @@ public class SequenceFetcher { sql.append(_tg.valueColumnName()).append(" FROM ").append(_tg.table()); sql.append(" WHERE ").append(_tg.pkColumnName()).append(" = ? FOR UPDATE"); - Transaction txn = Transaction.open("Sequence"); + TransactionLegacy txn = TransactionLegacy.open("Sequence"); PreparedStatement selectStmt = txn.prepareStatement(sql.toString()); if (_key == null) { diff --git a/framework/db/src/com/cloud/utils/db/Transaction.java b/framework/db/src/com/cloud/utils/db/Transaction.java index 8c2f1996a1c..4b19be088c8 100755 --- a/framework/db/src/com/cloud/utils/db/Transaction.java +++ b/framework/db/src/com/cloud/utils/db/Transaction.java @@ -16,1158 +16,39 @@ // under the License. package com.cloud.utils.db; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Savepoint; -import java.sql.Statement; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Properties; import java.util.concurrent.atomic.AtomicLong; -import javax.sql.DataSource; - -import org.apache.commons.dbcp.ConnectionFactory; -import org.apache.commons.dbcp.DriverManagerConnectionFactory; -import org.apache.commons.dbcp.PoolableConnectionFactory; -import org.apache.commons.dbcp.PoolingDataSource; -import org.apache.commons.pool.KeyedObjectPoolFactory; -import org.apache.commons.pool.impl.GenericObjectPool; -import org.apache.commons.pool.impl.StackKeyedObjectPoolFactory; -import org.apache.log4j.Logger; -import org.jasypt.encryption.pbe.StandardPBEStringEncryptor; -import org.jasypt.properties.EncryptableProperties; - -import com.cloud.utils.Pair; -import com.cloud.utils.PropertiesUtil; -import com.cloud.utils.crypt.EncryptionSecretKeyChecker; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.mgmt.JmxUtil; - -/** - * Transaction abstracts away the Connection object in JDBC. It allows the - * following things that the Connection object does not. - * - * 1. Transaction can be started at an entry point and whether the DB - * actions should be auto-commit or not determined at that point. - * 2. DB Connection is allocated only when it is needed. - * 3. Code does not need to know if a transaction has been started or not. - * It just starts/ends a transaction and we resolve it correctly with - * the previous actions. - * - * Note that this class is not synchronous but it doesn't need to be because - * it is stored with TLS and is one per thread. Use appropriately. - */ public class Transaction { - private static final Logger s_logger = Logger.getLogger(Transaction.class.getName() + "." + "Transaction"); - private static final Logger s_stmtLogger = Logger.getLogger(Transaction.class.getName() + "." + "Statement"); - private static final Logger s_lockLogger = Logger.getLogger(Transaction.class.getName() + "." + "Lock"); - private static final Logger s_connLogger = Logger.getLogger(Transaction.class.getName() + "." + "Connection"); + private final static AtomicLong counter = new AtomicLong(0); + private final static TransactionStatus STATUS = new TransactionStatus() { + }; - private static final ThreadLocal tls = new ThreadLocal(); - private static final String START_TXN = "start_txn"; - private static final String CURRENT_TXN = "current_txn"; - private static final String CREATE_TXN = "create_txn"; - private static final String CREATE_CONN = "create_conn"; - private static final String STATEMENT = "statement"; - private static final String ATTACHMENT = "attachment"; - - public static final short CLOUD_DB = 0; - public static final short USAGE_DB = 1; - public static final short AWSAPI_DB = 2; - public static final short SIMULATOR_DB = 3; - public static final short CONNECTED_DB = -1; - - private static AtomicLong s_id = new AtomicLong(); - private static final TransactionMBeanImpl s_mbean = new TransactionMBeanImpl(); - static { + @SuppressWarnings("deprecation") + public static T execute(TransactionCallbackWithException callback) throws E { + String name = "tx-" + counter.incrementAndGet(); + short databaseId = TransactionLegacy.CLOUD_DB; + TransactionLegacy currentTxn = TransactionLegacy.currentTxn(false); + if ( currentTxn != null ) { + databaseId = currentTxn.getDatabaseId(); + } + TransactionLegacy txn = TransactionLegacy.open(name, databaseId, false); try { - JmxUtil.registerMBean("Transaction", "Transaction", s_mbean); - } catch (Exception e) { - s_logger.error("Unable to register mbean for transaction", e); + txn.start(); + T result = callback.doInTransaction(STATUS); + txn.commit(); + return result; + } finally { + txn.close(); } - - /* FIXME: We need a better solution for this - * Initialize encryption if we need it for db.properties - */ - EncryptionSecretKeyChecker enc = new EncryptionSecretKeyChecker(); - enc.check(); } - private final LinkedList _stack; - private long _id; - - private final LinkedList> _lockTimes = new LinkedList>(); - - private String _name; - private Connection _conn; - private boolean _txn; - private short _dbId; - private long _txnTime; - private Statement _stmt; - private String _creator; - - private Transaction _prev = null; - - public static Transaction currentTxn() { - Transaction txn = tls.get(); - assert txn != null : "No Transaction on stack. Did you mark the method with @DB?"; - - assert checkAnnotation(3, txn) : "Did you even read the guide to use Transaction...IOW...other people's code? Try method can't be private. What about @DB? hmmm... could that be it? " + txn; - return txn; - } - - public static Transaction open(final short databaseId) { - String name = buildName(); - if (name == null) { - name = CURRENT_TXN; - } - return open(name, databaseId, true); - } - - // - // Usage of this transaction setup should be limited, it will always open a new transaction context regardless of whether or not there is other - // transaction context in the stack. It is used in special use cases that we want to control DB connection explicitly and in the mean time utilize - // the existing DAO features - // - public void transitToUserManagedConnection(Connection conn) { - assert(_conn == null /*&& _stack.size() <= 1*/) : "Can't change to a user managed connection unless the stack is empty and the db connection is null, you may have forgotten to invoke transitToAutoManagedConnection to close out the DB connection: " + toString(); - _conn = conn; - _dbId = CONNECTED_DB; - } - - public void transitToAutoManagedConnection(short dbId) { - // assert(_stack.size() <= 1) : "Can't change to auto managed connection unless your stack is empty"; - _dbId = dbId; - _conn = null; - } - - public static Transaction open(final String name) { - return open(name, CLOUD_DB, false); - } - - public static Transaction open(final String name, final short databaseId, final boolean forceDbChange) { - Transaction txn = tls.get(); - boolean isNew = false; - if (txn == null) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Creating the transaction: " + name); + public static T execute(final TransactionCallback callback) { + return execute(new TransactionCallbackWithException() { + @Override + public T doInTransaction(TransactionStatus status) throws RuntimeException { + return callback.doInTransaction(status); } - txn = new Transaction(name, false, databaseId); - tls.set(txn); - isNew = true; - } else if (forceDbChange) { - final short currentDbId = txn.getDatabaseId(); - if (currentDbId != databaseId) { - // we need to end the current transaction and switch databases - txn.close(txn.getName()); - - txn = new Transaction(name, false, databaseId); - tls.set(txn); - isNew = true; - } - } - - txn.takeOver(name, false); - if (isNew) { - s_mbean.addTransaction(txn); - } - return txn; + }); } - protected StackElement peekInStack(Object obj) { - final Iterator it = _stack.iterator(); - while (it.hasNext()) { - StackElement next = it.next(); - if (next.type == obj) { - return next; - } - } - return null; - } - - public void registerLock(String sql) { - if (_txn && s_lockLogger.isDebugEnabled()) { - Pair time = new Pair(sql, System.currentTimeMillis()); - _lockTimes.add(time); - } - } - - public boolean dbTxnStarted() { - return _txn; - } - - public static Connection getStandaloneConnectionWithException() throws SQLException { - Connection conn = s_ds.getConnection(); - if (s_connLogger.isTraceEnabled()) { - s_connLogger.trace("Retrieving a standalone connection: dbconn" + System.identityHashCode(conn)); - } - return conn; - } - - public static Connection getStandaloneConnection() { - try { - return getStandaloneConnectionWithException(); - } catch (SQLException e) { - s_logger.error("Unexpected exception: ", e); - return null; - } - } - - public static Connection getStandaloneUsageConnection() { - try { - Connection conn = s_usageDS.getConnection(); - if (s_connLogger.isTraceEnabled()) { - s_connLogger.trace("Retrieving a standalone connection for usage: dbconn" + System.identityHashCode(conn)); - } - return conn; - } catch (SQLException e) { - s_logger.warn("Unexpected exception: ", e); - return null; - } - } - - public static Connection getStandaloneAwsapiConnection() { - try { - Connection conn = s_awsapiDS.getConnection(); - if (s_connLogger.isTraceEnabled()) { - s_connLogger.trace("Retrieving a standalone connection for usage: dbconn" + System.identityHashCode(conn)); - } - return conn; - } catch (SQLException e) { - s_logger.warn("Unexpected exception: ", e); - return null; - } - } - - public static Connection getStandaloneSimulatorConnection() { - try { - Connection conn = s_simulatorDS.getConnection(); - if (s_connLogger.isTraceEnabled()) { - s_connLogger.trace("Retrieving a standalone connection for simulator: dbconn" + System.identityHashCode(conn)); - } - return conn; - } catch (SQLException e) { - s_logger.warn("Unexpected exception: ", e); - return null; - } - } - - protected void attach(TransactionAttachment value) { - _stack.push(new StackElement(ATTACHMENT, value)); - } - - protected TransactionAttachment detach(String name) { - Iterator it = _stack.descendingIterator(); - while (it.hasNext()) { - StackElement element = it.next(); - if (element.type == ATTACHMENT) { - TransactionAttachment att = (TransactionAttachment)element.ref; - if (name.equals(att.getName())) { - it.remove(); - return att; - } - } - } - assert false : "Are you sure you attached this: " + name; - return null; - } - - public static void attachToTxn(TransactionAttachment value) { - Transaction txn = tls.get(); - assert txn != null && txn.peekInStack(CURRENT_TXN) != null: "Come on....how can we attach something to the transaction if you haven't started it?"; - - txn.attach(value); - } - - public static TransactionAttachment detachFromTxn(String name) { - Transaction txn = tls.get(); - assert txn != null : "No Transaction in TLS"; - return txn.detach(name); - } - - protected static boolean checkAnnotation(int stack, Transaction txn) { - final StackTraceElement[] stacks = Thread.currentThread().getStackTrace(); - StackElement se = txn.peekInStack(CURRENT_TXN); - if (se == null) { - return false; - } - - StringBuffer sb = new StringBuffer(); - for (; stack < stacks.length; stack++) { - String methodName = stacks[stack].getMethodName(); - sb.append(" ").append(methodName); - if (methodName.equals(se.ref)){ - return true; - } - } - - // relax stack structure for several places that @DB required injection is not in place - s_logger.warn("Non-standard stack context that Transaction context is manaully placed into the calling chain. Stack chain: " + sb); - return true; - } - - protected static String buildName() { - if (s_logger.isDebugEnabled()) { - final StackTraceElement[] stacks = Thread.currentThread().getStackTrace(); - final StringBuilder str = new StringBuilder(); - int i = 3, j = 3; - while (j < 15 && i < stacks.length) { - StackTraceElement element = stacks[i]; - String filename = element.getFileName(); - String method = element.getMethodName(); - if ((filename != null && filename.equals("")) || (method != null && method.equals("invokeSuper"))) { - i++; - continue; - } - - str.append("-").append(stacks[i].getClassName().substring(stacks[i].getClassName().lastIndexOf(".") + 1)).append(".").append(stacks[i].getMethodName()).append(":").append(stacks[i].getLineNumber()); - j++; - i++; - } - return str.toString(); - } - - return ""; - } - - public Transaction(final String name, final boolean forLocking, final short databaseId) { - _name = name; - _conn = null; - _stack = new LinkedList(); - _txn = false; - _dbId = databaseId; - _id = s_id.incrementAndGet(); - _creator = Thread.currentThread().getName(); - } - - public String getCreator() { - return _creator; - } - - public long getId() { - return _id; - } - - public String getName() { - return _name; - } - - public Short getDatabaseId() { - return _dbId; - } - - @Override - public String toString() { - final StringBuilder str = new StringBuilder((_name != null ? _name : "")); - str.append(" : "); - for (final StackElement se : _stack) { - if (se.type == CURRENT_TXN) { - str.append(se.ref).append(", "); - } - } - - return str.toString(); - } - - protected void mark(final String name) { - _stack.push(new StackElement(CURRENT_TXN, name)); - } - - public boolean lock(final String name, final int timeoutSeconds) { - Merovingian2 lockMaster = Merovingian2.getLockMaster(); - if (lockMaster == null) { - throw new CloudRuntimeException("There's no support for locking yet"); - } - return lockMaster.acquire(name, timeoutSeconds); - } - - public boolean release(final String name) { - Merovingian2 lockMaster = Merovingian2.getLockMaster(); - if (lockMaster == null) { - throw new CloudRuntimeException("There's no support for locking yet"); - } - return lockMaster.release(name); - } - - public void start() { - if (s_logger.isTraceEnabled()) { - s_logger.trace("txn: start requested by: " + buildName()); - } - - _stack.push(new StackElement(START_TXN, null)); - - if (_txn) { - s_logger.trace("txn: has already been started."); - return; - } - - _txn = true; - - _txnTime = System.currentTimeMillis(); - if (_conn != null) { - try { - s_logger.trace("txn: set auto commit to false"); - _conn.setAutoCommit(false); - } catch (final SQLException e) { - s_logger.warn("Unable to set auto commit: ", e); - throw new CloudRuntimeException("Unable to set auto commit: ", e); - } - } - } - - protected void closePreviousStatement() { - if (_stmt != null) { - try { - if (s_stmtLogger.isTraceEnabled()) { - s_stmtLogger.trace("Closing: " + _stmt.toString()); - } - try { - ResultSet rs = _stmt.getResultSet(); - if (rs != null && _stmt.getResultSetHoldability() != ResultSet.HOLD_CURSORS_OVER_COMMIT) { - rs.close(); - } - } catch(SQLException e) { - s_stmtLogger.trace("Unable to close resultset"); - } - _stmt.close(); - } catch (final SQLException e) { - s_stmtLogger.trace("Unable to close statement: " + _stmt.toString()); - } finally { - _stmt = null; - } - } - } - - /** - * Prepares an auto close statement. The statement is closed automatically if it is - * retrieved with this method. - * - * @param sql sql String - * @return PreparedStatement - * @throws SQLException if problem with JDBC layer. - * - * @see java.sql.Connection - */ - public PreparedStatement prepareAutoCloseStatement(final String sql) throws SQLException { - PreparedStatement stmt = prepareStatement(sql); - closePreviousStatement(); - _stmt = stmt; - return stmt; - } - - public PreparedStatement prepareStatement(final String sql) throws SQLException { - final Connection conn = getConnection(); - final PreparedStatement pstmt = conn.prepareStatement(sql); - if (s_stmtLogger.isTraceEnabled()) { - s_stmtLogger.trace("Preparing: " + sql); - } - return pstmt; - } - - /** - * Prepares an auto close statement. The statement is closed automatically if it is - * retrieved with this method. - * - * @param sql sql String - * @param autoGeneratedKeys keys that are generated - * @return PreparedStatement - * @throws SQLException if problem with JDBC layer. - * - * @see java.sql.Connection - */ - public PreparedStatement prepareAutoCloseStatement(final String sql, final int autoGeneratedKeys) throws SQLException { - final Connection conn = getConnection(); - final PreparedStatement pstmt = conn.prepareStatement(sql, autoGeneratedKeys); - if (s_stmtLogger.isTraceEnabled()) { - s_stmtLogger.trace("Preparing: " + sql); - } - closePreviousStatement(); - _stmt = pstmt; - return pstmt; - } - - /** - * Prepares an auto close statement. The statement is closed automatically if it is - * retrieved with this method. - * - * @param sql sql String - * @param columnNames names of the columns - * @return PreparedStatement - * @throws SQLException if problem with JDBC layer. - * - * @see java.sql.Connection - */ - public PreparedStatement prepareAutoCloseStatement(final String sql, final String[] columnNames) throws SQLException { - final Connection conn = getConnection(); - final PreparedStatement pstmt = conn.prepareStatement(sql, columnNames); - if (s_stmtLogger.isTraceEnabled()) { - s_stmtLogger.trace("Preparing: " + sql); - } - closePreviousStatement(); - _stmt = pstmt; - return pstmt; - } - - /** - * Prepares an auto close statement. The statement is closed automatically if it is - * retrieved with this method. - * - * @param sql sql String - * @return PreparedStatement - * @throws SQLException if problem with JDBC layer. - * - * @see java.sql.Connection - */ - public PreparedStatement prepareAutoCloseStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - final Connection conn = getConnection(); - final PreparedStatement pstmt = conn.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability); - if (s_stmtLogger.isTraceEnabled()) { - s_stmtLogger.trace("Preparing: " + sql); - } - closePreviousStatement(); - _stmt = pstmt; - return pstmt; - } - - /** - * Returns the db connection. - * - * Note: that you can call getConnection() but beaware that - * all prepare statements from the Connection are not garbage - * collected! - * - * @return DB Connection but make sure you understand that - * you are responsible for closing the PreparedStatement. - * @throws SQLException - */ - public Connection getConnection() throws SQLException { - if (_conn == null) { - switch (_dbId) { - case CLOUD_DB: - if(s_ds != null) { - _conn = s_ds.getConnection(); - } else { - s_logger.warn("A static-initialized variable becomes null, process is dying?"); - throw new CloudRuntimeException("Database is not initialized, process is dying?"); - } - break; - case USAGE_DB: - if(s_usageDS != null) { - _conn = s_usageDS.getConnection(); - } else { - s_logger.warn("A static-initialized variable becomes null, process is dying?"); - throw new CloudRuntimeException("Database is not initialized, process is dying?"); - } - break; - case AWSAPI_DB: - if(s_awsapiDS != null) { - _conn = s_awsapiDS.getConnection(); - } else { - s_logger.warn("A static-initialized variable becomes null, process is dying?"); - throw new CloudRuntimeException("Database is not initialized, process is dying?"); - } - break; - - case SIMULATOR_DB: - if(s_simulatorDS != null) { - _conn = s_simulatorDS.getConnection(); - } else { - s_logger.warn("A static-initialized variable becomes null, process is dying?"); - throw new CloudRuntimeException("Database is not initialized, process is dying?"); - } - break; - default: - - throw new CloudRuntimeException("No database selected for the transaction"); - } - _conn.setAutoCommit(!_txn); - - // - // MySQL default transaction isolation level is REPEATABLE READ, - // to reduce chances of DB deadlock, we will use READ COMMITED isolation level instead - // see http://dev.mysql.com/doc/refman/5.0/en/innodb-deadlocks.html - // - _stack.push(new StackElement(CREATE_CONN, null)); - if (s_connLogger.isTraceEnabled()) { - s_connLogger.trace("Creating a DB connection with " + (_txn ? " txn: " : " no txn: ") + " for " + _dbId + ": dbconn" + System.identityHashCode(_conn) + ". Stack: " + buildName()); - } - } else { - s_logger.trace("conn: Using existing DB connection"); - } - - return _conn; - } - - protected boolean takeOver(final String name, final boolean create) { - if (_stack.size() != 0) { - if (!create) { - // If it is not a create transaction, then let's just use the current one. - if (s_logger.isTraceEnabled()) { - s_logger.trace("Using current transaction: " + toString()); - } - mark(name); - return false; - } - - final StackElement se = _stack.getFirst(); - if (se.type == CREATE_TXN) { - // This create is called inside of another create. Which is ok? - // We will let that create be responsible for cleaning up. - if (s_logger.isTraceEnabled()) { - s_logger.trace("Create using current transaction: " + toString()); - } - mark(name); - return false; - } - - s_logger.warn("Encountered a transaction that has leaked. Cleaning up. " + toString()); - cleanup(); - } - - if (s_logger.isTraceEnabled()) { - s_logger.trace("Took over the transaction: " + name); - } - _stack.push(new StackElement(create ? CREATE_TXN : CURRENT_TXN, name)); - _name = name; - return true; - } - - public void cleanup() { - closePreviousStatement(); - - removeUpTo(null, null); - if (_txn) { - rollbackTransaction(); - } - _txn = false; - _name = null; - - closeConnection(); - - _stack.clear(); - Merovingian2 lockMaster = Merovingian2.getLockMaster(); - if (lockMaster != null) { - lockMaster.cleanupThread(); - } - } - - public void close() { - removeUpTo(CURRENT_TXN, null); - - if (_stack.size() == 0) { - s_logger.trace("Transaction is done"); - cleanup(); - } - } - - /** - * close() is used by endTxn to close the connection. This method only - * closes the connection if the name is the same as what's stored. - * - * @param name - * @return true if this close actually closes the connection. false if not. - */ - public boolean close(final String name) { - if (_name == null) { // Already cleaned up. - if (s_logger.isTraceEnabled()) { - s_logger.trace("Already cleaned up." + buildName()); - } - return true; - } - - if (!_name.equals(name)) { - close(); - return false; - } - - if (s_logger.isDebugEnabled() && _stack.size() > 2) { - s_logger.debug("Transaction is not closed properly: " + toString() + ". Called by " + buildName()); - } - - cleanup(); - - s_logger.trace("All done"); - return true; - } - - protected boolean hasTxnInStack() { - return peekInStack(START_TXN) != null; - } - - protected void clearLockTimes() { - if (s_lockLogger.isDebugEnabled()) { - for (Pair time : _lockTimes) { - s_lockLogger.trace("SQL " + time.first() + " took " + (System.currentTimeMillis() - time.second())); - } - _lockTimes.clear(); - } - } - - public boolean commit() { - if (!_txn) { - s_logger.warn("txn: Commit called when it is not a transaction: " + buildName()); - return false; - } - - Iterator it = _stack.iterator(); - while (it.hasNext()) { - StackElement st = it.next(); - if (st.type == START_TXN) { - it.remove(); - break; - } - } - - if (hasTxnInStack()) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("txn: Not committing because transaction started elsewhere: " + buildName() + " / " + toString()); - } - return false; - } - - _txn = false; - try { - if (_conn != null) { - _conn.commit(); - s_logger.trace("txn: DB Changes committed. Time = " + (System.currentTimeMillis() - _txnTime)); - clearLockTimes(); - closeConnection(); - } - return true; - } catch (final SQLException e) { - rollbackTransaction(); - throw new CloudRuntimeException("Unable to commit or close the connection. ", e); - } - } - - protected void closeConnection() { - closePreviousStatement(); - - if (_conn == null) { - return; - } - - if (_txn) { - s_connLogger.trace("txn: Not closing DB connection because we're still in a transaction."); - return; - } - - try { - // we should only close db connection when it is not user managed - if (this._dbId != CONNECTED_DB) { - if (s_connLogger.isTraceEnabled()) { - s_connLogger.trace("Closing DB connection: dbconn" + System.identityHashCode(_conn)); - } - _conn.close(); - _conn = null; - } - - } catch (final SQLException e) { - s_logger.warn("Unable to close connection", e); - } - } - - protected void removeUpTo(String type, Object ref) { - boolean rollback = false; - Iterator it = _stack.iterator(); - while (it.hasNext()) { - StackElement item = it.next(); - - it.remove(); - - try { - if (item.type == type && (ref == null || item.ref == ref)) { - break; - } - - if (item.type == CURRENT_TXN) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Releasing the current txn: " + (item.ref != null ? item.ref : "")); - } - } else if (item.type == CREATE_CONN) { - closeConnection(); - } else if (item.type == START_TXN) { - if (item.ref == null) { - rollback = true; - } else { - try { - _conn.rollback((Savepoint)ref); - rollback = false; - } catch (final SQLException e) { - s_logger.warn("Unable to rollback Txn.", e); - } - } - } else if (item.type == STATEMENT) { - try { - if (s_stmtLogger.isTraceEnabled()) { - s_stmtLogger.trace("Closing: " + ref.toString()); - } - Statement stmt = (Statement)ref; - try { - ResultSet rs = stmt.getResultSet(); - if (rs != null) { - rs.close(); - } - } catch(SQLException e) { - s_stmtLogger.trace("Unable to close resultset"); - } - stmt.close(); - } catch (final SQLException e) { - s_stmtLogger.trace("Unable to close statement: " + item); - } - } else if (item.type == ATTACHMENT) { - TransactionAttachment att = (TransactionAttachment)item.ref; - if (s_logger.isTraceEnabled()) { - s_logger.trace("Cleaning up " + att.getName()); - } - att.cleanup(); - } - } catch(Exception e) { - s_logger.error("Unable to clean up " + item, e); - } - } - - if (rollback) { - rollback(); - } - } - - protected void rollbackTransaction() { - closePreviousStatement(); - if (!_txn) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Rollback called for " + _name + " when there's no transaction: " + buildName()); - } - return; - } - assert (!hasTxnInStack()) : "Who's rolling back transaction when there's still txn in stack?"; - _txn = false; - try { - if (_conn != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Rolling back the transaction: Time = " + (System.currentTimeMillis() - _txnTime) + " Name = " + _name + "; called by " + buildName()); - } - _conn.rollback(); - } - clearLockTimes(); - closeConnection(); - } catch(final SQLException e) { - s_logger.warn("Unable to rollback", e); - } - } - - protected void rollbackSavepoint(Savepoint sp) { - try { - if (_conn != null) { - _conn.rollback(sp); - } - } catch (SQLException e) { - s_logger.warn("Unable to rollback to savepoint " + sp); - } - - if (!hasTxnInStack()) { - _txn = false; - closeConnection(); - } - } - - public void rollback() { - Iterator it = _stack.iterator(); - while (it.hasNext()) { - StackElement st = it.next(); - if (st.type == START_TXN) { - if (st.ref == null) { - it.remove(); - } else { - rollback((Savepoint)st.ref); - return; - } - } - } - - rollbackTransaction(); - } - - public Savepoint setSavepoint() throws SQLException { - _txn = true; - StackElement st = new StackElement(START_TXN, null); - _stack.push(st); - final Connection conn = getConnection(); - final Savepoint sp = conn.setSavepoint(); - st.ref = sp; - - return sp; - } - - public Savepoint setSavepoint(final String name) throws SQLException { - _txn = true; - StackElement st = new StackElement(START_TXN, null); - _stack.push(st); - final Connection conn = getConnection(); - final Savepoint sp = conn.setSavepoint(name); - st.ref = sp; - - return sp; - } - - public void releaseSavepoint(final Savepoint sp) throws SQLException { - removeTxn(sp); - if (_conn != null) { - _conn.releaseSavepoint(sp); - } - - if (!hasTxnInStack()) { - _txn = false; - closeConnection(); - } - } - - protected boolean hasSavepointInStack(Savepoint sp) { - Iterator it = _stack.iterator(); - while (it.hasNext()) { - StackElement se = it.next(); - if (se.type == START_TXN && se.ref == sp) { - return true; - } - } - return false; - } - - protected void removeTxn(Savepoint sp) { - assert hasSavepointInStack(sp) : "Removing a save point that's not in the stack"; - - if (!hasSavepointInStack(sp)) { - return; - } - - Iterator it = _stack.iterator(); - while (it.hasNext()) { - StackElement se = it.next(); - if (se.type == START_TXN) { - it.remove(); - if (se.ref == sp) { - return; - } - } - } - } - - public void rollback(final Savepoint sp) { - removeTxn(sp); - - rollbackSavepoint(sp); - } - - public Connection getCurrentConnection() { - return _conn; - } - - public List getStack() { - return _stack; - } - - protected Transaction() { - _name = null; - _conn = null; - _stack = null; - _txn = false; - _dbId = -1; - } - - @Override - protected void finalize() throws Throwable { - if (!(_conn == null && (_stack == null || _stack.size() == 0))) { - assert (false) : "Oh Alex oh alex...something is wrong with how we're doing this"; - s_logger.error("Something went wrong that a transaction is orphaned before db connection is closed"); - cleanup(); - } - } - - protected class StackElement { - public String type; - public Object ref; - - public StackElement (String type, Object ref) { - this.type = type; - this.ref = ref; - } - - @Override - public String toString() { - return type + "-" + ref; - } - } - - private static DataSource s_ds; - private static DataSource s_usageDS; - private static DataSource s_awsapiDS; - private static DataSource s_simulatorDS; - - static { - // Initialize with assumed db.properties file - initDataSource("db.properties"); - } - - public static void initDataSource(String propsFileName) { - try { - File dbPropsFile = PropertiesUtil.findConfigFile(propsFileName); - final Properties dbProps; - if (EncryptionSecretKeyChecker.useEncryption()) { - StandardPBEStringEncryptor encryptor = EncryptionSecretKeyChecker.getEncryptor(); - dbProps = new EncryptableProperties(encryptor); - } else { - dbProps = new Properties(); - } - try { - dbProps.load(new FileInputStream(dbPropsFile)); - } catch (IOException e) { - s_logger.fatal("Unable to load db properties file, pl. check the classpath and file path configuration", e); - return; - } catch (NullPointerException e) { - s_logger.fatal("Unable to locate db properties file within classpath or absolute path: " + propsFileName); - return; - } - - // FIXME: If params are missing...default them???? - final int cloudMaxActive = Integer.parseInt(dbProps.getProperty("db.cloud.maxActive")); - final int cloudMaxIdle = Integer.parseInt(dbProps.getProperty("db.cloud.maxIdle")); - final long cloudMaxWait = Long.parseLong(dbProps.getProperty("db.cloud.maxWait")); - final String cloudUsername = dbProps.getProperty("db.cloud.username"); - final String cloudPassword = dbProps.getProperty("db.cloud.password"); - final String cloudHost = dbProps.getProperty("db.cloud.host"); - final int cloudPort = Integer.parseInt(dbProps.getProperty("db.cloud.port")); - final String cloudDbName = dbProps.getProperty("db.cloud.name"); - final boolean cloudAutoReconnect = Boolean.parseBoolean(dbProps.getProperty("db.cloud.autoReconnect")); - final String cloudValidationQuery = dbProps.getProperty("db.cloud.validationQuery"); - final String cloudIsolationLevel = dbProps.getProperty("db.cloud.isolation.level"); - - int isolationLevel = Connection.TRANSACTION_READ_COMMITTED; - if (cloudIsolationLevel == null) { - isolationLevel = Connection.TRANSACTION_READ_COMMITTED; - } else if (cloudIsolationLevel.equalsIgnoreCase("readcommitted")) { - isolationLevel = Connection.TRANSACTION_READ_COMMITTED; - } else if (cloudIsolationLevel.equalsIgnoreCase("repeatableread")) { - isolationLevel = Connection.TRANSACTION_REPEATABLE_READ; - } else if (cloudIsolationLevel.equalsIgnoreCase("serializable")) { - isolationLevel = Connection.TRANSACTION_SERIALIZABLE; - } else if (cloudIsolationLevel.equalsIgnoreCase("readuncommitted")) { - isolationLevel = Connection.TRANSACTION_READ_UNCOMMITTED; - } else { - s_logger.warn("Unknown isolation level " + cloudIsolationLevel + ". Using read uncommitted"); - } - - final boolean cloudTestOnBorrow = Boolean.parseBoolean(dbProps.getProperty("db.cloud.testOnBorrow")); - final boolean cloudTestWhileIdle = Boolean.parseBoolean(dbProps.getProperty("db.cloud.testWhileIdle")); - final long cloudTimeBtwEvictionRunsMillis = Long.parseLong(dbProps.getProperty("db.cloud.timeBetweenEvictionRunsMillis")); - final long cloudMinEvcitableIdleTimeMillis = Long.parseLong(dbProps.getProperty("db.cloud.minEvictableIdleTimeMillis")); - final boolean cloudPoolPreparedStatements = Boolean.parseBoolean(dbProps.getProperty("db.cloud.poolPreparedStatements")); - final String url = dbProps.getProperty("db.cloud.url.params"); - - final boolean useSSL = Boolean.parseBoolean(dbProps.getProperty("db.cloud.useSSL")); - if (useSSL) { - System.setProperty("javax.net.ssl.keyStore", dbProps.getProperty("db.cloud.keyStore")); - System.setProperty("javax.net.ssl.keyStorePassword", dbProps.getProperty("db.cloud.keyStorePassword")); - System.setProperty("javax.net.ssl.trustStore", dbProps.getProperty("db.cloud.trustStore")); - System.setProperty("javax.net.ssl.trustStorePassword", dbProps.getProperty("db.cloud.trustStorePassword")); - } - - final GenericObjectPool cloudConnectionPool = new GenericObjectPool(null, cloudMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION, - cloudMaxWait, cloudMaxIdle, cloudTestOnBorrow, false, cloudTimeBtwEvictionRunsMillis, 1, cloudMinEvcitableIdleTimeMillis, cloudTestWhileIdle); - - final ConnectionFactory cloudConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + cloudHost + ":" + cloudPort + "/" + cloudDbName + - "?autoReconnect=" + cloudAutoReconnect + (url != null ? "&" + url : "") + (useSSL ? "&useSSL=true" : ""), cloudUsername, cloudPassword); - - final KeyedObjectPoolFactory poolableObjFactory = (cloudPoolPreparedStatements ? new StackKeyedObjectPoolFactory() : null); - - final PoolableConnectionFactory cloudPoolableConnectionFactory = new PoolableConnectionFactory(cloudConnectionFactory, cloudConnectionPool, poolableObjFactory, - cloudValidationQuery, false, false, isolationLevel); - - // Default Data Source for CloudStack - s_ds = new PoolingDataSource(cloudPoolableConnectionFactory.getPool()); - - // Configure the usage db - final int usageMaxActive = Integer.parseInt(dbProps.getProperty("db.usage.maxActive")); - final int usageMaxIdle = Integer.parseInt(dbProps.getProperty("db.usage.maxIdle")); - final long usageMaxWait = Long.parseLong(dbProps.getProperty("db.usage.maxWait")); - final String usageUsername = dbProps.getProperty("db.usage.username"); - final String usagePassword = dbProps.getProperty("db.usage.password"); - final String usageHost = dbProps.getProperty("db.usage.host"); - final int usagePort = Integer.parseInt(dbProps.getProperty("db.usage.port")); - final String usageDbName = dbProps.getProperty("db.usage.name"); - final boolean usageAutoReconnect = Boolean.parseBoolean(dbProps.getProperty("db.usage.autoReconnect")); - final String usageUrl = dbProps.getProperty("db.usage.url.params"); - - final GenericObjectPool usageConnectionPool = new GenericObjectPool(null, usageMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION, - usageMaxWait, usageMaxIdle); - - final ConnectionFactory usageConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + usageHost + ":" + usagePort + "/" + usageDbName + - "?autoReconnect=" + usageAutoReconnect + (usageUrl != null ? "&" + usageUrl : ""), usageUsername, usagePassword); - - final PoolableConnectionFactory usagePoolableConnectionFactory = new PoolableConnectionFactory(usageConnectionFactory, usageConnectionPool, - new StackKeyedObjectPoolFactory(), null, false, false); - - // Data Source for usage server - s_usageDS = new PoolingDataSource(usagePoolableConnectionFactory.getPool()); - - // Configure awsapi db - final String awsapiDbName = dbProps.getProperty("db.awsapi.name"); - final GenericObjectPool awsapiConnectionPool = new GenericObjectPool(null, usageMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION, - usageMaxWait, usageMaxIdle); - final ConnectionFactory awsapiConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + cloudHost + ":" + cloudPort + "/" + awsapiDbName + - "?autoReconnect=" + usageAutoReconnect, cloudUsername, cloudPassword); - final PoolableConnectionFactory awsapiPoolableConnectionFactory = new PoolableConnectionFactory(awsapiConnectionFactory, awsapiConnectionPool, - new StackKeyedObjectPoolFactory(), null, false, false); - - // Data Source for awsapi - s_awsapiDS = new PoolingDataSource(awsapiPoolableConnectionFactory.getPool()); - - try { - // Configure the simulator db - final int simulatorMaxActive = Integer.parseInt(dbProps.getProperty("db.simulator.maxActive")); - final int simulatorMaxIdle = Integer.parseInt(dbProps.getProperty("db.simulator.maxIdle")); - final long simulatorMaxWait = Long.parseLong(dbProps.getProperty("db.simulator.maxWait")); - final String simulatorUsername = dbProps.getProperty("db.simulator.username"); - final String simulatorPassword = dbProps.getProperty("db.simulator.password"); - final String simulatorHost = dbProps.getProperty("db.simulator.host"); - final int simulatorPort = Integer.parseInt(dbProps.getProperty("db.simulator.port")); - final String simulatorDbName = dbProps.getProperty("db.simulator.name"); - final boolean simulatorAutoReconnect = Boolean.parseBoolean(dbProps.getProperty("db.simulator.autoReconnect")); - - final GenericObjectPool simulatorConnectionPool = new GenericObjectPool(null, simulatorMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION, - simulatorMaxWait, simulatorMaxIdle); - - final ConnectionFactory simulatorConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + simulatorHost + ":" + simulatorPort + "/" + simulatorDbName + - "?autoReconnect=" + simulatorAutoReconnect, simulatorUsername, simulatorPassword); - - final PoolableConnectionFactory simulatorPoolableConnectionFactory = new PoolableConnectionFactory(simulatorConnectionFactory, simulatorConnectionPool, - new StackKeyedObjectPoolFactory(), null, false, false); - s_simulatorDS = new PoolingDataSource(simulatorPoolableConnectionFactory.getPool()); - } catch (Exception e) { - s_logger.debug("Simulator DB properties are not available. Not initializing simulator DS"); - } - } catch (final Exception e) { - s_ds = getDefaultDataSource("cloud"); - s_usageDS = getDefaultDataSource("cloud_usage"); - s_simulatorDS = getDefaultDataSource("cloud_simulator"); - s_logger.warn("Unable to load db configuration, using defaults with 5 connections. Falling back on assumed datasource on localhost:3306 using username:password=cloud:cloud. Please check your configuration", e); - } - } - - private static DataSource getDefaultDataSource(final String database) { - final GenericObjectPool connectionPool = new GenericObjectPool(null, 5); - final ConnectionFactory connectionFactory = new DriverManagerConnectionFactory( - "jdbc:mysql://localhost:3306/" + database, "cloud", "cloud"); - final PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory( - connectionFactory, connectionPool, null, null, false, true); - return new PoolingDataSource( - /* connectionPool */poolableConnectionFactory.getPool()); - } - } diff --git a/framework/db/src/com/cloud/utils/db/TransactionCallback.java b/framework/db/src/com/cloud/utils/db/TransactionCallback.java new file mode 100644 index 00000000000..df07fa696aa --- /dev/null +++ b/framework/db/src/com/cloud/utils/db/TransactionCallback.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.cloud.utils.db; + +public interface TransactionCallback { + + public T doInTransaction(TransactionStatus status); + +} diff --git a/framework/db/src/com/cloud/utils/db/TransactionCallbackNoReturn.java b/framework/db/src/com/cloud/utils/db/TransactionCallbackNoReturn.java new file mode 100644 index 00000000000..65e378b7658 --- /dev/null +++ b/framework/db/src/com/cloud/utils/db/TransactionCallbackNoReturn.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.cloud.utils.db; + +public abstract class TransactionCallbackNoReturn implements TransactionCallback { + + @Override + public final Object doInTransaction(TransactionStatus status) { + doInTransactionWithoutResult(status); + return null; + } + + public abstract void doInTransactionWithoutResult(TransactionStatus status); + +} diff --git a/framework/db/src/com/cloud/utils/db/TransactionCallbackWithException.java b/framework/db/src/com/cloud/utils/db/TransactionCallbackWithException.java new file mode 100644 index 00000000000..a2f829db238 --- /dev/null +++ b/framework/db/src/com/cloud/utils/db/TransactionCallbackWithException.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.cloud.utils.db; + +public interface TransactionCallbackWithException { + + public T doInTransaction(TransactionStatus status) throws E; + +} diff --git a/framework/db/src/com/cloud/utils/db/TransactionCallbackWithExceptionNoReturn.java b/framework/db/src/com/cloud/utils/db/TransactionCallbackWithExceptionNoReturn.java new file mode 100644 index 00000000000..d5bc44fe7b3 --- /dev/null +++ b/framework/db/src/com/cloud/utils/db/TransactionCallbackWithExceptionNoReturn.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.cloud.utils.db; + +public abstract class TransactionCallbackWithExceptionNoReturn implements TransactionCallbackWithException { + + @Override + public final Boolean doInTransaction(TransactionStatus status) throws E { + doInTransactionWithoutResult(status); + return true; + } + + public abstract void doInTransactionWithoutResult(TransactionStatus status) throws E; + +} + diff --git a/framework/db/src/com/cloud/utils/db/TransactionContextBuilder.java b/framework/db/src/com/cloud/utils/db/TransactionContextBuilder.java index 40fcbbf5593..d60ab7b7f43 100644 --- a/framework/db/src/com/cloud/utils/db/TransactionContextBuilder.java +++ b/framework/db/src/com/cloud/utils/db/TransactionContextBuilder.java @@ -46,19 +46,19 @@ public class TransactionContextBuilder implements ComponentMethodInterceptor { @Override public Object interceptStart(Method method, Object target) { - return Transaction.open(method.getName()); + return TransactionLegacy.open(method.getName()); } @Override public void interceptComplete(Method method, Object target, Object objReturnedInInterceptStart) { - Transaction txn = (Transaction)objReturnedInInterceptStart; + TransactionLegacy txn = (TransactionLegacy)objReturnedInInterceptStart; if(txn != null) txn.close(); } @Override public void interceptException(Method method, Object target, Object objReturnedInInterceptStart) { - Transaction txn = (Transaction)objReturnedInInterceptStart; + TransactionLegacy txn = (TransactionLegacy)objReturnedInInterceptStart; if(txn != null) txn.close(); } diff --git a/framework/db/src/com/cloud/utils/db/TransactionContextInterceptor.java b/framework/db/src/com/cloud/utils/db/TransactionContextInterceptor.java new file mode 100644 index 00000000000..3f5d6d27db5 --- /dev/null +++ b/framework/db/src/com/cloud/utils/db/TransactionContextInterceptor.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.cloud.utils.db; + +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; + +public class TransactionContextInterceptor implements MethodInterceptor { + + public TransactionContextInterceptor() { + + } + @Override + public Object invoke(MethodInvocation m) throws Throwable { + TransactionLegacy txn = TransactionLegacy.open(m.getMethod().getName()); + try { + return m.proceed(); + } finally { + txn.close(); + } + } + +} diff --git a/framework/db/src/com/cloud/utils/db/TransactionContextListener.java b/framework/db/src/com/cloud/utils/db/TransactionContextListener.java new file mode 100644 index 00000000000..db0a706cb9f --- /dev/null +++ b/framework/db/src/com/cloud/utils/db/TransactionContextListener.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.cloud.utils.db; + +import org.apache.cloudstack.managed.context.ManagedContextListener; + +public class TransactionContextListener implements ManagedContextListener { + + @Override + public TransactionLegacy onEnterContext(boolean reentry) { + if ( ! reentry ) { + return TransactionLegacy.open(Thread.currentThread().getName()); + } + + return null; + } + + @Override + public void onLeaveContext(TransactionLegacy data, boolean reentry) { + if ( ! reentry ) { + data.close(); + } + } + +} diff --git a/framework/db/src/com/cloud/utils/db/TransactionLegacy.java b/framework/db/src/com/cloud/utils/db/TransactionLegacy.java new file mode 100755 index 00000000000..9cf7c3f7d47 --- /dev/null +++ b/framework/db/src/com/cloud/utils/db/TransactionLegacy.java @@ -0,0 +1,1194 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.utils.db; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Savepoint; +import java.sql.Statement; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.atomic.AtomicLong; + +import javax.sql.DataSource; + +import org.apache.commons.dbcp.ConnectionFactory; +import org.apache.commons.dbcp.DriverManagerConnectionFactory; +import org.apache.commons.dbcp.PoolableConnectionFactory; +import org.apache.commons.dbcp.PoolingDataSource; +import org.apache.commons.pool.KeyedObjectPoolFactory; +import org.apache.commons.pool.impl.GenericObjectPool; +import org.apache.commons.pool.impl.StackKeyedObjectPoolFactory; +import org.apache.log4j.Logger; +import org.jasypt.encryption.pbe.StandardPBEStringEncryptor; +import org.jasypt.properties.EncryptableProperties; + +import com.cloud.utils.Pair; +import com.cloud.utils.PropertiesUtil; +import com.cloud.utils.crypt.EncryptionSecretKeyChecker; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.mgmt.JmxUtil; + +/** + * Transaction abstracts away the Connection object in JDBC. It allows the + * following things that the Connection object does not. + * + * 1. Transaction can be started at an entry point and whether the DB + * actions should be auto-commit or not determined at that point. + * 2. DB Connection is allocated only when it is needed. + * 3. Code does not need to know if a transaction has been started or not. + * It just starts/ends a transaction and we resolve it correctly with + * the previous actions. + * + * Note that this class is not synchronous but it doesn't need to be because + * it is stored with TLS and is one per thread. Use appropriately. + */ +public class TransactionLegacy { + private static final Logger s_logger = Logger.getLogger(Transaction.class.getName() + "." + "Transaction"); + private static final Logger s_stmtLogger = Logger.getLogger(Transaction.class.getName() + "." + "Statement"); + private static final Logger s_lockLogger = Logger.getLogger(Transaction.class.getName() + "." + "Lock"); + private static final Logger s_connLogger = Logger.getLogger(Transaction.class.getName() + "." + "Connection"); + + private static final ThreadLocal tls = new ThreadLocal(); + private static final String START_TXN = "start_txn"; + private static final String CURRENT_TXN = "current_txn"; + private static final String CREATE_TXN = "create_txn"; + private static final String CREATE_CONN = "create_conn"; + private static final String STATEMENT = "statement"; + private static final String ATTACHMENT = "attachment"; + + public static final short CLOUD_DB = 0; + public static final short USAGE_DB = 1; + public static final short AWSAPI_DB = 2; + public static final short SIMULATOR_DB = 3; + + public static final short CONNECTED_DB = -1; + + private static AtomicLong s_id = new AtomicLong(); + private static final TransactionMBeanImpl s_mbean = new TransactionMBeanImpl(); + static { + try { + JmxUtil.registerMBean("Transaction", "Transaction", s_mbean); + } catch (Exception e) { + s_logger.error("Unable to register mbean for transaction", e); + } + + /* FIXME: We need a better solution for this + * Initialize encryption if we need it for db.properties + */ + EncryptionSecretKeyChecker enc = new EncryptionSecretKeyChecker(); + enc.check(); + } + + private final LinkedList _stack; + private long _id; + + private final LinkedList> _lockTimes = new LinkedList>(); + + private String _name; + private Connection _conn; + private boolean _txn; + private short _dbId; + private long _txnTime; + private Statement _stmt; + private String _creator; + + private TransactionLegacy _prev = null; + + public static TransactionLegacy currentTxn() { + return currentTxn(true); + } + + protected static TransactionLegacy currentTxn(boolean check) { + TransactionLegacy txn = tls.get(); + if (check) { + assert txn != null : "No Transaction on stack. Did you mark the method with @DB?"; + + assert checkAnnotation(4, txn) : "Did you even read the guide to use Transaction...IOW...other people's code? Try method can't be private. What about @DB? hmmm... could that be it? " + txn; + } + return txn; + } + + public static TransactionLegacy open(final short databaseId) { + String name = buildName(); + if (name == null) { + name = CURRENT_TXN; + } + return open(name, databaseId, true); + } + + // + // Usage of this transaction setup should be limited, it will always open a new transaction context regardless of whether or not there is other + // transaction context in the stack. It is used in special use cases that we want to control DB connection explicitly and in the mean time utilize + // the existing DAO features + // + public void transitToUserManagedConnection(Connection conn) { + if ( _conn != null ) + throw new IllegalStateException("Can't change to a user managed connection unless the db connection is null"); + + _conn = conn; + _dbId = CONNECTED_DB; + } + + public void transitToAutoManagedConnection(short dbId) { + // assert(_stack.size() <= 1) : "Can't change to auto managed connection unless your stack is empty"; + _dbId = dbId; + _conn = null; + } + + public static TransactionLegacy open(final String name) { + return open(name, TransactionLegacy.CLOUD_DB, false); + } + + public static TransactionLegacy open(final String name, final short databaseId, final boolean forceDbChange) { + TransactionLegacy txn = tls.get(); + boolean isNew = false; + if (txn == null) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("Creating the transaction: " + name); + } + txn = new TransactionLegacy(name, false, databaseId); + tls.set(txn); + isNew = true; + } else if (forceDbChange) { + final short currentDbId = txn.getDatabaseId(); + if (currentDbId != databaseId) { + // we need to end the current transaction and switch databases + txn.close(txn.getName()); + + txn = new TransactionLegacy(name, false, databaseId); + tls.set(txn); + isNew = true; + } + } + + txn.takeOver(name, false); + if (isNew) { + s_mbean.addTransaction(txn); + } + return txn; + } + + protected StackElement peekInStack(Object obj) { + final Iterator it = _stack.iterator(); + while (it.hasNext()) { + StackElement next = it.next(); + if (next.type == obj) { + return next; + } + } + return null; + } + + public void registerLock(String sql) { + if (_txn && s_lockLogger.isDebugEnabled()) { + Pair time = new Pair(sql, System.currentTimeMillis()); + _lockTimes.add(time); + } + } + + public boolean dbTxnStarted() { + return _txn; + } + + public static Connection getStandaloneConnectionWithException() throws SQLException { + Connection conn = s_ds.getConnection(); + if (s_connLogger.isTraceEnabled()) { + s_connLogger.trace("Retrieving a standalone connection: dbconn" + System.identityHashCode(conn)); + } + return conn; + } + + public static Connection getStandaloneConnection() { + try { + return getStandaloneConnectionWithException(); + } catch (SQLException e) { + s_logger.error("Unexpected exception: ", e); + return null; + } + } + + public static Connection getStandaloneUsageConnection() { + try { + Connection conn = s_usageDS.getConnection(); + if (s_connLogger.isTraceEnabled()) { + s_connLogger.trace("Retrieving a standalone connection for usage: dbconn" + System.identityHashCode(conn)); + } + return conn; + } catch (SQLException e) { + s_logger.warn("Unexpected exception: ", e); + return null; + } + } + + public static Connection getStandaloneAwsapiConnection() { + try { + Connection conn = s_awsapiDS.getConnection(); + if (s_connLogger.isTraceEnabled()) { + s_connLogger.trace("Retrieving a standalone connection for usage: dbconn" + System.identityHashCode(conn)); + } + return conn; + } catch (SQLException e) { + s_logger.warn("Unexpected exception: ", e); + return null; + } + } + + public static Connection getStandaloneSimulatorConnection() { + try { + Connection conn = s_simulatorDS.getConnection(); + if (s_connLogger.isTraceEnabled()) { + s_connLogger.trace("Retrieving a standalone connection for simulator: dbconn" + System.identityHashCode(conn)); + } + return conn; + } catch (SQLException e) { + s_logger.warn("Unexpected exception: ", e); + return null; + } + } + + protected void attach(TransactionAttachment value) { + _stack.push(new StackElement(ATTACHMENT, value)); + } + + protected TransactionAttachment detach(String name) { + Iterator it = _stack.descendingIterator(); + while (it.hasNext()) { + StackElement element = it.next(); + if (element.type == ATTACHMENT) { + TransactionAttachment att = (TransactionAttachment)element.ref; + if (name.equals(att.getName())) { + it.remove(); + return att; + } + } + } + assert false : "Are you sure you attached this: " + name; + return null; + } + + public static void attachToTxn(TransactionAttachment value) { + TransactionLegacy txn = tls.get(); + assert txn != null && txn.peekInStack(CURRENT_TXN) != null: "Come on....how can we attach something to the transaction if you haven't started it?"; + + txn.attach(value); + } + + public static TransactionAttachment detachFromTxn(String name) { + TransactionLegacy txn = tls.get(); + assert txn != null : "No Transaction in TLS"; + return txn.detach(name); + } + + protected static boolean checkAnnotation(int stack, TransactionLegacy txn) { + final StackTraceElement[] stacks = Thread.currentThread().getStackTrace(); + StackElement se = txn.peekInStack(CURRENT_TXN); + if (se == null) { + return false; + } + + StringBuffer sb = new StringBuffer(); + for (; stack < stacks.length; stack++) { + String methodName = stacks[stack].getMethodName(); + sb.append(" ").append(methodName); + if (methodName.equals(se.ref)){ + return true; + } + } + + // relax stack structure for several places that @DB required injection is not in place + s_logger.warn("Non-standard stack context that Transaction context is manaully placed into the calling chain. Stack chain: " + sb); + return true; + } + + protected static String buildName() { + if (s_logger.isDebugEnabled()) { + final StackTraceElement[] stacks = Thread.currentThread().getStackTrace(); + final StringBuilder str = new StringBuilder(); + int i = 3, j = 3; + while (j < 15 && i < stacks.length) { + StackTraceElement element = stacks[i]; + String filename = element.getFileName(); + String method = element.getMethodName(); + if ((filename != null && filename.equals("")) || (method != null && method.equals("invokeSuper"))) { + i++; + continue; + } + + str.append("-").append(stacks[i].getClassName().substring(stacks[i].getClassName().lastIndexOf(".") + 1)).append(".").append(stacks[i].getMethodName()).append(":").append(stacks[i].getLineNumber()); + j++; + i++; + } + return str.toString(); + } + + return ""; + } + + public TransactionLegacy(final String name, final boolean forLocking, final short databaseId) { + _name = name; + _conn = null; + _stack = new LinkedList(); + _txn = false; + _dbId = databaseId; + _id = s_id.incrementAndGet(); + _creator = Thread.currentThread().getName(); + } + + public String getCreator() { + return _creator; + } + + public long getId() { + return _id; + } + + public String getName() { + return _name; + } + + public Short getDatabaseId() { + return _dbId; + } + + @Override + public String toString() { + final StringBuilder str = new StringBuilder((_name != null ? _name : "")); + str.append(" : "); + for (final StackElement se : _stack) { + if (se.type == CURRENT_TXN) { + str.append(se.ref).append(", "); + } + } + + return str.toString(); + } + + protected void mark(final String name) { + _stack.push(new StackElement(CURRENT_TXN, name)); + } + + public boolean lock(final String name, final int timeoutSeconds) { + Merovingian2 lockMaster = Merovingian2.getLockMaster(); + if (lockMaster == null) { + throw new CloudRuntimeException("There's no support for locking yet"); + } + return lockMaster.acquire(name, timeoutSeconds); + } + + public boolean release(final String name) { + Merovingian2 lockMaster = Merovingian2.getLockMaster(); + if (lockMaster == null) { + throw new CloudRuntimeException("There's no support for locking yet"); + } + return lockMaster.release(name); + } + + /** + * @deprecated Use {@link Transaction} for new code + */ + @Deprecated + public void start() { + if (s_logger.isTraceEnabled()) { + s_logger.trace("txn: start requested by: " + buildName()); + } + + _stack.push(new StackElement(START_TXN, null)); + + if (_txn) { + s_logger.trace("txn: has already been started."); + return; + } + + _txn = true; + + _txnTime = System.currentTimeMillis(); + if (_conn != null) { + try { + s_logger.trace("txn: set auto commit to false"); + _conn.setAutoCommit(false); + } catch (final SQLException e) { + s_logger.warn("Unable to set auto commit: ", e); + throw new CloudRuntimeException("Unable to set auto commit: ", e); + } + } + } + + protected void closePreviousStatement() { + if (_stmt != null) { + try { + if (s_stmtLogger.isTraceEnabled()) { + s_stmtLogger.trace("Closing: " + _stmt.toString()); + } + try { + ResultSet rs = _stmt.getResultSet(); + if (rs != null && _stmt.getResultSetHoldability() != ResultSet.HOLD_CURSORS_OVER_COMMIT) { + rs.close(); + } + } catch(SQLException e) { + s_stmtLogger.trace("Unable to close resultset"); + } + _stmt.close(); + } catch (final SQLException e) { + s_stmtLogger.trace("Unable to close statement: " + _stmt.toString()); + } finally { + _stmt = null; + } + } + } + + /** + * Prepares an auto close statement. The statement is closed automatically if it is + * retrieved with this method. + * + * @param sql sql String + * @return PreparedStatement + * @throws SQLException if problem with JDBC layer. + * + * @see java.sql.Connection + */ + public PreparedStatement prepareAutoCloseStatement(final String sql) throws SQLException { + PreparedStatement stmt = prepareStatement(sql); + closePreviousStatement(); + _stmt = stmt; + return stmt; + } + + public PreparedStatement prepareStatement(final String sql) throws SQLException { + final Connection conn = getConnection(); + final PreparedStatement pstmt = conn.prepareStatement(sql); + if (s_stmtLogger.isTraceEnabled()) { + s_stmtLogger.trace("Preparing: " + sql); + } + return pstmt; + } + + /** + * Prepares an auto close statement. The statement is closed automatically if it is + * retrieved with this method. + * + * @param sql sql String + * @param autoGeneratedKeys keys that are generated + * @return PreparedStatement + * @throws SQLException if problem with JDBC layer. + * + * @see java.sql.Connection + */ + public PreparedStatement prepareAutoCloseStatement(final String sql, final int autoGeneratedKeys) throws SQLException { + final Connection conn = getConnection(); + final PreparedStatement pstmt = conn.prepareStatement(sql, autoGeneratedKeys); + if (s_stmtLogger.isTraceEnabled()) { + s_stmtLogger.trace("Preparing: " + sql); + } + closePreviousStatement(); + _stmt = pstmt; + return pstmt; + } + + /** + * Prepares an auto close statement. The statement is closed automatically if it is + * retrieved with this method. + * + * @param sql sql String + * @param columnNames names of the columns + * @return PreparedStatement + * @throws SQLException if problem with JDBC layer. + * + * @see java.sql.Connection + */ + public PreparedStatement prepareAutoCloseStatement(final String sql, final String[] columnNames) throws SQLException { + final Connection conn = getConnection(); + final PreparedStatement pstmt = conn.prepareStatement(sql, columnNames); + if (s_stmtLogger.isTraceEnabled()) { + s_stmtLogger.trace("Preparing: " + sql); + } + closePreviousStatement(); + _stmt = pstmt; + return pstmt; + } + + /** + * Prepares an auto close statement. The statement is closed automatically if it is + * retrieved with this method. + * + * @param sql sql String + * @return PreparedStatement + * @throws SQLException if problem with JDBC layer. + * + * @see java.sql.Connection + */ + public PreparedStatement prepareAutoCloseStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { + final Connection conn = getConnection(); + final PreparedStatement pstmt = conn.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability); + if (s_stmtLogger.isTraceEnabled()) { + s_stmtLogger.trace("Preparing: " + sql); + } + closePreviousStatement(); + _stmt = pstmt; + return pstmt; + } + + /** + * Returns the db connection. + * + * Note: that you can call getConnection() but beaware that + * all prepare statements from the Connection are not garbage + * collected! + * + * @return DB Connection but make sure you understand that + * you are responsible for closing the PreparedStatement. + * @throws SQLException + */ + public Connection getConnection() throws SQLException { + if (_conn == null) { + switch (_dbId) { + case CLOUD_DB: + if(s_ds != null) { + _conn = s_ds.getConnection(); + } else { + s_logger.warn("A static-initialized variable becomes null, process is dying?"); + throw new CloudRuntimeException("Database is not initialized, process is dying?"); + } + break; + case USAGE_DB: + if(s_usageDS != null) { + _conn = s_usageDS.getConnection(); + } else { + s_logger.warn("A static-initialized variable becomes null, process is dying?"); + throw new CloudRuntimeException("Database is not initialized, process is dying?"); + } + break; + case AWSAPI_DB: + if(s_awsapiDS != null) { + _conn = s_awsapiDS.getConnection(); + } else { + s_logger.warn("A static-initialized variable becomes null, process is dying?"); + throw new CloudRuntimeException("Database is not initialized, process is dying?"); + } + break; + + case SIMULATOR_DB: + if(s_simulatorDS != null) { + _conn = s_simulatorDS.getConnection(); + } else { + s_logger.warn("A static-initialized variable becomes null, process is dying?"); + throw new CloudRuntimeException("Database is not initialized, process is dying?"); + } + break; + default: + + throw new CloudRuntimeException("No database selected for the transaction"); + } + _conn.setAutoCommit(!_txn); + + // + // MySQL default transaction isolation level is REPEATABLE READ, + // to reduce chances of DB deadlock, we will use READ COMMITED isolation level instead + // see http://dev.mysql.com/doc/refman/5.0/en/innodb-deadlocks.html + // + _stack.push(new StackElement(CREATE_CONN, null)); + if (s_connLogger.isTraceEnabled()) { + s_connLogger.trace("Creating a DB connection with " + (_txn ? " txn: " : " no txn: ") + " for " + _dbId + ": dbconn" + System.identityHashCode(_conn) + ". Stack: " + buildName()); + } + } else { + s_logger.trace("conn: Using existing DB connection"); + } + + return _conn; + } + + protected boolean takeOver(final String name, final boolean create) { + if (_stack.size() != 0) { + if (!create) { + // If it is not a create transaction, then let's just use the current one. + if (s_logger.isTraceEnabled()) { + s_logger.trace("Using current transaction: " + toString()); + } + mark(name); + return false; + } + + final StackElement se = _stack.getFirst(); + if (se.type == CREATE_TXN) { + // This create is called inside of another create. Which is ok? + // We will let that create be responsible for cleaning up. + if (s_logger.isTraceEnabled()) { + s_logger.trace("Create using current transaction: " + toString()); + } + mark(name); + return false; + } + + s_logger.warn("Encountered a transaction that has leaked. Cleaning up. " + toString()); + cleanup(); + } + + if (s_logger.isTraceEnabled()) { + s_logger.trace("Took over the transaction: " + name); + } + _stack.push(new StackElement(create ? CREATE_TXN : CURRENT_TXN, name)); + _name = name; + return true; + } + + public void cleanup() { + closePreviousStatement(); + + removeUpTo(null, null); + if (_txn) { + rollbackTransaction(); + } + _txn = false; + _name = null; + + closeConnection(); + + _stack.clear(); + Merovingian2 lockMaster = Merovingian2.getLockMaster(); + if (lockMaster != null) { + lockMaster.cleanupThread(); + } + } + + public void close() { + removeUpTo(CURRENT_TXN, null); + + if (_stack.size() == 0) { + s_logger.trace("Transaction is done"); + cleanup(); + } + } + + /** + * close() is used by endTxn to close the connection. This method only + * closes the connection if the name is the same as what's stored. + * + * @param name + * @return true if this close actually closes the connection. false if not. + */ + public boolean close(final String name) { + if (_name == null) { // Already cleaned up. + if (s_logger.isTraceEnabled()) { + s_logger.trace("Already cleaned up." + buildName()); + } + return true; + } + + if (!_name.equals(name)) { + close(); + return false; + } + + if (s_logger.isDebugEnabled() && _stack.size() > 2) { + s_logger.debug("Transaction is not closed properly: " + toString() + ". Called by " + buildName()); + } + + cleanup(); + + s_logger.trace("All done"); + return true; + } + + protected boolean hasTxnInStack() { + return peekInStack(START_TXN) != null; + } + + protected void clearLockTimes() { + if (s_lockLogger.isDebugEnabled()) { + for (Pair time : _lockTimes) { + s_lockLogger.trace("SQL " + time.first() + " took " + (System.currentTimeMillis() - time.second())); + } + _lockTimes.clear(); + } + } + + public boolean commit() { + if (!_txn) { + s_logger.warn("txn: Commit called when it is not a transaction: " + buildName()); + return false; + } + + Iterator it = _stack.iterator(); + while (it.hasNext()) { + StackElement st = it.next(); + if (st.type == START_TXN) { + it.remove(); + break; + } + } + + if (hasTxnInStack()) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("txn: Not committing because transaction started elsewhere: " + buildName() + " / " + toString()); + } + return false; + } + + _txn = false; + try { + if (_conn != null) { + _conn.commit(); + s_logger.trace("txn: DB Changes committed. Time = " + (System.currentTimeMillis() - _txnTime)); + clearLockTimes(); + closeConnection(); + } + return true; + } catch (final SQLException e) { + rollbackTransaction(); + throw new CloudRuntimeException("Unable to commit or close the connection. ", e); + } + } + + protected void closeConnection() { + closePreviousStatement(); + + if (_conn == null) { + return; + } + + if (_txn) { + s_connLogger.trace("txn: Not closing DB connection because we're still in a transaction."); + return; + } + + try { + // we should only close db connection when it is not user managed + if (this._dbId != CONNECTED_DB) { + if (s_connLogger.isTraceEnabled()) { + s_connLogger.trace("Closing DB connection: dbconn" + System.identityHashCode(_conn)); + } + _conn.close(); + _conn = null; + } + + } catch (final SQLException e) { + s_logger.warn("Unable to close connection", e); + } + } + + protected void removeUpTo(String type, Object ref) { + boolean rollback = false; + Iterator it = _stack.iterator(); + while (it.hasNext()) { + StackElement item = it.next(); + + it.remove(); + + try { + if (item.type == type && (ref == null || item.ref == ref)) { + break; + } + + if (item.type == CURRENT_TXN) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("Releasing the current txn: " + (item.ref != null ? item.ref : "")); + } + } else if (item.type == CREATE_CONN) { + closeConnection(); + } else if (item.type == START_TXN) { + if (item.ref == null) { + rollback = true; + } else { + try { + _conn.rollback((Savepoint)ref); + rollback = false; + } catch (final SQLException e) { + s_logger.warn("Unable to rollback Txn.", e); + } + } + } else if (item.type == STATEMENT) { + try { + if (s_stmtLogger.isTraceEnabled()) { + s_stmtLogger.trace("Closing: " + ref.toString()); + } + Statement stmt = (Statement)ref; + try { + ResultSet rs = stmt.getResultSet(); + if (rs != null) { + rs.close(); + } + } catch(SQLException e) { + s_stmtLogger.trace("Unable to close resultset"); + } + stmt.close(); + } catch (final SQLException e) { + s_stmtLogger.trace("Unable to close statement: " + item); + } + } else if (item.type == ATTACHMENT) { + TransactionAttachment att = (TransactionAttachment)item.ref; + if (s_logger.isTraceEnabled()) { + s_logger.trace("Cleaning up " + att.getName()); + } + att.cleanup(); + } + } catch(Exception e) { + s_logger.error("Unable to clean up " + item, e); + } + } + + if (rollback) { + rollback(); + } + } + + protected void rollbackTransaction() { + closePreviousStatement(); + if (!_txn) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("Rollback called for " + _name + " when there's no transaction: " + buildName()); + } + return; + } + assert (!hasTxnInStack()) : "Who's rolling back transaction when there's still txn in stack?"; + _txn = false; + try { + if (_conn != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Rolling back the transaction: Time = " + (System.currentTimeMillis() - _txnTime) + " Name = " + _name + "; called by " + buildName()); + } + _conn.rollback(); + } + clearLockTimes(); + closeConnection(); + } catch(final SQLException e) { + s_logger.warn("Unable to rollback", e); + } + } + + protected void rollbackSavepoint(Savepoint sp) { + try { + if (_conn != null) { + _conn.rollback(sp); + } + } catch (SQLException e) { + s_logger.warn("Unable to rollback to savepoint " + sp); + } + + if (!hasTxnInStack()) { + _txn = false; + closeConnection(); + } + } + + public void rollback() { + Iterator it = _stack.iterator(); + while (it.hasNext()) { + StackElement st = it.next(); + if (st.type == START_TXN) { + if (st.ref == null) { + it.remove(); + } else { + rollback((Savepoint)st.ref); + return; + } + } + } + + rollbackTransaction(); + } + + public Savepoint setSavepoint() throws SQLException { + _txn = true; + StackElement st = new StackElement(START_TXN, null); + _stack.push(st); + final Connection conn = getConnection(); + final Savepoint sp = conn.setSavepoint(); + st.ref = sp; + + return sp; + } + + public Savepoint setSavepoint(final String name) throws SQLException { + _txn = true; + StackElement st = new StackElement(START_TXN, null); + _stack.push(st); + final Connection conn = getConnection(); + final Savepoint sp = conn.setSavepoint(name); + st.ref = sp; + + return sp; + } + + public void releaseSavepoint(final Savepoint sp) throws SQLException { + removeTxn(sp); + if (_conn != null) { + _conn.releaseSavepoint(sp); + } + + if (!hasTxnInStack()) { + _txn = false; + closeConnection(); + } + } + + protected boolean hasSavepointInStack(Savepoint sp) { + Iterator it = _stack.iterator(); + while (it.hasNext()) { + StackElement se = it.next(); + if (se.type == START_TXN && se.ref == sp) { + return true; + } + } + return false; + } + + protected void removeTxn(Savepoint sp) { + assert hasSavepointInStack(sp) : "Removing a save point that's not in the stack"; + + if (!hasSavepointInStack(sp)) { + return; + } + + Iterator it = _stack.iterator(); + while (it.hasNext()) { + StackElement se = it.next(); + if (se.type == START_TXN) { + it.remove(); + if (se.ref == sp) { + return; + } + } + } + } + + public void rollback(final Savepoint sp) { + removeTxn(sp); + + rollbackSavepoint(sp); + } + + public Connection getCurrentConnection() { + return _conn; + } + + public List getStack() { + return _stack; + } + + protected TransactionLegacy() { + _name = null; + _conn = null; + _stack = null; + _txn = false; + _dbId = -1; + } + + @Override + protected void finalize() throws Throwable { + if (!(_conn == null && (_stack == null || _stack.size() == 0))) { + assert (false) : "Oh Alex oh alex...something is wrong with how we're doing this"; + s_logger.error("Something went wrong that a transaction is orphaned before db connection is closed"); + cleanup(); + } + } + + protected class StackElement { + public String type; + public Object ref; + + public StackElement (String type, Object ref) { + this.type = type; + this.ref = ref; + } + + @Override + public String toString() { + return type + "-" + ref; + } + } + + private static DataSource s_ds; + private static DataSource s_usageDS; + private static DataSource s_awsapiDS; + private static DataSource s_simulatorDS; + + static { + // Initialize with assumed db.properties file + initDataSource("db.properties"); + } + + public static void initDataSource(String propsFileName) { + try { + File dbPropsFile = PropertiesUtil.findConfigFile(propsFileName); + final Properties dbProps; + if (EncryptionSecretKeyChecker.useEncryption()) { + StandardPBEStringEncryptor encryptor = EncryptionSecretKeyChecker.getEncryptor(); + dbProps = new EncryptableProperties(encryptor); + } else { + dbProps = new Properties(); + } + try { + dbProps.load(new FileInputStream(dbPropsFile)); + } catch (IOException e) { + s_logger.fatal("Unable to load db properties file, pl. check the classpath and file path configuration", e); + return; + } catch (NullPointerException e) { + s_logger.fatal("Unable to locate db properties file within classpath or absolute path: " + propsFileName); + return; + } + + // FIXME: If params are missing...default them???? + final int cloudMaxActive = Integer.parseInt(dbProps.getProperty("db.cloud.maxActive")); + final int cloudMaxIdle = Integer.parseInt(dbProps.getProperty("db.cloud.maxIdle")); + final long cloudMaxWait = Long.parseLong(dbProps.getProperty("db.cloud.maxWait")); + final String cloudUsername = dbProps.getProperty("db.cloud.username"); + final String cloudPassword = dbProps.getProperty("db.cloud.password"); + final String cloudHost = dbProps.getProperty("db.cloud.host"); + final int cloudPort = Integer.parseInt(dbProps.getProperty("db.cloud.port")); + final String cloudDbName = dbProps.getProperty("db.cloud.name"); + final boolean cloudAutoReconnect = Boolean.parseBoolean(dbProps.getProperty("db.cloud.autoReconnect")); + final String cloudValidationQuery = dbProps.getProperty("db.cloud.validationQuery"); + final String cloudIsolationLevel = dbProps.getProperty("db.cloud.isolation.level"); + + int isolationLevel = Connection.TRANSACTION_READ_COMMITTED; + if (cloudIsolationLevel == null) { + isolationLevel = Connection.TRANSACTION_READ_COMMITTED; + } else if (cloudIsolationLevel.equalsIgnoreCase("readcommitted")) { + isolationLevel = Connection.TRANSACTION_READ_COMMITTED; + } else if (cloudIsolationLevel.equalsIgnoreCase("repeatableread")) { + isolationLevel = Connection.TRANSACTION_REPEATABLE_READ; + } else if (cloudIsolationLevel.equalsIgnoreCase("serializable")) { + isolationLevel = Connection.TRANSACTION_SERIALIZABLE; + } else if (cloudIsolationLevel.equalsIgnoreCase("readuncommitted")) { + isolationLevel = Connection.TRANSACTION_READ_UNCOMMITTED; + } else { + s_logger.warn("Unknown isolation level " + cloudIsolationLevel + ". Using read uncommitted"); + } + + final boolean cloudTestOnBorrow = Boolean.parseBoolean(dbProps.getProperty("db.cloud.testOnBorrow")); + final boolean cloudTestWhileIdle = Boolean.parseBoolean(dbProps.getProperty("db.cloud.testWhileIdle")); + final long cloudTimeBtwEvictionRunsMillis = Long.parseLong(dbProps.getProperty("db.cloud.timeBetweenEvictionRunsMillis")); + final long cloudMinEvcitableIdleTimeMillis = Long.parseLong(dbProps.getProperty("db.cloud.minEvictableIdleTimeMillis")); + final boolean cloudPoolPreparedStatements = Boolean.parseBoolean(dbProps.getProperty("db.cloud.poolPreparedStatements")); + final String url = dbProps.getProperty("db.cloud.url.params"); + + final boolean useSSL = Boolean.parseBoolean(dbProps.getProperty("db.cloud.useSSL")); + if (useSSL) { + System.setProperty("javax.net.ssl.keyStore", dbProps.getProperty("db.cloud.keyStore")); + System.setProperty("javax.net.ssl.keyStorePassword", dbProps.getProperty("db.cloud.keyStorePassword")); + System.setProperty("javax.net.ssl.trustStore", dbProps.getProperty("db.cloud.trustStore")); + System.setProperty("javax.net.ssl.trustStorePassword", dbProps.getProperty("db.cloud.trustStorePassword")); + } + + final GenericObjectPool cloudConnectionPool = new GenericObjectPool(null, cloudMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION, + cloudMaxWait, cloudMaxIdle, cloudTestOnBorrow, false, cloudTimeBtwEvictionRunsMillis, 1, cloudMinEvcitableIdleTimeMillis, cloudTestWhileIdle); + + final ConnectionFactory cloudConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + cloudHost + ":" + cloudPort + "/" + cloudDbName + + "?autoReconnect=" + cloudAutoReconnect + (url != null ? "&" + url : "") + (useSSL ? "&useSSL=true" : ""), cloudUsername, cloudPassword); + + final KeyedObjectPoolFactory poolableObjFactory = (cloudPoolPreparedStatements ? new StackKeyedObjectPoolFactory() : null); + + final PoolableConnectionFactory cloudPoolableConnectionFactory = new PoolableConnectionFactory(cloudConnectionFactory, cloudConnectionPool, poolableObjFactory, + cloudValidationQuery, false, false, isolationLevel); + + // Default Data Source for CloudStack + s_ds = new PoolingDataSource(cloudPoolableConnectionFactory.getPool()); + + // Configure the usage db + final int usageMaxActive = Integer.parseInt(dbProps.getProperty("db.usage.maxActive")); + final int usageMaxIdle = Integer.parseInt(dbProps.getProperty("db.usage.maxIdle")); + final long usageMaxWait = Long.parseLong(dbProps.getProperty("db.usage.maxWait")); + final String usageUsername = dbProps.getProperty("db.usage.username"); + final String usagePassword = dbProps.getProperty("db.usage.password"); + final String usageHost = dbProps.getProperty("db.usage.host"); + final int usagePort = Integer.parseInt(dbProps.getProperty("db.usage.port")); + final String usageDbName = dbProps.getProperty("db.usage.name"); + final boolean usageAutoReconnect = Boolean.parseBoolean(dbProps.getProperty("db.usage.autoReconnect")); + final String usageUrl = dbProps.getProperty("db.usage.url.params"); + + final GenericObjectPool usageConnectionPool = new GenericObjectPool(null, usageMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION, + usageMaxWait, usageMaxIdle); + + final ConnectionFactory usageConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + usageHost + ":" + usagePort + "/" + usageDbName + + "?autoReconnect=" + usageAutoReconnect + (usageUrl != null ? "&" + usageUrl : ""), usageUsername, usagePassword); + + final PoolableConnectionFactory usagePoolableConnectionFactory = new PoolableConnectionFactory(usageConnectionFactory, usageConnectionPool, + new StackKeyedObjectPoolFactory(), null, false, false); + + // Data Source for usage server + s_usageDS = new PoolingDataSource(usagePoolableConnectionFactory.getPool()); + + // Configure awsapi db + final String awsapiDbName = dbProps.getProperty("db.awsapi.name"); + final GenericObjectPool awsapiConnectionPool = new GenericObjectPool(null, usageMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION, + usageMaxWait, usageMaxIdle); + final ConnectionFactory awsapiConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + cloudHost + ":" + cloudPort + "/" + awsapiDbName + + "?autoReconnect=" + usageAutoReconnect, cloudUsername, cloudPassword); + final PoolableConnectionFactory awsapiPoolableConnectionFactory = new PoolableConnectionFactory(awsapiConnectionFactory, awsapiConnectionPool, + new StackKeyedObjectPoolFactory(), null, false, false); + + // Data Source for awsapi + s_awsapiDS = new PoolingDataSource(awsapiPoolableConnectionFactory.getPool()); + + try { + // Configure the simulator db + final int simulatorMaxActive = Integer.parseInt(dbProps.getProperty("db.simulator.maxActive")); + final int simulatorMaxIdle = Integer.parseInt(dbProps.getProperty("db.simulator.maxIdle")); + final long simulatorMaxWait = Long.parseLong(dbProps.getProperty("db.simulator.maxWait")); + final String simulatorUsername = dbProps.getProperty("db.simulator.username"); + final String simulatorPassword = dbProps.getProperty("db.simulator.password"); + final String simulatorHost = dbProps.getProperty("db.simulator.host"); + final int simulatorPort = Integer.parseInt(dbProps.getProperty("db.simulator.port")); + final String simulatorDbName = dbProps.getProperty("db.simulator.name"); + final boolean simulatorAutoReconnect = Boolean.parseBoolean(dbProps.getProperty("db.simulator.autoReconnect")); + + final GenericObjectPool simulatorConnectionPool = new GenericObjectPool(null, simulatorMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION, + simulatorMaxWait, simulatorMaxIdle); + + final ConnectionFactory simulatorConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + simulatorHost + ":" + simulatorPort + "/" + simulatorDbName + + "?autoReconnect=" + simulatorAutoReconnect, simulatorUsername, simulatorPassword); + + final PoolableConnectionFactory simulatorPoolableConnectionFactory = new PoolableConnectionFactory(simulatorConnectionFactory, simulatorConnectionPool, + new StackKeyedObjectPoolFactory(), null, false, false); + s_simulatorDS = new PoolingDataSource(simulatorPoolableConnectionFactory.getPool()); + } catch (Exception e) { + s_logger.debug("Simulator DB properties are not available. Not initializing simulator DS"); + } + } catch (final Exception e) { + s_ds = getDefaultDataSource("cloud"); + s_usageDS = getDefaultDataSource("cloud_usage"); + s_simulatorDS = getDefaultDataSource("cloud_simulator"); + s_logger.warn("Unable to load db configuration, using defaults with 5 connections. Falling back on assumed datasource on localhost:3306 using username:password=cloud:cloud. Please check your configuration", e); + } + } + + private static DataSource getDefaultDataSource(final String database) { + final GenericObjectPool connectionPool = new GenericObjectPool(null, 5); + final ConnectionFactory connectionFactory = new DriverManagerConnectionFactory( + "jdbc:mysql://localhost:3306/" + database, "cloud", "cloud"); + final PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory( + connectionFactory, connectionPool, null, null, false, true); + return new PoolingDataSource( + /* connectionPool */poolableConnectionFactory.getPool()); + } + + /** + * Used for unit testing primarily + * + * @param conn + */ + protected void setConnection(Connection conn) { + this._conn = conn; + } +} diff --git a/framework/db/src/com/cloud/utils/db/TransactionMBeanImpl.java b/framework/db/src/com/cloud/utils/db/TransactionMBeanImpl.java index d51a9bd0cc7..73511b17ce4 100644 --- a/framework/db/src/com/cloud/utils/db/TransactionMBeanImpl.java +++ b/framework/db/src/com/cloud/utils/db/TransactionMBeanImpl.java @@ -25,21 +25,21 @@ import java.util.concurrent.ConcurrentHashMap; import javax.management.StandardMBean; -import com.cloud.utils.db.Transaction.StackElement; +import com.cloud.utils.db.TransactionLegacy.StackElement; public class TransactionMBeanImpl extends StandardMBean implements TransactionMBean { - Map _txns = new ConcurrentHashMap(); + Map _txns = new ConcurrentHashMap(); public TransactionMBeanImpl() { super(TransactionMBean.class, false); } - public void addTransaction(Transaction txn) { + public void addTransaction(TransactionLegacy txn) { _txns.put(txn.getId(), txn); } - public void removeTransaction(Transaction txn) { + public void removeTransaction(TransactionLegacy txn) { _txns.remove(txn.getId()); } @@ -53,7 +53,7 @@ public class TransactionMBeanImpl extends StandardMBean implements TransactionMB int[] count = new int[2]; count[0] = 0; count[1] = 0; - for (Transaction txn : _txns.values()) { + for (TransactionLegacy txn : _txns.values()) { if (txn.getStack().size() > 0) { count[0]++; } @@ -67,7 +67,7 @@ public class TransactionMBeanImpl extends StandardMBean implements TransactionMB @Override public List> getTransactions() { ArrayList> txns = new ArrayList>(); - for (Transaction info : _txns.values()) { + for (TransactionLegacy info : _txns.values()) { txns.add(toMap(info)); } return txns; @@ -76,7 +76,7 @@ public class TransactionMBeanImpl extends StandardMBean implements TransactionMB @Override public List> getActiveTransactions() { ArrayList> txns = new ArrayList>(); - for (Transaction txn : _txns.values()) { + for (TransactionLegacy txn : _txns.values()) { if (txn.getStack().size() > 0 || txn.getCurrentConnection() != null) { txns.add(toMap(txn)); } @@ -84,7 +84,7 @@ public class TransactionMBeanImpl extends StandardMBean implements TransactionMB return txns; } - protected Map toMap(Transaction txn) { + protected Map toMap(TransactionLegacy txn) { Map map = new HashMap(); map.put("name", txn.getName()); map.put("id", Long.toString(txn.getId())); @@ -103,7 +103,7 @@ public class TransactionMBeanImpl extends StandardMBean implements TransactionMB @Override public List> getTransactionsWithDatabaseConnection() { ArrayList> txns = new ArrayList>(); - for (Transaction txn : _txns.values()) { + for (TransactionLegacy txn : _txns.values()) { if (txn.getCurrentConnection() != null) { txns.add(toMap(txn)); } diff --git a/framework/db/src/com/cloud/utils/db/TransactionStatus.java b/framework/db/src/com/cloud/utils/db/TransactionStatus.java new file mode 100644 index 00000000000..616603c0932 --- /dev/null +++ b/framework/db/src/com/cloud/utils/db/TransactionStatus.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.cloud.utils.db; + +/** + * Placeholder for possible future features + */ +public interface TransactionStatus { +} diff --git a/framework/db/test/com/cloud/utils/db/DbTestDao.java b/framework/db/test/com/cloud/utils/db/DbTestDao.java index 9530b3b2d44..7db5ba867db 100644 --- a/framework/db/test/com/cloud/utils/db/DbTestDao.java +++ b/framework/db/test/com/cloud/utils/db/DbTestDao.java @@ -29,7 +29,7 @@ public class DbTestDao extends GenericDaoBase implements Generic @DB public void create(int fldInt, long fldLong, String fldString) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { txn.start(); @@ -48,7 +48,7 @@ public class DbTestDao extends GenericDaoBase implements Generic @DB public void update(int fldInt, long fldLong, String fldString) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { txn.start(); diff --git a/framework/db/test/com/cloud/utils/db/DbTestUtils.java b/framework/db/test/com/cloud/utils/db/DbTestUtils.java index 11ae1aa4d0b..2458b8c7e26 100644 --- a/framework/db/test/com/cloud/utils/db/DbTestUtils.java +++ b/framework/db/test/com/cloud/utils/db/DbTestUtils.java @@ -33,7 +33,7 @@ public class DbTestUtils { throw new RuntimeException("Unable to clean the database because I can't find " + file); } - Connection conn = Transaction.getStandaloneConnection(); + Connection conn = TransactionLegacy.getStandaloneConnection(); ScriptRunner runner = new ScriptRunner(conn, autoCommit, stopOnError); FileReader reader; @@ -63,7 +63,7 @@ public class DbTestUtils { throw new RuntimeException("Unable to clean the database because I can't find " + file); } - Connection conn = Transaction.getStandaloneUsageConnection(); + Connection conn = TransactionLegacy.getStandaloneUsageConnection(); ScriptRunner runner = new ScriptRunner(conn, autoCommit, stopOnError); FileReader reader; diff --git a/framework/db/test/com/cloud/utils/db/TestTransaction.java b/framework/db/test/com/cloud/utils/db/TestTransaction.java new file mode 100644 index 00000000000..4ee08f1f66f --- /dev/null +++ b/framework/db/test/com/cloud/utils/db/TestTransaction.java @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.cloud.utils.db; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import java.io.FileNotFoundException; +import java.sql.Connection; +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +public class TestTransaction { + + TransactionLegacy txn; + Connection conn; + + @Before + public void setup() { + setup(TransactionLegacy.CLOUD_DB); + } + + public void setup(short db) { + txn = TransactionLegacy.open(db); + conn = Mockito.mock(Connection.class); + txn.setConnection(conn); + } + + @After + public void after() { + TransactionLegacy.currentTxn().close(); + } + + @Test + public void testCommit() throws Exception { + assertEquals(42L, Transaction.execute(new TransactionCallback() { + @Override + public Object doInTransaction(TransactionStatus status) { + return 42L; + } + })); + + verify(conn).setAutoCommit(false); + verify(conn, times(1)).commit(); + verify(conn, times(0)).rollback(); + verify(conn, times(1)).close(); + } + + @Test + public void testRollback() throws Exception { + try { + Transaction.execute(new TransactionCallback() { + @Override + public Object doInTransaction(TransactionStatus status) { + throw new RuntimeException("Panic!"); + } + }); + fail(); + } catch (RuntimeException e) { + assertEquals("Panic!", e.getMessage()); + } + + verify(conn).setAutoCommit(false); + verify(conn, times(0)).commit(); + verify(conn, times(1)).rollback(); + verify(conn, times(1)).close(); + } + + @Test + public void testRollbackWithException() throws Exception { + try { + Transaction.execute(new TransactionCallbackWithException() { + @Override + public Object doInTransaction(TransactionStatus status) throws FileNotFoundException { + assertEquals(TransactionLegacy.CLOUD_DB, TransactionLegacy.currentTxn().getDatabaseId().shortValue()); + + throw new FileNotFoundException("Panic!"); + } + }); + fail(); + } catch (FileNotFoundException e) { + assertEquals("Panic!", e.getMessage()); + } + + verify(conn).setAutoCommit(false); + verify(conn, times(0)).commit(); + verify(conn, times(1)).rollback(); + verify(conn, times(1)).close(); + } + + @Test + public void testWithExceptionNoReturn() throws Exception { + final AtomicInteger i = new AtomicInteger(0); + assertTrue(Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) throws FileNotFoundException { + i.incrementAndGet(); + } + })); + + assertEquals(1, i.get()); + verify(conn).setAutoCommit(false); + verify(conn, times(1)).commit(); + verify(conn, times(0)).rollback(); + verify(conn, times(1)).close(); + } + + @Test + public void testOtherdatabaseRollback() throws Exception { + after(); + setup(TransactionLegacy.AWSAPI_DB); + + try { + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + assertEquals(TransactionLegacy.AWSAPI_DB, TransactionLegacy.currentTxn().getDatabaseId().shortValue()); + + throw new RuntimeException("Panic!"); + } + }); + fail(); + } catch (RuntimeException e) { + assertEquals("Panic!", e.getMessage()); + } + + + verify(conn).setAutoCommit(false); + verify(conn, times(0)).commit(); + verify(conn, times(1)).rollback(); + verify(conn, times(1)).close(); + } + +} diff --git a/framework/db/test/com/cloud/utils/db/TransactionTest.java b/framework/db/test/com/cloud/utils/db/TransactionTest.java index 101a533f836..92b2f36a2fc 100644 --- a/framework/db/test/com/cloud/utils/db/TransactionTest.java +++ b/framework/db/test/com/cloud/utils/db/TransactionTest.java @@ -41,7 +41,7 @@ public class TransactionTest { Connection conn = null; PreparedStatement pstmt = null; try { - conn = Transaction.getStandaloneConnection(); + conn = TransactionLegacy.getStandaloneConnection(); pstmt = conn.prepareStatement("CREATE TABLE `cloud`.`test` (" + "`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT," + "`fld_int` int unsigned," @@ -75,27 +75,27 @@ public class TransactionTest { */ public void testUserManagedConnection() { DbTestDao testDao = ComponentContext.inject(DbTestDao.class); - Transaction txn = Transaction.open("SingleConnectionThread"); + TransactionLegacy txn = TransactionLegacy.open("SingleConnectionThread"); Connection conn = null; try { - conn = Transaction.getStandaloneConnectionWithException(); + conn = TransactionLegacy.getStandaloneConnectionWithException(); txn.transitToUserManagedConnection(conn); // try two SQLs to make sure that they are using the same connection // acquired above. testDao.create(1, 1, "Record 1"); - Connection checkConn = Transaction.currentTxn().getConnection(); + Connection checkConn = TransactionLegacy.currentTxn().getConnection(); if (checkConn != conn) { Assert.fail("A new db connection is acquired instead of using old one after create sql"); } testDao.update(2, 2, "Record 1"); - Connection checkConn2 = Transaction.currentTxn().getConnection(); + Connection checkConn2 = TransactionLegacy.currentTxn().getConnection(); if (checkConn2 != conn) { Assert.fail("A new db connection is acquired instead of using old one after update sql"); } } catch (SQLException e) { Assert.fail(e.getMessage()); } finally { - txn.transitToAutoManagedConnection(Transaction.CLOUD_DB); + txn.transitToAutoManagedConnection(TransactionLegacy.CLOUD_DB); txn.close(); if (conn != null) { @@ -117,28 +117,28 @@ public class TransactionTest { // acquire a db connection and keep it Connection conn = null; try { - conn = Transaction.getStandaloneConnectionWithException(); + conn = TransactionLegacy.getStandaloneConnectionWithException(); } catch (SQLException ex) { throw new CloudRuntimeException("Problem with getting db connection", ex); } // start heartbeat loop, make sure that each loop still use the same // connection - Transaction txn = null; + TransactionLegacy txn = null; for (int i = 0; i < 3; i++) { - txn = Transaction.open("HeartbeatSimulator"); + txn = TransactionLegacy.open("HeartbeatSimulator"); try { txn.transitToUserManagedConnection(conn); testDao.create(i, i, "Record " + i); - Connection checkConn = Transaction.currentTxn().getConnection(); + Connection checkConn = TransactionLegacy.currentTxn().getConnection(); if (checkConn != conn) { Assert.fail("A new db connection is acquired instead of using old one in loop " + i); } } catch (SQLException e) { Assert.fail(e.getMessage()); } finally { - txn.transitToAutoManagedConnection(Transaction.CLOUD_DB); + txn.transitToAutoManagedConnection(TransactionLegacy.CLOUD_DB); txn.close(); } } @@ -161,7 +161,7 @@ public class TransactionTest { Connection conn = null; PreparedStatement pstmt = null; try { - conn = Transaction.getStandaloneConnection(); + conn = TransactionLegacy.getStandaloneConnection(); pstmt = conn.prepareStatement("truncate table `cloud`.`test`"); pstmt.execute(); @@ -189,7 +189,7 @@ public class TransactionTest { Connection conn = null; PreparedStatement pstmt = null; try { - conn = Transaction.getStandaloneConnection(); + conn = TransactionLegacy.getStandaloneConnection(); pstmt = conn.prepareStatement("DROP TABLE IF EXISTS `cloud`.`test`"); pstmt.execute(); diff --git a/framework/db/test/db.properties b/framework/db/test/db.properties new file mode 100644 index 00000000000..cc1215ff35c --- /dev/null +++ b/framework/db/test/db.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# Just here to make the unit test not blow up \ No newline at end of file diff --git a/framework/ipc/resources/META-INF/cloudstack/core/spring-framework-ipc-core-context.xml b/framework/ipc/resources/META-INF/cloudstack/core/spring-framework-ipc-core-context.xml new file mode 100644 index 00000000000..effa23efded --- /dev/null +++ b/framework/ipc/resources/META-INF/cloudstack/core/spring-framework-ipc-core-context.xml @@ -0,0 +1,59 @@ + + + + + + + + org.apache.cloudstack.framework + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/framework/jobs/resources/META-INF/cloudstack/core/spring-framework-jobs-core-context.xml b/framework/jobs/resources/META-INF/cloudstack/core/spring-framework-jobs-core-context.xml new file mode 100644 index 00000000000..85cad0216c0 --- /dev/null +++ b/framework/jobs/resources/META-INF/cloudstack/core/spring-framework-jobs-core-context.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java index fb3845caa31..ed161e75d2c 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java @@ -32,7 +32,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; public class AsyncJobDaoImpl extends GenericDaoBase implements AsyncJobDao { private static final Logger s_logger = Logger.getLogger(AsyncJobDaoImpl.class.getName()); @@ -182,7 +182,7 @@ public class AsyncJobDaoImpl extends GenericDaoBase implements + ", job_result='" + jobResultMessage + "' where job_status=" + JobInfo.Status.IN_PROGRESS.ordinal() + " AND (job_executing_msid=? OR (job_executing_msid IS NULL AND job_init_msid=?))"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(sql); diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java index 20d8ba69fdc..d4ca0d76cb7 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java @@ -34,7 +34,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.db.UpdateBuilder; import com.cloud.utils.exception.CloudRuntimeException; @@ -157,7 +157,7 @@ public class AsyncJobJoinMapDaoImpl extends GenericDaoBase findJobsToWake(long joinedJobId) { // TODO: We should fix this. We shouldn't be crossing daos in a dao code. List standaloneList = new ArrayList(); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); String sql = "SELECT job_id FROM async_job_join_map WHERE join_job_id = ? AND job_id NOT IN (SELECT content_id FROM sync_queue_item)"; try { PreparedStatement pstmt = txn.prepareStatement(sql); @@ -231,7 +231,7 @@ public class AsyncJobJoinMapDaoImpl extends GenericDaoBase findJobsToWakeBetween(Date cutDate) { List standaloneList = new ArrayList(); - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { String sql = "SELECT job_id FROM async_job_join_map WHERE next_wakeup < ? AND expiration > ? AND job_id NOT IN (SELECT content_id FROM sync_queue_item)"; PreparedStatement pstmt = txn.prepareStatement(sql); @@ -260,7 +260,7 @@ public class AsyncJobJoinMapDaoImpl extends GenericDaoBase wakeupByJoinedJobCompletion(long joinedJobId) { // List standaloneList = new ArrayList(); // -// Transaction txn = Transaction.currentTxn(); +// TransactionLegacy txn = TransactionLegacy.currentTxn(); // PreparedStatement pstmt = null; // try { // txn.start(); diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/SyncQueueDaoImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/SyncQueueDaoImpl.java index f7d9d72dc0b..01efc4e91d3 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/SyncQueueDaoImpl.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/SyncQueueDaoImpl.java @@ -30,7 +30,7 @@ import com.cloud.utils.DateUtil; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; public class SyncQueueDaoImpl extends GenericDaoBase implements SyncQueueDao { private static final Logger s_logger = Logger.getLogger(SyncQueueDaoImpl.class.getName()); @@ -51,7 +51,7 @@ public class SyncQueueDaoImpl extends GenericDaoBase implemen String sql = "INSERT IGNORE INTO sync_queue(sync_objtype, sync_objid, created, last_updated)" + " values(?, ?, ?, ?)"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(sql); diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/SyncQueueItemDaoImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/SyncQueueItemDaoImpl.java index 0cd231f6b4b..2f04a7cc890 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/SyncQueueItemDaoImpl.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/SyncQueueItemDaoImpl.java @@ -37,7 +37,7 @@ 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; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @DB public class SyncQueueItemDaoImpl extends GenericDaoBase implements SyncQueueItemDao { @@ -83,7 +83,7 @@ public class SyncQueueItemDaoImpl extends GenericDaoBase " ORDER BY i.id " + " LIMIT 0, ?"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(sql); diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java index 93d50c11233..ffc7b3ae052 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java @@ -70,8 +70,11 @@ import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.ExceptionUtil; import com.cloud.utils.mgmt.JmxUtil; @@ -177,19 +180,22 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, @SuppressWarnings("unchecked") @Override @DB - public long submitAsyncJob(AsyncJob job, String syncObjType, long syncObjId) { - Transaction txt = Transaction.currentTxn(); + public long submitAsyncJob(final AsyncJob job, final String syncObjType, final long syncObjId) { try { @SuppressWarnings("rawtypes") - GenericDao dao = GenericDaoBase.getDao(job.getClass()); + final GenericDao dao = GenericDaoBase.getDao(job.getClass()); - txt.start(); - job.setInitMsid(getMsid()); - dao.persist(job); + return Transaction.execute(new TransactionCallback() { + @Override + public Long doInTransaction(TransactionStatus status) { + job.setInitMsid(getMsid()); + dao.persist(job); - syncAsyncJobExecution(job, syncObjType, syncObjId, 1); - txt.commit(); - return job.getId(); + syncAsyncJobExecution(job, syncObjType, syncObjId, 1); + + return job.getId(); + } + }); } catch (Exception e) { String errMsg = "Unable to schedule async job for command " + job.getCmd() + ", unexpected exception."; s_logger.warn(errMsg, e); @@ -199,123 +205,110 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, @Override @DB - public void completeAsyncJob(long jobId, Status jobStatus, int resultCode, String resultObject) { + public void completeAsyncJob(final long jobId, final Status jobStatus, final int resultCode, final String resultObject) { if (s_logger.isDebugEnabled()) { s_logger.debug("Complete async job-" + jobId + ", jobStatus: " + jobStatus + ", resultCode: " + resultCode + ", result: " + resultObject); } - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - AsyncJobVO job = _jobDao.findById(jobId); - if (job == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("job-" + jobId + " no longer exists, we just log completion info here. " + jobStatus + ", resultCode: " + resultCode + ", result: " + - resultObject); - } - - txn.rollback(); - return; + final AsyncJobVO job = _jobDao.findById(jobId); + if (job == null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("job-" + jobId + " no longer exists, we just log completion info here. " + jobStatus + ", resultCode: " + resultCode + ", result: " + + resultObject); } - if (job.getStatus() != JobInfo.Status.IN_PROGRESS) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("job-" + jobId + " is already completed."); - } - - txn.rollback(); - return; - } - - job.setCompleteMsid(getMsid()); - job.setStatus(jobStatus); - job.setResultCode(resultCode); - - // reset attached object - job.setInstanceType(null); - job.setInstanceId(null); - - if (resultObject != null) { - job.setResult(resultObject); - } - - job.setLastUpdated(DateUtil.currentGMTTime()); - _jobDao.update(jobId, job); - - List wakeupList = wakeupByJoinedJobCompletion(jobId); - _joinMapDao.disjoinAllJobs(jobId); - - txn.commit(); - - for (Long id : wakeupList) { - // TODO, we assume that all jobs in this category is API job only - AsyncJobVO jobToWakeup = _jobDao.findById(id); - if (jobToWakeup != null && (jobToWakeup.getPendingSignals() & AsyncJob.Constants.SIGNAL_MASK_WAKEUP) != 0) - scheduleExecution(jobToWakeup, false); - } - - _messageBus.publish(null, AsyncJob.Topics.JOB_STATE, PublishScope.GLOBAL, jobId); - } catch (Exception e) { - s_logger.error("Unexpected exception while completing async job-" + jobId, e); - txn.rollback(); + return; } + + if (job.getStatus() != JobInfo.Status.IN_PROGRESS) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("job-" + jobId + " is already completed."); + } + + return; + } + + List wakeupList = Transaction.execute(new TransactionCallback>() { + @Override + public List doInTransaction(TransactionStatus status) { + job.setCompleteMsid(getMsid()); + job.setStatus(jobStatus); + job.setResultCode(resultCode); + + // reset attached object + job.setInstanceType(null); + job.setInstanceId(null); + + if (resultObject != null) { + job.setResult(resultObject); + } + + job.setLastUpdated(DateUtil.currentGMTTime()); + _jobDao.update(jobId, job); + + List wakeupList = wakeupByJoinedJobCompletion(jobId); + _joinMapDao.disjoinAllJobs(jobId); + + return wakeupList; + } + }); + + for (Long id : wakeupList) { + // TODO, we assume that all jobs in this category is API job only + AsyncJobVO jobToWakeup = _jobDao.findById(id); + if (jobToWakeup != null && (jobToWakeup.getPendingSignals() & AsyncJob.Constants.SIGNAL_MASK_WAKEUP) != 0) + scheduleExecution(jobToWakeup, false); + } + + _messageBus.publish(null, AsyncJob.Topics.JOB_STATE, PublishScope.GLOBAL, jobId); } @Override @DB - public void updateAsyncJobStatus(long jobId, int processStatus, String resultObject) { + public void updateAsyncJobStatus(final long jobId, final int processStatus, final String resultObject) { if (s_logger.isDebugEnabled()) { s_logger.debug("Update async-job progress, job-" + jobId + ", processStatus: " + processStatus + ", result: " + resultObject); } - Transaction txt = Transaction.currentTxn(); - try { - txt.start(); - AsyncJobVO job = _jobDao.findById(jobId); - if (job == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("job-" + jobId + " no longer exists, we just log progress info here. progress status: " + processStatus); - } - - txt.rollback(); - return; + final AsyncJobVO job = _jobDao.findById(jobId); + if (job == null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("job-" + jobId + " no longer exists, we just log progress info here. progress status: " + processStatus); } - job.setProcessStatus(processStatus); - if (resultObject != null) { - job.setResult(resultObject); - } - job.setLastUpdated(DateUtil.currentGMTTime()); - _jobDao.update(jobId, job); - txt.commit(); - } catch (Exception e) { - s_logger.error("Unexpected exception while updating async job-" + jobId + " status: ", e); - txt.rollback(); + return; } + + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + job.setProcessStatus(processStatus); + if (resultObject != null) { + job.setResult(resultObject); + } + job.setLastUpdated(DateUtil.currentGMTTime()); + _jobDao.update(jobId, job); + } + }); } @Override @DB - public void updateAsyncJobAttachment(long jobId, String instanceType, Long instanceId) { + public void updateAsyncJobAttachment(final long jobId, final String instanceType, final Long instanceId) { if (s_logger.isDebugEnabled()) { s_logger.debug("Update async-job attachment, job-" + jobId + ", instanceType: " + instanceType + ", instanceId: " + instanceId); } - Transaction txt = Transaction.currentTxn(); - try { - txt.start(); - - AsyncJobVO job = _jobDao.createForUpdate(); - job.setInstanceType(instanceType); - job.setInstanceId(instanceId); - job.setLastUpdated(DateUtil.currentGMTTime()); - _jobDao.update(jobId, job); - - txt.commit(); - } catch (Exception e) { - s_logger.error("Unexpected exception while updating async job-" + jobId + " attachment: ", e); - txt.rollback(); - } + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + AsyncJobVO job = _jobDao.createForUpdate(); + job.setInstanceType(instanceType); + job.setInstanceId(instanceId); + job.setLastUpdated(DateUtil.currentGMTTime()); + _jobDao.update(jobId, job); + } + }); } @Override @@ -493,15 +486,12 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, return new ManagedContextRunnable() { @Override protected void runInContext() { - Transaction txn = null; long runNumber = getJobRunNumber(); try { // // setup execution environment // - txn = Transaction.open(Transaction.CLOUD_DB); - try { JmxUtil.registerMBean("AsyncJobManager", "Active Job " + job.getId(), new AsyncJobMBeanImpl(job)); } catch (Exception e) { @@ -564,9 +554,6 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, s_logger.trace("Unable to unregister job " + job.getId() + " to JMX monitoring due to exception " + ExceptionUtil.toString(e)); } - if (txn != null) - txn.close(); - // // clean execution environment // @@ -690,7 +677,6 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, return new ManagedContextRunnable() { @Override protected void runInContext() { - Transaction txn = Transaction.open("AsyncJobManagerImpl.getHeartbeatTask"); try { List l = _queueMgr.dequeueFromAny(getMsid(), MAX_ONETIME_SCHEDULE_SIZE); if (l != null && l.size() > 0) { @@ -711,12 +697,6 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, } } catch (Throwable e) { s_logger.error("Unexpected exception when trying to execute queue item, ", e); - } finally { - try { - txn.close(); - } catch (Throwable e) { - s_logger.error("Unexpected exception", e); - } } } }; @@ -785,13 +765,15 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, } @DB - protected void expungeAsyncJob(AsyncJobVO job) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - _jobDao.expunge(job.getId()); - //purge corresponding sync queue item - _queueMgr.purgeAsyncJobQueueItemId(job.getId()); - txn.commit(); + protected void expungeAsyncJob(final AsyncJobVO job) { + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + _jobDao.expunge(job.getId()); + //purge corresponding sync queue item + _queueMgr.purgeAsyncJobQueueItemId(job.getId()); + } + }); } private long getMsid() { @@ -825,58 +807,60 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, Collections.sort(result); Long[] ids = result.toArray(new Long[result.size()]); - SearchCriteria jobsSC = JobIdsSearch.create("ids", ids); - SearchCriteria queueItemsSC = QueueJobIdsSearch.create("contentIds", ids); + final SearchCriteria jobsSC = JobIdsSearch.create("ids", ids); + final SearchCriteria queueItemsSC = QueueJobIdsSearch.create("contentIds", ids); - Transaction txn = Transaction.currentTxn(); - txn.start(); - AsyncJobVO job = _jobDao.createForUpdate(); - job.setPendingSignals(AsyncJob.Constants.SIGNAL_MASK_WAKEUP); - _jobDao.update(job, jobsSC); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + AsyncJobVO job = _jobDao.createForUpdate(); + job.setPendingSignals(AsyncJob.Constants.SIGNAL_MASK_WAKEUP); + _jobDao.update(job, jobsSC); - SyncQueueItemVO item = _queueItemDao.createForUpdate(); - item.setLastProcessNumber(null); - item.setLastProcessMsid(null); - _queueItemDao.update(item, queueItemsSC); - txn.commit(); + SyncQueueItemVO item = _queueItemDao.createForUpdate(); + item.setLastProcessNumber(null); + item.setLastProcessMsid(null); + _queueItemDao.update(item, queueItemsSC); + } + }); } return _joinMapDao.findJobsToWake(joinedJobId); } @DB protected List wakeupScan() { - Date cutDate = DateUtil.currentGMTTime(); - Transaction txn = Transaction.currentTxn(); + final Date cutDate = DateUtil.currentGMTTime(); SearchCriteria sc = JoinJobTimeSearch.create(); sc.setParameters("beginTime", cutDate); sc.setParameters("endTime", cutDate); - List result = _joinMapDao.customSearch(sc, null); + final List result = _joinMapDao.customSearch(sc, null); - txn.start(); - if (result.size() > 0) { - Collections.sort(result); - Long[] ids = result.toArray(new Long[result.size()]); + return Transaction.execute(new TransactionCallback>() { + @Override + public List doInTransaction(TransactionStatus status) { + if (result.size() > 0) { + Collections.sort(result); + Long[] ids = result.toArray(new Long[result.size()]); - AsyncJobVO job = _jobDao.createForUpdate(); - job.setPendingSignals(AsyncJob.Constants.SIGNAL_MASK_WAKEUP); + AsyncJobVO job = _jobDao.createForUpdate(); + job.setPendingSignals(AsyncJob.Constants.SIGNAL_MASK_WAKEUP); - SearchCriteria sc2 = JobIdsSearch.create("ids", ids); - SearchCriteria queueItemsSC = QueueJobIdsSearch.create("contentIds", ids); + SearchCriteria sc2 = JobIdsSearch.create("ids", ids); + SearchCriteria queueItemsSC = QueueJobIdsSearch.create("contentIds", ids); - _jobDao.update(job, sc2); + _jobDao.update(job, sc2); - SyncQueueItemVO item = _queueItemDao.createForUpdate(); - item.setLastProcessNumber(null); - item.setLastProcessMsid(null); - _queueItemDao.update(item, queueItemsSC); - } + SyncQueueItemVO item = _queueItemDao.createForUpdate(); + item.setLastProcessNumber(null); + item.setLastProcessMsid(null); + _queueItemDao.update(item, queueItemsSC); + } - List wakupIds = _joinMapDao.findJobsToWakeBetween(cutDate); - txn.commit(); - - return wakupIds; + return _joinMapDao.findJobsToWakeBetween(cutDate); + } + }); } @Override @@ -933,18 +917,18 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, @Override public void onManagementNodeLeft(List nodeList, long selfNodeId) { - for (ManagementServerHost msHost : nodeList) { - Transaction txn = Transaction.open(Transaction.CLOUD_DB); + for (final ManagementServerHost msHost : nodeList) { try { - txn.start(); - List items = _queueMgr.getActiveQueueItems(msHost.getId(), true); - cleanupPendingJobs(items); - _jobDao.resetJobProcess(msHost.getId(), ApiErrorCode.INTERNAL_ERROR.getHttpCode(), "job cancelled because of management server restart"); - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + List items = _queueMgr.getActiveQueueItems(msHost.getId(), true); + cleanupPendingJobs(items); + _jobDao.resetJobProcess(msHost.getId(), ApiErrorCode.INTERNAL_ERROR.getHttpCode(), "job cancelled because of management server restart"); + } + }); } catch (Throwable e) { s_logger.warn("Unexpected exception ", e); - } finally { - txn.close(); } } } diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/SyncQueueManagerImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/SyncQueueManagerImpl.java index b9b5d6bdabd..7fb02454c88 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/SyncQueueManagerImpl.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/SyncQueueManagerImpl.java @@ -21,8 +21,8 @@ import java.util.Date; import java.util.List; import javax.inject.Inject; -import org.apache.log4j.Logger; +import org.apache.log4j.Logger; import org.apache.cloudstack.framework.jobs.dao.SyncQueueDao; import org.apache.cloudstack.framework.jobs.dao.SyncQueueItemDao; @@ -30,6 +30,9 @@ import com.cloud.utils.DateUtil; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; public class SyncQueueManagerImpl extends ManagerBase implements SyncQueueManager { @@ -40,84 +43,83 @@ public class SyncQueueManagerImpl extends ManagerBase implements SyncQueueManage @Override @DB - public SyncQueueVO queue(String syncObjType, long syncObjId, String itemType, long itemId, long queueSizeLimit) { - Transaction txn = Transaction.currentTxn(); + public SyncQueueVO queue(final String syncObjType, final long syncObjId, final String itemType, final long itemId, final long queueSizeLimit) { try { - txn.start(); + return Transaction.execute(new TransactionCallback() { + @Override + public SyncQueueVO doInTransaction(TransactionStatus status) { + _syncQueueDao.ensureQueue(syncObjType, syncObjId); + SyncQueueVO queueVO = _syncQueueDao.find(syncObjType, syncObjId); + if(queueVO == null) + throw new CloudRuntimeException("Unable to queue item into DB, DB is full?"); - _syncQueueDao.ensureQueue(syncObjType, syncObjId); - SyncQueueVO queueVO = _syncQueueDao.find(syncObjType, syncObjId); - if(queueVO == null) - throw new CloudRuntimeException("Unable to queue item into DB, DB is full?"); - - queueVO.setQueueSizeLimit(queueSizeLimit); - _syncQueueDao.update(queueVO.getId(), queueVO); - - Date dt = DateUtil.currentGMTTime(); - SyncQueueItemVO item = new SyncQueueItemVO(); - item.setQueueId(queueVO.getId()); - item.setContentType(itemType); - item.setContentId(itemId); - item.setCreated(dt); - - _syncQueueItemDao.persist(item); - txn.commit(); - - return queueVO; - } catch(Exception e) { - s_logger.error("Unexpected exception: ", e); - txn.rollback(); - } - return null; - } - - @Override - @DB - public SyncQueueItemVO dequeueFromOne(long queueId, Long msid) { - Transaction txt = Transaction.currentTxn(); - try { - txt.start(); - - SyncQueueVO queueVO = _syncQueueDao.lockRow(queueId, true); - if(queueVO == null) { - s_logger.error("Sync queue(id: " + queueId + ") does not exist"); - txt.commit(); - return null; - } - - if(queueReadyToProcess(queueVO)) { - SyncQueueItemVO itemVO = _syncQueueItemDao.getNextQueueItem(queueVO.getId()); - if(itemVO != null) { - Long processNumber = queueVO.getLastProcessNumber(); - if(processNumber == null) - processNumber = new Long(1); - else - processNumber = processNumber + 1; - Date dt = DateUtil.currentGMTTime(); - queueVO.setLastProcessNumber(processNumber); - queueVO.setLastUpdated(dt); - queueVO.setQueueSize(queueVO.getQueueSize() + 1); + queueVO.setQueueSizeLimit(queueSizeLimit); _syncQueueDao.update(queueVO.getId(), queueVO); - itemVO.setLastProcessMsid(msid); - itemVO.setLastProcessNumber(processNumber); - itemVO.setLastProcessTime(dt); - _syncQueueItemDao.update(itemVO.getId(), itemVO); + Date dt = DateUtil.currentGMTTime(); + SyncQueueItemVO item = new SyncQueueItemVO(); + item.setQueueId(queueVO.getId()); + item.setContentType(itemType); + item.setContentId(itemId); + item.setCreated(dt); - txt.commit(); - return itemVO; - } else { - if(s_logger.isDebugEnabled()) - s_logger.debug("Sync queue (" + queueId + ") is currently empty"); + _syncQueueItemDao.persist(item); + return queueVO; } - } else { - if(s_logger.isDebugEnabled()) - s_logger.debug("There is a pending process in sync queue(id: " + queueId + ")"); - } - txt.commit(); + }); + } catch(Exception e) { + s_logger.error("Unexpected exception: ", e); + } + return null; + } + + @Override + @DB + public SyncQueueItemVO dequeueFromOne(final long queueId, final Long msid) { + try { + return Transaction.execute(new TransactionCallback() { + @Override + public SyncQueueItemVO doInTransaction(TransactionStatus status) { + SyncQueueVO queueVO = _syncQueueDao.lockRow(queueId, true); + if(queueVO == null) { + s_logger.error("Sync queue(id: " + queueId + ") does not exist"); + return null; + } + + if(queueReadyToProcess(queueVO)) { + SyncQueueItemVO itemVO = _syncQueueItemDao.getNextQueueItem(queueVO.getId()); + if(itemVO != null) { + Long processNumber = queueVO.getLastProcessNumber(); + if(processNumber == null) + processNumber = new Long(1); + else + processNumber = processNumber + 1; + Date dt = DateUtil.currentGMTTime(); + queueVO.setLastProcessNumber(processNumber); + queueVO.setLastUpdated(dt); + queueVO.setQueueSize(queueVO.getQueueSize() + 1); + _syncQueueDao.update(queueVO.getId(), queueVO); + + itemVO.setLastProcessMsid(msid); + itemVO.setLastProcessNumber(processNumber); + itemVO.setLastProcessTime(dt); + _syncQueueItemDao.update(itemVO.getId(), itemVO); + + return itemVO; + } else { + if(s_logger.isDebugEnabled()) + s_logger.debug("Sync queue (" + queueId + ") is currently empty"); + } + } else { + if(s_logger.isDebugEnabled()) + s_logger.debug("There is a pending process in sync queue(id: " + queueId + ")"); + } + + return null; + } + }); } catch(Exception e) { s_logger.error("Unexpected exception: ", e); - txt.rollback(); } return null; @@ -125,101 +127,104 @@ public class SyncQueueManagerImpl extends ManagerBase implements SyncQueueManage @Override @DB - public List dequeueFromAny(Long msid, int maxItems) { + public List dequeueFromAny(final Long msid, final int maxItems) { + + final List resultList = new ArrayList(); - List resultList = new ArrayList(); - Transaction txt = Transaction.currentTxn(); try { - txt.start(); - - List l = _syncQueueItemDao.getNextQueueItems(maxItems); - if(l != null && l.size() > 0) { - for(SyncQueueItemVO item : l) { - SyncQueueVO queueVO = _syncQueueDao.lockRow(item.getQueueId(), true); - SyncQueueItemVO itemVO = _syncQueueItemDao.lockRow(item.getId(), true); - if(queueReadyToProcess(queueVO) && itemVO.getLastProcessNumber() == null) { - Long processNumber = queueVO.getLastProcessNumber(); - if(processNumber == null) - processNumber = new Long(1); - else - processNumber = processNumber + 1; - - Date dt = DateUtil.currentGMTTime(); - queueVO.setLastProcessNumber(processNumber); - queueVO.setLastUpdated(dt); - queueVO.setQueueSize(queueVO.getQueueSize() + 1); - _syncQueueDao.update(queueVO.getId(), queueVO); - - itemVO.setLastProcessMsid(msid); - itemVO.setLastProcessNumber(processNumber); - itemVO.setLastProcessTime(dt); - _syncQueueItemDao.update(item.getId(), itemVO); - - resultList.add(item); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + List l = _syncQueueItemDao.getNextQueueItems(maxItems); + if(l != null && l.size() > 0) { + for(SyncQueueItemVO item : l) { + SyncQueueVO queueVO = _syncQueueDao.lockRow(item.getQueueId(), true); + SyncQueueItemVO itemVO = _syncQueueItemDao.lockRow(item.getId(), true); + if(queueReadyToProcess(queueVO) && itemVO.getLastProcessNumber() == null) { + Long processNumber = queueVO.getLastProcessNumber(); + if(processNumber == null) + processNumber = new Long(1); + else + processNumber = processNumber + 1; + + Date dt = DateUtil.currentGMTTime(); + queueVO.setLastProcessNumber(processNumber); + queueVO.setLastUpdated(dt); + queueVO.setQueueSize(queueVO.getQueueSize() + 1); + _syncQueueDao.update(queueVO.getId(), queueVO); + + itemVO.setLastProcessMsid(msid); + itemVO.setLastProcessNumber(processNumber); + itemVO.setLastProcessTime(dt); + _syncQueueItemDao.update(item.getId(), itemVO); + + resultList.add(item); + } + } } } - } - txt.commit(); + }); + return resultList; } catch(Exception e) { s_logger.error("Unexpected exception: ", e); - txt.rollback(); } + return null; } @Override @DB - public void purgeItem(long queueItemId) { - Transaction txt = Transaction.currentTxn(); + public void purgeItem(final long queueItemId) { try { - txt.start(); - - SyncQueueItemVO itemVO = _syncQueueItemDao.findById(queueItemId); - if(itemVO != null) { - SyncQueueVO queueVO = _syncQueueDao.lockRow(itemVO.getQueueId(), true); - - _syncQueueItemDao.expunge(itemVO.getId()); - - // if item is active, reset queue information - if (itemVO.getLastProcessMsid() != null) { - queueVO.setLastUpdated(DateUtil.currentGMTTime()); - // decrement the count - assert (queueVO.getQueueSize() > 0) : "Count reduce happens when it's already <= 0!"; - queueVO.setQueueSize(queueVO.getQueueSize() - 1); - _syncQueueDao.update(queueVO.getId(), queueVO); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + SyncQueueItemVO itemVO = _syncQueueItemDao.findById(queueItemId); + if(itemVO != null) { + SyncQueueVO queueVO = _syncQueueDao.lockRow(itemVO.getQueueId(), true); + + _syncQueueItemDao.expunge(itemVO.getId()); + + // if item is active, reset queue information + if (itemVO.getLastProcessMsid() != null) { + queueVO.setLastUpdated(DateUtil.currentGMTTime()); + // decrement the count + assert (queueVO.getQueueSize() > 0) : "Count reduce happens when it's already <= 0!"; + queueVO.setQueueSize(queueVO.getQueueSize() - 1); + _syncQueueDao.update(queueVO.getId(), queueVO); + } + } } - } - txt.commit(); + }); } catch(Exception e) { s_logger.error("Unexpected exception: ", e); - txt.rollback(); } } @Override @DB - public void returnItem(long queueItemId) { - Transaction txt = Transaction.currentTxn(); + public void returnItem(final long queueItemId) { try { - txt.start(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + SyncQueueItemVO itemVO = _syncQueueItemDao.findById(queueItemId); + if(itemVO != null) { + SyncQueueVO queueVO = _syncQueueDao.lockRow(itemVO.getQueueId(), true); - SyncQueueItemVO itemVO = _syncQueueItemDao.findById(queueItemId); - if(itemVO != null) { - SyncQueueVO queueVO = _syncQueueDao.lockRow(itemVO.getQueueId(), true); + itemVO.setLastProcessMsid(null); + itemVO.setLastProcessNumber(null); + itemVO.setLastProcessTime(null); + _syncQueueItemDao.update(queueItemId, itemVO); - itemVO.setLastProcessMsid(null); - itemVO.setLastProcessNumber(null); - itemVO.setLastProcessTime(null); - _syncQueueItemDao.update(queueItemId, itemVO); - - queueVO.setLastUpdated(DateUtil.currentGMTTime()); - _syncQueueDao.update(queueVO.getId(), queueVO); - } - txt.commit(); + queueVO.setLastUpdated(DateUtil.currentGMTTime()); + _syncQueueDao.update(queueVO.getId(), queueVO); + } + } + }); } catch(Exception e) { s_logger.error("Unexpected exception: ", e); - txt.rollback(); } } diff --git a/framework/pom.xml b/framework/pom.xml index 4ea2df14cf2..14e3368d4ba 100644 --- a/framework/pom.xml +++ b/framework/pom.xml @@ -38,5 +38,7 @@ db config managed-context + spring/lifecycle + spring/module diff --git a/framework/spring/lifecycle/pom.xml b/framework/spring/lifecycle/pom.xml new file mode 100644 index 00000000000..647101c69ca --- /dev/null +++ b/framework/spring/lifecycle/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + cloud-framework-spring-lifecycle + Apache CloudStack Framework - Spring Life Cycle + + org.apache.cloudstack + cloud-maven-standard + 4.3.0-SNAPSHOT + ../../../maven-standard/pom.xml + + + + org.apache.cloudstack + cloud-utils + ${project.version} + + + org.apache.cloudstack + cloud-framework-config + ${project.version} + + + diff --git a/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/AbstractBeanCollector.java b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/AbstractBeanCollector.java new file mode 100644 index 00000000000..a3c0d600c71 --- /dev/null +++ b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/AbstractBeanCollector.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.lifecycle; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; + +/** + * This class provides a method to do basically the same as @Inject of a type, but + * it will only find the types in the current context and not the parent. This class + * should only be used for very specific Spring bootstrap logic. In general @Inject + * is infinitely better. Basically you need a very good reason to use this. + * + */ +public abstract class AbstractBeanCollector extends AbstractSmartLifeCycle implements BeanPostProcessor { + + Class[] typeClasses = new Class[] {}; + Map, Set> beans = new HashMap, Set>(); + + @Override + public int getPhase() { + return 2000; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + for ( Class typeClass : typeClasses ) { + if ( typeClass.isAssignableFrom(bean.getClass()) ) { + doPostProcessBeforeInitialization(bean, beanName); + break; + } + } + + return bean; + } + + protected void doPostProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + } + + protected void doPostProcessAfterInitialization(Object bean, Class typeClass, String beanName) throws BeansException { + Set beansOfType = beans.get(typeClass); + + if ( beansOfType == null ) { + beansOfType = new HashSet(); + beans.put(typeClass, beansOfType); + } + + beansOfType.add(bean); + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + for ( Class typeClass : typeClasses ) { + if ( typeClass.isAssignableFrom(bean.getClass()) ) { + doPostProcessAfterInitialization(bean, typeClass, beanName); + } + } + + return bean; + } + + protected Set getBeans(Class typeClass) { + @SuppressWarnings("unchecked") + Set result = (Set) beans.get(typeClass); + + if ( result == null ) + return Collections.emptySet(); + + return result; + } + + public Class getTypeClass() { + if ( typeClasses == null || typeClasses.length == 0 ) + return null; + + return typeClasses[0]; + } + + public void setTypeClass(Class typeClass) { + this.typeClasses = new Class[] { typeClass }; + } + + public Class[] getTypeClasses() { + return typeClasses; + } + + public void setTypeClasses(Class[] typeClasses) { + this.typeClasses = typeClasses; + } + +} diff --git a/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/AbstractSmartLifeCycle.java b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/AbstractSmartLifeCycle.java new file mode 100644 index 00000000000..071817b0b66 --- /dev/null +++ b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/AbstractSmartLifeCycle.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.lifecycle; + +import org.springframework.context.SmartLifecycle; + +public abstract class AbstractSmartLifeCycle implements SmartLifecycle { + + boolean running = false; + + @Override + public void start() { + running = true; + } + + @Override + public void stop() { + running = false; + } + + @Override + public boolean isRunning() { + return running; + } + + @Override + public boolean isAutoStartup() { + return true; + } + + @Override + public void stop(Runnable callback) { + stop(); + callback.run(); + } + +} diff --git a/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycle.java b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycle.java new file mode 100644 index 00000000000..1b7ea513061 --- /dev/null +++ b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycle.java @@ -0,0 +1,169 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.lifecycle; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import javax.management.InstanceAlreadyExistsException; +import javax.management.MBeanRegistrationException; +import javax.management.MalformedObjectNameException; +import javax.management.NotCompliantMBeanException; +import javax.naming.ConfigurationException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.cloud.utils.component.ComponentLifecycle; +import com.cloud.utils.component.SystemIntegrityChecker; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.mgmt.JmxUtil; +import com.cloud.utils.mgmt.ManagementBean; + +public class CloudStackExtendedLifeCycle extends AbstractBeanCollector { + + private static final Logger log = LoggerFactory.getLogger(CloudStackExtendedLifeCycle.class); + + Map> sorted = new TreeMap>(); + + public CloudStackExtendedLifeCycle() { + super(); + setTypeClasses(new Class[] { + ComponentLifecycle.class, + SystemIntegrityChecker.class + }); + } + + @Override + public void start() { + sortBeans(); + checkIntegrity(); + configure(); + + super.start(); + } + + protected void checkIntegrity() { + for ( SystemIntegrityChecker checker : getBeans(SystemIntegrityChecker.class) ) { + log.info("Running system integrity checker {}", checker); + + checker.check(); + } + } + + public void startBeans() { + log.info("Starting CloudStack Components"); + + with(new WithComponentLifeCycle() { + @Override + public void with(ComponentLifecycle lifecycle) { + lifecycle.start(); + + if ( lifecycle instanceof ManagementBean ) { + ManagementBean mbean = (ManagementBean)lifecycle; + try { + JmxUtil.registerMBean(mbean); + } catch (MalformedObjectNameException e) { + log.warn("Unable to register MBean: " + mbean.getName(), e); + } catch (InstanceAlreadyExistsException e) { + log.warn("Unable to register MBean: " + mbean.getName(), e); + } catch (MBeanRegistrationException e) { + log.warn("Unable to register MBean: " + mbean.getName(), e); + } catch (NotCompliantMBeanException e) { + log.warn("Unable to register MBean: " + mbean.getName(), e); + } + log.info("Registered MBean: " + mbean.getName()); + } + } + }); + + log.info("Done Starting CloudStack Components"); + } + + public void stopBeans() { + with(new WithComponentLifeCycle() { + @Override + public void with(ComponentLifecycle lifecycle) { + lifecycle.stop(); + } + }); + } + + private void configure() { + log.info("Configuring CloudStack Components"); + + with(new WithComponentLifeCycle() { + @Override + public void with(ComponentLifecycle lifecycle) { + try { + lifecycle.configure(lifecycle.getName(), lifecycle.getConfigParams()); + } catch (ConfigurationException e) { + log.error("Failed to configure {}", lifecycle.getName(), e); + throw new CloudRuntimeException(e); + } + } + }); + + log.info("Done Configuring CloudStack Components"); + } + + private void sortBeans() { + for ( ComponentLifecycle lifecycle : getBeans(ComponentLifecycle.class) ) { + Set set = sorted.get(lifecycle.getRunLevel()); + + if ( set == null ) { + set = new HashSet(); + sorted.put(lifecycle.getRunLevel(), set); + } + + set.add(lifecycle); + } + } + + @Override + public void stop() { + with(new WithComponentLifeCycle() { + @Override + public void with(ComponentLifecycle lifecycle) { + lifecycle.stop(); + } + }); + + super.stop(); + } + + protected void with(WithComponentLifeCycle with) { + for ( Set lifecycles : sorted.values() ) { + for ( ComponentLifecycle lifecycle : lifecycles ) { + with.with(lifecycle); + } + } + } + + @Override + public int getPhase() { + return 2000; + } + + private static interface WithComponentLifeCycle { + public void with(ComponentLifecycle lifecycle); + } +} diff --git a/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycleStart.java b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycleStart.java new file mode 100644 index 00000000000..33d4aea24e4 --- /dev/null +++ b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycleStart.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.lifecycle; + +public class CloudStackExtendedLifeCycleStart extends AbstractSmartLifeCycle implements Runnable { + + CloudStackExtendedLifeCycle lifeCycle; + + @Override + public void stop() { + lifeCycle.stopBeans(); + super.stop(); + } + + @Override + public int getPhase() { + return 3000; + } + + public CloudStackExtendedLifeCycle getLifeCycle() { + return lifeCycle; + } + + public void setLifeCycle(CloudStackExtendedLifeCycle lifeCycle) { + this.lifeCycle = lifeCycle; + } + + @Override + public void run() { + lifeCycle.startBeans(); + } + +} diff --git a/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackLog4jSetup.java b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackLog4jSetup.java new file mode 100644 index 00000000000..163703d0447 --- /dev/null +++ b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackLog4jSetup.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.lifecycle; + +import org.springframework.context.SmartLifecycle; + +import com.cloud.utils.LogUtils; + +public class CloudStackLog4jSetup implements SmartLifecycle { + + @Override + public void start() { + LogUtils.initLog4j("log4j-cloud.xml"); + } + + @Override + public void stop() { + } + + @Override + public boolean isRunning() { + return false; + } + + @Override + public int getPhase() { + return 0; + } + + @Override + public boolean isAutoStartup() { + return true; + } + + @Override + public void stop(Runnable callback) { + callback.run(); + } + +} \ No newline at end of file diff --git a/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/ConfigDepotLifeCycle.java b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/ConfigDepotLifeCycle.java new file mode 100644 index 00000000000..b380028964e --- /dev/null +++ b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/ConfigDepotLifeCycle.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.lifecycle; + +import javax.inject.Inject; + +import org.apache.cloudstack.framework.config.ConfigDepotAdmin; +import org.apache.cloudstack.framework.config.Configurable; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; + +public class ConfigDepotLifeCycle implements BeanPostProcessor { + + @Inject + ConfigDepotAdmin configDepotAdmin; + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + if ( bean instanceof Configurable ) { + configDepotAdmin.populateConfiguration((Configurable)bean); + } + + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + return bean; + } + +} diff --git a/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/registry/DumpRegistry.java b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/registry/DumpRegistry.java new file mode 100644 index 00000000000..5614a32aee5 --- /dev/null +++ b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/registry/DumpRegistry.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.lifecycle.registry; + +import java.util.List; + +import com.cloud.utils.component.ComponentLifecycleBase; +import com.cloud.utils.component.Named; +import com.cloud.utils.component.Registry; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DumpRegistry extends ComponentLifecycleBase { + + private static final Logger log = LoggerFactory.getLogger(DumpRegistry.class); + + List> registries; + + public List> getRegistries() { + return registries; + } + + @Inject + public void setRegistries(List> registries) { + this.registries = registries; + } + + @Override + public boolean start() { + for ( Registry registry : registries ) { + StringBuilder buffer = new StringBuilder(); + + for ( Object o : registry.getRegistered() ) { + if ( buffer.length() > 0 ) + buffer.append(", "); + + buffer.append(getName(o)); + } + + log.info("Registry [{}] contains [{}]", registry.getName(), buffer); + } + + return super.start(); + } + + protected String getName(Object o) { + String name = null; + if (o instanceof Named) { + name = ((Named) o).getName(); + } + + if (name == null) { + name = o.getClass().getSimpleName(); + } + + return name; + } +} diff --git a/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/registry/ExtensionRegistry.java b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/registry/ExtensionRegistry.java new file mode 100644 index 00000000000..2bd362eb8e3 --- /dev/null +++ b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/registry/ExtensionRegistry.java @@ -0,0 +1,245 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.lifecycle.registry; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; + +import javax.annotation.PostConstruct; + +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.BeanNameAware; + +import com.cloud.utils.component.Named; +import com.cloud.utils.component.Registry; + +public class ExtensionRegistry implements Registry, Configurable, BeanNameAware { + + private static final Logger log = LoggerFactory.getLogger(ExtensionRegistry.class); + + String name; + String beanName; + + String orderConfigKey; + String orderConfigDefault; + ConfigKey orderConfigKeyObj; + + String excludeKey; + String excludeDefault; + ConfigKey excludeKeyObj; + + String configComponentName; + List preRegistered; + List registered = new CopyOnWriteArrayList(); + List readOnly = Collections.unmodifiableList(registered); + + @Override + public boolean register(Object item) { + if ( registered.contains(item) ) + return false; + + String[] order = new String[] {}; + Set exclude = new HashSet(); + + if ( orderConfigKeyObj != null ) { + Object value = orderConfigKeyObj.value(); + if ( value != null && value.toString().trim().length() > 0 ) { + order = value.toString().trim().split("\\s*,\\s*"); + } + } + + if ( excludeKeyObj != null ) { + Object value = excludeKeyObj.value(); + if ( value != null && value.toString().trim().length() > 0 ) { + for ( String e : value.toString().trim().split("\\s*,\\s*") ) { + exclude.add(e); + } + } + } + + String name = getName(item); + + if ( name != null && exclude.size() > 0 && exclude.contains(name) ) { + return false; + } + + if ( name == null && order.length > 0 ) { + throw new RuntimeException("getName() is null for [" + item + "]"); + } + + int i = 0; + for ( String orderTest : order ) { + if ( orderTest.equals(name) ) { + registered.add(i, item); + i = -1; + break; + } + + if ( registered.size() <= i ) { + break; + } + + if ( getName(registered.get(i)).equals(orderTest) ) { + i++; + } + } + + if ( i != -1 ) { + registered.add(item); + } + + log.debug("Registering extension [{}] in [{}]", name, this.name); + + return true; + } + + protected String getName(Object object) { + if ( object instanceof Named ) { + String name = ((Named)object).getName(); + if ( name != null ) + return name; + } + + return object == null ? null : object.getClass().getSimpleName(); + } + + @Override + public void unregister(Object type) { + registered.remove(type); + } + + @Override + public List getRegistered() { + return readOnly; + } + + @Override + public String getConfigComponentName() { + return configComponentName == null ? this.getClass().getSimpleName() : configComponentName; + } + + @Override + public ConfigKey[] getConfigKeys() { + List> result = new ArrayList>(); + + if ( orderConfigKey != null && orderConfigKeyObj == null ) { + orderConfigKeyObj = new ConfigKey("Advanced", String.class, orderConfigKey, orderConfigDefault, + "The order of precedence for the extensions", false); + } + + if ( orderConfigKeyObj != null ) + result.add(orderConfigKeyObj); + + if ( excludeKey != null && excludeKeyObj == null ) { + excludeKeyObj = new ConfigKey("Advanced", String.class, excludeKey, excludeDefault, + "Extensions to exclude from being registered", false); + } + + if ( excludeKeyObj != null ) { + result.add(excludeKeyObj); + } + + return result.toArray(new ConfigKey[result.size()]); + } + + @PostConstruct + public void init() { + if ( name == null ) { + for ( String part : beanName.replaceAll("([A-Z])", " $1").split("\\s+") ) { + part = StringUtils.capitalize(part.toLowerCase());; + + name = name == null ? part : name + " " + part; + } + } + + if ( preRegistered != null ) { + for ( Object o : preRegistered ) { + register(o); + } + } + } + + + public String getOrderConfigKey() { + return orderConfigKey; + } + + public void setOrderConfigKey(String orderConfigKey) { + this.orderConfigKey = orderConfigKey; + } + + public void setConfigComponentName(String configComponentName) { + this.configComponentName = configComponentName; + } + + public String getOrderConfigDefault() { + return orderConfigDefault; + } + + public void setOrderConfigDefault(String orderConfigDefault) { + this.orderConfigDefault = orderConfigDefault; + } + + public String getExcludeKey() { + return excludeKey; + } + + public void setExcludeKey(String excludeKey) { + this.excludeKey = excludeKey; + } + + public String getExcludeDefault() { + return excludeDefault; + } + + public void setExcludeDefault(String excludeDefault) { + this.excludeDefault = excludeDefault; + } + + @Override + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public void setBeanName(String name) { + this.beanName = name; + } + + public List getPreRegistered() { + return preRegistered; + } + + public void setPreRegistered(List preRegistered) { + this.preRegistered = preRegistered; + } + +} diff --git a/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/registry/PluggableServiceLifecycle.java b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/registry/PluggableServiceLifecycle.java new file mode 100644 index 00000000000..3eeeed83c7b --- /dev/null +++ b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/registry/PluggableServiceLifecycle.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.lifecycle.registry; + +import com.cloud.utils.component.ComponentContext; +import com.cloud.utils.component.PluggableService; + +public class PluggableServiceLifecycle extends RegistryLifecycle { + + @Override + public void start() { + super.start(); + + for (Object obj : beans) { + if (obj instanceof PluggableService) { + for (Class cmd : ((PluggableService) obj).getCommands()) { + ComponentContext.addDelegateContext(cmd, applicationContext); + } + } + } + } + + @Override + public void stop() { + for (Object obj : beans) { + if (obj instanceof PluggableService) { + for (Class cmd : ((PluggableService) obj).getCommands()) { + ComponentContext.removeDelegateContext(cmd); + } + } + } + + super.stop(); + } + + +} diff --git a/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/registry/RegistryLifecycle.java b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/registry/RegistryLifecycle.java new file mode 100644 index 00000000000..bd7a0334a6f --- /dev/null +++ b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/registry/RegistryLifecycle.java @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.lifecycle.registry; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.SmartLifecycle; + +import com.cloud.utils.component.Registry; + +public class RegistryLifecycle implements BeanPostProcessor, SmartLifecycle, ApplicationContextAware { + + private static final Logger log = LoggerFactory.getLogger(RegistryLifecycle.class); + + Registry registry; + + /* The bean name works around circular dependency issues in Spring. This shouldn't be + * needed if your beans are already nicely organized. If they look like spaghetti, then you + * can use this. + */ + String registryBeanName; + Set beans = new HashSet(); + Class typeClass; + ApplicationContext applicationContext; + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + if ( typeClass.isAssignableFrom(bean.getClass()) ) + beans.add(bean); + + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + return bean; + } + + @Override + public void start() { + Iterator iter = beans.iterator(); + Registry registry = lookupRegistry(); + + while ( iter.hasNext() ) { + Object next = iter.next(); + if ( registry.register(next) ) { + log.debug("Registered {}", next); + } else { + iter.remove(); + } + } + } + + @Override + public void stop() { + Registry registry = lookupRegistry(); + + for ( Object bean : beans ) { + registry.unregister(bean); + } + + beans.clear(); + } + + @Override + public boolean isRunning() { + return false; + } + + @Override + public int getPhase() { + return 2000; + } + + @Override + public boolean isAutoStartup() { + return true; + } + + @Override + public void stop(Runnable callback) { + stop(); + callback.run(); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + @SuppressWarnings("unchecked") + protected Registry lookupRegistry() { + return registry == null ? applicationContext.getBean(registryBeanName, Registry.class) : registry; + } + + public Registry getRegistry() { + return registry; + } + + public void setRegistry(Registry registry) { + this.registry = registry; + } + + public Class getTypeClass() { + return typeClass; + } + + public void setTypeClass(Class typeClass) { + this.typeClass = typeClass; + } + + public String getRegistryBeanName() { + return registryBeanName; + } + + public void setRegistryBeanName(String registryBeanName) { + this.registryBeanName = registryBeanName; + } + +} diff --git a/framework/spring/module/pom.xml b/framework/spring/module/pom.xml new file mode 100644 index 00000000000..b9d95a8447f --- /dev/null +++ b/framework/spring/module/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + cloud-framework-spring-module + + org.apache.cloudstack + cloud-maven-standard + 4.3.0-SNAPSHOT + ../../../maven-standard/pom.xml + + + + org.apache.cloudstack + cloud-utils + ${project.version} + + + commons-io + commons-io + + + org.springframework + spring-web + + + javax.servlet + servlet-api + provided + true + + + diff --git a/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/context/ResourceApplicationContext.java b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/context/ResourceApplicationContext.java new file mode 100644 index 00000000000..60d0262ab36 --- /dev/null +++ b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/context/ResourceApplicationContext.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.module.context; + +import org.springframework.context.support.AbstractXmlApplicationContext; +import org.springframework.core.io.Resource; + +public class ResourceApplicationContext extends AbstractXmlApplicationContext { + + Resource[] configResources; + String applicationName = ""; + + public ResourceApplicationContext() { + } + + public ResourceApplicationContext(Resource... configResources) { + super(); + this.configResources = configResources; + } + + @Override + protected Resource[] getConfigResources() { + return configResources; + } + + public void setConfigResources(Resource[] configResources) { + this.configResources = configResources; + } + + @Override + public String getApplicationName() { + return applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + +} diff --git a/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/factory/CloudStackSpringContext.java b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/factory/CloudStackSpringContext.java new file mode 100644 index 00000000000..e624a5b04d4 --- /dev/null +++ b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/factory/CloudStackSpringContext.java @@ -0,0 +1,137 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.module.factory; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.cloudstack.spring.module.locator.ModuleDefinitionLocator; +import org.apache.cloudstack.spring.module.locator.impl.ClasspathModuleDefinitionLocator; +import org.apache.cloudstack.spring.module.model.ModuleDefinition; +import org.apache.cloudstack.spring.module.model.ModuleDefinitionSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.io.Resource; + +public class CloudStackSpringContext { + + private static final Logger log = LoggerFactory.getLogger(CloudStackSpringContext.class); + + public static final String CLOUDSTACK_CONTEXT = "META-INF/cloudstack"; + public static final String CLOUDSTACK_BASE = "bootstrap"; + + ModuleBasedContextFactory factory = new ModuleBasedContextFactory(); + ModuleDefinitionLocator loader = new ClasspathModuleDefinitionLocator(); + ModuleDefinitionSet moduleDefinitionSet; + String baseName; + String contextName; + + public CloudStackSpringContext(String context, String base) throws IOException { + this.baseName = base; + this.contextName = context; + + factory = new ModuleBasedContextFactory(); + loader = new ClasspathModuleDefinitionLocator(); + init(); + } + + public CloudStackSpringContext() throws IOException { + this(CLOUDSTACK_CONTEXT, CLOUDSTACK_BASE); + } + + public void init() throws IOException { + Collection defs = loader.locateModules(contextName); + + if ( defs.size() == 0 ) + throw new RuntimeException("No modules found to load for Spring"); + + moduleDefinitionSet = factory.loadModules(defs, baseName); + } + + public void registerShutdownHook() { + ApplicationContext base = moduleDefinitionSet.getApplicationContext(baseName); + + if ( base instanceof ConfigurableApplicationContext ) { + ((ConfigurableApplicationContext)base).registerShutdownHook(); + } + } + + public ModuleDefinition getModuleDefinitionForWeb(String name) { + ModuleDefinition def = moduleDefinitionSet.getModuleDefinition(name); + + if ( def != null ) { + return def; + } + + /* Grab farthest descendant that is deterministic */ + def = moduleDefinitionSet.getModuleDefinition(baseName); + + if ( def == null ) { + throw new RuntimeException("Failed to find base spring module to extend for web"); + } + + while ( def.getChildren().size() == 1 ) { + def = def.getChildren().iterator().next(); + } + + return def; + } + + public ApplicationContext getApplicationContextForWeb(String name) { + ModuleDefinition def = getModuleDefinitionForWeb(name); + + return moduleDefinitionSet.getApplicationContext(def.getName()); + } + + public String[] getConfigLocationsForWeb(String name, String[] configured) { + if ( configured == null ) + configured = new String[] {}; + + ModuleDefinition def = getModuleDefinitionForWeb(name); + + List inherited = new ArrayList(); + + while ( def != null ) { + inherited.addAll(def.getInheritableContextLocations()); + def = moduleDefinitionSet.getModuleDefinition(def.getParentName()); + } + + List urlList = new ArrayList(); + + for ( Resource r : inherited ) { + try { + String urlString = r.getURL().toExternalForm(); + urlList.add(urlString); + } catch (IOException e) { + log.error("Failed to create URL for {}", r.getDescription(), e); + } + } + + String[] result = new String[urlList.size() + configured.length]; + result = urlList.toArray(result); + + System.arraycopy(configured, 0, result, urlList.size(), configured.length); + + return result; + } +} diff --git a/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/factory/ModuleBasedContextFactory.java b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/factory/ModuleBasedContextFactory.java new file mode 100644 index 00000000000..3f89d3ab935 --- /dev/null +++ b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/factory/ModuleBasedContextFactory.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.module.factory; + +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.apache.cloudstack.spring.module.model.ModuleDefinition; +import org.apache.cloudstack.spring.module.model.ModuleDefinitionSet; +import org.apache.cloudstack.spring.module.model.impl.DefaultModuleDefinitionSet; + +public class ModuleBasedContextFactory { + + public ModuleDefinitionSet loadModules(Collection defs, String root) throws IOException { + + Map modules = wireUpModules(root, defs); + + DefaultModuleDefinitionSet moduleSet = new DefaultModuleDefinitionSet(modules, root); + moduleSet.load(); + + return moduleSet; + } + + protected Map wireUpModules(String root, Collection defs) throws IOException { + Map modules = new HashMap(); + + for ( ModuleDefinition def : defs ) { + modules.put(def.getName(), def); + } + + ModuleDefinition rootDef = null; + Map result = new HashMap(); + + for ( ModuleDefinition def : modules.values() ) { + if ( def.getName().equals(root) ) { + rootDef = def; + } + + if ( def.getParentName() != null ) { + ModuleDefinition parentDef = modules.get(def.getParentName()); + + if ( parentDef != null ) + parentDef.addChild(def); + } + } + + return traverse(rootDef, result); + } + + protected Map traverse(ModuleDefinition base, Map result) { + if ( base == null ) + return result; + + if ( result.containsKey(base.getName()) ) { + throw new RuntimeException("Circular dependency to [" + base.getName() + "] from current set " + + result.keySet()); + } + + result.put(base.getName(), base); + + for ( ModuleDefinition childDef : base.getChildren() ) + traverse(childDef, result); + + return result; + } +} diff --git a/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/locator/ModuleDefinitionLocator.java b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/locator/ModuleDefinitionLocator.java new file mode 100644 index 00000000000..6b14e0abfd7 --- /dev/null +++ b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/locator/ModuleDefinitionLocator.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.module.locator; + +import java.io.IOException; +import java.util.Collection; + +import org.apache.cloudstack.spring.module.model.ModuleDefinition; + +/** + * Responsible for locating the ModuleDefinition for a given context. The implementation + * of this class should take extra care to set the ClassLoader of the ModuleDefinition + * properly. + * + */ +public interface ModuleDefinitionLocator { + + Collection locateModules(String context) throws IOException; + +} diff --git a/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/locator/impl/ClasspathModuleDefinitionLocator.java b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/locator/impl/ClasspathModuleDefinitionLocator.java new file mode 100644 index 00000000000..c9deacc23e8 --- /dev/null +++ b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/locator/impl/ClasspathModuleDefinitionLocator.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.module.locator.impl; + +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.apache.cloudstack.spring.module.locator.ModuleDefinitionLocator; +import org.apache.cloudstack.spring.module.model.ModuleDefinition; +import org.apache.cloudstack.spring.module.model.impl.DefaultModuleDefinition; +import org.apache.cloudstack.spring.module.util.ModuleLocationUtils; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; + +public class ClasspathModuleDefinitionLocator implements ModuleDefinitionLocator { + + protected ResourcePatternResolver getResolver() { + return new PathMatchingResourcePatternResolver(); + } + + public Collection locateModules(String context) throws IOException { + ResourcePatternResolver resolver = getResolver(); + + Map allModules = discoverModules(context, resolver); + + return allModules.values(); + } + + protected Map discoverModules(String baseDir, ResourcePatternResolver resolver) throws IOException { + Map result = new HashMap(); + + for ( Resource r : resolver.getResources(ModuleLocationUtils.getModulesLocation(baseDir)) ) { + DefaultModuleDefinition def = new DefaultModuleDefinition(baseDir, r, resolver); + def.init(); + + if ( def.isValid() ) + result.put(def.getName(), def); + } + + return result; + } + +} diff --git a/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/model/ModuleDefinition.java b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/model/ModuleDefinition.java new file mode 100644 index 00000000000..b3c46474224 --- /dev/null +++ b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/model/ModuleDefinition.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.module.model; + +import java.util.Collection; +import java.util.List; + +import org.springframework.core.io.Resource; + +public interface ModuleDefinition { + + ClassLoader getClassLoader(); + + String getName(); + + String getParentName(); + + List getConfigLocations(); + + List getContextLocations(); + + List getInheritableContextLocations(); + + List getOverrideContextLocations(); + + boolean isValid(); + + Collection getChildren(); + + void addChild(ModuleDefinition childDef); + +} diff --git a/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/model/ModuleDefinitionSet.java b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/model/ModuleDefinitionSet.java new file mode 100644 index 00000000000..635a7a193df --- /dev/null +++ b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/model/ModuleDefinitionSet.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.module.model; + +import org.springframework.context.ApplicationContext; +import org.springframework.core.io.Resource; + +public interface ModuleDefinitionSet { + + ModuleDefinition getModuleDefinition(String name); + + ApplicationContext getApplicationContext(String name); + + Resource[] getConfigResources(String name); + +} diff --git a/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/model/impl/DefaultModuleDefinition.java b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/model/impl/DefaultModuleDefinition.java new file mode 100644 index 00000000000..6c5180874b8 --- /dev/null +++ b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/model/impl/DefaultModuleDefinition.java @@ -0,0 +1,167 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.module.model.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.TreeMap; + +import org.apache.cloudstack.spring.module.model.ModuleDefinition; +import org.apache.cloudstack.spring.module.util.ModuleLocationUtils; +import org.apache.commons.io.IOUtils; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.util.StringUtils; + +public class DefaultModuleDefinition implements ModuleDefinition { + + public static final String NAME = "name"; + public static final String PARENT = "parent"; + + String name; + String baseDir; + String parent; + Resource moduleProperties; + ResourcePatternResolver resolver; + boolean valid; + + List configLocations; + List contextLocations; + List inheritableContextLocations; + List overrideContextLocations; + Map children = new TreeMap(); + + public DefaultModuleDefinition(String baseDir, Resource moduleProperties, ResourcePatternResolver resolver) { + this.baseDir = baseDir; + this.resolver = resolver; + this.moduleProperties = moduleProperties; + } + + public void init() throws IOException { + + if ( ! moduleProperties.exists() ) { + return; + } + + resolveNameAndParent(); + + contextLocations = Arrays.asList(resolver.getResources(ModuleLocationUtils.getContextLocation(baseDir, name))); + configLocations = Arrays.asList(resolver.getResources(ModuleLocationUtils.getDefaultsLocation(baseDir, name))); + inheritableContextLocations = Arrays.asList(resolver.getResources(ModuleLocationUtils.getInheritableContextLocation(baseDir, name))); + overrideContextLocations = Arrays.asList(resolver.getResources(ModuleLocationUtils.getOverrideContextLocation(baseDir, name))); + + valid = true; + } + + protected void resolveNameAndParent() throws IOException { + InputStream is = null; + + try { + is = moduleProperties.getInputStream(); + Properties props = new Properties(); + props.load(is); + + name = props.getProperty(NAME); + parent = props.getProperty(PARENT); + + if ( ! StringUtils.hasText(name) ) { + throw new IOException("Missing name property in [" + location() + "]"); + } + + if ( ! StringUtils.hasText(parent) ) { + parent = null; + } + + checkNameMatchesSelf(); + } finally { + IOUtils.closeQuietly(is); + } + } + + protected void checkNameMatchesSelf() throws IOException { + String expectedLocation = ModuleLocationUtils.getModuleLocation(baseDir, name); + Resource self = resolver.getResource(expectedLocation); + + if ( ! self.exists() ) { + throw new IOException("Resource [" + location() + "] is expected to exist at [" + + expectedLocation + "] please ensure the name property is correct"); + } + + String moduleUrl = moduleProperties.getURL().toExternalForm(); + String selfUrl = self.getURL().toExternalForm(); + + if ( ! moduleUrl.equals(selfUrl) ) { + throw new IOException("Resource [" + location() + "] and [" + + self.getURL() + "] do not appear to be the same resource, " + + "please ensure the name property is correct"); + } + } + + private String location() throws IOException { + return moduleProperties.getURL().toString(); + } + + public void addChild(ModuleDefinition def) { + children.put(def.getName(), def); + } + + public Collection getChildren() { + return children.values(); + } + + public String getName() { + return name; + } + + public String getParentName() { + return parent; + } + + public List getConfigLocations() { + return configLocations; + } + + public List getContextLocations() { + return contextLocations; + } + + public List getInheritableContextLocations() { + return inheritableContextLocations; + } + + @Override + public List getOverrideContextLocations() { + return overrideContextLocations; + } + + public boolean isValid() { + return valid; + } + + public ClassLoader getClassLoader() { + return resolver.getClassLoader(); + } + + +} diff --git a/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/model/impl/DefaultModuleDefinitionSet.java b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/model/impl/DefaultModuleDefinitionSet.java new file mode 100644 index 00000000000..15df839cf1a --- /dev/null +++ b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/model/impl/DefaultModuleDefinitionSet.java @@ -0,0 +1,243 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.module.model.impl; + +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.EmptyStackException; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Stack; + +import org.apache.cloudstack.spring.module.context.ResourceApplicationContext; +import org.apache.cloudstack.spring.module.model.ModuleDefinition; +import org.apache.cloudstack.spring.module.model.ModuleDefinitionSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; + +public class DefaultModuleDefinitionSet implements ModuleDefinitionSet { + + private static final Logger log = LoggerFactory.getLogger(DefaultModuleDefinitionSet.class); + + public static final String DEFAULT_CONFIG_RESOURCES = "DefaultConfigResources"; + public static final String DEFAULT_CONFIG_XML = "defaults-context.xml"; + + String root; + Map modules; + Map contexts = new HashMap(); + ApplicationContext rootContext = null; + + public DefaultModuleDefinitionSet(Map modules, String root) { + super(); + this.root = root; + this.modules = modules; + } + + public void load() throws IOException { + if ( ! loadRootContext() ) + return; + + printHierarchy(); + loadContexts(); + startContexts(); + } + + protected boolean loadRootContext() { + ModuleDefinition def = modules.get(root); + + if ( def == null ) + return false; + + ApplicationContext defaultsContext = getDefaultsContext(); + + rootContext = loadContext(def, defaultsContext); + + return true; + } + + protected void startContexts() { + withModule(new WithModule() { + public void with(ModuleDefinition def, Stack parents) { + try { + ApplicationContext context = getApplicationContext(def.getName()); + try { + Runnable runnable = context.getBean("moduleStartup", Runnable.class); + log.info("Starting module [{}]", def.getName()); + runnable.run(); + } catch ( BeansException e ) { + // Ignore + } + } catch ( EmptyStackException e ) { + // The root context is already loaded, so ignore the exception + } + } + }); + } + + protected void loadContexts() { + withModule(new WithModule() { + public void with(ModuleDefinition def, Stack parents) { + try { + ApplicationContext parent = getApplicationContext(parents.peek().getName()); + loadContext(def, parent); + } catch ( EmptyStackException e ) { + // The root context is already loaded, so ignore the exception + } + } + }); + } + protected ApplicationContext loadContext(ModuleDefinition def, ApplicationContext parent) { + ResourceApplicationContext context = new ResourceApplicationContext(); + context.setApplicationName("/" + def.getName()); + + Resource[] resources = getConfigResources(def.getName()); + context.setConfigResources(resources); + context.setParent(parent); + context.setClassLoader(def.getClassLoader()); + + long start = System.currentTimeMillis(); + if ( log.isInfoEnabled() ) { + for ( Resource resource : resources ) { + log.info("Loading module context [{}] from {}", def.getName(), resource); + } + } + context.refresh(); + log.info("Loaded module context [{}] in {} ms", def.getName(), (System.currentTimeMillis() - start)); + + contexts.put(def.getName(), context); + + return context; + } + + protected boolean shouldLoad(ModuleDefinition def) { + return true; + } + + protected ApplicationContext getDefaultsContext() { + URL config = DefaultModuleDefinitionSet.class.getResource(DEFAULT_CONFIG_XML); + + ResourceApplicationContext context = new ResourceApplicationContext(new UrlResource(config)); + context.setApplicationName("/defaults"); + context.refresh(); + + @SuppressWarnings("unchecked") + final List resources = (List) context.getBean(DEFAULT_CONFIG_RESOURCES); + + withModule(new WithModule() { + public void with(ModuleDefinition def, Stack parents) { + for ( Resource defaults : def.getConfigLocations() ) { + resources.add(defaults); + } + } + }); + + return context; + } + + protected void printHierarchy() { + withModule(new WithModule() { + public void with(ModuleDefinition def, Stack parents) { + log.info(String.format("Module Hierarchy:%" + ((parents.size() * 2) + 1) + "s%s", "", def.getName())); + } + }); + } + + protected void withModule(WithModule with) { + ModuleDefinition rootDef = modules.get(root); + withModule(rootDef, new Stack(), with); + } + + protected void withModule(ModuleDefinition def, Stack parents, WithModule with) { + if ( def == null ) + return; + + if ( ! shouldLoad(def) ) { + return; + } + + with.with(def, parents); + + parents.push(def); + + for ( ModuleDefinition child : def.getChildren() ) { + withModule(child, parents, with); + } + + parents.pop(); + } + + private static interface WithModule { + public void with(ModuleDefinition def, Stack parents); + } + + @Configuration + public static class ConfigContext { + + List resources; + + public ConfigContext(List resources) { + super(); + this.resources = resources; + } + + @Bean(name = DEFAULT_CONFIG_RESOURCES) + public List defaultConfigResources() { + return new ArrayList(); + } + } + + public ApplicationContext getApplicationContext(String name) { + return contexts.get(name); + } + + public Resource[] getConfigResources(String name) { + Set resources = new LinkedHashSet(); + + ModuleDefinition original = null; + ModuleDefinition def = original = modules.get(name); + + if ( def == null ) + return new Resource[] {}; + + resources.addAll(def.getContextLocations()); + + while ( def != null ) { + resources.addAll(def.getInheritableContextLocations()); + def = modules.get(def.getParentName()); + } + + resources.addAll(original.getOverrideContextLocations()); + + return resources.toArray(new Resource[resources.size()]); + } + + public ModuleDefinition getModuleDefinition(String name) { + return modules.get(name); + } +} diff --git a/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/util/Main.java b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/util/Main.java new file mode 100644 index 00000000000..3a9660c4793 --- /dev/null +++ b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/util/Main.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.module.util; + +import org.apache.cloudstack.spring.module.factory.CloudStackSpringContext; + +public class Main { + + long start = System.currentTimeMillis(); + + public Main() { + + } + + public void start() throws Exception { + CloudStackSpringContext context = new CloudStackSpringContext(); + context.registerShutdownHook(); + + if ( Boolean.getBoolean("force.exit") ) { + System.exit(0); + } + } + + public long getTime() { + return System.currentTimeMillis() - start; + } + + + public static void main(String... args) { + Main main = new Main(); + + try { + main.start(); + System.out.println("STARTUP COMPLETE [" + main.getTime() + "] ms"); + } catch ( Exception e ) { + e.printStackTrace(); + System.out.println("STARTUP FAILED [" + main.getTime() + "] ms"); + System.err.println("STARTUP FAILED [" + main.getTime() + "] ms"); + System.exit(1); + } + } +} diff --git a/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/util/ModuleLocationUtils.java b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/util/ModuleLocationUtils.java new file mode 100644 index 00000000000..eeab154b395 --- /dev/null +++ b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/util/ModuleLocationUtils.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.module.util; + +public class ModuleLocationUtils { + + private static final String ALL_MODULE_PROPERTIES = "classpath*:%s/*/module.properties"; + private static final String MODULE_PROPERTIES = "classpath:%s/%s/module.properties"; + private static final String CONTEXT_LOCATION = "classpath*:%s/%s/*context.xml"; + private static final String INHERTIABLE_CONTEXT_LOCATION = "classpath*:%s/%s/*context-inheritable.xml"; + private static final String OVERRIDE_CONTEXT_LOCATION = "classpath*:%s/%s/*context-override.xml"; + private static final String DEFAULTS_LOCATION = "classpath*:%s/%s/*defaults.properties"; + + public static String getModulesLocation(String baseDir) { + return String.format(ALL_MODULE_PROPERTIES, baseDir); + } + + public static String getModuleLocation(String baseDir, String name) { + return String.format(MODULE_PROPERTIES, baseDir, name); + } + + public static String getContextLocation(String baseDir, String name) { + return String.format(CONTEXT_LOCATION, baseDir, name); + } + + public static String getInheritableContextLocation(String baseDir, String name) { + return String.format(INHERTIABLE_CONTEXT_LOCATION, baseDir, name); + } + + public static String getOverrideContextLocation(String baseDir, String name) { + return String.format(OVERRIDE_CONTEXT_LOCATION, baseDir, name); + } + + public static String getDefaultsLocation(String baseDir, String name) { + return String.format(DEFAULTS_LOCATION, baseDir, name); + } +} diff --git a/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/web/CloudStackContextLoaderListener.java b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/web/CloudStackContextLoaderListener.java new file mode 100644 index 00000000000..e704437774b --- /dev/null +++ b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/web/CloudStackContextLoaderListener.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.module.web; + +import java.io.IOException; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; + +import org.apache.cloudstack.spring.module.factory.CloudStackSpringContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.web.context.ConfigurableWebApplicationContext; +import org.springframework.web.context.ContextLoaderListener; + +public class CloudStackContextLoaderListener extends ContextLoaderListener { + + public static final String WEB_PARENT_MODULE = "parentModule"; + public static final String WEB_PARENT_MODULE_DEFAULT = "web"; + + private static final Logger log = LoggerFactory.getLogger(CloudStackContextLoaderListener.class); + + CloudStackSpringContext cloudStackContext; + String configuredParentName; + + @Override + protected ApplicationContext loadParentContext(ServletContext servletContext) { + return cloudStackContext.getApplicationContextForWeb(configuredParentName); + } + + @Override + public void contextInitialized(ServletContextEvent event) { + try { + cloudStackContext = new CloudStackSpringContext(); + } catch (IOException e) { + log.error("Failed to start CloudStack", e); + throw new RuntimeException("Failed to initialize CloudStack Spring modules", e); + } + + configuredParentName = event.getServletContext().getInitParameter(WEB_PARENT_MODULE); + if ( configuredParentName == null ) { + configuredParentName = WEB_PARENT_MODULE_DEFAULT; + } + + super.contextInitialized(event); + } + + @Override + protected void customizeContext(ServletContext servletContext, ConfigurableWebApplicationContext applicationContext) { + super.customizeContext(servletContext, applicationContext); + + String[] newLocations = cloudStackContext.getConfigLocationsForWeb(configuredParentName, + applicationContext.getConfigLocations()); + + applicationContext.setConfigLocations(newLocations); + } + +} diff --git a/framework/spring/module/src/main/resources/org/apache/cloudstack/spring/module/model/impl/defaults-context.xml b/framework/spring/module/src/main/resources/org/apache/cloudstack/spring/module/model/impl/defaults-context.xml new file mode 100644 index 00000000000..b19833a735b --- /dev/null +++ b/framework/spring/module/src/main/resources/org/apache/cloudstack/spring/module/model/impl/defaults-context.xml @@ -0,0 +1,28 @@ + + + + + + diff --git a/framework/spring/module/src/test/java/org/apache/cloudstack/spring/module/factory/InitTest.java b/framework/spring/module/src/test/java/org/apache/cloudstack/spring/module/factory/InitTest.java new file mode 100644 index 00000000000..db3549b73b1 --- /dev/null +++ b/framework/spring/module/src/test/java/org/apache/cloudstack/spring/module/factory/InitTest.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.module.factory; + +import javax.annotation.PostConstruct; + +public class InitTest { + + public static boolean initted = false; + + @PostConstruct + public void init() { + setInitted(true); + } + + public boolean isInitted() { + return initted; + } + + public void setInitted(boolean initted) { + InitTest.initted = initted; + } +} diff --git a/framework/spring/module/src/test/java/org/apache/cloudstack/spring/module/factory/ModuleBasedContextFactoryTest.java b/framework/spring/module/src/test/java/org/apache/cloudstack/spring/module/factory/ModuleBasedContextFactoryTest.java new file mode 100644 index 00000000000..2947615d597 --- /dev/null +++ b/framework/spring/module/src/test/java/org/apache/cloudstack/spring/module/factory/ModuleBasedContextFactoryTest.java @@ -0,0 +1,121 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.module.factory; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.Collection; + +import org.apache.cloudstack.spring.module.locator.impl.ClasspathModuleDefinitionLocator; +import org.apache.cloudstack.spring.module.model.ModuleDefinition; +import org.apache.cloudstack.spring.module.model.ModuleDefinitionSet; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.context.ApplicationContext; + +public class ModuleBasedContextFactoryTest { + + Collection defs; + + @Before + public void setUp() throws IOException { + InstantiationCounter.count = 0; + + ClasspathModuleDefinitionLocator locator = new ClasspathModuleDefinitionLocator(); + defs = locator.locateModules("testhierarchy"); + } + + @Test + public void testLoad() throws IOException { + + ModuleBasedContextFactory factory = new ModuleBasedContextFactory(); + + ModuleDefinitionSet set = factory.loadModules(defs, "base"); + + assertNotNull(set.getApplicationContext("base")); + } + + @Test + public void testOverride() throws IOException { + + InitTest.initted = false; + + ModuleBasedContextFactory factory = new ModuleBasedContextFactory(); + + ModuleDefinitionSet set = factory.loadModules(defs, "base"); + + assertTrue(!InitTest.initted); + assertEquals("a string", set.getApplicationContext("child1").getBean("override", String.class)); + } + + @Test + public void testBeans() throws IOException { + ModuleBasedContextFactory factory = new ModuleBasedContextFactory(); + ModuleDefinitionSet set = factory.loadModules(defs, "base"); + + testBeansInContext(set, "base", 1, new String[] { "base" }, new String[] { "child1", "child2", "child1-1" }); + testBeansInContext(set, "child1", 2, new String[] { "base", "child1" }, new String[] { "child2", "child1-1" }); + testBeansInContext(set, "child2", 4, new String[] { "base", "child2" }, new String[] { "child1", "child1-1" }); + testBeansInContext(set, "child1-1", 3, new String[] { "base", "child1", "child1-1" }, new String[] { "child2" }); + } + + protected void testBeansInContext(ModuleDefinitionSet set, String name, int order, String[] parents, String[] notTheres) { + ApplicationContext context = set.getApplicationContext(name); + + String nameBean = context.getBean("name", String.class); + assertEquals(name, nameBean); + + for ( String parent : parents ) { + String parentBean = context.getBean(parent, String.class); + assertEquals(parent, parentBean); + } + + for ( String notThere : notTheres ) { + try { + context.getBean(notThere, String.class); + fail(); + } catch ( NoSuchBeanDefinitionException e ) { + } + } + + int count = context.getBean("count", InstantiationCounter.class).getCount(); + + assertEquals(order, count); + } + + public static class InstantiationCounter { + public static Integer count = 0; + + int myCount; + + public InstantiationCounter() { + synchronized (count) { + myCount = count + 1; + count = myCount; + } + } + + public int getCount() { + return myCount; + } + + } +} diff --git a/framework/spring/module/src/test/java/org/apache/cloudstack/spring/module/locator/impl/ClasspathModuleDefinitionSetLocatorTest.java b/framework/spring/module/src/test/java/org/apache/cloudstack/spring/module/locator/impl/ClasspathModuleDefinitionSetLocatorTest.java new file mode 100644 index 00000000000..5114187b9a5 --- /dev/null +++ b/framework/spring/module/src/test/java/org/apache/cloudstack/spring/module/locator/impl/ClasspathModuleDefinitionSetLocatorTest.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.module.locator.impl; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.Collection; + +import org.apache.cloudstack.spring.module.model.ModuleDefinition; +import org.junit.Test; + +public class ClasspathModuleDefinitionSetLocatorTest { + + @Test + public void testDiscover() throws IOException { + ClasspathModuleDefinitionLocator factory = new ClasspathModuleDefinitionLocator(); + + Collection modules = factory.locateModules("testhierarchy"); + + assertEquals(5, modules.size()); + } + +} diff --git a/framework/spring/module/src/test/java/org/apache/cloudstack/spring/module/model/impl/DefaultModuleDefinitionTest.java b/framework/spring/module/src/test/java/org/apache/cloudstack/spring/module/model/impl/DefaultModuleDefinitionTest.java new file mode 100644 index 00000000000..31a82baab20 --- /dev/null +++ b/framework/spring/module/src/test/java/org/apache/cloudstack/spring/module/model/impl/DefaultModuleDefinitionTest.java @@ -0,0 +1,131 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.spring.module.model.impl; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import org.apache.cloudstack.spring.module.util.ModuleLocationUtils; +import org.junit.Test; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; + +public class DefaultModuleDefinitionTest { + + ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + + protected DefaultModuleDefinition createDef(String name) { + Resource resource = + resolver.getResource(ModuleLocationUtils.getModuleLocation("testfiles", name)); + + return new DefaultModuleDefinition("testfiles", resource, resolver); + } + + @Test + public void testBlankName() { + DefaultModuleDefinition def = createDef("blankname"); + + try { + def.init(); + fail(); + } catch ( IOException e ) { + assertTrue(e.getMessage().contains("Missing name property")); + } + + } + + @Test + public void testMissingName() { + DefaultModuleDefinition def = createDef("missingname"); + + try { + def.init(); + fail(); + } catch ( IOException e ) { + assertTrue(e.getMessage().contains("Missing name property")); + } + + } + + @Test + public void testBadName() { + DefaultModuleDefinition def = createDef("badname"); + + try { + def.init(); + fail(); + } catch ( IOException e ) { + assertTrue(e.getMessage().contains("is expected to exist at")); + } + } + + @Test + public void testGood() throws IOException { + DefaultModuleDefinition def = createDef("good"); + def.init(); + assertTrue(def.isValid()); + } + + @Test + public void testWrongName() { + DefaultModuleDefinition def = createDef("wrongname"); + + try { + def.init(); + fail(); + } catch ( IOException e ) { + assertTrue(e.getMessage().contains("do not appear to be the same resource")); + } + } + + @Test + public void testAllFiles() throws IOException { + DefaultModuleDefinition def = createDef("all"); + + def.init(); + + assertEquals(2, def.getContextLocations().size()); + has(def.getContextLocations(), "empty-context.xml", "empty2-context.xml"); + + assertEquals(2, def.getConfigLocations().size()); + has(def.getConfigLocations(), "test2-defaults.properties", "defaults.properties"); + + assertEquals(2, def.getInheritableContextLocations().size()); + has(def.getInheritableContextLocations(), "empty-context-inheritable.xml", "empty2-context-inheritable.xml"); + } + + protected void has(List resources, String... files) throws IOException { + int count = 0; + + for ( Resource r : resources ) { + for ( String file : files ) { + if ( r.getURL().toExternalForm().contains(file) ) { + count++; + break; + } + } + } + + assertEquals(resources + " does not contain " + Arrays.toString(files), files.length, count); + } +} diff --git a/framework/spring/module/src/test/resources/testfiles/all/defaults.properties b/framework/spring/module/src/test/resources/testfiles/all/defaults.properties new file mode 100644 index 00000000000..c08d10b386a --- /dev/null +++ b/framework/spring/module/src/test/resources/testfiles/all/defaults.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +blah=1 diff --git a/framework/spring/module/src/test/resources/testfiles/all/empty-context-inheritable.xml b/framework/spring/module/src/test/resources/testfiles/all/empty-context-inheritable.xml new file mode 100644 index 00000000000..7c6b8fd47b1 --- /dev/null +++ b/framework/spring/module/src/test/resources/testfiles/all/empty-context-inheritable.xml @@ -0,0 +1,26 @@ + + + + diff --git a/framework/spring/module/src/test/resources/testfiles/all/empty-context.xml b/framework/spring/module/src/test/resources/testfiles/all/empty-context.xml new file mode 100644 index 00000000000..7c6b8fd47b1 --- /dev/null +++ b/framework/spring/module/src/test/resources/testfiles/all/empty-context.xml @@ -0,0 +1,26 @@ + + + + diff --git a/framework/spring/module/src/test/resources/testfiles/all/empty2-context-inheritable.xml b/framework/spring/module/src/test/resources/testfiles/all/empty2-context-inheritable.xml new file mode 100644 index 00000000000..7c6b8fd47b1 --- /dev/null +++ b/framework/spring/module/src/test/resources/testfiles/all/empty2-context-inheritable.xml @@ -0,0 +1,26 @@ + + + + diff --git a/framework/spring/module/src/test/resources/testfiles/all/empty2-context.xml b/framework/spring/module/src/test/resources/testfiles/all/empty2-context.xml new file mode 100644 index 00000000000..7c6b8fd47b1 --- /dev/null +++ b/framework/spring/module/src/test/resources/testfiles/all/empty2-context.xml @@ -0,0 +1,26 @@ + + + + diff --git a/framework/spring/module/src/test/resources/testfiles/all/module.properties b/framework/spring/module/src/test/resources/testfiles/all/module.properties new file mode 100644 index 00000000000..3faaf94b5ea --- /dev/null +++ b/framework/spring/module/src/test/resources/testfiles/all/module.properties @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=all diff --git a/framework/spring/module/src/test/resources/testfiles/all/test2-defaults.properties b/framework/spring/module/src/test/resources/testfiles/all/test2-defaults.properties new file mode 100644 index 00000000000..00ae6c00d2e --- /dev/null +++ b/framework/spring/module/src/test/resources/testfiles/all/test2-defaults.properties @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + diff --git a/framework/spring/module/src/test/resources/testfiles/badname/module.properties b/framework/spring/module/src/test/resources/testfiles/badname/module.properties new file mode 100644 index 00000000000..354accfa8ab --- /dev/null +++ b/framework/spring/module/src/test/resources/testfiles/badname/module.properties @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=what diff --git a/framework/spring/module/src/test/resources/testfiles/blankname/module.properties b/framework/spring/module/src/test/resources/testfiles/blankname/module.properties new file mode 100644 index 00000000000..b11279b50c6 --- /dev/null +++ b/framework/spring/module/src/test/resources/testfiles/blankname/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# A bunch of whitespace is after name +name= diff --git a/framework/spring/module/src/test/resources/testfiles/good/empty-context.xml b/framework/spring/module/src/test/resources/testfiles/good/empty-context.xml new file mode 100644 index 00000000000..7c6b8fd47b1 --- /dev/null +++ b/framework/spring/module/src/test/resources/testfiles/good/empty-context.xml @@ -0,0 +1,26 @@ + + + + diff --git a/framework/spring/module/src/test/resources/testfiles/good/module.properties b/framework/spring/module/src/test/resources/testfiles/good/module.properties new file mode 100644 index 00000000000..47e60ec2ce1 --- /dev/null +++ b/framework/spring/module/src/test/resources/testfiles/good/module.properties @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=good diff --git a/framework/spring/module/src/test/resources/testfiles/missingname/module.properties b/framework/spring/module/src/test/resources/testfiles/missingname/module.properties new file mode 100644 index 00000000000..00ae6c00d2e --- /dev/null +++ b/framework/spring/module/src/test/resources/testfiles/missingname/module.properties @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + diff --git a/framework/spring/module/src/test/resources/testfiles/wrongname/module.properties b/framework/spring/module/src/test/resources/testfiles/wrongname/module.properties new file mode 100644 index 00000000000..47e60ec2ce1 --- /dev/null +++ b/framework/spring/module/src/test/resources/testfiles/wrongname/module.properties @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=good diff --git a/framework/spring/module/src/test/resources/testhierarchy/base/module.properties b/framework/spring/module/src/test/resources/testhierarchy/base/module.properties new file mode 100644 index 00000000000..955a32c2521 --- /dev/null +++ b/framework/spring/module/src/test/resources/testhierarchy/base/module.properties @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=base diff --git a/framework/spring/module/src/test/resources/testhierarchy/base/test-context-inheritable.xml b/framework/spring/module/src/test/resources/testhierarchy/base/test-context-inheritable.xml new file mode 100644 index 00000000000..188301e599c --- /dev/null +++ b/framework/spring/module/src/test/resources/testhierarchy/base/test-context-inheritable.xml @@ -0,0 +1,28 @@ + + + + + + diff --git a/framework/spring/module/src/test/resources/testhierarchy/base/test-context.xml b/framework/spring/module/src/test/resources/testhierarchy/base/test-context.xml new file mode 100644 index 00000000000..a72d8c6128a --- /dev/null +++ b/framework/spring/module/src/test/resources/testhierarchy/base/test-context.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + diff --git a/framework/spring/module/src/test/resources/testhierarchy/child1-1/module.properties b/framework/spring/module/src/test/resources/testhierarchy/child1-1/module.properties new file mode 100644 index 00000000000..4abe53f1b94 --- /dev/null +++ b/framework/spring/module/src/test/resources/testhierarchy/child1-1/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=child1-1 +parent=child1 diff --git a/framework/spring/module/src/test/resources/testhierarchy/child1-1/test-context.xml b/framework/spring/module/src/test/resources/testhierarchy/child1-1/test-context.xml new file mode 100644 index 00000000000..7a2a9ad6d9b --- /dev/null +++ b/framework/spring/module/src/test/resources/testhierarchy/child1-1/test-context.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + diff --git a/framework/spring/module/src/test/resources/testhierarchy/child1/module.properties b/framework/spring/module/src/test/resources/testhierarchy/child1/module.properties new file mode 100644 index 00000000000..9f4df489fe3 --- /dev/null +++ b/framework/spring/module/src/test/resources/testhierarchy/child1/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=child1 +parent=base diff --git a/framework/spring/module/src/test/resources/testhierarchy/child1/test-context-override.xml b/framework/spring/module/src/test/resources/testhierarchy/child1/test-context-override.xml new file mode 100644 index 00000000000..ceffeb5bfff --- /dev/null +++ b/framework/spring/module/src/test/resources/testhierarchy/child1/test-context-override.xml @@ -0,0 +1,30 @@ + + + + + + + + diff --git a/framework/spring/module/src/test/resources/testhierarchy/child1/test-context.xml b/framework/spring/module/src/test/resources/testhierarchy/child1/test-context.xml new file mode 100644 index 00000000000..f906183fcc6 --- /dev/null +++ b/framework/spring/module/src/test/resources/testhierarchy/child1/test-context.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + diff --git a/framework/spring/module/src/test/resources/testhierarchy/child2/module.properties b/framework/spring/module/src/test/resources/testhierarchy/child2/module.properties new file mode 100644 index 00000000000..f03edfcc347 --- /dev/null +++ b/framework/spring/module/src/test/resources/testhierarchy/child2/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=child2 +parent=base diff --git a/framework/spring/module/src/test/resources/testhierarchy/child2/test-context.xml b/framework/spring/module/src/test/resources/testhierarchy/child2/test-context.xml new file mode 100644 index 00000000000..24bac54818d --- /dev/null +++ b/framework/spring/module/src/test/resources/testhierarchy/child2/test-context.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/framework/spring/module/src/test/resources/testhierarchy/orphan1/module.properties b/framework/spring/module/src/test/resources/testhierarchy/orphan1/module.properties new file mode 100644 index 00000000000..d4a0e6cce2d --- /dev/null +++ b/framework/spring/module/src/test/resources/testhierarchy/orphan1/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=orphan1 +parent=missing1 diff --git a/framework/spring/module/src/test/resources/testhierarchy/orphan1/test-context.xml b/framework/spring/module/src/test/resources/testhierarchy/orphan1/test-context.xml new file mode 100644 index 00000000000..658beeae5de --- /dev/null +++ b/framework/spring/module/src/test/resources/testhierarchy/orphan1/test-context.xml @@ -0,0 +1,30 @@ + + + + + + + + diff --git a/packaging/centos63/cloud-management.rc b/packaging/centos63/cloud-management.rc index 35f31b28538..2f04793b79c 100755 --- a/packaging/centos63/cloud-management.rc +++ b/packaging/centos63/cloud-management.rc @@ -57,6 +57,8 @@ stop() { done if [ "$(ps --pid $pid | grep -c $pid)" -eq "0" ]; then log_success_msg "Stopping ${NAME}:" + rm -f /var/run/${NAME}.pid + rm -f /var/lock/subsys/${NAME} else log_failure_msg "Stopping ${NAME}:" fi @@ -77,7 +79,7 @@ set_ulimit() { } handle_pid_file() { - if [ "$1" -ne 0 ] ; then + if [ "$1" -ne 0 ] && [ "$1" -ne 3 ]; then echo "The pid file locates at /var/run/${NAME}.pid and lock file at /var/lock/subsys/${NAME}. Starting ${NAME} will take care of them or you can manually clean up." fi diff --git a/packaging/centos63/cloud.spec b/packaging/centos63/cloud.spec index 17fb2b13308..ebe45113eb1 100644 --- a/packaging/centos63/cloud.spec +++ b/packaging/centos63/cloud.spec @@ -172,6 +172,8 @@ echo Doing CloudStack build cp packaging/centos63/replace.properties build/replace.properties echo VERSION=%{_maventag} >> build/replace.properties echo PACKAGE=%{name} >> build/replace.properties +touch build/gitrev.txt +echo $(git rev-parse HEAD) > build/gitrev.txt if [ "%{_ossnoss}" == "NOREDIST" -o "%{_ossnoss}" == "noredist" ] ; then echo "Executing mvn packaging with non-redistributable libraries ..." @@ -199,6 +201,7 @@ mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/scripts mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/vms mkdir -p ${RPM_BUILD_ROOT}%{python_sitearch}/ +mkdir -p ${RPM_BUILD_ROOT}%/usr/bin cp -r scripts/* ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/scripts install -D systemvm/dist/systemvm.iso ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/vms/systemvm.iso install -D systemvm/dist/systemvm.zip ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/vms/systemvm.zip @@ -206,6 +209,8 @@ install python/lib/cloud_utils.py ${RPM_BUILD_ROOT}%{python_sitearch}/cloud_util cp -r python/lib/cloudutils ${RPM_BUILD_ROOT}%{python_sitearch}/ python -m py_compile ${RPM_BUILD_ROOT}%{python_sitearch}/cloud_utils.py python -m compileall ${RPM_BUILD_ROOT}%{python_sitearch}/cloudutils +cp build/gitrev.txt ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/scripts +cp packaging/centos63/cloudstack-sccs ${RPM_BUILD_ROOT}/usr/bin mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/scripts/network/cisco cp -r plugins/network-elements/cisco-vnmc/scripts/network/cisco/* ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/scripts/network/cisco @@ -317,7 +322,7 @@ cp awsapi/resource/Axis2/axis2.xml ${RPM_BUILD_ROOT}%{_datadir}/%{name}-bridge/w cp awsapi/target/WEB-INF/services/cloud-ec2.aar ${RPM_BUILD_ROOT}%{_datadir}/%{name}-bridge/webapps/awsapi/WEB-INF/services -for name in applicationContext.xml cloud-bridge.properties commons-logging.properties ec2-service.properties ; do +for name in cloud-bridge.properties commons-logging.properties ec2-service.properties ; do mv ${RPM_BUILD_ROOT}%{_datadir}/%{name}-bridge/webapps/awsapi/WEB-INF/classes/$name \ ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/management/$name done @@ -481,11 +486,20 @@ if [ -f "%{_sysconfdir}/cloud.rpmsave/agent/agent.properties" ]; then mv %{_sysconfdir}/cloud.rpmsave/agent/agent.properties %{_sysconfdir}/cloud.rpmsave/agent/agent.properties.rpmsave fi +%preun usage +/sbin/service cloudstack-usage stop || true +if [ "$1" == "0" ] ; then + /sbin/chkconfig --del cloudstack-usage > /dev/null 2>&1 || true + /sbin/service cloudstack-usage stop > /dev/null 2>&1 || true +fi + %post usage if [ -f "%{_sysconfdir}/%{name}/management/db.properties" ]; then echo Replacing db.properties with management server db.properties rm -f %{_sysconfdir}/%{name}/usage/db.properties ln -s %{_sysconfdir}/%{name}/management/db.properties %{_sysconfdir}/%{name}/usage/db.properties + /sbin/chkconfig --add cloudstack-usage > /dev/null 2>&1 || true + /sbin/chkconfig --level 345 cloudstack-usage on > /dev/null 2>&1 || true fi #%post awsapi @@ -522,7 +536,6 @@ fi %config(noreplace) %{_sysconfdir}/%{name}/management/tomcat-users.xml %config(noreplace) %{_sysconfdir}/%{name}/management/web.xml %config(noreplace) %{_sysconfdir}/%{name}/management/environment.properties -%config(noreplace) %{_sysconfdir}/%{name}/management/applicationContext.xml %config(noreplace) %{_sysconfdir}/%{name}/management/cloud-bridge.properties %config(noreplace) %{_sysconfdir}/%{name}/management/commons-logging.properties %config(noreplace) %{_sysconfdir}/%{name}/management/ec2-service.properties @@ -572,6 +585,7 @@ fi %dir %attr(0755,root,root) %{python_sitearch}/cloudutils %dir %attr(0755,root,root) %{_datadir}/%{name}-common/vms %attr(0755,root,root) %{_datadir}/%{name}-common/scripts +%attr(0755,root,root) /usr/bin/cloudstack-sccs %attr(0644, root, root) %{_datadir}/%{name}-common/vms/systemvm.iso %attr(0644, root, root) %{_datadir}/%{name}-common/vms/systemvm.zip %attr(0644,root,root) %{python_sitearch}/cloud_utils.py diff --git a/packaging/centos63/cloudstack-sccs b/packaging/centos63/cloudstack-sccs new file mode 100644 index 00000000000..e05d372c7fe --- /dev/null +++ b/packaging/centos63/cloudstack-sccs @@ -0,0 +1,20 @@ +#!/bin/sh + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +cat /usr/share/cloudstack-common/scripts/gitrev.txt diff --git a/patches/systemvm/debian/config/opt/cloud/bin/savepassword.sh b/patches/systemvm/debian/config/opt/cloud/bin/savepassword.sh new file mode 100644 index 00000000000..9c597572b55 --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/savepassword.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by the License. +# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Automatically generated by addcopyright.py at 04/03/2012 + + + + + +# Usage +# save_password -v -p + +source /root/func.sh + +lock="passwdlock" +#default timeout value is 30 mins as password reset command is not synchronized on agent side any more, +#and multiple commands can be sent to the same VR at a time +locked=$(getLockFile $lock 1800) +if [ "$locked" != "1" ] +then + exit 1 +fi + +PASSWD_FILE=/var/cache/cloud/passwords + +while getopts 'v:p:' OPTION +do + case $OPTION in + v) VM_IP="$OPTARG" + ;; + p) + ENCODEDPASSWORD="$OPTARG" + PASSWORD=$(echo $ENCODEDPASSWORD | tr '[a-m][n-z][A-M][N-Z]' '[n-z][a-m][N-Z][A-M]') + ;; + ?) echo "Incorrect usage" + unlock_exit 1 $lock $locked + ;; + esac +done + +[ -f $PASSWD_FILE ] || touch $PASSWD_FILE + +sed -i /$VM_IP/d $PASSWD_FILE + +ps aux | grep serve_password.sh |grep -v grep 2>&1 > /dev/null +if [ $? -eq 0 ] +then + echo "$VM_IP=$PASSWORD" >> $PASSWD_FILE +else + echo "$VM_IP=saved_password" >> $PASSWD_FILE +fi + +unlock_exit $? $lock $locked diff --git a/plugins/acl/static-role-based/resources/META-INF/cloudstack/acl-static-role-based/module.properties b/plugins/acl/static-role-based/resources/META-INF/cloudstack/acl-static-role-based/module.properties new file mode 100644 index 00000000000..06fc721bc09 --- /dev/null +++ b/plugins/acl/static-role-based/resources/META-INF/cloudstack/acl-static-role-based/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=acl-static-role-based +parent=api \ No newline at end of file diff --git a/plugins/acl/static-role-based/resources/META-INF/cloudstack/acl-static-role-based/spring-acl-static-role-based-context.xml b/plugins/acl/static-role-based/resources/META-INF/cloudstack/acl-static-role-based/spring-acl-static-role-based-context.xml new file mode 100644 index 00000000000..f13acc190b6 --- /dev/null +++ b/plugins/acl/static-role-based/resources/META-INF/cloudstack/acl-static-role-based/spring-acl-static-role-based-context.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/plugins/affinity-group-processors/explicit-dedication/resources/META-INF/cloudstack/explicit-dedication/module.properties b/plugins/affinity-group-processors/explicit-dedication/resources/META-INF/cloudstack/explicit-dedication/module.properties new file mode 100644 index 00000000000..e204fe7ce43 --- /dev/null +++ b/plugins/affinity-group-processors/explicit-dedication/resources/META-INF/cloudstack/explicit-dedication/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=explicit-dedication +parent=planner \ No newline at end of file diff --git a/plugins/affinity-group-processors/explicit-dedication/resources/META-INF/cloudstack/explicit-dedication/spring-explicit-dedication-context.xml b/plugins/affinity-group-processors/explicit-dedication/resources/META-INF/cloudstack/explicit-dedication/spring-explicit-dedication-context.xml new file mode 100644 index 00000000000..5864f947765 --- /dev/null +++ b/plugins/affinity-group-processors/explicit-dedication/resources/META-INF/cloudstack/explicit-dedication/spring-explicit-dedication-context.xml @@ -0,0 +1,36 @@ + + + + + + + + + diff --git a/plugins/affinity-group-processors/explicit-dedication/src/org/apache/cloudstack/affinity/ExplicitDedicationProcessor.java b/plugins/affinity-group-processors/explicit-dedication/src/org/apache/cloudstack/affinity/ExplicitDedicationProcessor.java index da231723d32..cc1d3f350e6 100644 --- a/plugins/affinity-group-processors/explicit-dedication/src/org/apache/cloudstack/affinity/ExplicitDedicationProcessor.java +++ b/plugins/affinity-group-processors/explicit-dedication/src/org/apache/cloudstack/affinity/ExplicitDedicationProcessor.java @@ -24,7 +24,6 @@ import javax.ejb.Local; import javax.inject.Inject; import org.apache.log4j.Logger; - import org.apache.cloudstack.affinity.dao.AffinityGroupDao; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; @@ -48,6 +47,8 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; @@ -410,7 +411,7 @@ public class ExplicitDedicationProcessor extends AffinityProcessorBase implement @DB @Override - public void handleDeleteGroup(AffinityGroup group) { + public void handleDeleteGroup(final AffinityGroup group) { // When a group of the 'ExplicitDedication' type gets deleted, make sure // to remove the dedicated resources in the group as well. if (group != null) { @@ -419,20 +420,21 @@ public class ExplicitDedicationProcessor extends AffinityProcessorBase implement if (s_logger.isDebugEnabled()) { s_logger.debug("Releasing the dedicated resources under group: " + group); } - Transaction txn = Transaction.currentTxn(); - txn.start(); - SearchBuilder listByAffinityGroup = _dedicatedDao.createSearchBuilder(); - listByAffinityGroup.and("affinityGroupId", listByAffinityGroup.entity().getAffinityGroupId(), - SearchCriteria.Op.EQ); - listByAffinityGroup.done(); - SearchCriteria sc = listByAffinityGroup.create(); - sc.setParameters("affinityGroupId", group.getId()); - - _dedicatedDao.lockRows(sc, null, true); - _dedicatedDao.remove(sc); - - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + SearchBuilder listByAffinityGroup = _dedicatedDao.createSearchBuilder(); + listByAffinityGroup.and("affinityGroupId", listByAffinityGroup.entity().getAffinityGroupId(), + SearchCriteria.Op.EQ); + listByAffinityGroup.done(); + SearchCriteria sc = listByAffinityGroup.create(); + sc.setParameters("affinityGroupId", group.getId()); + + _dedicatedDao.lockRows(sc, null, true); + _dedicatedDao.remove(sc); + } + }); } else { if (s_logger.isDebugEnabled()) { s_logger.debug("No dedicated resources to releease under group: " + group); diff --git a/plugins/affinity-group-processors/host-anti-affinity/resources/META-INF/cloudstack/host-anti-affinity/module.properties b/plugins/affinity-group-processors/host-anti-affinity/resources/META-INF/cloudstack/host-anti-affinity/module.properties new file mode 100644 index 00000000000..1ea1e8417fe --- /dev/null +++ b/plugins/affinity-group-processors/host-anti-affinity/resources/META-INF/cloudstack/host-anti-affinity/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=host-anti-affinity +parent=planner \ No newline at end of file diff --git a/plugins/affinity-group-processors/host-anti-affinity/resources/META-INF/cloudstack/host-anti-affinity/spring-host-anti-affinity-context.xml b/plugins/affinity-group-processors/host-anti-affinity/resources/META-INF/cloudstack/host-anti-affinity/spring-host-anti-affinity-context.xml new file mode 100644 index 00000000000..bc09cc3c60d --- /dev/null +++ b/plugins/affinity-group-processors/host-anti-affinity/resources/META-INF/cloudstack/host-anti-affinity/spring-host-anti-affinity-context.xml @@ -0,0 +1,37 @@ + + + + + + + + + + diff --git a/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java b/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java index 860240faef0..5be109e533b 100755 --- a/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java +++ b/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java @@ -16,14 +16,24 @@ // under the License. package org.apache.cloudstack.discovery; -import com.cloud.serializer.Param; -import com.cloud.user.User; -import com.cloud.utils.ReflectUtil; -import com.cloud.utils.StringUtils; -import com.cloud.utils.component.PluggableService; -import com.google.gson.annotations.SerializedName; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.ejb.Local; +import javax.inject.Inject; + import org.apache.cloudstack.acl.APIChecker; -import org.apache.cloudstack.api.*; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.BaseAsyncCreateCmd; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.command.user.discovery.ListApisCmd; import org.apache.cloudstack.api.response.ApiDiscoveryResponse; import org.apache.cloudstack.api.response.ApiParameterResponse; @@ -32,27 +42,29 @@ import org.apache.cloudstack.api.response.ListResponse; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import javax.annotation.PostConstruct; -import javax.ejb.Local; -import javax.inject.Inject; -import java.lang.reflect.Field; -import java.util.*; +import com.cloud.serializer.Param; +import com.cloud.user.User; +import com.cloud.utils.ReflectUtil; +import com.cloud.utils.StringUtils; +import com.cloud.utils.component.ComponentLifecycleBase; +import com.cloud.utils.component.PluggableService; +import com.google.gson.annotations.SerializedName; @Component @Local(value = ApiDiscoveryService.class) -public class ApiDiscoveryServiceImpl implements ApiDiscoveryService { +public class ApiDiscoveryServiceImpl extends ComponentLifecycleBase implements ApiDiscoveryService { private static final Logger s_logger = Logger.getLogger(ApiDiscoveryServiceImpl.class); - @Inject protected List _apiAccessCheckers = null; - @Inject protected List _services = null; + List _apiAccessCheckers = null; + List _services = null; private static Map s_apiNameDiscoveryResponseMap = null; protected ApiDiscoveryServiceImpl() { super(); } - @PostConstruct - void init() { + @Override + public boolean start() { if (s_apiNameDiscoveryResponseMap == null) { long startTime = System.nanoTime(); s_apiNameDiscoveryResponseMap = new HashMap(); @@ -66,6 +78,8 @@ public class ApiDiscoveryServiceImpl implements ApiDiscoveryService { long endTime = System.nanoTime(); s_logger.info("Api Discovery Service: Annotation, docstrings, api relation graph processed in " + (endTime - startTime) / 1000000.0 + " ms"); } + + return true; } protected Map> cacheResponseMap(Set> cmdClasses) { @@ -249,4 +263,21 @@ public class ApiDiscoveryServiceImpl implements ApiDiscoveryService { cmdList.add(ListApisCmd.class); return cmdList; } + + public List getApiAccessCheckers() { + return _apiAccessCheckers; + } + + public void setApiAccessCheckers(List _apiAccessCheckers) { + this._apiAccessCheckers = _apiAccessCheckers; + } + + public List getServices() { + return _services; + } + + @Inject + public void setServices(List _services) { + this._services = _services; + } } diff --git a/plugins/api/discovery/test/org/apache/cloudstack/discovery/ApiDiscoveryTest.java b/plugins/api/discovery/test/org/apache/cloudstack/discovery/ApiDiscoveryTest.java index afff746c848..a34484becab 100644 --- a/plugins/api/discovery/test/org/apache/cloudstack/discovery/ApiDiscoveryTest.java +++ b/plugins/api/discovery/test/org/apache/cloudstack/discovery/ApiDiscoveryTest.java @@ -65,7 +65,7 @@ public class ApiDiscoveryTest { Set> cmdClasses = new HashSet>(); cmdClasses.add(ListApisCmd.class); - _discoveryService.init(); + _discoveryService.start(); _discoveryService.cacheResponseMap(cmdClasses); } diff --git a/plugins/api/rate-limit/resources/META-INF/cloudstack/rate-limit/module.properties b/plugins/api/rate-limit/resources/META-INF/cloudstack/rate-limit/module.properties new file mode 100644 index 00000000000..c998a87d937 --- /dev/null +++ b/plugins/api/rate-limit/resources/META-INF/cloudstack/rate-limit/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=rate-limit +parent=api \ No newline at end of file diff --git a/plugins/api/rate-limit/resources/META-INF/cloudstack/rate-limit/spring-rate-limit-context.xml b/plugins/api/rate-limit/resources/META-INF/cloudstack/rate-limit/spring-rate-limit-context.xml new file mode 100644 index 00000000000..17153cf1c9d --- /dev/null +++ b/plugins/api/rate-limit/resources/META-INF/cloudstack/rate-limit/spring-rate-limit-context.xml @@ -0,0 +1,32 @@ + + + + + + diff --git a/plugins/dedicated-resources/resources/META-INF/cloudstack/core/spring-dedicated-resources-core-context.xml b/plugins/dedicated-resources/resources/META-INF/cloudstack/core/spring-dedicated-resources-core-context.xml new file mode 100644 index 00000000000..e2879f71086 --- /dev/null +++ b/plugins/dedicated-resources/resources/META-INF/cloudstack/core/spring-dedicated-resources-core-context.xml @@ -0,0 +1,33 @@ + + + + + + diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java b/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java index 6a6b47ccfd7..cda46efe2ee 100755 --- a/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java +++ b/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java @@ -48,7 +48,6 @@ import org.apache.cloudstack.api.response.DedicatePodResponse; import org.apache.cloudstack.api.response.DedicateZoneResponse; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; - import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -79,6 +78,9 @@ import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.UserVmVO; import com.cloud.vm.dao.UserVmDao; @@ -113,7 +115,7 @@ public class DedicatedResourceManagerImpl implements DedicatedService { @Override @DB @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Zone") - public List dedicateZone(Long zoneId, Long domainId, String accountName) { + public List dedicateZone(final Long zoneId, final Long domainId, final String accountName) { Long accountId = null; List hosts = null; if(accountName != null){ @@ -124,7 +126,7 @@ public class DedicatedResourceManagerImpl implements DedicatedService { List childDomainIds = getDomainChildIds(domainId); childDomainIds.add(domainId); checkAccountAndDomain(accountId, domainId); - DataCenterVO dc = _zoneDao.findById(zoneId); + final DataCenterVO dc = _zoneDao.findById(zoneId); if (dc == null) { throw new InvalidParameterValueException("Unable to find zone by id " + zoneId); } else { @@ -220,46 +222,50 @@ public class DedicatedResourceManagerImpl implements DedicatedService { checkHostsSuitabilityForExplicitDedication(accountId, childDomainIds, hosts); - Transaction txn = Transaction.currentTxn(); - txn.start(); - // find or create the affinity group by name under this account/domain - AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountId); - if (group == null) { - s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group"); - throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support."); - } + final Long accountIdFinal = accountId; + return Transaction.execute(new TransactionCallback>() { + @Override + public List doInTransaction(TransactionStatus status) { + // find or create the affinity group by name under this account/domain + AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountIdFinal); + if (group == null) { + s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group"); + throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support."); + } + + DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(zoneId, null, null, null, null, null, + group.getId()); + try { + dedicatedResource.setDomainId(domainId); + if (accountIdFinal != null) { + dedicatedResource.setAccountId(accountIdFinal); + } + dedicatedResource = _dedicatedDao.persist(dedicatedResource); + + // save the domainId in the zone + dc.setDomainId(domainId); + if (!_zoneDao.update(zoneId, dc)) { + throw new CloudRuntimeException( + "Failed to dedicate zone, could not set domainId. Please contact Cloud Support."); + } + + } catch (Exception e) { + s_logger.error("Unable to dedicate zone due to " + e.getMessage(), e); + throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support."); + } + + List result = new ArrayList(); + result.add(dedicatedResource); + return result; - DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(zoneId, null, null, null, null, null, - group.getId()); - try { - dedicatedResource.setDomainId(domainId); - if (accountId != null) { - dedicatedResource.setAccountId(accountId); } - dedicatedResource = _dedicatedDao.persist(dedicatedResource); - - // save the domainId in the zone - dc.setDomainId(domainId); - if (!_zoneDao.update(zoneId, dc)) { - throw new CloudRuntimeException( - "Failed to dedicate zone, could not set domainId. Please contact Cloud Support."); - } - - } catch (Exception e) { - s_logger.error("Unable to dedicate zone due to " + e.getMessage(), e); - throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support."); - } - txn.commit(); - - List result = new ArrayList(); - result.add(dedicatedResource); - return result; + }); } @Override @DB @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Pod") - public List dedicatePod(Long podId, Long domainId, String accountName) { + public List dedicatePod(final Long podId, final Long domainId, final String accountName) { Long accountId = null; if(accountName != null){ Account caller = CallContext.current().getCallingAccount(); @@ -353,37 +359,40 @@ public class DedicatedResourceManagerImpl implements DedicatedService { checkHostsSuitabilityForExplicitDedication(accountId, childDomainIds, hosts); - Transaction txn = Transaction.currentTxn(); - txn.start(); - // find or create the affinity group by name under this account/domain - AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountId); - if (group == null) { - s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group"); - throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support."); - } - DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, podId, null, null, null, null, - group.getId()); - try { - dedicatedResource.setDomainId(domainId); - if (accountId != null) { - dedicatedResource.setAccountId(accountId); - } - dedicatedResource = _dedicatedDao.persist(dedicatedResource); - } catch (Exception e) { - s_logger.error("Unable to dedicate pod due to " + e.getMessage(), e); - throw new CloudRuntimeException("Failed to dedicate pod. Please contact Cloud Support."); - } - txn.commit(); + final Long accountIdFinal = accountId; + return Transaction.execute(new TransactionCallback>() { + @Override + public List doInTransaction(TransactionStatus status) { + // find or create the affinity group by name under this account/domain + AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountIdFinal); + if (group == null) { + s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group"); + throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support."); + } + DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, podId, null, null, null, null, + group.getId()); + try { + dedicatedResource.setDomainId(domainId); + if (accountIdFinal != null) { + dedicatedResource.setAccountId(accountIdFinal); + } + dedicatedResource = _dedicatedDao.persist(dedicatedResource); + } catch (Exception e) { + s_logger.error("Unable to dedicate pod due to " + e.getMessage(), e); + throw new CloudRuntimeException("Failed to dedicate pod. Please contact Cloud Support."); + } - List result = new ArrayList(); - result.add(dedicatedResource); - return result; + List result = new ArrayList(); + result.add(dedicatedResource); + return result; + } + }); } @Override @DB @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Cluster") - public List dedicateCluster(Long clusterId, Long domainId, String accountName) { + public List dedicateCluster(final Long clusterId, final Long domainId, final String accountName) { Long accountId = null; List hosts = null; if(accountName != null){ @@ -463,37 +472,40 @@ public class DedicatedResourceManagerImpl implements DedicatedService { checkHostsSuitabilityForExplicitDedication(accountId, childDomainIds, hosts); - Transaction txn = Transaction.currentTxn(); - txn.start(); - // find or create the affinity group by name under this account/domain - AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountId); - if (group == null) { - s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group"); - throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support."); - } - DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, null, clusterId, null, null, null, - group.getId()); - try { - dedicatedResource.setDomainId(domainId); - if (accountId != null) { - dedicatedResource.setAccountId(accountId); - } - dedicatedResource = _dedicatedDao.persist(dedicatedResource); - } catch (Exception e) { - s_logger.error("Unable to dedicate host due to " + e.getMessage(), e); - throw new CloudRuntimeException("Failed to dedicate cluster. Please contact Cloud Support."); - } - txn.commit(); + final Long accountIdFinal = accountId; + return Transaction.execute(new TransactionCallback>() { + @Override + public List doInTransaction(TransactionStatus status) { + // find or create the affinity group by name under this account/domain + AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountIdFinal); + if (group == null) { + s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group"); + throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support."); + } + DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, null, clusterId, null, null, null, + group.getId()); + try { + dedicatedResource.setDomainId(domainId); + if (accountIdFinal != null) { + dedicatedResource.setAccountId(accountIdFinal); + } + dedicatedResource = _dedicatedDao.persist(dedicatedResource); + } catch (Exception e) { + s_logger.error("Unable to dedicate host due to " + e.getMessage(), e); + throw new CloudRuntimeException("Failed to dedicate cluster. Please contact Cloud Support."); + } - List result = new ArrayList(); - result.add(dedicatedResource); - return result; + List result = new ArrayList(); + result.add(dedicatedResource); + return result; + } + }); } @Override @DB @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Host") - public List dedicateHost(Long hostId, Long domainId, String accountName) { + public List dedicateHost(final Long hostId, final Long domainId, final String accountName) { Long accountId = null; if(accountName != null){ Account caller = CallContext.current().getCallingAccount(); @@ -558,31 +570,35 @@ public class DedicatedResourceManagerImpl implements DedicatedService { childDomainIds.add(domainId); checkHostSuitabilityForExplicitDedication(accountId, childDomainIds, hostId); - Transaction txn = Transaction.currentTxn(); - txn.start(); - // find or create the affinity group by name under this account/domain - AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountId); - if (group == null) { - s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group"); - throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support."); - } - DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, null, null, hostId, null, null, - group.getId()); - try { - dedicatedResource.setDomainId(domainId); - if (accountId != null) { - dedicatedResource.setAccountId(accountId); - } - dedicatedResource = _dedicatedDao.persist(dedicatedResource); - } catch (Exception e) { - s_logger.error("Unable to dedicate host due to " + e.getMessage(), e); - throw new CloudRuntimeException("Failed to dedicate host. Please contact Cloud Support."); - } - txn.commit(); + final Long accountIdFinal = accountId; + return Transaction.execute(new TransactionCallback>() { + @Override + public List doInTransaction(TransactionStatus status) { + // find or create the affinity group by name under this account/domain + AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountIdFinal); + if (group == null) { + s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group"); + throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support."); + } + DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, null, null, hostId, null, null, + group.getId()); + try { + dedicatedResource.setDomainId(domainId); + if (accountIdFinal != null) { + dedicatedResource.setAccountId(accountIdFinal); + } + dedicatedResource = _dedicatedDao.persist(dedicatedResource); + } catch (Exception e) { + s_logger.error("Unable to dedicate host due to " + e.getMessage(), e); + throw new CloudRuntimeException("Failed to dedicate host. Please contact Cloud Support."); + } + + List result = new ArrayList(); + result.add(dedicatedResource); + return result; + } + }); - List result = new ArrayList(); - result.add(dedicatedResource); - return result; } private AffinityGroup findOrCreateDedicatedAffinityGroup(Long domainId, Long accountId) { @@ -889,9 +905,8 @@ public class DedicatedResourceManagerImpl implements DedicatedService { @Override @DB @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE_RELEASE, eventDescription = "Releasing dedicated resource") - public boolean releaseDedicatedResource(Long zoneId, Long podId, Long clusterId, Long hostId) throws InvalidParameterValueException{ + public boolean releaseDedicatedResource(final Long zoneId, Long podId, Long clusterId, Long hostId) throws InvalidParameterValueException{ DedicatedResourceVO resource = null; - Long resourceId = null; if (zoneId != null) { resource = _dedicatedDao.findByZoneId(zoneId); } @@ -907,26 +922,28 @@ public class DedicatedResourceManagerImpl implements DedicatedService { if (resource == null){ throw new InvalidParameterValueException("No Dedicated Resource available to release"); } else { - Transaction txn = Transaction.currentTxn(); - txn.start(); - resourceId = resource.getId(); - if (!_dedicatedDao.remove(resourceId)) { - throw new CloudRuntimeException("Failed to delete Resource " + resourceId); - } - if (zoneId != null) { - // remove the domainId set in zone - DataCenterVO dc = _zoneDao.findById(zoneId); - if (dc != null) { - dc.setDomainId(null); - dc.setDomain(null); - if (!_zoneDao.update(zoneId, dc)) { - throw new CloudRuntimeException( - "Failed to release dedicated zone, could not clear domainId. Please contact Cloud Support."); + final DedicatedResourceVO resourceFinal = resource; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + Long resourceId = resourceFinal.getId(); + if (!_dedicatedDao.remove(resourceId)) { + throw new CloudRuntimeException("Failed to delete Resource " + resourceId); + } + if (zoneId != null) { + // remove the domainId set in zone + DataCenterVO dc = _zoneDao.findById(zoneId); + if (dc != null) { + dc.setDomainId(null); + dc.setDomain(null); + if (!_zoneDao.update(zoneId, dc)) { + throw new CloudRuntimeException( + "Failed to release dedicated zone, could not clear domainId. Please contact Cloud Support."); + } + } } } - } - - txn.commit(); + }); // find the group associated and check if there are any more // resources under that group diff --git a/plugins/deployment-planners/implicit-dedication/resources/META-INF/cloudstack/implicit-dedication/module.properties b/plugins/deployment-planners/implicit-dedication/resources/META-INF/cloudstack/implicit-dedication/module.properties new file mode 100644 index 00000000000..6cda90463a3 --- /dev/null +++ b/plugins/deployment-planners/implicit-dedication/resources/META-INF/cloudstack/implicit-dedication/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=implicit-dedication +parent=planner \ No newline at end of file diff --git a/plugins/deployment-planners/implicit-dedication/resources/META-INF/cloudstack/implicit-dedication/spring-implicit-dedication-context.xml b/plugins/deployment-planners/implicit-dedication/resources/META-INF/cloudstack/implicit-dedication/spring-implicit-dedication-context.xml new file mode 100644 index 00000000000..d14b4502ab9 --- /dev/null +++ b/plugins/deployment-planners/implicit-dedication/resources/META-INF/cloudstack/implicit-dedication/spring-implicit-dedication-context.xml @@ -0,0 +1,25 @@ + + + + + + + + + diff --git a/plugins/deployment-planners/user-concentrated-pod/resources/META-INF/cloudstack/user-concentrated-pod/module.properties b/plugins/deployment-planners/user-concentrated-pod/resources/META-INF/cloudstack/user-concentrated-pod/module.properties new file mode 100644 index 00000000000..7a430b28228 --- /dev/null +++ b/plugins/deployment-planners/user-concentrated-pod/resources/META-INF/cloudstack/user-concentrated-pod/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=user-concentrated-pod +parent=planner \ No newline at end of file diff --git a/plugins/deployment-planners/user-concentrated-pod/resources/META-INF/cloudstack/user-concentrated-pod/spring-user-concentrated-pod-context.xml b/plugins/deployment-planners/user-concentrated-pod/resources/META-INF/cloudstack/user-concentrated-pod/spring-user-concentrated-pod-context.xml new file mode 100644 index 00000000000..e26cb2be57e --- /dev/null +++ b/plugins/deployment-planners/user-concentrated-pod/resources/META-INF/cloudstack/user-concentrated-pod/spring-user-concentrated-pod-context.xml @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManagerImpl.java b/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManagerImpl.java index 8f7b6d8df8d..e0c2f57d62d 100644 --- a/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManagerImpl.java +++ b/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManagerImpl.java @@ -50,7 +50,7 @@ import com.cloud.netapp.dao.PoolDao; import com.cloud.netapp.dao.VolumeDao; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -225,7 +225,7 @@ public class NetappManagerImpl extends ManagerBase implements NetappManager throw new ResourceInUseException("There are luns on the volume"); } - final Transaction txn = Transaction.currentTxn(); + final TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); PoolVO pool = _poolDao.findById(volume.getPoolId()); if (pool == null) { @@ -388,7 +388,7 @@ public class NetappManagerImpl extends ManagerBase implements NetappManager } Long volumeId = null; - final Transaction txn = Transaction.currentTxn(); + final TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); NetappVolumeVO volume = null; volume = _volumeDao.findVolume(ipAddress, aggName, volName); @@ -624,7 +624,7 @@ public class NetappManagerImpl extends ManagerBase implements NetappManager String[] result = new String[3]; StringBuilder lunName = new StringBuilder("lun-"); LunVO lun = null; - final Transaction txn = Transaction.currentTxn(); + final TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); PoolVO pool = _poolDao.findPool(poolName); @@ -802,7 +802,7 @@ public class NetappManagerImpl extends ManagerBase implements NetappManager @DB public void destroyLunOnFiler(String lunName) throws InvalidParameterValueException, ServerException{ - final Transaction txn = Transaction.currentTxn(); + final TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); LunVO lun = _lunDao.findByName(lunName); diff --git a/plugins/host-allocators/random/resources/META-INF/cloudstack/host-allocator-random/module.properties b/plugins/host-allocators/random/resources/META-INF/cloudstack/host-allocator-random/module.properties new file mode 100644 index 00000000000..9a04174ec7f --- /dev/null +++ b/plugins/host-allocators/random/resources/META-INF/cloudstack/host-allocator-random/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=host-allocator-random +parent=allocator \ No newline at end of file diff --git a/plugins/host-allocators/random/resources/META-INF/cloudstack/host-allocator-random/spring-host-allocator-random-context.xml b/plugins/host-allocators/random/resources/META-INF/cloudstack/host-allocator-random/spring-host-allocator-random-context.xml new file mode 100644 index 00000000000..8df1bdb97cc --- /dev/null +++ b/plugins/host-allocators/random/resources/META-INF/cloudstack/host-allocator-random/spring-host-allocator-random-context.xml @@ -0,0 +1,34 @@ + + + + + + + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/module.properties b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/module.properties new file mode 100644 index 00000000000..654b0d8b5cb --- /dev/null +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=baremetal-compute +parent=compute \ No newline at end of file diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml new file mode 100644 index 00000000000..cce68051239 --- /dev/null +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/module.properties b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/module.properties new file mode 100644 index 00000000000..3307c8cfbd3 --- /dev/null +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=baremetal-discoverer +parent=discoverer \ No newline at end of file diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml new file mode 100644 index 00000000000..8792909ffed --- /dev/null +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/module.properties b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/module.properties new file mode 100644 index 00000000000..acfe59415de --- /dev/null +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=baremetal-network +parent=network \ No newline at end of file diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml new file mode 100644 index 00000000000..40d9f505775 --- /dev/null +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/module.properties b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/module.properties new file mode 100644 index 00000000000..c6c4e744b75 --- /dev/null +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=baremetal-planner +parent=planner \ No newline at end of file diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml new file mode 100644 index 00000000000..8c14c3e2903 --- /dev/null +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-storage/module.properties b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-storage/module.properties new file mode 100644 index 00000000000..b4269a853e0 --- /dev/null +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-storage/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=baremetal-storage +parent=storage \ No newline at end of file diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-storage/spring-baremetal-storage-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-storage/spring-baremetal-storage-context.xml new file mode 100644 index 00000000000..e0a9e36ef7d --- /dev/null +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-storage/spring-baremetal-storage-context.xml @@ -0,0 +1,32 @@ + + + + + + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml new file mode 100644 index 00000000000..11cc6c89e3f --- /dev/null +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java index 314c9577279..4c07dae70ab 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java @@ -255,15 +255,12 @@ public class BareMetalPingServiceImpl extends BareMetalPxeServiceBase implements } BaremetalPxeVO vo = new BaremetalPxeVO(); - Transaction txn = Transaction.currentTxn(); vo.setHostId(pxeServer.getId()); vo.setNetworkServiceProviderId(ntwkSvcProvider.getId()); vo.setPodId(pod.getId()); vo.setPhysicalNetworkId(pcmd.getPhysicalNetworkId()); vo.setDeviceType(BaremetalPxeType.PING.toString()); - txn.start(); _pxeDao.persist(vo); - txn.commit(); return vo; } diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java index a814530b2f7..fa7abd58331 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java @@ -517,7 +517,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource count++; } - return success ? new StopAnswer(cmd, "Success", 0, true) : new StopAnswer(cmd, "IPMI power off failed", false); + return success ? new StopAnswer(cmd, "Success", true) : new StopAnswer(cmd, "IPMI power off failed", false); } protected StartAnswer execute(StartCommand cmd) { diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java index 787137778cd..29e180deafc 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java @@ -22,7 +22,6 @@ import javax.ejb.Local; import javax.inject.Inject; import org.apache.log4j.Logger; - import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -53,6 +52,8 @@ import com.cloud.network.guru.DirectPodBasedNetworkGuru; import com.cloud.network.guru.NetworkGuru; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachineProfile; @@ -100,18 +101,18 @@ public class BaremetaNetworkGuru extends DirectPodBasedNetworkGuru { } else { // we need to get a new ip address if we try to deploy a vm in a // different pod - IPAddressVO ipVO = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), oldIp); + final IPAddressVO ipVO = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), oldIp); if (ipVO != null) { PodVlanMapVO mapVO = _podVlanDao.listPodVlanMapsByVlan(ipVO.getVlanId()); if (mapVO.getPodId() != dest.getPod().getId()) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - - // release the old ip here - _ipAddrMgr.markIpAsUnavailable(ipVO.getId()); - _ipAddressDao.unassignIpAddress(ipVO.getId()); - - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // release the old ip here + _ipAddrMgr.markIpAsUnavailable(ipVO.getId()); + _ipAddressDao.unassignIpAddress(ipVO.getId()); + } + }); nic.setIp4Address(null); getNewIp = true; diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java index 6cf94f2db94..8057cd42f91 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java @@ -50,7 +50,6 @@ import com.cloud.utils.component.AdapterBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.QueryBuilder; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; import com.cloud.vm.ReservationContext; @@ -115,14 +114,11 @@ public class BaremetalDhcpElement extends AdapterBase implements DhcpServiceProv return false; } - Transaction txn = Transaction.currentTxn(); - txn.start(); nic.setMacAddress(host.getPrivateMacAddress()); NicVO vo = _nicDao.findById(nic.getId()); assert vo != null : "Where ths nic " + nic.getId() + " going???"; vo.setMacAddress(nic.getMacAddress()); _nicDao.update(vo.getId(), vo); - txn.commit(); return true; } diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java index 9e1fd65a239..82397f5b31b 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java @@ -69,7 +69,6 @@ import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.QueryBuilder; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; @@ -278,10 +277,7 @@ public class BaremetalDhcpManagerImpl extends ManagerBase implements BaremetalDh vo.setHostId(dhcpServer.getId()); vo.setNetworkServiceProviderId(ntwkSvcProvider.getId()); vo.setPhysicalNetworkId(cmd.getPhysicalNetworkId()); - Transaction txn = Transaction.currentTxn(); - txn.start(); _extDhcpDao.persist(vo); - txn.commit(); return vo; } diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java index aa0ff1c0360..cb4babf93d7 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java @@ -27,11 +27,10 @@ import java.util.Map; import javax.ejb.Local; import javax.inject.Inject; -import org.apache.log4j.Logger; - import org.apache.cloudstack.api.AddBaremetalKickStartPxeCmd; import org.apache.cloudstack.api.AddBaremetalPxeCmd; import org.apache.cloudstack.api.ListBaremetalPxeServersCmd; +import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; import com.cloud.agent.api.baremetal.IpmISetBootDevCommand; @@ -58,7 +57,6 @@ import com.cloud.uservm.UserVm; import com.cloud.utils.db.DB; import com.cloud.utils.db.QueryBuilder; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; @@ -225,14 +223,11 @@ public class BaremetalKickStartServiceImpl extends BareMetalPxeServiceBase imple } BaremetalPxeVO vo = new BaremetalPxeVO(); - Transaction txn = Transaction.currentTxn(); vo.setHostId(pxeServer.getId()); vo.setNetworkServiceProviderId(ntwkSvcProvider.getId()); vo.setPhysicalNetworkId(kcmd.getPhysicalNetworkId()); vo.setDeviceType(BaremetalPxeType.KICK_START.toString()); - txn.start(); _pxeDao.persist(vo); - txn.commit(); return vo; } diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java index 244ce8c823c..b9dbc776692 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java @@ -48,7 +48,6 @@ import com.cloud.utils.component.AdapterBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.QueryBuilder; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; @@ -117,14 +116,11 @@ public class BaremetalPxeElement extends AdapterBase implements NetworkElement { VMInstanceVO vo = _vmDao.findById(vm.getId()); if (vo.getLastHostId() == null) { - Transaction txn = Transaction.currentTxn(); - txn.start(); nic.setMacAddress(dest.getHost().getPrivateMacAddress()); NicVO nicVo = _nicDao.findById(nic.getId()); assert vo != null : "Where ths nic " + nic.getId() + " going???"; nicVo.setMacAddress(nic.getMacAddress()); _nicDao.update(nicVo.getId(), nicVo); - txn.commit(); /*This vm is just being created */ if (!_pxeMgr.prepare(vm, nic, dest, context)) { diff --git a/plugins/hypervisors/kvm/resources/META-INF/cloudstack/kvm-compute/module.properties b/plugins/hypervisors/kvm/resources/META-INF/cloudstack/kvm-compute/module.properties new file mode 100644 index 00000000000..11379727073 --- /dev/null +++ b/plugins/hypervisors/kvm/resources/META-INF/cloudstack/kvm-compute/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=kvm-compute +parent=compute \ No newline at end of file diff --git a/plugins/hypervisors/kvm/resources/META-INF/cloudstack/kvm-compute/spring-kvm-compute-context.xml b/plugins/hypervisors/kvm/resources/META-INF/cloudstack/kvm-compute/spring-kvm-compute-context.xml new file mode 100644 index 00000000000..ce596f22bbf --- /dev/null +++ b/plugins/hypervisors/kvm/resources/META-INF/cloudstack/kvm-compute/spring-kvm-compute-context.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index cddfac9a7a7..51ba743b05e 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -1040,7 +1040,7 @@ ServerResource { s_logger.debug("matchPifFileInDirectory: file name '"+fname+"'"); if (fname.startsWith("eth") || fname.startsWith("bond") || fname.startsWith("vlan") || fname.startsWith("em") - || fname.matches("^p\\d+p\\d+")) { + || fname.matches("^p\\d+p\\d+.*")) { return fname; } } @@ -3257,7 +3257,7 @@ ServerResource { } state = State.Stopped; - return new StopAnswer(cmd, result, 0, true); + return new StopAnswer(cmd, result, true); } catch (LibvirtException e) { return new StopAnswer(cmd, e.getMessage(), false); } finally { diff --git a/plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-compute/module.properties b/plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-compute/module.properties new file mode 100644 index 00000000000..1d93fa1efe7 --- /dev/null +++ b/plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-compute/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=ovm-compute +parent=compute \ No newline at end of file diff --git a/plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-compute/spring-ovm-compute-context.xml b/plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-compute/spring-ovm-compute-context.xml new file mode 100644 index 00000000000..b12672a6a45 --- /dev/null +++ b/plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-compute/spring-ovm-compute-context.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + diff --git a/plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-discoverer/module.properties b/plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-discoverer/module.properties new file mode 100644 index 00000000000..3a4b1f8740f --- /dev/null +++ b/plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-discoverer/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=ovm-discoverer +parent=discoverer \ No newline at end of file diff --git a/plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-discoverer/spring-ovm-discoverer-context.xml b/plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-discoverer/spring-ovm-discoverer-context.xml new file mode 100644 index 00000000000..b0f2a15519f --- /dev/null +++ b/plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-discoverer/spring-ovm-discoverer-context.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java b/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java index 1eddedc6f19..2d0d67b2f41 100755 --- a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java +++ b/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java @@ -732,7 +732,7 @@ public class OvmResourceBase implements ServerResource, HypervisorResource { vm = OvmVm.getDetails(_conn, vmName); } catch (XmlRpcException e) { s_logger.debug("Unable to get details of vm: " + vmName + ", treating it as stopped", e); - return new StopAnswer(cmd, "success", 0, true); + return new StopAnswer(cmd, "success", true); } deleteAllNetworkRulesForVm(vmName); @@ -740,7 +740,7 @@ public class OvmResourceBase implements ServerResource, HypervisorResource { cleanup(vm); state = State.Stopped; - return new StopAnswer(cmd, "success", 0, true); + return new StopAnswer(cmd, "success", true); } catch (Exception e) { s_logger.debug("Stop " + vmName + "failed", e); return new StopAnswer(cmd, e.getMessage(), false); diff --git a/plugins/hypervisors/simulator/resources/META-INF/cloudstack/core/spring-simulator-core-context.xml b/plugins/hypervisors/simulator/resources/META-INF/cloudstack/core/spring-simulator-core-context.xml new file mode 100644 index 00000000000..4905ae80b8f --- /dev/null +++ b/plugins/hypervisors/simulator/resources/META-INF/cloudstack/core/spring-simulator-core-context.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + diff --git a/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-compute/module.properties b/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-compute/module.properties new file mode 100644 index 00000000000..7b12a088161 --- /dev/null +++ b/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-compute/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=simulator-compute +parent=compute \ No newline at end of file diff --git a/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-compute/spring-simulator-compute-context.xml b/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-compute/spring-simulator-compute-context.xml new file mode 100644 index 00000000000..11462333d0e --- /dev/null +++ b/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-compute/spring-simulator-compute-context.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-discoverer/module.properties b/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-discoverer/module.properties new file mode 100644 index 00000000000..536cf1562fd --- /dev/null +++ b/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-discoverer/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=simulator-discoverer +parent=discoverer \ No newline at end of file diff --git a/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-discoverer/spring-simulator-discover-context.xml b/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-discoverer/spring-simulator-discover-context.xml new file mode 100644 index 00000000000..323f64fdac7 --- /dev/null +++ b/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-discoverer/spring-simulator-discover-context.xml @@ -0,0 +1,36 @@ + + + + + + + + + + diff --git a/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-planner/module.properties b/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-planner/module.properties new file mode 100644 index 00000000000..055be735d25 --- /dev/null +++ b/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-planner/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=simulator-planner +parent=planner \ No newline at end of file diff --git a/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-planner/spring-context.xml b/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-planner/spring-context.xml new file mode 100644 index 00000000000..8c14c3e2903 --- /dev/null +++ b/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-planner/spring-context.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-storage/module.properties b/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-storage/module.properties new file mode 100644 index 00000000000..97a1784c82a --- /dev/null +++ b/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-storage/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=simulator-storage +parent=storage \ No newline at end of file diff --git a/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-storage/spring-simulator-storage-context.xml b/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-storage/spring-simulator-storage-context.xml new file mode 100644 index 00000000000..4cb73e60bae --- /dev/null +++ b/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-storage/spring-simulator-storage-context.xml @@ -0,0 +1,33 @@ + + + + + + diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java index fcc1b4f2209..4071aeb4c46 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java @@ -16,6 +16,25 @@ // under the License. package com.cloud.agent.manager; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.regex.PatternSyntaxException; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.CheckHealthCommand; @@ -31,7 +50,12 @@ import com.cloud.dc.dao.HostPodDao; import com.cloud.exception.DiscoveryException; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; -import com.cloud.resource.*; +import com.cloud.resource.AgentResourceBase; +import com.cloud.resource.AgentRoutingResource; +import com.cloud.resource.AgentStorageResource; +import com.cloud.resource.Discoverer; +import com.cloud.resource.ResourceManager; +import com.cloud.resource.SimulatorSecondaryDiscoverer; import com.cloud.simulator.MockHost; import com.cloud.simulator.MockHostVO; import com.cloud.simulator.MockVMVO; @@ -41,27 +65,9 @@ import com.cloud.utils.Pair; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; -import org.apache.cloudstack.api.command.admin.host.AddSecondaryStorageCmd; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -import javax.ejb.Local; -import javax.inject.Inject; -import javax.naming.ConfigurationException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.regex.PatternSyntaxException; @Component @Local(value = { MockAgentManager.class }) @@ -81,10 +87,13 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage MockStorageManager _storageMgr = null; @Inject ResourceManager _resourceMgr; - @Inject + SimulatorSecondaryDiscoverer discoverer; @Inject HostDao hostDao; + + List discoverers; + private SecureRandom random; private final Map _resources = new ConcurrentHashMap(); private ThreadPoolExecutor _executor; @@ -159,7 +168,7 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage mockHost.setVersion(this.getClass().getPackage().getImplementationVersion()); mockHost.setResource("com.cloud.agent.AgentRoutingResource"); - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); mockHost = _mockHostDao.persist(mockHost); @@ -170,7 +179,7 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage throw new CloudRuntimeException("Error configuring agent", ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -256,7 +265,7 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage private void handleSystemVMStop() { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { if (this.mode.equalsIgnoreCase("Stop")) { txn.start(); @@ -279,7 +288,7 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage throw new CloudRuntimeException("Unable to get host " + guid + " due to " + ex.getMessage(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -323,7 +332,7 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage mockHost.setVersion(this.getClass().getPackage().getImplementationVersion()); mockHost.setResource(resource); mockHost.setVmId(vmId); - Transaction simtxn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy simtxn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { simtxn.start(); mockHost = _mockHostDao.persist(mockHost); @@ -334,7 +343,7 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage + ex.getMessage(), ex); } finally { simtxn.close(); - simtxn = Transaction.open(Transaction.CLOUD_DB); + simtxn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); simtxn.close(); } @@ -366,7 +375,7 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage @Override public MockHost getHost(String guid) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); MockHost _host = _mockHostDao.findByGuid(guid); @@ -382,7 +391,7 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage throw new CloudRuntimeException("Unable to get host " + guid + " due to " + ex.getMessage(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @@ -391,7 +400,7 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage public GetHostStatsAnswer getHostStatistic(GetHostStatsCommand cmd) { String hostGuid = cmd.getHostGuid(); MockHost host = null; - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); host = _mockHostDao.findByGuid(hostGuid); @@ -404,11 +413,11 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage throw new CloudRuntimeException("Unable to get host " + hostGuid + " due to " + ex.getMessage(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } - Transaction vmtxn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy vmtxn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { vmtxn.start(); List vms = _mockVmDao.findByHostId(host.getId()); @@ -435,7 +444,7 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage + ex.getMessage(), ex); } finally { vmtxn.close(); - vmtxn = Transaction.open(Transaction.CLOUD_DB); + vmtxn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); vmtxn.close(); } } @@ -452,6 +461,17 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage @Override public boolean start() { + for ( Discoverer discoverer : discoverers ) { + if ( discoverer instanceof SimulatorSecondaryDiscoverer ) { + this.discoverer = (SimulatorSecondaryDiscoverer)discoverer; + break; + } + } + + if ( this.discoverer == null ) { + throw new IllegalStateException("Failed to find SimulatorSecondaryDiscoverer"); + } + return true; } @@ -477,4 +497,13 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage } return new CheckNetworkAnswer(cmd, true, "Network Setup check by names is done"); } + + public List getDiscoverers() { + return discoverers; + } + + @Inject + public void setDiscoverers(List discoverers) { + this.discoverers = discoverers; + } } diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java index d23575bfee3..64463d486ae 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java @@ -76,7 +76,7 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.template.TemplateProp; import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.ManagerBase; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine.State; @@ -120,7 +120,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa VMTemplateDao templateDao; private MockVolumeVO findVolumeFromSecondary(String path, String ssUrl, MockVolumeType type) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); String volumePath = path.replaceAll(ssUrl, ""); @@ -141,7 +141,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Unable to find volume " + path + " on secondary " + ssUrl, ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @@ -154,7 +154,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa return new PrimaryStorageDownloadAnswer("Can't find primary storage"); } - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); MockStoragePoolVO primaryStorage = null; try { txn.start(); @@ -168,7 +168,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when finding primary storagee " + cmd.getPoolUuid(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -179,7 +179,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa newVolume.setPoolId(primaryStorage.getId()); newVolume.setSize(template.getSize()); newVolume.setType(MockVolumeType.VOLUME); - txn = Transaction.open(Transaction.SIMULATOR_DB); + txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); _mockVolumeDao.persist(newVolume); @@ -189,7 +189,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when saving volume " + newVolume, ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } return new PrimaryStorageDownloadAnswer(newVolume.getPath(), newVolume.getSize()); @@ -200,7 +200,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa StorageFilerTO sf = cmd.getPool(); DiskProfile dskch = cmd.getDiskCharacteristics(); MockStoragePoolVO storagePool = null; - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); storagePool = _mockStoragePoolDao.findByUuid(sf.getUuid()); @@ -213,7 +213,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when finding storage " + sf.getUuid(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -224,7 +224,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa volume.setPath(storagePool.getMountPoint() + volumeName); volume.setSize(dskch.getSize()); volume.setType(MockVolumeType.VOLUME); - txn = Transaction.open(Transaction.SIMULATOR_DB); + txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); volume = _mockVolumeDao.persist(volume); @@ -234,7 +234,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when saving volume " + volume, ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -246,7 +246,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa @Override public AttachVolumeAnswer AttachVolume(AttachVolumeCommand cmd) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); String poolid = cmd.getPoolUuid(); @@ -270,7 +270,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa + cmd.getVmName(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @@ -284,7 +284,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa } String vmName = cmd.getVmName(); - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); MockVMVO vm = null; try { txn.start(); @@ -298,7 +298,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when attaching iso to vm " + vm.getName(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } return new Answer(cmd); @@ -306,7 +306,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa @Override public Answer DeleteStoragePool(DeleteStoragePoolCommand cmd) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); MockStoragePoolVO storage = _mockStoragePoolDao.findByUuid(cmd.getPool().getUuid()); @@ -321,7 +321,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when deleting storage pool " + cmd.getPool().getPath(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @@ -329,7 +329,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa @Override public ModifyStoragePoolAnswer ModifyStoragePool(ModifyStoragePoolCommand cmd) { StorageFilerTO sf = cmd.getPool(); - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); MockStoragePoolVO storagePool = null; try { txn.start(); @@ -361,7 +361,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when modifying storage pool " + cmd.getPool().getPath(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap()); @@ -370,7 +370,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa @Override public Answer CreateStoragePool(CreateStoragePoolCommand cmd) { StorageFilerTO sf = cmd.getPool(); - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); MockStoragePoolVO storagePool = null; try { txn.start(); @@ -402,7 +402,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when creating storage pool " + cmd.getPool().getPath(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap()); @@ -410,7 +410,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa @Override public Answer SecStorageSetup(SecStorageSetupCommand cmd) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); MockSecStorageVO storage = null; try { txn.start(); @@ -424,7 +424,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when setting up sec storage" + cmd.getSecUrl(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } return new SecStorageSetupAnswer(storage.getMountPoint()); @@ -432,7 +432,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa @Override public Answer ListVolumes(ListVolumeCommand cmd) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); MockSecStorageVO storage = null; try { txn.start(); @@ -446,11 +446,11 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when finding sec storage " + cmd.getSecUrl(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } - txn = Transaction.open(Transaction.SIMULATOR_DB); + txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); List volumes = _mockVolumeDao.findByStorageIdAndType(storage.getId(), @@ -468,7 +468,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when finding template on sec storage " + storage.getId(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @@ -483,7 +483,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa MockSecStorageVO storage = null; String nfsUrl = ((NfsTO) store).getUrl(); - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); storage = _mockSecStorageDao.findByUrl(nfsUrl); try { txn.start(); @@ -501,14 +501,14 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when finding template on sec storage " + storage.getId(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @Override public Answer Destroy(DestroyCommand cmd) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); MockVolumeVO volume = _mockVolumeDao.findByStoragePathAndType(cmd.getVolume().getPath()); @@ -530,7 +530,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when destroying volume " + cmd.getVolume().getPath(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } return new Answer(cmd); @@ -539,7 +539,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa @Override public DownloadAnswer Download(DownloadCommand cmd) { MockSecStorageVO ssvo = null; - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); ssvo = _mockSecStorageDao.findByUrl(cmd.getSecUrl()); @@ -553,7 +553,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error accessing secondary storage " + cmd.getSecUrl(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -564,7 +564,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa volume.setSize(0); volume.setType(MockVolumeType.TEMPLATE); volume.setStatus(Status.DOWNLOAD_IN_PROGRESS); - txn = Transaction.open(Transaction.SIMULATOR_DB); + txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); volume = _mockVolumeDao.persist(volume); @@ -574,7 +574,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when saving volume " + volume, ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } return new DownloadAnswer(String.valueOf(volume.getId()), 0, "Downloading", Status.DOWNLOAD_IN_PROGRESS, @@ -583,7 +583,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa @Override public DownloadAnswer DownloadProcess(DownloadProgressCommand cmd) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); String volumeId = cmd.getJobId(); @@ -616,7 +616,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error during download job " + cmd.getJobId(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @@ -624,7 +624,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa @Override public GetStorageStatsAnswer GetStorageStats(GetStorageStatsCommand cmd) { String uuid = cmd.getStorageId(); - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); if (uuid == null) { @@ -653,7 +653,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("DBException during storage stats collection for pool " + uuid, ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @@ -663,7 +663,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa String volPath = cmd.getVolumePath(); MockVolumeVO volume = null; MockStoragePoolVO storagePool = null; - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); volume = _mockVolumeDao.findByStoragePathAndType(volPath); @@ -680,7 +680,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Unable to perform snapshot", ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -693,7 +693,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa snapshot.setPoolId(storagePool.getId()); snapshot.setType(MockVolumeType.SNAPSHOT); snapshot.setStatus(Status.DOWNLOADED); - txn = Transaction.open(Transaction.SIMULATOR_DB); + txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); snapshot = _mockVolumeDao.persist(snapshot); @@ -703,7 +703,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when saving snapshot " + snapshot, ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -717,7 +717,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa MockVolumeVO volume = null; MockVolumeVO snapshot = null; MockSecStorageVO secStorage = null; - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); volume = _mockVolumeDao.findByStoragePathAndType(cmd.getVolumePath()); @@ -742,7 +742,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when backing up snapshot"); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -754,7 +754,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa newsnapshot.setSize(snapshot.getSize()); newsnapshot.setStatus(Status.DOWNLOADED); newsnapshot.setType(MockVolumeType.SNAPSHOT); - txn = Transaction.open(Transaction.SIMULATOR_DB); + txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); snapshot = _mockVolumeDao.persist(snapshot); @@ -764,7 +764,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when backing up snapshot " + newsnapshot, ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -773,7 +773,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa @Override public CreateVolumeFromSnapshotAnswer CreateVolumeFromSnapshot(CreateVolumeFromSnapshotCommand cmd) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); MockVolumeVO backSnapshot = null; MockStoragePoolVO primary = null; try { @@ -795,7 +795,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when creating volume from snapshot", ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -808,7 +808,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa volume.setSize(backSnapshot.getSize()); volume.setStatus(Status.DOWNLOADED); volume.setType(MockVolumeType.VOLUME); - txn = Transaction.open(Transaction.SIMULATOR_DB); + txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); _mockVolumeDao.persist(volume); @@ -818,7 +818,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when creating volume from snapshot " + volume, ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -828,7 +828,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa @Override public Answer Delete(DeleteCommand cmd) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); MockVolumeVO template = _mockVolumeDao.findByStoragePathAndType(cmd.getData().getPath()); @@ -842,7 +842,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when deleting object"); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } return new Answer(cmd); @@ -879,7 +879,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa @Override public void preinstallTemplates(String url, long zoneId) { MockSecStorageVO storage = null; - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); storage = _mockSecStorageDao.findByUrl(url); @@ -933,14 +933,14 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa } catch (Exception ex) { throw new CloudRuntimeException("Unable to find sec storage at " + url, ex); } finally { - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @Override public StoragePoolInfo getLocalStorage(String hostGuid) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); MockHost host = null; MockStoragePoolVO storagePool = null; try { @@ -953,7 +953,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Unable to find host " + hostGuid, ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -965,7 +965,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa storagePool.setCapacity(DEFAULT_HOST_STORAGE_SIZE); storagePool.setHostGuid(hostGuid); storagePool.setStorageType(StoragePoolType.Filesystem); - txn = Transaction.open(Transaction.SIMULATOR_DB); + txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); storagePool = _mockStoragePoolDao.persist(storagePool); @@ -975,7 +975,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when saving storagePool " + storagePool, ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @@ -985,7 +985,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa @Override public StoragePoolInfo getLocalStorage(String hostGuid, Long storageSize) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); MockHost host = null; try { txn.start(); @@ -996,13 +996,13 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Unable to find host " + hostGuid, ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } if (storageSize == null) { storageSize = DEFAULT_HOST_STORAGE_SIZE; } - txn = Transaction.open(Transaction.SIMULATOR_DB); + txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); MockStoragePoolVO storagePool = null; try { txn.start(); @@ -1013,7 +1013,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when finding storagePool " + storagePool, ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } if (storagePool == null) { @@ -1024,7 +1024,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa storagePool.setCapacity(storageSize); storagePool.setHostGuid(hostGuid); storagePool.setStorageType(StoragePoolType.Filesystem); - txn = Transaction.open(Transaction.SIMULATOR_DB); + txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); storagePool = _mockStoragePoolDao.persist(storagePool); @@ -1034,7 +1034,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when saving storagePool " + storagePool, ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @@ -1044,7 +1044,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa @Override public CreatePrivateTemplateAnswer CreatePrivateTemplateFromSnapshot(CreatePrivateTemplateFromSnapshotCommand cmd) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); MockVolumeVO snapshot = null; MockSecStorageVO sec = null; try { @@ -1066,7 +1066,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa txn.commit(); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -1078,7 +1078,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa template.setSize(snapshot.getSize()); template.setStatus(Status.DOWNLOADED); template.setType(MockVolumeType.TEMPLATE); - txn = Transaction.open(Transaction.SIMULATOR_DB); + txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); template = _mockVolumeDao.persist(template); @@ -1088,7 +1088,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when saving template " + template, ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -1098,7 +1098,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa @Override public Answer ComputeChecksum(ComputeChecksumCommand cmd) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); MockVolumeVO volume = _mockVolumeDao.findByName(cmd.getTemplatePath()); @@ -1116,14 +1116,14 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa return new Answer(cmd, true, md5); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @Override public CreatePrivateTemplateAnswer CreatePrivateTemplateFromVolume(CreatePrivateTemplateFromVolumeCommand cmd) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); MockVolumeVO volume = null; MockSecStorageVO sec = null; try { @@ -1143,7 +1143,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa throw new CloudRuntimeException("Error when creating private template from volume"); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -1155,7 +1155,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa template.setSize(volume.getSize()); template.setStatus(Status.DOWNLOADED); template.setType(MockVolumeType.TEMPLATE); - txn = Transaction.open(Transaction.SIMULATOR_DB); + txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); template = _mockVolumeDao.persist(template); @@ -1166,7 +1166,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa + template.getName(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -1176,7 +1176,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa @Override public CopyVolumeAnswer CopyVolume(CopyVolumeCommand cmd) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); boolean toSecondaryStorage = cmd.toSecondaryStorage(); MockSecStorageVO sec = null; MockStoragePoolVO primaryStorage = null; @@ -1193,11 +1193,11 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa + cmd.getSecondaryStorageURL(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } - txn = Transaction.open(Transaction.SIMULATOR_DB); + txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); primaryStorage = _mockStoragePoolDao.findByUuid(cmd.getPool().getUuid()); @@ -1211,12 +1211,12 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa + cmd.getPool(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } MockVolumeVO volume = null; - txn = Transaction.open(Transaction.SIMULATOR_DB); + txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); volume = _mockVolumeDao.findByStoragePathAndType(cmd.getVolumePath()); @@ -1230,7 +1230,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa + cmd.getVolumePath(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -1243,7 +1243,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa vol.setSize(volume.getSize()); vol.setStatus(Status.DOWNLOADED); vol.setType(MockVolumeType.VOLUME); - txn = Transaction.open(Transaction.SIMULATOR_DB); + txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); vol = _mockVolumeDao.persist(vol); @@ -1254,7 +1254,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa + vol.getName(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } return new CopyVolumeAnswer(cmd, true, null, sec.getMountPoint(), vol.getPath()); @@ -1266,7 +1266,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa vol.setSize(volume.getSize()); vol.setStatus(Status.DOWNLOADED); vol.setType(MockVolumeType.VOLUME); - txn = Transaction.open(Transaction.SIMULATOR_DB); + txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); vol = _mockVolumeDao.persist(vol); @@ -1277,7 +1277,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa + vol.getName(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } return new CopyVolumeAnswer(cmd, true, null, primaryStorage.getMountPoint(), vol.getPath()); diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java index 64df113ea91..28e235e556e 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java @@ -72,7 +72,7 @@ import com.cloud.simulator.dao.MockVMDao; import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.component.ManagerBase; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine.State; import org.apache.log4j.Logger; @@ -111,7 +111,7 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { int cpuHz, long ramSize, String bootArgs, String hostGuid) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); MockHost host = null; MockVm vm = null; try { @@ -128,7 +128,7 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { throw new CloudRuntimeException("Unable to start VM " + vmName, ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } @@ -153,7 +153,7 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { } else if (vmName.startsWith("i-")) { vm.setType("User"); } - txn = Transaction.open(Transaction.SIMULATOR_DB); + txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); vm = _mockVmDao.persist((MockVMVO) vm); @@ -163,13 +163,13 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { throw new CloudRuntimeException("unable to save vm to db " + vm.getName(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } else { if(vm.getState() == State.Stopped) { vm.setState(State.Running); - txn = Transaction.open(Transaction.SIMULATOR_DB); + txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); _mockVmDao.update(vm.getId(), (MockVMVO)vm); @@ -179,7 +179,7 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { throw new CloudRuntimeException("unable to update vm " + vm.getName(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @@ -230,7 +230,7 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { @Override public Map getVms(String hostGuid) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); List vms = _mockVmDao.findByHostGuid(hostGuid); @@ -245,7 +245,7 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { throw new CloudRuntimeException("unable to fetch vms from host " + hostGuid, ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @@ -282,7 +282,7 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { @Override public Map getVmStates(String hostGuid) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); Map states = new HashMap(); @@ -301,7 +301,7 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { throw new CloudRuntimeException("unable to fetch vms from host " + hostGuid, ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @@ -338,7 +338,7 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { @Override public CheckVirtualMachineAnswer checkVmState(CheckVirtualMachineCommand cmd) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); MockVMVO vm = _mockVmDao.findByVmName(cmd.getVmName()); @@ -353,7 +353,7 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { throw new CloudRuntimeException("unable to fetch vm state " + cmd.getVmName(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @@ -378,7 +378,7 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { @Override public MigrateAnswer Migrate(MigrateCommand cmd, SimulatorInfo info) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); String vmName = cmd.getVmName(); @@ -405,14 +405,14 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { throw new CloudRuntimeException("unable to migrate vm " + cmd.getVmName(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @Override public PrepareForMigrationAnswer prepareForMigrate(PrepareForMigrationCommand cmd) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); VirtualMachineTO vmTo = cmd.getVirtualMachine(); try { txn.start(); @@ -425,7 +425,7 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { throw new CloudRuntimeException("unable to find vm " + vmTo.getName(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); return new PrepareForMigrationAnswer(cmd); } @@ -438,7 +438,7 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { @Override public Answer CleanupNetworkRules(CleanupNetworkRulesCmd cmd, SimulatorInfo info) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); List rules = _mockSecurityDao.findByHost(info.getHostUuid()); @@ -455,7 +455,7 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { throw new CloudRuntimeException("unable to clean up rules", ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @@ -503,7 +503,7 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { @Override public StopAnswer stopVM(StopCommand cmd) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); String vmName = cmd.getVmName(); @@ -517,20 +517,20 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { _mockAgentMgr.handleSystemVMStop(vm.getId()); } txn.commit(); - return new StopAnswer(cmd, null, new Integer(0), true); + return new StopAnswer(cmd, null, true); } catch (Exception ex) { txn.rollback(); throw new CloudRuntimeException("unable to stop vm " + cmd.getVmName(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @Override public RebootAnswer rebootVM(RebootCommand cmd) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); MockVm vm = _mockVmDao.findByVmName(cmd.getVmName()); @@ -545,7 +545,7 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager { throw new CloudRuntimeException("unable to stop vm " + cmd.getVmName(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java index f6bd2b651ba..f30bd3661d0 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java @@ -99,7 +99,7 @@ import com.cloud.utils.Pair; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.component.PluggableService; import com.cloud.utils.db.DB; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine.State; import org.apache.cloudstack.storage.command.DeleteCommand; @@ -182,7 +182,7 @@ public class SimulatorManagerImpl extends ManagerBase implements SimulatorManage @DB @Override public Answer simulate(Command cmd, String hostGuid) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { MockHost host = _mockHost.findByGuid(hostGuid); String cmdName = cmd.toString(); @@ -373,7 +373,7 @@ public class SimulatorManagerImpl extends ManagerBase implements SimulatorManage return new Answer(cmd, false, e.toString()); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } } @@ -403,7 +403,7 @@ public class SimulatorManagerImpl extends ManagerBase implements SimulatorManage @Override public boolean configureSimulator(Long zoneId, Long podId, Long clusterId, Long hostId, String command, String values) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB); try { txn.start(); MockConfigurationVO config = _mockConfigDao.findByCommand(zoneId, podId, clusterId, hostId, command); @@ -427,7 +427,7 @@ public class SimulatorManagerImpl extends ManagerBase implements SimulatorManage throw new CloudRuntimeException("Unable to configure simulator because of " + ex.getMessage(), ex); } finally { txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); + txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); } return true; diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java index 8a03c4b9598..9a27d748a29 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java +++ b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java @@ -231,7 +231,7 @@ public class AgentRoutingResource extends AgentStorageResource { return new StopAnswer(cmd, result.getDetails(), false); } - answer = new StopAnswer(cmd, null, 0, true); + answer = new StopAnswer(cmd, null, true); Pair data = _runningVms.get(vmName); if (data != null) { this.usedCpu -= data.first(); diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockConfigurationDaoImpl.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockConfigurationDaoImpl.java index fd825b751ed..a681c061a28 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockConfigurationDaoImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockConfigurationDaoImpl.java @@ -20,7 +20,7 @@ import com.cloud.simulator.MockConfigurationVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import org.springframework.stereotype.Component; import javax.ejb.Local; @@ -117,7 +117,7 @@ public class MockConfigurationDaoImpl extends GenericDaoBase volumeMap, Host srcHost, Host destHost) { - return Priority.HYPERVISOR; + public StrategyPriority canHandle(Map volumeMap, Host srcHost, Host destHost) { + return StrategyPriority.HYPERVISOR; } @Override diff --git a/plugins/hypervisors/ucs/resources/META-INF/cloudstack/core/spring-ucs-core-context.xml b/plugins/hypervisors/ucs/resources/META-INF/cloudstack/core/spring-ucs-core-context.xml new file mode 100644 index 00000000000..47732f46092 --- /dev/null +++ b/plugins/hypervisors/ucs/resources/META-INF/cloudstack/core/spring-ucs-core-context.xml @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java index 9dfe91d5124..4239482d1cb 100755 --- a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java +++ b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java @@ -226,10 +226,7 @@ public class UcsManagerImpl implements UcsManager { vo.setZoneId(cmd.getZoneId()); vo.setName(cmd.getName()); - Transaction txn = Transaction.currentTxn(); - txn.start(); mgrvo = ucsDao.persist(vo); - txn.commit(); UcsManagerResponse rsp = new UcsManagerResponse(); rsp.setId(String.valueOf(vo.getId())); rsp.setName(vo.getName()); diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/core/spring-vmware-core-context.xml b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/core/spring-vmware-core-context.xml new file mode 100644 index 00000000000..406ffe16b4e --- /dev/null +++ b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/core/spring-vmware-core-context.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-compute/module.properties b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-compute/module.properties new file mode 100644 index 00000000000..b605835b94f --- /dev/null +++ b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-compute/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=vmware-compute +parent=compute \ No newline at end of file diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-compute/spring-vmware-compute-context.xml b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-compute/spring-vmware-compute-context.xml new file mode 100644 index 00000000000..402640db8fe --- /dev/null +++ b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-compute/spring-vmware-compute-context.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-compute/vmware-defaults.properties b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-compute/vmware-defaults.properties new file mode 100644 index 00000000000..334e9fffaa9 --- /dev/null +++ b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-compute/vmware-defaults.properties @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +premium=true diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-discoverer/module.properties b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-discoverer/module.properties new file mode 100644 index 00000000000..0d726f85b48 --- /dev/null +++ b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-discoverer/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=vmware-discoverer +parent=discoverer \ No newline at end of file diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-discoverer/spring-vmware-discoverer-context.xml b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-discoverer/spring-vmware-discoverer-context.xml new file mode 100644 index 00000000000..933f0e8a723 --- /dev/null +++ b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-discoverer/spring-vmware-discoverer-context.xml @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-network/module.properties b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-network/module.properties new file mode 100644 index 00000000000..91ea24cc557 --- /dev/null +++ b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-network/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=vmware-network +parent=network \ No newline at end of file diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-network/spring-vmware-network-context.xml b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-network/spring-vmware-network-context.xml new file mode 100644 index 00000000000..440356b3f53 --- /dev/null +++ b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-network/spring-vmware-network-context.xml @@ -0,0 +1,34 @@ + + + + + + + + \ No newline at end of file diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-storage/module.properties b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-storage/module.properties new file mode 100644 index 00000000000..9c3bab68940 --- /dev/null +++ b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-storage/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=vmware-storage +parent=storage \ No newline at end of file diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-storage/spring-vmware-storage-context.xml b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-storage/spring-vmware-storage-context.xml new file mode 100644 index 00000000000..bb428bfbdeb --- /dev/null +++ b/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-storage/spring-vmware-storage-context.xml @@ -0,0 +1,33 @@ + + + + + + diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java index fd7b3b48795..58255bf2e58 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java @@ -60,10 +60,12 @@ import com.cloud.hypervisor.vmware.resource.VmwareResource; import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.network.NetworkModel; import com.cloud.network.Networks.TrafficType; +import com.cloud.network.Network; import com.cloud.network.PhysicalNetwork; import com.cloud.network.VmwareTrafficLabel; import com.cloud.network.dao.CiscoNexusVSMDeviceDao; import com.cloud.network.element.CiscoNexusVSMElement; +import com.cloud.network.element.NetworkElement; import com.cloud.resource.Discoverer; import com.cloud.resource.DiscovererBase; import com.cloud.resource.ResourceManager; @@ -105,8 +107,8 @@ public class VmwareServerDiscoverer extends DiscovererBase implements ResourceManager _resourceMgr; @Inject CiscoNexusVSMDeviceDao _nexusDao; - @Inject CiscoNexusVSMElement _nexusElement; + List networkElements; @Inject NetworkModel _netmgr; @Inject @@ -450,6 +452,15 @@ public class VmwareServerDiscoverer extends DiscovererBase implements } } } + + protected CiscoNexusVSMElement getCiscoNexusVSMElement() { + for ( NetworkElement networkElement : networkElements ) { + if ( networkElement instanceof CiscoNexusVSMElement ) + return (CiscoNexusVSMElement)networkElement; + } + + throw new IllegalStateException("Failed to CiscoNexusVSMElement"); + } private VmwareDatacenterVO fetchVmwareDatacenterByZone(Long dcId) throws DiscoveryException { VmwareDatacenterVO vmwareDc; @@ -640,6 +651,16 @@ public class VmwareServerDiscoverer extends DiscovererBase implements } + @Override + public boolean start() { + if ( ! super.start() ) + return false; + + _nexusElement = getCiscoNexusVSMElement(); + + return true; + } + @Override public boolean stop() { _resourceMgr.unregisterResourceStateAdapter(this.getClass() @@ -791,4 +812,14 @@ public class VmwareServerDiscoverer extends DiscovererBase implements } _urlParams.putAll(params); } + + public List getNetworkElements() { + return networkElements; + } + + @Inject + public void setNetworkElements(List networkElements) { + this.networkElements = networkElements; + } + } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index 211f6685c57..9af0aa002d8 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -120,6 +120,8 @@ import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; import com.cloud.utils.ssh.SshHelper; @@ -1091,32 +1093,12 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw // Add DC to database into vmware_data_center table vmwareDc = new VmwareDatacenterVO(guid, vmwareDcName, vCenterHost, userName, password); - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - vmwareDc = _vmwareDcDao.persist(vmwareDc); - txn.commit(); - } catch (Exception e) { - txn.rollback(); - s_logger.error("Failed to persist VMware datacenter details to database. Exception: " + e.getMessage()); - throw new CloudRuntimeException(e.getMessage()); - } + vmwareDc = _vmwareDcDao.persist(vmwareDc); // Map zone with vmware datacenter vmwareDcZoneMap = new VmwareDatacenterZoneMapVO(zoneId, vmwareDc.getId()); - txn = Transaction.currentTxn(); - try { - txn.start(); - vmwareDcZoneMap = _vmwareDcZoneMapDao.persist(vmwareDcZoneMap); - txn.commit(); - } catch (Exception e) { - txn.rollback(); - s_logger.error("Failed to associate VMware datacenter with zone " + zoneId + ". Exception: " + e.getMessage()); - // Removing VMware datacenter from vmware_data_center table because association with zone failed. - _vmwareDcDao.remove(vmwareDcZoneMap.getId()); - throw new CloudRuntimeException(e.getMessage()); - } + vmwareDcZoneMap = _vmwareDcZoneMapDao.persist(vmwareDcZoneMap); // Set custom field for this DC if (addDcCustomFieldDef) { @@ -1152,40 +1134,35 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw validateZoneWithResources(zoneId, "remove VMware datacenter to zone"); // Get DC associated with this zone - VmwareDatacenterZoneMapVO vmwareDcZoneMap; VmwareDatacenterVO vmwareDatacenter; String vmwareDcName; - long vmwareDcId; String vCenterHost; String userName; String password; DatacenterMO dcMo = null; Transaction txn; - vmwareDcZoneMap = _vmwareDcZoneMapDao.findByZoneId(zoneId); + final VmwareDatacenterZoneMapVO vmwareDcZoneMap = _vmwareDcZoneMapDao.findByZoneId(zoneId); // Check if zone is associated with VMware DC if (vmwareDcZoneMap == null) { throw new CloudRuntimeException("Zone " + zoneId + " is not associated with any VMware datacenter."); } - vmwareDcId = vmwareDcZoneMap.getVmwareDcId(); + final long vmwareDcId = vmwareDcZoneMap.getVmwareDcId(); vmwareDatacenter = _vmwareDcDao.findById(vmwareDcId); vmwareDcName = vmwareDatacenter.getVmwareDatacenterName(); vCenterHost = vmwareDatacenter.getVcenterHost(); userName = vmwareDatacenter.getUser(); password = vmwareDatacenter.getPassword(); - txn = Transaction.currentTxn(); - try { - txn.start(); - // Remove the VMware datacenter entry in table vmware_data_center - _vmwareDcDao.remove(vmwareDcId); - // Remove the map entry in table vmware_data_center_zone_map - _vmwareDcZoneMapDao.remove(vmwareDcZoneMap.getId()); - txn.commit(); - } catch (Exception e) { - s_logger.info("Caught exception when trying to delete VMware datacenter record." + e.getMessage()); - throw new CloudRuntimeException("Failed to delete VMware datacenter."); - } + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // Remove the VMware datacenter entry in table vmware_data_center + _vmwareDcDao.remove(vmwareDcId); + // Remove the map entry in table vmware_data_center_zone_map + _vmwareDcZoneMapDao.remove(vmwareDcZoneMap.getId()); + } + }); // Construct context VmwareContext context = null; diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index a35a9661cda..77e799d5c82 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -2052,7 +2052,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String args = " -v " + vmIpAddress; if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domain router " + controlIp + ", /root/savepassword.sh " + args + " -p " + StringUtils.getMaskedPasswordForDisplay(cmd.getPassword())); + s_logger.debug("Run command on domain router " + controlIp + ", /opt/cloud/bin/savepassword.sh " + args + " -p " + StringUtils.getMaskedPasswordForDisplay(cmd.getPassword())); } args += " -p " + password; @@ -2060,7 +2060,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa try { VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, "/root/savepassword.sh " + args); + Pair result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/savepassword.sh " + args); if (!result.first()) { s_logger.error("savepassword command on domain router " + controlIp + " failed, message: " + result.second()); @@ -3857,11 +3857,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (getVmState(vmMo) != State.Stopped) { if (vmMo.safePowerOff(_shutdown_waitMs)) { state = State.Stopped; - return new StopAnswer(cmd, "Stop VM " + cmd.getVmName() + " Succeed", 0, true); + return new StopAnswer(cmd, "Stop VM " + cmd.getVmName() + " Succeed", true); } else { String msg = "Have problem in powering off VM " + cmd.getVmName() + ", let the process continue"; s_logger.warn(msg); - return new StopAnswer(cmd, msg, 0, true); + return new StopAnswer(cmd, msg, true); } } else { state = State.Stopped; @@ -3869,7 +3869,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String msg = "VM " + cmd.getVmName() + " is already in stopped state"; s_logger.info(msg); - return new StopAnswer(cmd, msg, 0, true); + return new StopAnswer(cmd, msg, true); } finally { synchronized (_vms) { _vms.put(cmd.getVmName(), state); @@ -3882,7 +3882,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String msg = "VM " + cmd.getVmName() + " is no longer in vSphere"; s_logger.info(msg); - return new StopAnswer(cmd, msg, 0, true); + return new StopAnswer(cmd, msg, true); } } catch (Exception e) { if (e instanceof RemoteException) { diff --git a/plugins/hypervisors/vmware/src/com/cloud/network/CiscoNexusVSMDeviceManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/network/CiscoNexusVSMDeviceManagerImpl.java index 9ec64ffce9d..1b08a5caceb 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/network/CiscoNexusVSMDeviceManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/network/CiscoNexusVSMDeviceManagerImpl.java @@ -38,6 +38,8 @@ import com.cloud.resource.ResourceManager; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.network.dao.CiscoNexusVSMDeviceDao; import com.cloud.network.dao.PortProfileDao; @@ -131,29 +133,13 @@ public abstract class CiscoNexusVSMDeviceManagerImpl extends AdapterBase { if (VSMObj == null) { // Create the VSM record. For now, we aren't using the vsmName field. VSMObj = new CiscoNexusVSMDeviceVO(ipaddress, username, password); - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - _ciscoNexusVSMDeviceDao.persist(VSMObj); - txn.commit(); - } catch (Exception e) { - txn.rollback(); - throw new CloudRuntimeException(e.getMessage()); - } + _ciscoNexusVSMDeviceDao.persist(VSMObj); } // At this stage, we have a VSM record for sure. Connect the VSM to the cluster Id. long vsmId = _ciscoNexusVSMDeviceDao.getVSMbyIpaddress(ipaddress).getId(); ClusterVSMMapVO connectorObj = new ClusterVSMMapVO(clusterId, vsmId); - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - _clusterVSMDao.persist(connectorObj); - txn.commit(); - } catch (Exception e) { - txn.rollback(); - throw new CloudRuntimeException(e.getMessage()); - } + _clusterVSMDao.persist(connectorObj); // Now, get a list of all the ESXi servers in this cluster. // This is effectively a select * from host where cluster_id=clusterId; @@ -196,7 +182,7 @@ public abstract class CiscoNexusVSMDeviceManagerImpl extends AdapterBase { } @DB - public boolean deleteCiscoNexusVSM(long vsmId) throws ResourceInUseException { + public boolean deleteCiscoNexusVSM(final long vsmId) throws ResourceInUseException { CiscoNexusVSMDeviceVO cisconexusvsm = _ciscoNexusVSMDeviceDao.findById(vsmId); if (cisconexusvsm == null) { // This entry is already not present. Return success. @@ -225,20 +211,16 @@ public abstract class CiscoNexusVSMDeviceManagerImpl extends AdapterBase { } // Iterate through the cluster list again, this time, delete the VSM. - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - // Remove the VSM entry in CiscoNexusVSMDeviceVO's table. - _ciscoNexusVSMDeviceDao.remove(vsmId); - // Remove the current record as well from ClusterVSMMapVO's table. - _clusterVSMDao.removeByVsmId(vsmId); - // There are no hosts at this stage in the cluster, so we don't need - // to notify any resources or remove host details. - txn.commit(); - } catch (Exception e) { - s_logger.info("Caught exception when trying to delete VSM record.." + e.getMessage()); - throw new CloudRuntimeException("Failed to delete VSM"); - } + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // Remove the VSM entry in CiscoNexusVSMDeviceVO's table. + _ciscoNexusVSMDeviceDao.remove(vsmId); + // Remove the current record as well from ClusterVSMMapVO's table. + _clusterVSMDao.removeByVsmId(vsmId); + } + }); + return true; } @@ -252,15 +234,7 @@ public abstract class CiscoNexusVSMDeviceManagerImpl extends AdapterBase { if (cisconexusvsm.getvsmDeviceState() == CiscoNexusVSMDeviceVO.VSMDeviceState.Disabled) { // it's currently disabled. So change it to enabled and write it out to the db. cisconexusvsm.setVsmDeviceState(CiscoNexusVSMDeviceVO.VSMDeviceState.Enabled); - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - _ciscoNexusVSMDeviceDao.persist(cisconexusvsm); - txn.commit(); - } catch (Exception e) { - txn.rollback(); - throw new CloudRuntimeException(e.getMessage()); - } + _ciscoNexusVSMDeviceDao.persist(cisconexusvsm); } return cisconexusvsm; @@ -276,15 +250,7 @@ public abstract class CiscoNexusVSMDeviceManagerImpl extends AdapterBase { if (cisconexusvsm.getvsmDeviceState() == CiscoNexusVSMDeviceVO.VSMDeviceState.Enabled) { // it's currently disabled. So change it to enabled and write it out to the db. cisconexusvsm.setVsmDeviceState(CiscoNexusVSMDeviceVO.VSMDeviceState.Disabled); - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - _ciscoNexusVSMDeviceDao.persist(cisconexusvsm); - txn.commit(); - } catch (Exception e) { - txn.rollback(); - throw new CloudRuntimeException(e.getMessage()); - } + _ciscoNexusVSMDeviceDao.persist(cisconexusvsm); } return cisconexusvsm; diff --git a/plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElement.java b/plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElement.java index 6c6ce557310..92564dd2c4e 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElement.java +++ b/plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElement.java @@ -61,6 +61,8 @@ import com.cloud.utils.cisco.n1kv.vsm.NetconfHelper; import com.cloud.utils.component.Manager; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; @@ -260,7 +262,7 @@ public class CiscoNexusVSMElement extends CiscoNexusVSMDeviceManagerImpl impleme } @DB - public Pair validateAndAddVsm(String vsmIp, String vsmUser, String vsmPassword, long clusterId, String clusterName) throws ResourceInUseException { + public Pair validateAndAddVsm(final String vsmIp, final String vsmUser, final String vsmPassword, final long clusterId, String clusterName) throws ResourceInUseException { CiscoNexusVSMDeviceVO vsm = null; boolean vsmAdded = false; Long vsmId = 0L; @@ -293,36 +295,24 @@ public class CiscoNexusVSMElement extends CiscoNexusVSMDeviceManagerImpl impleme } } // persist credentials to database if the VSM entry is not already in the db. - if (_vsmDao.getVSMbyIpaddress(vsmIp) == null) { - vsm = new CiscoNexusVSMDeviceVO(vsmIp, vsmUser, vsmPassword); - txn = Transaction.currentTxn(); - try { - txn.start(); - vsm = _vsmDao.persist(vsm); - txn.commit(); - } catch (Exception e) { - txn.rollback(); - s_logger.error("Failed to persist Cisco Nexus 1000v VSM details to database. Exception: " + e.getMessage()); - throw new CloudRuntimeException(e.getMessage()); + vsm = Transaction.execute(new TransactionCallback() { + @Override + public CiscoNexusVSMDeviceVO doInTransaction(TransactionStatus status) { + CiscoNexusVSMDeviceVO vsm = null; + if (_vsmDao.getVSMbyIpaddress(vsmIp) == null) { + vsm = new CiscoNexusVSMDeviceVO(vsmIp, vsmUser, vsmPassword); + vsm = _vsmDao.persist(vsm); + } + // Create a mapping between the cluster and the vsm. + vsm = _vsmDao.getVSMbyIpaddress(vsmIp); + if (vsm != null) { + ClusterVSMMapVO connectorObj = new ClusterVSMMapVO(clusterId, vsm.getId()); + _clusterVSMDao.persist(connectorObj); + } + return vsm; } - } - // Create a mapping between the cluster and the vsm. - vsm = _vsmDao.getVSMbyIpaddress(vsmIp); - if (vsm != null) { - ClusterVSMMapVO connectorObj = new ClusterVSMMapVO(clusterId, vsm.getId()); - txn = Transaction.currentTxn(); - try { - txn.start(); - _clusterVSMDao.persist(connectorObj); - txn.commit(); - } catch (Exception e) { - txn.rollback(); - s_logger.error("Failed to associate Cisco Nexus 1000v VSM with cluster: " + clusterName + ". Exception: " + e.getMessage()); - _vsmDao.remove(vsm.getId()); // Removing VSM from virtual_supervisor_module table because association with cluster failed. - // Cluster would be deleted from cluster table by callee. - throw new CloudRuntimeException(e.getMessage()); - } - } + }); + } else { String msg; msg = "The global parameter " + Config.VmwareUseNexusVSwitch.toString() + diff --git a/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java b/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java index f5f23a2b4e0..5c9b3af52b9 100644 --- a/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java +++ b/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java @@ -28,7 +28,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority.Priority; +import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -64,17 +64,17 @@ public class VmwareStorageMotionStrategy implements DataMotionStrategy { @Inject VMInstanceDao instanceDao; @Override - public Priority canHandle(DataObject srcData, DataObject destData) { - return Priority.CANT_HANDLE; + public StrategyPriority canHandle(DataObject srcData, DataObject destData) { + return StrategyPriority.CANT_HANDLE; } @Override - public Priority canHandle(Map volumeMap, Host srcHost, Host destHost) { + public StrategyPriority canHandle(Map volumeMap, Host srcHost, Host destHost) { if (srcHost.getHypervisorType() == HypervisorType.VMware && destHost.getHypervisorType() == HypervisorType.VMware) { s_logger.debug(this.getClass() + " can handle the request because the hosts have VMware hypervisor"); - return Priority.HYPERVISOR; + return StrategyPriority.HYPERVISOR; } - return Priority.CANT_HANDLE; + return StrategyPriority.CANT_HANDLE; } @Override diff --git a/plugins/hypervisors/vmware/test/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategyTest.java b/plugins/hypervisors/vmware/test/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategyTest.java index c19480c2c59..1234728f364 100644 --- a/plugins/hypervisors/vmware/test/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategyTest.java +++ b/plugins/hypervisors/vmware/test/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategyTest.java @@ -25,7 +25,7 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority.Priority; +import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCallFuture; @@ -100,8 +100,8 @@ public class VmwareStorageMotionStrategyTest { when(srcHost.getHypervisorType()).thenReturn(HypervisorType.VMware); when(destHost.getHypervisorType()).thenReturn(HypervisorType.VMware); Map volumeMap = new HashMap(); - Priority canHandle = strategy.canHandle(volumeMap, srcHost, destHost); - assertTrue("The strategy is only supposed to handle vmware hosts", canHandle == Priority.HYPERVISOR); + StrategyPriority canHandle = strategy.canHandle(volumeMap, srcHost, destHost); + assertTrue("The strategy is only supposed to handle vmware hosts", canHandle == StrategyPriority.HYPERVISOR); } @Test @@ -111,8 +111,8 @@ public class VmwareStorageMotionStrategyTest { when(srcHost.getHypervisorType()).thenReturn(HypervisorType.XenServer); when(destHost.getHypervisorType()).thenReturn(HypervisorType.XenServer); Map volumeMap = new HashMap(); - Priority canHandle = strategy.canHandle(volumeMap, srcHost, destHost); - assertFalse("The strategy is only supposed to handle vmware hosts", canHandle == Priority.HYPERVISOR); + StrategyPriority canHandle = strategy.canHandle(volumeMap, srcHost, destHost); + assertFalse("The strategy is only supposed to handle vmware hosts", canHandle == StrategyPriority.HYPERVISOR); } @Test diff --git a/plugins/hypervisors/xen/resources/META-INF/cloudstack/xenserver-compute/module.properties b/plugins/hypervisors/xen/resources/META-INF/cloudstack/xenserver-compute/module.properties new file mode 100644 index 00000000000..c6c91f658fc --- /dev/null +++ b/plugins/hypervisors/xen/resources/META-INF/cloudstack/xenserver-compute/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=xenserver-compute +parent=compute \ No newline at end of file diff --git a/plugins/hypervisors/xen/resources/META-INF/cloudstack/xenserver-compute/spring-xenserver-compute-context.xml b/plugins/hypervisors/xen/resources/META-INF/cloudstack/xenserver-compute/spring-xenserver-compute-context.xml new file mode 100644 index 00000000000..e024ad837c8 --- /dev/null +++ b/plugins/hypervisors/xen/resources/META-INF/cloudstack/xenserver-compute/spring-xenserver-compute-context.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + diff --git a/plugins/hypervisors/xen/resources/META-INF/cloudstack/xenserver-discoverer/module.properties b/plugins/hypervisors/xen/resources/META-INF/cloudstack/xenserver-discoverer/module.properties new file mode 100644 index 00000000000..10d0ecdf729 --- /dev/null +++ b/plugins/hypervisors/xen/resources/META-INF/cloudstack/xenserver-discoverer/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=xenserver-discoverer +parent=discoverer \ No newline at end of file diff --git a/plugins/hypervisors/xen/resources/META-INF/cloudstack/xenserver-discoverer/spring-xenserver-discoverer-context.xml b/plugins/hypervisors/xen/resources/META-INF/cloudstack/xenserver-discoverer/spring-xenserver-discoverer-context.xml new file mode 100644 index 00000000000..c3010072dfe --- /dev/null +++ b/plugins/hypervisors/xen/resources/META-INF/cloudstack/xenserver-discoverer/spring-xenserver-discoverer-context.xml @@ -0,0 +1,25 @@ + + + + + + + + diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 92fbab28bd2..f16a6f5e5d8 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -207,9 +207,9 @@ import com.cloud.storage.template.TemplateProp; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; +import com.cloud.utils.Ternary; import com.cloud.utils.S3Utils; import com.cloud.utils.StringUtils; -import com.cloud.utils.Ternary; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.vm.DiskProfile; @@ -1349,8 +1349,18 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe throw new CloudRuntimeException("Unable to handle boot loader type: " + vmSpec.getBootloader()); } } + + try { + finalizeVmMetaData(vm, conn, vmSpec); + } catch ( Exception e) { + throw new CloudRuntimeException("Unable to finalize VM MetaData: " + vmSpec); + } return vm; } + + protected void finalizeVmMetaData(VM vm, Connection conn, VirtualMachineTO vmSpec) throws Exception { + } + protected String handleVmStartFailure(Connection conn, String vmName, VM vm, String message, Throwable th) { String msg = "Unable to start " + vmName + " due to " + message; @@ -2228,16 +2238,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Connection conn = getConnection(); final String password = cmd.getPassword(); final String routerPrivateIPAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - final String vmName = cmd.getVmName(); final String vmIpAddress = cmd.getVmIpAddress(); - final String local = vmName; - // Run save_password_to_domr.sh - String args = "-r " + routerPrivateIPAddress; + String args = "savepassword.sh " + routerPrivateIPAddress; args += " -v " + vmIpAddress; args += " -p " + password; - args += " " + local; - String result = callHostPlugin(conn, "vmops", "savePassword", "args", args); + String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); if (result == null || result.isEmpty()) { return new Answer(cmd, false, "savePassword failed"); @@ -2866,8 +2872,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return state == null ? State.Unknown : state; } - protected HashMap> getAllVms(Connection conn) { - final HashMap> vmStates = new HashMap>(); + protected HashMap> getAllVms(Connection conn) { + final HashMap> vmStates = new HashMap>(); Map vm_map = null; for (int i = 0; i < 2; i++) { try { @@ -2897,6 +2903,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_logger.trace("VM " + record.nameLabel + ": powerstate = " + ps + "; vm state=" + state.toString()); } Host host = record.residentOn; + String xstoolsversion = getVMXenToolsVersion(record.platform); String host_uuid = null; if( ! isRefNull(host) ) { try { @@ -2908,7 +2915,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } catch (XmlRpcException e) { s_logger.error("Failed to get host uuid for host " + host.toWireString(), e); } - vmStates.put(record.nameLabel, new Pair(host_uuid, state)); + vmStates.put(record.nameLabel, new Ternary(host_uuid, state, xstoolsversion)); } } @@ -3919,7 +3926,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_logger.info("VM does not exist on XenServer" + _host.uuid); s_vms.remove(_cluster, _name, vmName); } - return new StopAnswer(cmd, "VM does not exist", 0 , true); + return new StopAnswer(cmd, "VM does not exist", true); } for (VM vm : vms) { VM.Record vmr = vm.getRecord(conn); @@ -3976,6 +3983,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } catch (NumberFormatException e) { s_logger.error("Error while reading the platform:timeoffset field of the instance", e); } + String xentoolsversion = getVMXenToolsVersion(platform); Set vifs = vm.getVIFs(conn); List networks = new ArrayList(); @@ -3997,7 +4005,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe // network might be destroyed by other host } } - return new StopAnswer(cmd, "Stop VM " + vmName + " Succeed", 0, timeoffset, true); + return new StopAnswer(cmd, "Stop VM " + vmName + " Succeed", xentoolsversion, timeoffset, true); } } catch (XenAPIException e) { String msg = "VM destroy failed in Stop " + vmName + " Command due to " + e.toString(); @@ -4029,6 +4037,30 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new StopAnswer(cmd, "Stop VM failed", false); } + + /*Override by subclass*/ + protected String getVMXenToolsVersion(Map platform) { + return "xenserver56"; + } + + + private List getVdis(Connection conn, VM vm) { + List vdis = new ArrayList(); + try { + Set vbds =vm.getVBDs(conn); + for( VBD vbd : vbds ) { + vdis.add(vbd.getVDI(conn)); + } + } catch (XenAPIException e) { + String msg = "getVdis can not get VPD due to " + e.toString(); + s_logger.warn(msg, e); + } catch (XmlRpcException e) { + String msg = "getVdis can not get VPD due to " + e.getMessage(); + s_logger.warn(msg, e); + } + return vdis; + } + protected String connect(Connection conn, final String vmName, final String ipAddress, final int port) { for (int i = 0; i <= _retry; i++) { try { @@ -4877,7 +4909,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Host.Record hostr = poolr.master.getRecord(conn); if (_host.uuid.equals(hostr.uuid)) { - HashMap> allStates=fullClusterSync(conn); + HashMap> allStates=fullClusterSync(conn); cmd.setClusterVMStateChanges(allStates); } } catch (Throwable e) { @@ -7059,7 +7091,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - success = true; details = null; } else if (cmd.getCommandSwitch().equals(ManageSnapshotCommand.DESTROY_SNAPSHOT)) { @@ -7079,7 +7110,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe details += ", reason: " + e.toString(); s_logger.warn(details, e); } - return new ManageSnapshotAnswer(cmd, snapshotId, snapshotUUID, success, details); } @@ -8003,13 +8033,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } catch (Throwable e) { s_logger.warn("Check for master failed, failing the Cluster sync command"); return new Answer(cmd); - } - HashMap> newStates = deltaClusterSync(conn); + } + HashMap> newStates = deltaClusterSync(conn); return new ClusterSyncAnswer(cmd.getClusterId(), newStates); } - protected HashMap> fullClusterSync(Connection conn) { + protected HashMap> fullClusterSync(Connection conn) { synchronized (_cluster.intern()) { s_vms.clear(_cluster); } @@ -8022,12 +8052,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String vm_name = record.nameLabel; VmPowerState ps = record.powerState; final State state = convertToState(ps); + String xstoolsversion = getVMXenToolsVersion(record.platform); Host host = record.residentOn; String host_uuid = null; if( ! isRefNull(host) ) { host_uuid = host.getUuid(conn); synchronized (_cluster.intern()) { - s_vms.put(_cluster, host_uuid, vm_name, state); + s_vms.put(_cluster, host_uuid, vm_name, state, xstoolsversion); } } if (s_logger.isTraceEnabled()) { @@ -8043,38 +8074,50 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } - protected HashMap> deltaClusterSync(Connection conn) { - final HashMap> changes = new HashMap>(); + protected HashMap> deltaClusterSync(Connection conn) { + final HashMap> changes = new HashMap>(); synchronized (_cluster.intern()) { - HashMap> newStates = getAllVms(conn); + HashMap> newStates = getAllVms(conn); if (newStates == null) { s_logger.warn("Unable to get the vm states so no state sync at this point."); return null; } - HashMap> oldStates = new HashMap>(s_vms.size(_cluster)); + HashMap> oldStates = new HashMap>(s_vms.size(_cluster)); oldStates.putAll(s_vms.getClusterVmState(_cluster)); - for (final Map.Entry> entry : newStates.entrySet()) { + for (final Map.Entry> entry : newStates.entrySet()) { final String vm = entry.getKey(); - + String xstoolsversion = entry.getValue().third(); State newState = entry.getValue().second(); String host_uuid = entry.getValue().first(); - final Pair oldState = oldStates.remove(vm); + final Ternary oldState = oldStates.remove(vm); + + // check if xstoolsversion changed + if (xstoolsversion != null && oldState != null){ + if (xstoolsversion != oldState.third() && newState != State.Stopped && newState != State.Stopping){ + s_logger.warn("Detecting a change in xstoolsversion for " + vm); + changes.put(vm, new Ternary(host_uuid, newState, xstoolsversion)); + s_logger.debug("11. The VM " + vm + " is in " + newState + " state"); + s_vms.put(_cluster, host_uuid, vm, newState, xstoolsversion); + continue; + } + } //check if host is changed if (host_uuid != null && oldState != null){ if (!host_uuid.equals(oldState.first()) && newState != State.Stopped && newState != State.Stopping){ s_logger.warn("Detecting a change in host for " + vm); - changes.put(vm, new Pair(host_uuid, newState)); + changes.put(vm, new Ternary(host_uuid, newState, null)); s_logger.debug("11. The VM " + vm + " is in " + newState + " state"); - s_vms.put(_cluster, host_uuid, vm, newState); + s_vms.put(_cluster, host_uuid, vm, newState, xstoolsversion); continue; } } + if (newState == State.Stopped && oldState != null && oldState.second() != State.Stopping && oldState.second() != State.Stopped) { newState = getRealPowerState(conn, vm); } @@ -8088,42 +8131,42 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe continue; } if (oldState == null) { - s_vms.put(_cluster, host_uuid, vm, newState); + s_vms.put(_cluster, host_uuid, vm, newState, xstoolsversion); s_logger.warn("Detecting a new state but couldn't find a old state so adding it to the changes: " + vm); - changes.put(vm, new Pair(host_uuid, newState)); + changes.put(vm, new Ternary(host_uuid, newState, null)); } else if (oldState.second() == State.Starting) { if (newState == State.Running) { s_logger.debug("12. The VM " + vm + " is in " + State.Running + " state"); - s_vms.put(_cluster, host_uuid, vm, newState); + s_vms.put(_cluster, host_uuid, vm, newState, xstoolsversion); } else if (newState == State.Stopped) { s_logger.warn("Ignoring vm " + vm + " because of a lag in starting the vm."); } } else if (oldState.second() == State.Migrating) { if (newState == State.Running) { s_logger.debug("Detected that an migrating VM is now running: " + vm); - s_vms.put(_cluster, host_uuid, vm, newState); + s_vms.put(_cluster, host_uuid, vm, newState, xstoolsversion); } } else if (oldState.second() == State.Stopping) { if (newState == State.Stopped) { s_logger.debug("13. The VM " + vm + " is in " + State.Stopped + " state"); - s_vms.put(_cluster, host_uuid, vm, newState); + s_vms.put(_cluster, host_uuid, vm, newState, xstoolsversion); } else if (newState == State.Running) { s_logger.warn("Ignoring vm " + vm + " because of a lag in stopping the vm. "); } } else if (oldState.second() != newState) { s_logger.debug("14. The VM " + vm + " is in " + newState + " state was " + oldState.second()); - s_vms.put(_cluster, host_uuid, vm, newState); + s_vms.put(_cluster, host_uuid, vm, newState, xstoolsversion); if (newState == State.Stopped) { /* * if (s_vmsKilled.remove(vm)) { s_logger.debug("VM " + vm + " has been killed for storage. "); * newState = State.Error; } */ } - changes.put(vm, new Pair(host_uuid, newState)); + changes.put(vm, new Ternary(host_uuid, newState, null)); } } - for (final Map.Entry> entry : oldStates.entrySet()) { + for (final Map.Entry> entry : oldStates.entrySet()) { final String vm = entry.getKey(); final State oldState = entry.getValue().second(); String host_uuid = entry.getValue().first(); @@ -8145,7 +8188,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } else { State newState = State.Stopped; s_logger.warn("The VM is now missing marking it as Stopped " + vm); - changes.put(vm, new Pair(host_uuid, newState)); + changes.put(vm, new Ternary(host_uuid, newState, null)); } } } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java index 214dbd4059a..4a9b526766e 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java @@ -169,7 +169,6 @@ public class XenServer56FP1Resource extends XenServer56Resource { vmr.actionsAfterCrash = Types.OnCrashBehaviour.DESTROY; vmr.actionsAfterShutdown = Types.OnNormalExit.DESTROY; - Map details = vmSpec.getDetails(); if (isDmcEnabled(conn, host) && vmSpec.isEnableDynamicallyScaleVm()) { //scaling is allowed vmr.memoryStaticMin = getStaticMin(vmSpec.getOs(), vmSpec.getBootloader() == BootloaderType.CD, vmSpec.getMinRam(), vmSpec.getMaxRam()); @@ -193,18 +192,21 @@ public class XenServer56FP1Resource extends XenServer56Resource { vmr.VCPUsMax = 32L; } - String timeoffset = details.get("timeoffset"); - if (timeoffset != null) { - Map platform = vmr.platform; - platform.put("timeoffset", timeoffset); - vmr.platform = platform; - } + Map details = vmSpec.getDetails(); + if ( details != null ) { + String timeoffset = details.get("timeoffset"); + if (timeoffset != null) { + Map platform = vmr.platform; + platform.put("timeoffset", timeoffset); + vmr.platform = platform; + } - String coresPerSocket = details.get("cpu.corespersocket"); - if (coresPerSocket != null) { - Map platform = vmr.platform; - platform.put("cores-per-socket", coresPerSocket); - vmr.platform = platform; + String coresPerSocket = details.get("cpu.corespersocket"); + if (coresPerSocket != null) { + Map platform = vmr.platform; + platform.put("cores-per-socket", coresPerSocket); + vmr.platform = platform; + } } vmr.VCPUsAtStartup = (long) vmSpec.getCpus(); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java index c3c0307ca1b..2603922fd18 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java @@ -452,5 +452,27 @@ public class XenServer610Resource extends XenServer56FP1Resource { @Override protected void plugDom0Vif(Connection conn, VIF dom0Vif) throws XmlRpcException, XenAPIException { // do nothing. In xenserver 6.1 and beyond this step isn't needed. + } + + @Override + protected String getVMXenToolsVersion(Map platform) { + if (platform.containsKey("device_id")) { + return "xenserver61"; + } + return "xenserver56"; } + + @Override + protected void finalizeVmMetaData(VM vm, Connection conn, VirtualMachineTO vmSpec) throws Exception { + Map details = vmSpec.getDetails(); + if ( details!= null ) { + String xentoolsversion = details.get("hypervisortoolsversion"); + if ( xentoolsversion == null || !xentoolsversion.equalsIgnoreCase("xenserver61") ) { + Map platform = vm.getPlatform(conn); + platform.remove("device_id"); + vm.setPlatform(conn, platform); + } + } + } + } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java index 33f2bf96606..f22fb286c8a 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java @@ -20,20 +20,20 @@ import java.util.HashMap; import java.util.Map; import org.apache.log4j.Logger; import java.util.concurrent.ConcurrentHashMap; -import com.cloud.utils.Pair; +import com.cloud.utils.Ternary; import com.cloud.vm.VirtualMachine.State; public class XenServerPoolVms { private static final Logger s_logger = Logger.getLogger(XenServerPoolVms.class); - private final Map>> _cluster_vms = - new ConcurrentHashMap>>(); + private final Map>> _cluster_vms = + new ConcurrentHashMap>>(); - public HashMap> getClusterVmState(String clusterId){ - HashMap> _vms= _cluster_vms.get(clusterId); + public HashMap> getClusterVmState(String clusterId){ + HashMap> _vms= _cluster_vms.get(clusterId); if (_vms==null) { - HashMap> vmStates = new HashMap>(); + HashMap> vmStates = new HashMap>(); _cluster_vms.put(clusterId, vmStates); return vmStates; } @@ -41,40 +41,47 @@ public class XenServerPoolVms { } public void clear(String clusterId){ - HashMap> _vms= getClusterVmState(clusterId); + HashMap> _vms= getClusterVmState(clusterId); _vms.clear(); } public State getState(String clusterId, String name){ - HashMap> vms = getClusterVmState(clusterId); - Pair pv = vms.get(name); + HashMap> vms = getClusterVmState(clusterId); + Ternary pv = vms.get(name); return pv == null ? State.Stopped : pv.second(); // if a VM is absent on the cluster, it is effectively in stopped state. } + + + public void put(String clusterId, String hostUuid, String name, State state, String xstoolsversion){ + HashMap> vms= getClusterVmState(clusterId); + vms.put(name, new Ternary(hostUuid, state, xstoolsversion)); + } + public void put(String clusterId, String hostUuid, String name, State state){ - HashMap> vms= getClusterVmState(clusterId); - vms.put(name, new Pair(hostUuid, state)); + HashMap> vms= getClusterVmState(clusterId); + vms.put(name, new Ternary(hostUuid, state, null)); } public void remove(String clusterId, String hostUuid, String name){ - HashMap> vms= getClusterVmState(clusterId); + HashMap> vms= getClusterVmState(clusterId); vms.remove(name); } - public void putAll(String clusterId, HashMap> new_vms){ - HashMap> vms= getClusterVmState(clusterId); + public void putAll(String clusterId, HashMap> new_vms){ + HashMap> vms= getClusterVmState(clusterId); vms.putAll(new_vms); } public int size(String clusterId){ - HashMap> vms= getClusterVmState(clusterId); + HashMap> vms= getClusterVmState(clusterId); return vms.size(); } @Override public String toString(){ StringBuilder sbuf = new StringBuilder("PoolVms="); - for (HashMap> clusterVM: _cluster_vms.values()){ + for (HashMap> clusterVM: _cluster_vms.values()){ for (String vmname: clusterVM.keySet()){ sbuf.append(vmname).append("-").append(clusterVM.get(vmname).second()).append(","); } diff --git a/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java b/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java index 8578a9aa46c..3dc7dd86cbc 100644 --- a/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java +++ b/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java @@ -28,7 +28,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority.Priority; +import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -71,18 +71,18 @@ public class XenServerStorageMotionStrategy implements DataMotionStrategy { @Inject VMInstanceDao instanceDao; @Override - public Priority canHandle(DataObject srcData, DataObject destData) { - return Priority.CANT_HANDLE; + public StrategyPriority canHandle(DataObject srcData, DataObject destData) { + return StrategyPriority.CANT_HANDLE; } @Override - public Priority canHandle(Map volumeMap, Host srcHost, Host destHost) { + public StrategyPriority canHandle(Map volumeMap, Host srcHost, Host destHost) { if (srcHost.getHypervisorType() == HypervisorType.XenServer && destHost.getHypervisorType() == HypervisorType.XenServer) { - return Priority.HYPERVISOR; + return StrategyPriority.HYPERVISOR; } - return Priority.CANT_HANDLE; + return StrategyPriority.CANT_HANDLE; } @Override diff --git a/plugins/network-elements/bigswitch-vns/resources/META-INF/cloudstack/vns/module.properties b/plugins/network-elements/bigswitch-vns/resources/META-INF/cloudstack/vns/module.properties new file mode 100644 index 00000000000..5783d38e5cb --- /dev/null +++ b/plugins/network-elements/bigswitch-vns/resources/META-INF/cloudstack/vns/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=vns +parent=network \ No newline at end of file diff --git a/plugins/network-elements/bigswitch-vns/resources/META-INF/cloudstack/vns/spring-vns-context.xml b/plugins/network-elements/bigswitch-vns/resources/META-INF/cloudstack/vns/spring-vns-context.xml new file mode 100644 index 00000000000..d5bb92afe3d --- /dev/null +++ b/plugins/network-elements/bigswitch-vns/resources/META-INF/cloudstack/vns/spring-vns-context.xml @@ -0,0 +1,36 @@ + + + + + + + + + + diff --git a/plugins/network-elements/bigswitch-vns/src/com/cloud/network/element/BigSwitchVnsElement.java b/plugins/network-elements/bigswitch-vns/src/com/cloud/network/element/BigSwitchVnsElement.java index cb6e7fcec61..6b75634f653 100644 --- a/plugins/network-elements/bigswitch-vns/src/com/cloud/network/element/BigSwitchVnsElement.java +++ b/plugins/network-elements/bigswitch-vns/src/com/cloud/network/element/BigSwitchVnsElement.java @@ -29,7 +29,6 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; - import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice; import com.cloud.agent.AgentManager; @@ -84,6 +83,9 @@ import com.cloud.resource.UnableDeleteHostException; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; @@ -329,11 +331,10 @@ public class BigSwitchVnsElement extends AdapterBase implements @DB public BigSwitchVnsDeviceVO addBigSwitchVnsDevice(AddBigSwitchVnsDeviceCmd cmd) { ServerResource resource = new BigSwitchVnsResource(); - String deviceName = VnsConstants.BigSwitchVns.getName(); + final String deviceName = VnsConstants.BigSwitchVns.getName(); NetworkDevice networkDevice = NetworkDevice .getNetworkDevice(deviceName); - Long physicalNetworkId = cmd.getPhysicalNetworkId(); - BigSwitchVnsDeviceVO bigswitchVnsDevice = null; + final Long physicalNetworkId = cmd.getPhysicalNetworkId(); PhysicalNetworkVO physicalNetwork = _physicalNetworkDao .findById(physicalNetworkId); @@ -344,7 +345,7 @@ public class BigSwitchVnsElement extends AdapterBase implements } long zoneId = physicalNetwork.getDataCenterId(); - PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao + final PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao .findByServiceProvider(physicalNetwork.getId(), networkDevice.getNetworkServiceProvder()); if (ntwkSvcProvider == null) { @@ -377,33 +378,33 @@ public class BigSwitchVnsElement extends AdapterBase implements Map hostdetails = new HashMap(); hostdetails.putAll(params); - Transaction txn = Transaction.currentTxn(); try { resource.configure(cmd.getHost(), hostdetails); - Host host = _resourceMgr.addHost(zoneId, resource, + final Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.L2Networking, params); if (host != null) { - txn.start(); - - bigswitchVnsDevice = new BigSwitchVnsDeviceVO(host.getId(), - physicalNetworkId, ntwkSvcProvider.getProviderName(), - deviceName); - _bigswitchVnsDao.persist(bigswitchVnsDevice); - - DetailVO detail = new DetailVO(host.getId(), - "bigswitchvnsdeviceid", - String.valueOf(bigswitchVnsDevice.getId())); - _hostDetailsDao.persist(detail); - - txn.commit(); - return bigswitchVnsDevice; + return Transaction.execute(new TransactionCallback() { + @Override + public BigSwitchVnsDeviceVO doInTransaction(TransactionStatus status) { + BigSwitchVnsDeviceVO bigswitchVnsDevice = new BigSwitchVnsDeviceVO(host.getId(), + physicalNetworkId, ntwkSvcProvider.getProviderName(), + deviceName); + _bigswitchVnsDao.persist(bigswitchVnsDevice); + + DetailVO detail = new DetailVO(host.getId(), + "bigswitchvnsdeviceid", + String.valueOf(bigswitchVnsDevice.getId())); + _hostDetailsDao.persist(detail); + + return bigswitchVnsDevice; + } + }); } else { throw new CloudRuntimeException( "Failed to add BigSwitch Vns Device due to internal error."); } } catch (ConfigurationException e) { - txn.rollback(); throw new CloudRuntimeException(e.getMessage()); } } diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java index e27a0599b0b..5beb1bae520 100644 --- a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java +++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java @@ -29,7 +29,6 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; - import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice; @@ -71,6 +70,7 @@ import com.cloud.dc.dao.ClusterVSMMapDao; import com.cloud.dc.dao.VlanDao; import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; @@ -123,7 +123,11 @@ import com.cloud.user.Account; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.db.EntityManager; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.exception.ExceptionUtil; import com.cloud.utils.net.NetUtils; import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; @@ -274,11 +278,11 @@ public class CiscoVnmcElement extends AdapterBase implements SourceNatServicePro } @Override - public boolean implement(Network network, NetworkOffering offering, - DeployDestination dest, ReservationContext context) + public boolean implement(final Network network, final NetworkOffering offering, + final DeployDestination dest, final ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { - DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId()); + final DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId()); if (zone.getNetworkType() == NetworkType.Basic) { s_logger.debug("Not handling network implement in zone of type " + NetworkType.Basic); @@ -289,7 +293,7 @@ public class CiscoVnmcElement extends AdapterBase implements SourceNatServicePro return false; } - List devices = _ciscoVnmcDao.listByPhysicalNetwork(network.getPhysicalNetworkId()); + final List devices = _ciscoVnmcDao.listByPhysicalNetwork(network.getPhysicalNetworkId()); if (devices.isEmpty()) { s_logger.error("No Cisco Vnmc device on network " + network.getName()); return false; @@ -312,114 +316,119 @@ public class CiscoVnmcElement extends AdapterBase implements SourceNatServicePro return false; } - Transaction txn = Transaction.currentTxn(); - boolean status = false; try { - txn.start(); + Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientAddressCapacityException, ResourceUnavailableException { - // ensure that there is an ASA 1000v assigned to this network - CiscoAsa1000vDevice assignedAsa = assignAsa1000vToNetwork(network); - if (assignedAsa == null) { - s_logger.error("Unable to assign ASA 1000v device to network " + network.getName()); - return false; - } - - ClusterVO asaCluster = _clusterDao.findById(assignedAsa.getClusterId()); - ClusterVSMMapVO clusterVsmMap = _clusterVsmMapDao.findByClusterId(assignedAsa.getClusterId()); - if (clusterVsmMap == null) { - s_logger.error("Vmware cluster " + asaCluster.getName() + " has no Cisco Nexus VSM device associated with it"); - return false; - } - - CiscoNexusVSMDeviceVO vsmDevice = _vsmDeviceDao.findById(clusterVsmMap.getVsmId()); - if (vsmDevice == null) { - s_logger.error("Unable to load details of Cisco Nexus VSM device associated with cluster " + asaCluster.getName()); - return false; - } - - CiscoVnmcControllerVO ciscoVnmcDevice = devices.get(0); - HostVO ciscoVnmcHost = _hostDao.findById(ciscoVnmcDevice.getHostId()); - _hostDao.loadDetails(ciscoVnmcHost); - Account owner = context.getAccount(); - PublicIp sourceNatIp = _ipAddrMgr.assignSourceNatIpAddressToGuestNetwork(owner, network); - long vlanId = Long.parseLong(BroadcastDomainType.getValue(network.getBroadcastUri())); - - List vlanVOList = _vlanDao.listVlansByPhysicalNetworkId(network.getPhysicalNetworkId()); - List publicGateways = new ArrayList(); - for (VlanVO vlanVO : vlanVOList) { - publicGateways.add(vlanVO.getVlanGateway()); - } - - // due to VNMC limitation of not allowing source NAT ip as the outside ip of firewall, - // an additional public ip needs to acquired for assigning as firewall outside ip. - // In case there are already additional ip addresses available (network restart) use one - // of them such that it is not the source NAT ip - IpAddress outsideIp = null; - List publicIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null); - for (IPAddressVO ip : publicIps) { - if (!ip.isSourceNat()) { - outsideIp = ip; - break; + // ensure that there is an ASA 1000v assigned to this network + CiscoAsa1000vDevice assignedAsa = assignAsa1000vToNetwork(network); + if (assignedAsa == null) { + s_logger.error("Unable to assign ASA 1000v device to network " + network.getName()); + throw new CloudRuntimeException("Unable to assign ASA 1000v device to network " + network.getName()); + } + + ClusterVO asaCluster = _clusterDao.findById(assignedAsa.getClusterId()); + ClusterVSMMapVO clusterVsmMap = _clusterVsmMapDao.findByClusterId(assignedAsa.getClusterId()); + if (clusterVsmMap == null) { + s_logger.error("Vmware cluster " + asaCluster.getName() + " has no Cisco Nexus VSM device associated with it"); + throw new CloudRuntimeException("Vmware cluster " + asaCluster.getName() + " has no Cisco Nexus VSM device associated with it"); + } + + CiscoNexusVSMDeviceVO vsmDevice = _vsmDeviceDao.findById(clusterVsmMap.getVsmId()); + if (vsmDevice == null) { + s_logger.error("Unable to load details of Cisco Nexus VSM device associated with cluster " + asaCluster.getName()); + throw new CloudRuntimeException("Unable to load details of Cisco Nexus VSM device associated with cluster " + asaCluster.getName()); + } + + CiscoVnmcControllerVO ciscoVnmcDevice = devices.get(0); + HostVO ciscoVnmcHost = _hostDao.findById(ciscoVnmcDevice.getHostId()); + _hostDao.loadDetails(ciscoVnmcHost); + Account owner = context.getAccount(); + PublicIp sourceNatIp = _ipAddrMgr.assignSourceNatIpAddressToGuestNetwork(owner, network); + long vlanId = Long.parseLong(BroadcastDomainType.getValue(network.getBroadcastUri())); + + List vlanVOList = _vlanDao.listVlansByPhysicalNetworkId(network.getPhysicalNetworkId()); + List publicGateways = new ArrayList(); + for (VlanVO vlanVO : vlanVOList) { + publicGateways.add(vlanVO.getVlanGateway()); + } + + // due to VNMC limitation of not allowing source NAT ip as the outside ip of firewall, + // an additional public ip needs to acquired for assigning as firewall outside ip. + // In case there are already additional ip addresses available (network restart) use one + // of them such that it is not the source NAT ip + IpAddress outsideIp = null; + List publicIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null); + for (IPAddressVO ip : publicIps) { + if (!ip.isSourceNat()) { + outsideIp = ip; + break; + } + } + if (outsideIp == null) { // none available, acquire one + try { + Account caller = CallContext.current().getCallingAccount(); + long callerUserId = CallContext.current().getCallingUserId(); + outsideIp = _ipAddrMgr.allocateIp(owner, false, caller, callerUserId, zone); + } catch (ResourceAllocationException e) { + s_logger.error("Unable to allocate additional public Ip address. Exception details " + e); + throw new CloudRuntimeException("Unable to allocate additional public Ip address. Exception details " + e); + } + + try { + outsideIp = _ipAddrMgr.associateIPToGuestNetwork(outsideIp.getId(), network.getId(), true); + } catch (ResourceAllocationException e) { + s_logger.error("Unable to assign allocated additional public Ip " + outsideIp.getAddress().addr() + " to network with vlan " + vlanId + ". Exception details " + + e); + throw new CloudRuntimeException("Unable to assign allocated additional public Ip " + outsideIp.getAddress().addr() + " to network with vlan " + vlanId + ". Exception details " + + e); + } + } + + // create logical edge firewall in VNMC + String gatewayNetmask = NetUtils.getCidrNetmask(network.getCidr()); + // due to ASA limitation of allowing single subnet to be assigned to firewall interfaces, + // all public ip addresses must be from same subnet, this essentially means single public subnet in zone + if (!createLogicalEdgeFirewall(vlanId, network.getGateway(), gatewayNetmask, + outsideIp.getAddress().addr(), sourceNatIp.getNetmask(), publicGateways, ciscoVnmcHost.getId())) { + s_logger.error("Failed to create logical edge firewall in Cisco VNMC device for network " + network.getName()); + throw new CloudRuntimeException("Failed to create logical edge firewall in Cisco VNMC device for network " + network.getName()); + } + + // create stuff in VSM for ASA device + if (!configureNexusVsmForAsa(vlanId, network.getGateway(), + vsmDevice.getUserName(), vsmDevice.getPassword(), vsmDevice.getipaddr(), + assignedAsa.getInPortProfile(), ciscoVnmcHost.getId())) { + s_logger.error("Failed to configure Cisco Nexus VSM " + vsmDevice.getipaddr() + + " for ASA device for network " + network.getName()); + throw new CloudRuntimeException("Failed to configure Cisco Nexus VSM " + vsmDevice.getipaddr() + + " for ASA device for network " + network.getName()); + } + + // configure source NAT + if (!configureSourceNat(vlanId, network.getCidr(), sourceNatIp, ciscoVnmcHost.getId())) { + s_logger.error("Failed to configure source NAT in Cisco VNMC device for network " + network.getName()); + throw new CloudRuntimeException("Failed to configure source NAT in Cisco VNMC device for network " + network.getName()); + } + + // associate Asa 1000v instance with logical edge firewall + if (!associateAsaWithLogicalEdgeFirewall(vlanId, assignedAsa.getManagementIp(), ciscoVnmcHost.getId())) { + s_logger.error("Failed to associate Cisco ASA 1000v (" + assignedAsa.getManagementIp() + + ") with logical edge firewall in VNMC for network " + network.getName()); + throw new CloudRuntimeException("Failed to associate Cisco ASA 1000v (" + assignedAsa.getManagementIp() + + ") with logical edge firewall in VNMC for network " + network.getName()); + } } - } - if (outsideIp == null) { // none available, acquire one - try { - Account caller = CallContext.current().getCallingAccount(); - long callerUserId = CallContext.current().getCallingUserId(); - outsideIp = _ipAddrMgr.allocateIp(owner, false, caller, callerUserId, zone); - } catch (ResourceAllocationException e) { - s_logger.error("Unable to allocate additional public Ip address. Exception details " + e); - return false; - } - - try { - outsideIp = _ipAddrMgr.associateIPToGuestNetwork(outsideIp.getId(), network.getId(), true); - } catch (ResourceAllocationException e) { - s_logger.error("Unable to assign allocated additional public Ip " + outsideIp.getAddress().addr() + " to network with vlan " + vlanId + ". Exception details " - + e); - return false; - } - } - - // create logical edge firewall in VNMC - String gatewayNetmask = NetUtils.getCidrNetmask(network.getCidr()); - // due to ASA limitation of allowing single subnet to be assigned to firewall interfaces, - // all public ip addresses must be from same subnet, this essentially means single public subnet in zone - if (!createLogicalEdgeFirewall(vlanId, network.getGateway(), gatewayNetmask, - outsideIp.getAddress().addr(), sourceNatIp.getNetmask(), publicGateways, ciscoVnmcHost.getId())) { - s_logger.error("Failed to create logical edge firewall in Cisco VNMC device for network " + network.getName()); - return false; - } - - // create stuff in VSM for ASA device - if (!configureNexusVsmForAsa(vlanId, network.getGateway(), - vsmDevice.getUserName(), vsmDevice.getPassword(), vsmDevice.getipaddr(), - assignedAsa.getInPortProfile(), ciscoVnmcHost.getId())) { - s_logger.error("Failed to configure Cisco Nexus VSM " + vsmDevice.getipaddr() + - " for ASA device for network " + network.getName()); - return false; - } - - // configure source NAT - if (!configureSourceNat(vlanId, network.getCidr(), sourceNatIp, ciscoVnmcHost.getId())) { - s_logger.error("Failed to configure source NAT in Cisco VNMC device for network " + network.getName()); - return false; - } - - // associate Asa 1000v instance with logical edge firewall - if (!associateAsaWithLogicalEdgeFirewall(vlanId, assignedAsa.getManagementIp(), ciscoVnmcHost.getId())) { - s_logger.error("Failed to associate Cisco ASA 1000v (" + assignedAsa.getManagementIp() + - ") with logical edge firewall in VNMC for network " + network.getName()); - return false; - } - - status = true; - txn.commit(); - } finally { - if (!status) { - txn.rollback(); - //FIXME: also undo changes in VNMC, VSM if anything failed - } + }); + } catch (CloudRuntimeException e) { + s_logger.error("CiscoVnmcElement failed", e); + return false; + } catch (Exception e) { + ExceptionUtil.rethrowRuntime(e); + ExceptionUtil.rethrow(e, InsufficientAddressCapacityException.class); + ExceptionUtil.rethrow(e, ResourceUnavailableException.class); + throw new IllegalStateException(e); } return true; @@ -522,9 +531,9 @@ public class CiscoVnmcElement extends AdapterBase implements SourceNatServicePro @Override public CiscoVnmcController addCiscoVnmcResource(AddCiscoVnmcResourceCmd cmd) { - String deviceName = Provider.CiscoVnmc.getName(); + final String deviceName = Provider.CiscoVnmc.getName(); NetworkDevice networkDevice = NetworkDevice.getNetworkDevice(deviceName); - Long physicalNetworkId = cmd.getPhysicalNetworkId(); + final Long physicalNetworkId = cmd.getPhysicalNetworkId(); CiscoVnmcController ciscoVnmcResource = null; PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); @@ -533,7 +542,7 @@ public class CiscoVnmcElement extends AdapterBase implements SourceNatServicePro } long zoneId = physicalNetwork.getDataCenterId(); - PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(physicalNetwork.getId(), + final PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(physicalNetwork.getId(), networkDevice.getNetworkServiceProvder()); if (ntwkSvcProvider == null) { throw new CloudRuntimeException("Network Service Provider: " + networkDevice.getNetworkServiceProvder() + @@ -560,27 +569,27 @@ public class CiscoVnmcElement extends AdapterBase implements SourceNatServicePro hostdetails.putAll(params); ServerResource resource = new CiscoVnmcResource(); - Transaction txn = Transaction.currentTxn(); try { resource.configure(cmd.getHost(), hostdetails); - Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.ExternalFirewall, params); + final Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.ExternalFirewall, params); if (host != null) { - txn.start(); - - ciscoVnmcResource = new CiscoVnmcControllerVO(host.getId(), physicalNetworkId, ntwkSvcProvider.getProviderName(), deviceName); - _ciscoVnmcDao.persist((CiscoVnmcControllerVO)ciscoVnmcResource); - - DetailVO detail = new DetailVO(host.getId(), "deviceid", String.valueOf(ciscoVnmcResource.getId())); - _hostDetailsDao.persist(detail); - - txn.commit(); - return ciscoVnmcResource; + return Transaction.execute(new TransactionCallback() { + @Override + public CiscoVnmcController doInTransaction(TransactionStatus status) { + CiscoVnmcController ciscoVnmcResource = new CiscoVnmcControllerVO(host.getId(), physicalNetworkId, ntwkSvcProvider.getProviderName(), deviceName); + _ciscoVnmcDao.persist((CiscoVnmcControllerVO)ciscoVnmcResource); + + DetailVO detail = new DetailVO(host.getId(), "deviceid", String.valueOf(ciscoVnmcResource.getId())); + _hostDetailsDao.persist(detail); + + return ciscoVnmcResource; + } + }); } else { throw new CloudRuntimeException("Failed to add Cisco Vnmc device due to internal error."); } } catch (ConfigurationException e) { - txn.rollback(); throw new CloudRuntimeException(e.getMessage()); } } diff --git a/plugins/network-elements/elastic-loadbalancer/resources/META-INF/cloudstack/elb/module.properties b/plugins/network-elements/elastic-loadbalancer/resources/META-INF/cloudstack/elb/module.properties new file mode 100644 index 00000000000..a8e3b9c8669 --- /dev/null +++ b/plugins/network-elements/elastic-loadbalancer/resources/META-INF/cloudstack/elb/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=elb +parent=network \ No newline at end of file diff --git a/plugins/network-elements/elastic-loadbalancer/resources/META-INF/cloudstack/elb/spring-elb-context.xml b/plugins/network-elements/elastic-loadbalancer/resources/META-INF/cloudstack/elb/spring-elb-context.xml new file mode 100644 index 00000000000..247153c4558 --- /dev/null +++ b/plugins/network-elements/elastic-loadbalancer/resources/META-INF/cloudstack/elb/spring-elb-context.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java b/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java index 3f8fc5c6f9d..5c6f2e7dd63 100644 --- a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java +++ b/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java @@ -123,6 +123,10 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionCallbackWithException; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; import com.cloud.vm.DomainRouterVO; @@ -311,7 +315,7 @@ public class ElasticLoadBalancerManagerImpl extends ManagerBase implements Elast maxconn = offering.getConcurrentConnections().toString(); } LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs,elbVm.getPublicIpAddress(), - _nicDao.getIpAddress(guestNetworkId, elbVm.getId()),elbVm.getPrivateIpAddress(), null, null, maxconn); + _nicDao.getIpAddress(guestNetworkId, elbVm.getId()),elbVm.getPrivateIpAddress(), null, null, maxconn, offering.isKeepAliveEnabled()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, elbVm.getPrivateIpAddress()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, @@ -582,19 +586,21 @@ public class ElasticLoadBalancerManagerImpl extends ManagerBase implements Elast } @DB - public PublicIp allocDirectIp(Account account, long guestNetworkId) throws InsufficientAddressCapacityException { - Network frontEndNetwork = _networkModel.getNetwork(guestNetworkId); - Transaction txn = Transaction.currentTxn(); - txn.start(); - - PublicIp ip = _ipAddrMgr.assignPublicIpAddress(frontEndNetwork.getDataCenterId(), null, account, VlanType.DirectAttached, frontEndNetwork.getId(), null, true); - IPAddressVO ipvo = _ipAddressDao.findById(ip.getId()); - ipvo.setAssociatedWithNetworkId(frontEndNetwork.getId()); - _ipAddressDao.update(ipvo.getId(), ipvo); - txn.commit(); - s_logger.info("Acquired frontend IP for ELB " + ip); + public PublicIp allocDirectIp(final Account account, final long guestNetworkId) throws InsufficientAddressCapacityException { + return Transaction.execute(new TransactionCallbackWithException() { + @Override + public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException { + Network frontEndNetwork = _networkModel.getNetwork(guestNetworkId); - return ip; + PublicIp ip = _ipAddrMgr.assignPublicIpAddress(frontEndNetwork.getDataCenterId(), null, account, VlanType.DirectAttached, frontEndNetwork.getId(), null, true); + IPAddressVO ipvo = _ipAddressDao.findById(ip.getId()); + ipvo.setAssociatedWithNetworkId(frontEndNetwork.getId()); + _ipAddressDao.update(ipvo.getId(), ipvo); + s_logger.info("Acquired frontend IP for ELB " + ip); + + return ip; + } + }); } public void releaseIp(long ipId, long userId, Account caller) { diff --git a/plugins/network-elements/internal-loadbalancer/resources/META-INF/cloudstack/core/spring-internallb-core-context.xml b/plugins/network-elements/internal-loadbalancer/resources/META-INF/cloudstack/core/spring-internallb-core-context.xml new file mode 100644 index 00000000000..c03887931b8 --- /dev/null +++ b/plugins/network-elements/internal-loadbalancer/resources/META-INF/cloudstack/core/spring-internallb-core-context.xml @@ -0,0 +1,37 @@ + + + + + + + + + + diff --git a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java index 5da6e022906..b6269ebae9d 100644 --- a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java +++ b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java @@ -461,7 +461,7 @@ public class InternalLoadBalancerVMManagerImpl extends ManagerBase implements In } LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs, guestNic.getIp4Address(), guestNic.getIp4Address(), internalLbVm.getPrivateIpAddress(), - _itMgr.toNicTO(guestNicProfile, internalLbVm.getHypervisorType()), internalLbVm.getVpcId(), maxconn); + _itMgr.toNicTO(guestNicProfile, internalLbVm.getHypervisorType()), internalLbVm.getVpcId(), maxconn, offering.isKeepAliveEnabled()); cmd.lbStatsVisibility = _configDao.getValue(Config.NetworkLBHaproxyStatsVisbility.key()); cmd.lbStatsUri = _configDao.getValue(Config.NetworkLBHaproxyStatsUri.key()); diff --git a/plugins/network-elements/juniper-srx/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java b/plugins/network-elements/juniper-srx/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java index af67b026de0..85210379af7 100644 --- a/plugins/network-elements/juniper-srx/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java +++ b/plugins/network-elements/juniper-srx/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java @@ -95,7 +95,7 @@ import com.cloud.vm.VirtualMachineProfile; PortForwardingServiceProvider.class, IpDeployer.class, SourceNatServiceProvider.class, RemoteAccessVPNServiceProvider.class}) public class JuniperSRXExternalFirewallElement extends ExternalFirewallDeviceManagerImpl implements SourceNatServiceProvider, FirewallServiceProvider, -PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer, JuniperSRXFirewallElementService, StaticNatServiceProvider { +PortForwardingServiceProvider, IpDeployer, JuniperSRXFirewallElementService, StaticNatServiceProvider { private static final Logger s_logger = Logger.getLogger(JuniperSRXExternalFirewallElement.class); @@ -225,42 +225,6 @@ PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer, Junip return applyFirewallRules(config, rules); } - @Override - public boolean startVpn(Network config, RemoteAccessVpn vpn) throws ResourceUnavailableException { - if (!canHandle(config, Service.Vpn)) { - return false; - } - - return manageRemoteAccessVpn(true, config, vpn); - - } - - @Override - public boolean stopVpn(Network config, RemoteAccessVpn vpn) throws ResourceUnavailableException { - if (!canHandle(config, Service.Vpn)) { - return false; - } - - return manageRemoteAccessVpn(false, config, vpn); - } - - @Override - public String[] applyVpnUsers(RemoteAccessVpn vpn, List users) throws ResourceUnavailableException { - Network config = _networksDao.findById(vpn.getNetworkId()); - - if (!canHandle(config, Service.Vpn)) { - return null; - } - - boolean result = manageRemoteAccessVpnUsers(config, vpn, users); - String[] results = new String[users.size()]; - for (int i = 0; i < results.length; i++) { - results[i] = String.valueOf(result); - } - - return results; - } - @Override public Provider getProvider() { return Provider.JuniperSRX; diff --git a/plugins/network-elements/midonet/resources/META-INF/cloudstack/midonet/module.properties b/plugins/network-elements/midonet/resources/META-INF/cloudstack/midonet/module.properties new file mode 100644 index 00000000000..786ccc8dbe5 --- /dev/null +++ b/plugins/network-elements/midonet/resources/META-INF/cloudstack/midonet/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=midonet +parent=network \ No newline at end of file diff --git a/plugins/network-elements/midonet/resources/META-INF/cloudstack/midonet/spring-midonet-context.xml b/plugins/network-elements/midonet/resources/META-INF/cloudstack/midonet/spring-midonet-context.xml new file mode 100644 index 00000000000..400f7dd6ed6 --- /dev/null +++ b/plugins/network-elements/midonet/resources/META-INF/cloudstack/midonet/spring-midonet-context.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + diff --git a/plugins/network-elements/midonet/src/com/cloud/network/guru/MidoNetPublicNetworkGuru.java b/plugins/network-elements/midonet/src/com/cloud/network/guru/MidoNetPublicNetworkGuru.java index eccf4aa3944..c11c8719496 100644 --- a/plugins/network-elements/midonet/src/com/cloud/network/guru/MidoNetPublicNetworkGuru.java +++ b/plugins/network-elements/midonet/src/com/cloud/network/guru/MidoNetPublicNetworkGuru.java @@ -46,6 +46,8 @@ import com.cloud.user.AccountVO; import com.cloud.user.dao.AccountDao; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; @@ -206,16 +208,15 @@ public class MidoNetPublicNetworkGuru extends PublicNetworkGuru { s_logger.debug("public network deallocate network: networkId: " + nic.getNetworkId() + ", ip: " + nic.getIp4Address()); } - IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIp4Address()); + final IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIp4Address()); if (ip != null && nic.getReservationStrategy() != Nic.ReservationStrategy.Managed) { - - Transaction txn = Transaction.currentTxn(); - txn.start(); - - _ipAddrMgr.markIpAsUnavailable(ip.getId()); - _ipAddressDao.unassignIpAddress(ip.getId()); - - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + _ipAddrMgr.markIpAsUnavailable(ip.getId()); + _ipAddressDao.unassignIpAddress(ip.getId()); + } + }); } nic.deallocate(); diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java index d63b14f8a58..8101864840b 100644 --- a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java +++ b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java @@ -31,7 +31,6 @@ import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice; import org.apache.cloudstack.region.gslb.GslbServiceProvider; - import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -110,13 +109,14 @@ import com.cloud.offering.NetworkOffering; import com.cloud.utils.NumbersUtil; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.UrlUtil; import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; - import com.google.gson.Gson; @Local(value = {NetworkElement.class, StaticNatServiceProvider.class, LoadBalancingServiceProvider.class, GslbServiceProvider.class}) @@ -409,9 +409,9 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } @DB - private ExternalLoadBalancerDeviceVO configureNetscalerLoadBalancer(long lbDeviceId, Long capacity, Boolean dedicatedUse, List newPodsConfig) { - ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId); - Map lbDetails = _detailsDao.findDetails(lbDeviceVo.getHostId()); + private ExternalLoadBalancerDeviceVO configureNetscalerLoadBalancer(final long lbDeviceId, Long capacity, Boolean dedicatedUse, List newPodsConfig) { + final ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId); + final Map lbDetails = _detailsDao.findDetails(lbDeviceVo.getHostId()); if ((lbDeviceVo == null) || !isNetscalerDevice(lbDeviceVo.getDeviceName())) { throw new InvalidParameterValueException("No netscaler device found with ID: " + lbDeviceId); @@ -425,7 +425,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } } - List podsToAssociate = new ArrayList(); + final List podsToAssociate = new ArrayList(); if (newPodsConfig != null && newPodsConfig.size() > 0) { for (Long podId: newPodsConfig) { HostPodVO pod = _podDao.findById(podId); @@ -441,7 +441,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } } - List podsToDeassociate = new ArrayList(); + final List podsToDeassociate = new ArrayList(); for (Long podId: currentPodsConfig) { if (!newPodsConfig.contains(podId)) { podsToDeassociate.add(podId); @@ -482,26 +482,28 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl lbDeviceVo.setIsDedicatedDevice(dedicatedUse); } - Transaction txn = Transaction.currentTxn(); - txn.start(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + _lbDeviceDao.update(lbDeviceId, lbDeviceVo); + + for (Long podId: podsToAssociate) { + NetScalerPodVO nsPodVo = new NetScalerPodVO(lbDeviceId, podId); + _netscalerPodDao.persist(nsPodVo); + } + + for (Long podId: podsToDeassociate) { + NetScalerPodVO nsPodVo = _netscalerPodDao.findByPodId(podId); + _netscalerPodDao.remove(nsPodVo.getId()); + } + + // FIXME get the row lock to avoid race condition + _detailsDao.persist(lbDeviceVo.getHostId(), lbDetails); - _lbDeviceDao.update(lbDeviceId, lbDeviceVo); - - for (Long podId: podsToAssociate) { - NetScalerPodVO nsPodVo = new NetScalerPodVO(lbDeviceId, podId); - _netscalerPodDao.persist(nsPodVo); - } - - for (Long podId: podsToDeassociate) { - NetScalerPodVO nsPodVo = _netscalerPodDao.findByPodId(podId); - _netscalerPodDao.remove(nsPodVo.getId()); - } - - // FIXME get the row lock to avoid race condition - _detailsDao.persist(lbDeviceVo.getHostId(), lbDetails); + } + }); HostVO host = _hostDao.findById(lbDeviceVo.getHostId()); - txn.commit(); - + _agentMgr.reconnect(host.getId()); return lbDeviceVo; } diff --git a/plugins/network-elements/nicira-nvp/resources/META-INF/cloudstack/nvp/module.properties b/plugins/network-elements/nicira-nvp/resources/META-INF/cloudstack/nvp/module.properties new file mode 100644 index 00000000000..92f92a4b4b0 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/resources/META-INF/cloudstack/nvp/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=nvp +parent=network \ No newline at end of file diff --git a/plugins/network-elements/nicira-nvp/resources/META-INF/cloudstack/nvp/spring-nvp-context.xml b/plugins/network-elements/nicira-nvp/resources/META-INF/cloudstack/nvp/spring-nvp-context.xml new file mode 100644 index 00000000000..302b072c8d0 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/resources/META-INF/cloudstack/nvp/spring-nvp-context.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java index 5400dd4137c..ef8ec863c9a 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java @@ -30,7 +30,6 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; - import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice; @@ -114,6 +113,8 @@ import com.cloud.user.Account; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.vm.NicProfile; @@ -552,12 +553,10 @@ public class NiciraNvpElement extends AdapterBase implements @DB public NiciraNvpDeviceVO addNiciraNvpDevice(AddNiciraNvpDeviceCmd cmd) { ServerResource resource = new NiciraNvpResource(); - String deviceName = Network.Provider.NiciraNvp.getName(); + final String deviceName = Network.Provider.NiciraNvp.getName(); NetworkDevice networkDevice = NetworkDevice .getNetworkDevice(deviceName); - Long physicalNetworkId = cmd.getPhysicalNetworkId(); - NiciraNvpDeviceVO niciraNvpDevice = null; - + final Long physicalNetworkId = cmd.getPhysicalNetworkId(); PhysicalNetworkVO physicalNetwork = _physicalNetworkDao .findById(physicalNetworkId); if (physicalNetwork == null) { @@ -567,7 +566,7 @@ public class NiciraNvpElement extends AdapterBase implements } long zoneId = physicalNetwork.getDataCenterId(); - PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao + final PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao .findByServiceProvider(physicalNetwork.getId(), networkDevice.getNetworkServiceProvder()); if (ntwkSvcProvider == null) { @@ -606,33 +605,33 @@ public class NiciraNvpElement extends AdapterBase implements Map hostdetails = new HashMap(); hostdetails.putAll(params); - Transaction txn = Transaction.currentTxn(); try { resource.configure(cmd.getHost(), hostdetails); - Host host = _resourceMgr.addHost(zoneId, resource, + final Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.L2Networking, params); if (host != null) { - txn.start(); + return Transaction.execute(new TransactionCallback() { + @Override + public NiciraNvpDeviceVO doInTransaction(TransactionStatus status) { + NiciraNvpDeviceVO niciraNvpDevice = new NiciraNvpDeviceVO(host.getId(), + physicalNetworkId, ntwkSvcProvider.getProviderName(), + deviceName); + _niciraNvpDao.persist(niciraNvpDevice); + + DetailVO detail = new DetailVO(host.getId(), + "niciranvpdeviceid", String.valueOf(niciraNvpDevice + .getId())); + _hostDetailsDao.persist(detail); - niciraNvpDevice = new NiciraNvpDeviceVO(host.getId(), - physicalNetworkId, ntwkSvcProvider.getProviderName(), - deviceName); - _niciraNvpDao.persist(niciraNvpDevice); - - DetailVO detail = new DetailVO(host.getId(), - "niciranvpdeviceid", String.valueOf(niciraNvpDevice - .getId())); - _hostDetailsDao.persist(detail); - - txn.commit(); - return niciraNvpDevice; + return niciraNvpDevice; + } + }); } else { throw new CloudRuntimeException( "Failed to add Nicira Nvp Device due to internal error."); } } catch (ConfigurationException e) { - txn.rollback(); throw new CloudRuntimeException(e.getMessage()); } } diff --git a/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/module.properties b/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/module.properties new file mode 100644 index 00000000000..c3fa5ff294b --- /dev/null +++ b/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=ovs +parent=network diff --git a/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml b/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml new file mode 100644 index 00000000000..9180eebd040 --- /dev/null +++ b/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + diff --git a/plugins/network-elements/stratosphere-ssp/resources/META-INF/cloudstack/ssp/module.properties b/plugins/network-elements/stratosphere-ssp/resources/META-INF/cloudstack/ssp/module.properties new file mode 100644 index 00000000000..5a99e561b04 --- /dev/null +++ b/plugins/network-elements/stratosphere-ssp/resources/META-INF/cloudstack/ssp/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=ssp +parent=network \ No newline at end of file diff --git a/plugins/network-elements/stratosphere-ssp/resources/META-INF/cloudstack/ssp/spring-ssp-context.xml b/plugins/network-elements/stratosphere-ssp/resources/META-INF/cloudstack/ssp/spring-ssp-context.xml new file mode 100644 index 00000000000..528f3e3e38c --- /dev/null +++ b/plugins/network-elements/stratosphere-ssp/resources/META-INF/cloudstack/ssp/spring-ssp-context.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + diff --git a/plugins/network-elements/vxlan/resources/META-INF/cloudstack/vxlan/module.properties b/plugins/network-elements/vxlan/resources/META-INF/cloudstack/vxlan/module.properties new file mode 100644 index 00000000000..4c2c7f7f7ce --- /dev/null +++ b/plugins/network-elements/vxlan/resources/META-INF/cloudstack/vxlan/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=vxlan +parent=network \ No newline at end of file diff --git a/plugins/network-elements/vxlan/resources/META-INF/cloudstack/vxlan/spring-vxlan-context.xml b/plugins/network-elements/vxlan/resources/META-INF/cloudstack/vxlan/spring-vxlan-context.xml new file mode 100644 index 00000000000..fcf0b0189eb --- /dev/null +++ b/plugins/network-elements/vxlan/resources/META-INF/cloudstack/vxlan/spring-vxlan-context.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/plugins/storage/image/default/resources/META-INF/cloudstack/storage-image-default/module.properties b/plugins/storage/image/default/resources/META-INF/cloudstack/storage-image-default/module.properties new file mode 100644 index 00000000000..8381f6eff18 --- /dev/null +++ b/plugins/storage/image/default/resources/META-INF/cloudstack/storage-image-default/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=storage-image-default +parent=storage \ No newline at end of file diff --git a/plugins/storage/image/default/resources/META-INF/cloudstack/storage-image-default/spring-storage-image-default-context.xml b/plugins/storage/image/default/resources/META-INF/cloudstack/storage-image-default/spring-storage-image-default-context.xml new file mode 100644 index 00000000000..6d3c63c2772 --- /dev/null +++ b/plugins/storage/image/default/resources/META-INF/cloudstack/storage-image-default/spring-storage-image-default-context.xml @@ -0,0 +1,33 @@ + + + + + + diff --git a/plugins/storage/image/s3/resources/META-INF/cloudstack/storage-image-s3/module.properties b/plugins/storage/image/s3/resources/META-INF/cloudstack/storage-image-s3/module.properties new file mode 100644 index 00000000000..da571e2dda9 --- /dev/null +++ b/plugins/storage/image/s3/resources/META-INF/cloudstack/storage-image-s3/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=storage-image-s3 +parent=storage \ No newline at end of file diff --git a/plugins/storage/image/s3/resources/META-INF/cloudstack/storage-image-s3/spring-storage-image-s3-context.xml b/plugins/storage/image/s3/resources/META-INF/cloudstack/storage-image-s3/spring-storage-image-s3-context.xml new file mode 100644 index 00000000000..610506340a8 --- /dev/null +++ b/plugins/storage/image/s3/resources/META-INF/cloudstack/storage-image-s3/spring-storage-image-s3-context.xml @@ -0,0 +1,34 @@ + + + + + + + diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index f31aea3bcb1..6b5175eedae 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -67,13 +67,21 @@ public class S3ImageStoreDriverImpl extends BaseImageStoreDriverImpl { .get(ApiConstants.S3_SOCKET_TIMEOUT)), imgStore.getCreated(), _configDao.getValue(Config.S3EnableRRS.toString()) == null ? false : Boolean.parseBoolean(_configDao .getValue(Config.S3EnableRRS.toString())), - _configDao.getValue(Config.S3EnableMultiPartUpload.toString()) == null ? true : Boolean.parseBoolean(_configDao - .getValue(Config.S3EnableMultiPartUpload.toString())) + getMaxSingleUploadSizeInBytes() ); } + private long getMaxSingleUploadSizeInBytes() { + try { + return Long.parseLong(_configDao.getValue(Config.S3MaxSingleUploadSize.toString())) * 1024L * 1024L * 1024L; + } catch (NumberFormatException e) { + // use default 5GB + return 5L * 1024L * 1024L * 1024L; + } + } + @Override public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format, DataObject dataObject) { // for S3, no need to do anything, just return template url for diff --git a/plugins/storage/image/swift/resources/META-INF/cloudstack/storage-image-swift/module.properties b/plugins/storage/image/swift/resources/META-INF/cloudstack/storage-image-swift/module.properties new file mode 100644 index 00000000000..1fa4be6f5e5 --- /dev/null +++ b/plugins/storage/image/swift/resources/META-INF/cloudstack/storage-image-swift/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=storage-image-swift +parent=storage \ No newline at end of file diff --git a/plugins/storage/image/swift/resources/META-INF/cloudstack/storage-image-swift/spring-storage-image-swift-context.xml b/plugins/storage/image/swift/resources/META-INF/cloudstack/storage-image-swift/spring-storage-image-swift-context.xml new file mode 100644 index 00000000000..5e986e88360 --- /dev/null +++ b/plugins/storage/image/swift/resources/META-INF/cloudstack/storage-image-swift/spring-storage-image-swift-context.xml @@ -0,0 +1,33 @@ + + + + + + diff --git a/plugins/storage/volume/default/resources/META-INF/cloudstack/storage-volume-default/module.properties b/plugins/storage/volume/default/resources/META-INF/cloudstack/storage-volume-default/module.properties new file mode 100644 index 00000000000..61369884987 --- /dev/null +++ b/plugins/storage/volume/default/resources/META-INF/cloudstack/storage-volume-default/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=storage-volume-default +parent=storage \ No newline at end of file diff --git a/plugins/storage/volume/default/resources/META-INF/cloudstack/storage-volume-default/spring-storage-volume-default-context.xml b/plugins/storage/volume/default/resources/META-INF/cloudstack/storage-volume-default/spring-storage-volume-default-context.xml new file mode 100644 index 00000000000..8b50455315d --- /dev/null +++ b/plugins/storage/volume/default/resources/META-INF/cloudstack/storage-volume-default/spring-storage-volume-default-context.xml @@ -0,0 +1,35 @@ + + + + + + + + diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index 3eaeb1f080c..82dc34769b8 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -18,6 +18,35 @@ */ package org.apache.cloudstack.storage.datastore.driver; +import java.util.UUID; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService; +import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.storage.command.CommandResult; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; +import org.apache.cloudstack.storage.command.CopyCommand; +import org.apache.cloudstack.storage.command.CreateObjectCommand; +import org.apache.cloudstack.storage.command.DeleteCommand; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.apache.cloudstack.storage.volume.VolumeObject; +import org.apache.log4j.Logger; + import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.ResizeVolumeAnswer; import com.cloud.agent.api.storage.ResizeVolumeCommand; @@ -42,25 +71,6 @@ import com.cloud.template.TemplateManager; import com.cloud.utils.NumbersUtil; import com.cloud.vm.dao.VMInstanceDao; -import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService; -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; -import org.apache.cloudstack.engine.subsystem.api.storage.*; -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.storage.command.CommandResult; -import org.apache.cloudstack.storage.command.CopyCmdAnswer; -import org.apache.cloudstack.storage.command.CopyCommand; -import org.apache.cloudstack.storage.command.CreateObjectCommand; -import org.apache.cloudstack.storage.command.DeleteCommand; -import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; -import org.apache.cloudstack.storage.to.TemplateObjectTO; -import org.apache.cloudstack.storage.volume.VolumeObject; - -import org.apache.log4j.Logger; - -import javax.inject.Inject; -import java.util.UUID; - public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver { private static final Logger s_logger = Logger.getLogger(CloudStackPrimaryDataStoreDriverImpl.class); @Inject @@ -296,5 +306,4 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri callback.complete(result); } - } diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java index 9a7012494e4..5e0dd958f34 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java @@ -472,6 +472,8 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements PrimaryDataStore HypervisorType hType = null; if(hostPoolRecords.size() > 0 ){ hType = getHypervisorType(hostPoolRecords.get(0).getHostId()); + } else { + return false; } // Remove the SR associated with the Xenserver diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java index ece7b260cd4..75e8823a1b5 100644 --- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java @@ -16,11 +16,18 @@ // under the License. package org.apache.cloudstack.storage.datastore.driver; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.to.DataStoreTO; -import com.cloud.agent.api.to.DataTO; -import com.cloud.storage.dao.StoragePoolHostDao; -import org.apache.cloudstack.engine.subsystem.api.storage.*; +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcContext; @@ -29,7 +36,10 @@ import org.apache.cloudstack.storage.command.CreateObjectCommand; import org.apache.cloudstack.storage.datastore.DataObjectManager; import org.apache.log4j.Logger; -import javax.inject.Inject; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; +import com.cloud.storage.dao.StoragePoolHostDao; public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver { private static final Logger s_logger = Logger.getLogger(SamplePrimaryDataStoreDriverImpl.class); diff --git a/plugins/storage/volume/solidfire/resources/META-INF/cloudstack/storage-volume-solidfire/module.properties b/plugins/storage/volume/solidfire/resources/META-INF/cloudstack/storage-volume-solidfire/module.properties new file mode 100644 index 00000000000..335a9d2b45e --- /dev/null +++ b/plugins/storage/volume/solidfire/resources/META-INF/cloudstack/storage-volume-solidfire/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=storage-volume-solidfire +parent=storage \ No newline at end of file diff --git a/plugins/storage/volume/solidfire/resources/META-INF/cloudstack/storage-volume-solidfire/spring-storage-volume-solidfire-context.xml b/plugins/storage/volume/solidfire/resources/META-INF/cloudstack/storage-volume-solidfire/spring-storage-volume-solidfire-context.xml new file mode 100644 index 00000000000..a83e3cab7e3 --- /dev/null +++ b/plugins/storage/volume/solidfire/resources/META-INF/cloudstack/storage-volume-solidfire/spring-storage-volume-solidfire-context.xml @@ -0,0 +1,33 @@ + + + + + + diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java index 8046b6cfd1b..a02474d7371 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java @@ -20,12 +20,19 @@ import java.util.List; import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.*; +import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO; +import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.util.SolidFireUtil; import org.apache.commons.lang.StringUtils; @@ -39,9 +46,9 @@ import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeDetailsDao; -import com.cloud.user.AccountVO; -import com.cloud.user.AccountDetailsDao; import com.cloud.user.AccountDetailVO; +import com.cloud.user.AccountDetailsDao; +import com.cloud.user.AccountVO; import com.cloud.user.dao.AccountDao; public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { @@ -122,10 +129,10 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { String clusterAdminPassword = sfConnection.getClusterAdminPassword(); long accountNumber = SolidFireUtil.createSolidFireAccount(mVip, mPort, - clusterAdminUsername, clusterAdminPassword, sfAccountName); + clusterAdminUsername, clusterAdminPassword, sfAccountName); return SolidFireUtil.getSolidFireAccountById(mVip, mPort, - clusterAdminUsername, clusterAdminPassword, accountNumber); + clusterAdminUsername, clusterAdminPassword, accountNumber); } private void updateCsDbWithAccountInfo(long csAccountId, SolidFireUtil.SolidFireAccount sfAccount) { @@ -174,18 +181,22 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { _targetSecret = targetSecret; } + @Override public String getInitiatorUsername() { return _initiatorUsername; } + @Override public String getInitiatorSecret() { return _initiatorSecret; } + @Override public String getTargetUsername() { return _targetUsername; } + @Override public String getTargetSecret() { return _targetSecret; } @@ -268,7 +279,7 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { Long maxIops = volumeInfo.getMaxIops(); if (minIops == null || minIops <= 0 || - maxIops == null || maxIops <= 0) { + maxIops == null || maxIops <= 0) { long defaultMaxIops = getDefaultMaxIops(storagePoolId); iops = new Iops(getDefaultMinIops(storagePoolId), defaultMaxIops, getDefaultBurstIops(storagePoolId, defaultMaxIops)); @@ -328,22 +339,22 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { _minIops = minIops; _maxIops = maxIops; _burstIops = burstIops; - } + } - public long getMinIops() - { - return _minIops; - } + public long getMinIops() + { + return _minIops; + } - public long getMaxIops() - { - return _maxIops; - } + public long getMaxIops() + { + return _maxIops; + } - public long getBurstIops() - { - return _burstIops; - } + public long getBurstIops() + { + return _burstIops; + } } private void deleteSolidFireVolume(VolumeInfo volumeInfo, SolidFireConnection sfConnection) @@ -501,14 +512,14 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { _volumeDao.deleteVolumesByInstance(volumeInfo.getId()); -// if (!sfAccountHasVolume(sfAccountId, sfConnection)) { -// // delete the account from the SolidFire SAN -// deleteSolidFireAccount(sfAccountId, sfConnection); -// -// // delete the info in the account_details table -// // that's related to the SolidFire account -// _accountDetailsDao.deleteDetails(account.getAccountId()); -// } + // if (!sfAccountHasVolume(sfAccountId, sfConnection)) { + // // delete the account from the SolidFire SAN + // deleteSolidFireAccount(sfAccountId, sfConnection); + // + // // delete the info in the account_details table + // // that's related to the SolidFire account + // _accountDetailsDao.deleteDetails(account.getAccountId()); + // } StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId); diff --git a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/AopTestAdvice.java b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/AopTestAdvice.java index 902f5953eb1..233b0461150 100644 --- a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/AopTestAdvice.java +++ b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/AopTestAdvice.java @@ -18,11 +18,11 @@ package org.apache.cloudstack.storage.test; import org.aspectj.lang.ProceedingJoinPoint; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; public class AopTestAdvice { public Object AopTestMethod(ProceedingJoinPoint call) throws Throwable { - Transaction txn = Transaction.open(call.getSignature().getName()); + TransactionLegacy txn = TransactionLegacy.open(call.getSignature().getName()); Object ret = null; try { ret = call.proceed(); diff --git a/plugins/user-authenticators/ldap/resources/META-INF/cloudstack/ldap/module.properties b/plugins/user-authenticators/ldap/resources/META-INF/cloudstack/ldap/module.properties new file mode 100644 index 00000000000..4659ab51fd6 --- /dev/null +++ b/plugins/user-authenticators/ldap/resources/META-INF/cloudstack/ldap/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=ldap +parent=api \ No newline at end of file diff --git a/plugins/user-authenticators/ldap/resources/META-INF/cloudstack/ldap/spring-ldap-context.xml b/plugins/user-authenticators/ldap/resources/META-INF/cloudstack/ldap/spring-ldap-context.xml new file mode 100644 index 00000000000..34a2befe971 --- /dev/null +++ b/plugins/user-authenticators/ldap/resources/META-INF/cloudstack/ldap/spring-ldap-context.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + diff --git a/plugins/user-authenticators/md5/resources/META-INF/cloudstack/md5/module.properties b/plugins/user-authenticators/md5/resources/META-INF/cloudstack/md5/module.properties new file mode 100644 index 00000000000..03ba7397117 --- /dev/null +++ b/plugins/user-authenticators/md5/resources/META-INF/cloudstack/md5/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=md5 +parent=api \ No newline at end of file diff --git a/plugins/user-authenticators/md5/resources/META-INF/cloudstack/md5/spring-md5-context.xml b/plugins/user-authenticators/md5/resources/META-INF/cloudstack/md5/spring-md5-context.xml new file mode 100644 index 00000000000..4a8e64dd864 --- /dev/null +++ b/plugins/user-authenticators/md5/resources/META-INF/cloudstack/md5/spring-md5-context.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/plugins/user-authenticators/plain-text/resources/META-INF/cloudstack/plaintext/module.properties b/plugins/user-authenticators/plain-text/resources/META-INF/cloudstack/plaintext/module.properties new file mode 100644 index 00000000000..5a295638f0f --- /dev/null +++ b/plugins/user-authenticators/plain-text/resources/META-INF/cloudstack/plaintext/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=plaintext +parent=api \ No newline at end of file diff --git a/plugins/user-authenticators/plain-text/resources/META-INF/cloudstack/plaintext/spring-plaintext-context.xml b/plugins/user-authenticators/plain-text/resources/META-INF/cloudstack/plaintext/spring-plaintext-context.xml new file mode 100644 index 00000000000..639411a1086 --- /dev/null +++ b/plugins/user-authenticators/plain-text/resources/META-INF/cloudstack/plaintext/spring-plaintext-context.xml @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/plugins/user-authenticators/sha256salted/resources/META-INF/cloudstack/sha256salted/module.properties b/plugins/user-authenticators/sha256salted/resources/META-INF/cloudstack/sha256salted/module.properties new file mode 100644 index 00000000000..c70a2f516ec --- /dev/null +++ b/plugins/user-authenticators/sha256salted/resources/META-INF/cloudstack/sha256salted/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=sha256salted +parent=api \ No newline at end of file diff --git a/plugins/user-authenticators/sha256salted/resources/META-INF/cloudstack/sha256salted/spring-sha256salted-context.xml b/plugins/user-authenticators/sha256salted/resources/META-INF/cloudstack/sha256salted/spring-sha256salted-context.xml new file mode 100644 index 00000000000..e379718549e --- /dev/null +++ b/plugins/user-authenticators/sha256salted/resources/META-INF/cloudstack/sha256salted/spring-sha256salted-context.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/pom.xml b/pom.xml index d8c6f405d7f..679acedac80 100644 --- a/pom.xml +++ b/pom.xml @@ -73,7 +73,7 @@ 1.2 1.0-20081010.060147 5.1 - 3.1.2.RELEASE + 3.2.4.RELEASE 1.9.5 1.3.22 2.6 @@ -173,6 +173,7 @@ client services maven-standard + quickcloud @@ -359,7 +360,12 @@ org.aspectj aspectjtools - 1.6.2 + 1.7.0 + + + org.aspectj + aspectjweaver + 1.7.0 org.apache.axis @@ -424,6 +430,11 @@ install src test + + + ${basedir}/resources + + test/resources @@ -563,7 +574,7 @@ tools/devcloud/basebuild/puppet-devcloudinitial/files/network.conf tools/appliance/definitions/devcloud/* tools/appliance/definitions/systemvmtemplate/* - tools/appliance/definitions/systemvmtemplate64/* + tools/appliance/definitions/systemvm64template/* tools/appliance/definitions/builtin/* tools/cli/cloudmonkey.egg-info/* tools/devcloud/src/deps/boxes/basebox-build/definition.rb diff --git a/python/lib/cloudutils/serviceConfig.py b/python/lib/cloudutils/serviceConfig.py index 5c552c0b756..4ed9a57079c 100755 --- a/python/lib/cloudutils/serviceConfig.py +++ b/python/lib/cloudutils/serviceConfig.py @@ -727,7 +727,7 @@ class sudoersConfig(serviceCfgBase): def config(self): try: cfo = configFileOps("/etc/sudoers", self) - cfo.addEntry("cloud ALL ", "NOPASSWD : ALL") + cfo.addEntry("cloud ALL ", "NOPASSWD : /bin/chmod, /bin/cp, /bin/mkdir, /bin/mount, /bin/umount") cfo.rmEntry("Defaults", "requiretty", " ") cfo.save() return True diff --git a/quickcloud/pom.xml b/quickcloud/pom.xml new file mode 100644 index 00000000000..1b9975e8e42 --- /dev/null +++ b/quickcloud/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + cloud-quickcloud + Apache CloudStack Framework - QuickCloud + + org.apache.cloudstack + cloud-maven-standard + 4.3.0-SNAPSHOT + ../maven-standard/pom.xml + + diff --git a/quickcloud/src/main/resources/META-INF/cloudstack/core/spring-quickcloud-core-context-override.xml b/quickcloud/src/main/resources/META-INF/cloudstack/core/spring-quickcloud-core-context-override.xml new file mode 100644 index 00000000000..35e4cbe54e1 --- /dev/null +++ b/quickcloud/src/main/resources/META-INF/cloudstack/core/spring-quickcloud-core-context-override.xml @@ -0,0 +1,32 @@ + + + + + + diff --git a/scripts/vm/hypervisor/xenserver/setupxenserver.sh b/scripts/vm/hypervisor/xenserver/setupxenserver.sh index e4b6f3e3372..311f2738bb3 100755 --- a/scripts/vm/hypervisor/xenserver/setupxenserver.sh +++ b/scripts/vm/hypervisor/xenserver/setupxenserver.sh @@ -49,7 +49,7 @@ sed -i 's/0\.0\.0\.0/127\.0\.0\.1/' /opt/xensource/libexec/qemu-dm-wrapper 2>&1 sed -i /NOZEROCONF/d /etc/sysconfig/network echo "NOZEROCONF=yes" >> /etc/sysconfig/network -[ -f /etc/cron.hourly/logrotate ] || mv /etc/cron.daily/logrotate /etc/cron.hourly 2>&1 +mv -n /etc/cron.daily/logrotate /etc/cron.hourly 2>&1 # more aio thread echo 1048576 >/proc/sys/fs/aio-max-nr diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index 83efc67b002..18233d905c8 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -1464,7 +1464,7 @@ def network_rules(session, args): vm_mac = args.get('vmMAC') signature = args.pop('signature') seqno = args.pop('seqno') - sec_ips = args.pop("secIps") + sec_ips = args.get("secIps") deflated = 'false' if 'deflated' in args: deflated = args.pop('deflated') diff --git a/server/conf/cloudstack-sudoers.in b/server/conf/cloudstack-sudoers.in index dcfb17b3ddf..069016434c7 100644 --- a/server/conf/cloudstack-sudoers.in +++ b/server/conf/cloudstack-sudoers.in @@ -18,5 +18,5 @@ # The CloudStack management server needs sudo permissions # without a password. -@MSUSER@ ALL =NOPASSWD : ALL +@MSUSER@ ALL =NOPASSWD : /bin/chmod, /bin/cp, /bin/mkdir, /bin/mount, /bin/umount diff --git a/server/pom.xml b/server/pom.xml index 6446b7eca28..c7978e2dd38 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -81,6 +81,12 @@ org.apache.cloudstack cloud-utils ${project.version} + + + xml-apis + xml-apis + + org.apache.cloudstack @@ -92,6 +98,12 @@ org.reflections reflections + + + xml-apis + xml-apis + + org.apache.cloudstack @@ -128,9 +140,6 @@ resources - - **/*.xml - diff --git a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml new file mode 100644 index 00000000000..11b69d213ad --- /dev/null +++ b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/server/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml b/server/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml new file mode 100644 index 00000000000..fd2f5fbb3fd --- /dev/null +++ b/server/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/server/resources/META-INF/cloudstack/server-alert-adapter-backend/module.properties b/server/resources/META-INF/cloudstack/server-alert-adapter-backend/module.properties new file mode 100644 index 00000000000..120c91d3f41 --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-alert-adapter-backend/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=server-alert-adapter-backend +parent=backend \ No newline at end of file diff --git a/server/resources/META-INF/cloudstack/server-alert-adapter-backend/spring-server-alert-adapter-backend-context.xml b/server/resources/META-INF/cloudstack/server-alert-adapter-backend/spring-server-alert-adapter-backend-context.xml new file mode 100644 index 00000000000..f7670e5810b --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-alert-adapter-backend/spring-server-alert-adapter-backend-context.xml @@ -0,0 +1,32 @@ + + + + + + diff --git a/server/resources/META-INF/cloudstack/server-alert-adapter-compute/module.properties b/server/resources/META-INF/cloudstack/server-alert-adapter-compute/module.properties new file mode 100644 index 00000000000..12213f44910 --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-alert-adapter-compute/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=server-alert-adapter-compute +parent=compute \ No newline at end of file diff --git a/server/resources/META-INF/cloudstack/server-alert-adapter-compute/spring-server-alert-adapter-compute-context.xml b/server/resources/META-INF/cloudstack/server-alert-adapter-compute/spring-server-alert-adapter-compute-context.xml new file mode 100644 index 00000000000..e918ce08e40 --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-alert-adapter-compute/spring-server-alert-adapter-compute-context.xml @@ -0,0 +1,32 @@ + + + + + + diff --git a/server/resources/META-INF/cloudstack/server-alert-adapter-storage/module.properties b/server/resources/META-INF/cloudstack/server-alert-adapter-storage/module.properties new file mode 100644 index 00000000000..c156009acbd --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-alert-adapter-storage/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=server-alert-adapter-storage +parent=storage \ No newline at end of file diff --git a/server/resources/META-INF/cloudstack/server-alert-adapter-storage/spring-server-alert-adapter-storage-context.xml b/server/resources/META-INF/cloudstack/server-alert-adapter-storage/spring-server-alert-adapter-storage-context.xml new file mode 100644 index 00000000000..713d9e363cc --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-alert-adapter-storage/spring-server-alert-adapter-storage-context.xml @@ -0,0 +1,32 @@ + + + + + + diff --git a/server/resources/META-INF/cloudstack/server-allocator/module.properties b/server/resources/META-INF/cloudstack/server-allocator/module.properties new file mode 100644 index 00000000000..f69c483deb6 --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-allocator/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=server-allocator +parent=allocator \ No newline at end of file diff --git a/server/resources/META-INF/cloudstack/server-allocator/spring-server-allocator-context.xml b/server/resources/META-INF/cloudstack/server-allocator/spring-server-allocator-context.xml new file mode 100644 index 00000000000..cc2924e5e02 --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-allocator/spring-server-allocator-context.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + diff --git a/server/resources/META-INF/cloudstack/server-api/module.properties b/server/resources/META-INF/cloudstack/server-api/module.properties new file mode 100644 index 00000000000..74a9c504207 --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-api/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=server-api +parent=api \ No newline at end of file diff --git a/server/resources/META-INF/cloudstack/server-api/spring-server-api-context.xml b/server/resources/META-INF/cloudstack/server-api/spring-server-api-context.xml new file mode 100644 index 00000000000..20e2f460933 --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-api/spring-server-api-context.xml @@ -0,0 +1,33 @@ + + + + + + + \ No newline at end of file diff --git a/server/resources/META-INF/cloudstack/server-compute/module.properties b/server/resources/META-INF/cloudstack/server-compute/module.properties new file mode 100644 index 00000000000..7b42a910871 --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-compute/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=server-compute +parent=compute \ No newline at end of file diff --git a/server/resources/META-INF/cloudstack/server-compute/spring-server-compute-context.xml b/server/resources/META-INF/cloudstack/server-compute/spring-server-compute-context.xml new file mode 100644 index 00000000000..1311902ff5d --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-compute/spring-server-compute-context.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + diff --git a/server/resources/META-INF/cloudstack/server-discoverer/module.properties b/server/resources/META-INF/cloudstack/server-discoverer/module.properties new file mode 100644 index 00000000000..0c4f5e1c3e5 --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-discoverer/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=server-discoverer +parent=discoverer \ No newline at end of file diff --git a/server/resources/META-INF/cloudstack/server-discoverer/spring-server-discoverer-context.xml b/server/resources/META-INF/cloudstack/server-discoverer/spring-server-discoverer-context.xml new file mode 100644 index 00000000000..90666d13143 --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-discoverer/spring-server-discoverer-context.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + diff --git a/server/resources/META-INF/cloudstack/server-fencer/module.properties b/server/resources/META-INF/cloudstack/server-fencer/module.properties new file mode 100644 index 00000000000..b4a868498bf --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-fencer/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=server-fencer +parent=compute \ No newline at end of file diff --git a/server/resources/META-INF/cloudstack/server-fencer/spring-server-fencer-context.xml b/server/resources/META-INF/cloudstack/server-fencer/spring-server-fencer-context.xml new file mode 100644 index 00000000000..3312d5fb288 --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-fencer/spring-server-fencer-context.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + diff --git a/server/resources/META-INF/cloudstack/server-investigator/module.properties b/server/resources/META-INF/cloudstack/server-investigator/module.properties new file mode 100644 index 00000000000..85e68824cf3 --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-investigator/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=server-investigator +parent=compute \ No newline at end of file diff --git a/server/resources/META-INF/cloudstack/server-investigator/spring-server-investigator-context.xml b/server/resources/META-INF/cloudstack/server-investigator/spring-server-investigator-context.xml new file mode 100644 index 00000000000..24e6e33c456 --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-investigator/spring-server-investigator-context.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/server/resources/META-INF/cloudstack/server-network/module.properties b/server/resources/META-INF/cloudstack/server-network/module.properties new file mode 100644 index 00000000000..95a7d1bacfb --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-network/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=server-network +parent=network \ No newline at end of file diff --git a/server/resources/META-INF/cloudstack/server-network/spring-server-network-context.xml b/server/resources/META-INF/cloudstack/server-network/spring-server-network-context.xml new file mode 100644 index 00000000000..553ae44eacb --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-network/spring-server-network-context.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/server/resources/META-INF/cloudstack/server-planner/module.properties b/server/resources/META-INF/cloudstack/server-planner/module.properties new file mode 100644 index 00000000000..541b7693be0 --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-planner/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=server-planner +parent=planner \ No newline at end of file diff --git a/server/resources/META-INF/cloudstack/server-planner/spring-server-planner-context.xml b/server/resources/META-INF/cloudstack/server-planner/spring-server-planner-context.xml new file mode 100644 index 00000000000..36f3ed02a3f --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-planner/spring-server-planner-context.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/server/resources/META-INF/cloudstack/server-storage/module.properties b/server/resources/META-INF/cloudstack/server-storage/module.properties new file mode 100644 index 00000000000..9eaf2d0a684 --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-storage/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=server-storage +parent=storage \ No newline at end of file diff --git a/server/resources/META-INF/cloudstack/server-storage/spring-server-storage-context.xml b/server/resources/META-INF/cloudstack/server-storage/spring-server-storage-context.xml new file mode 100644 index 00000000000..8b90200a97e --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-storage/spring-server-storage-context.xml @@ -0,0 +1,34 @@ + + + + + + + diff --git a/server/resources/META-INF/cloudstack/server-template-adapter/module.properties b/server/resources/META-INF/cloudstack/server-template-adapter/module.properties new file mode 100644 index 00000000000..85ba3176b80 --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-template-adapter/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=server-template-adapter +parent=storage \ No newline at end of file diff --git a/server/resources/META-INF/cloudstack/server-template-adapter/spring-server-template-adapter-context.xml b/server/resources/META-INF/cloudstack/server-template-adapter/spring-server-template-adapter-context.xml new file mode 100644 index 00000000000..1eeb27c7099 --- /dev/null +++ b/server/resources/META-INF/cloudstack/server-template-adapter/spring-server-template-adapter-context.xml @@ -0,0 +1,32 @@ + + + + + + diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index fa397ed3249..1eba98fc450 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -217,7 +217,7 @@ import com.cloud.resource.ResourceManager; import com.cloud.server.Criteria; import com.cloud.server.ManagementServer; import com.cloud.server.ResourceTag; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.server.StatsCollector; import com.cloud.server.TaggedResourceService; import com.cloud.service.ServiceOfferingVO; @@ -1154,11 +1154,11 @@ public class ApiDBUtils { return vmSnapshot; } - public static String getUuid(String resourceId, TaggedResourceType resourceType) { + public static String getUuid(String resourceId, ResourceObjectType resourceType) { return _taggedResourceService.getUuid(resourceId, resourceType); } - public static List listByResourceTypeAndId(TaggedResourceType type, long resourceId) { + public static List listByResourceTypeAndId(ResourceObjectType type, long resourceId) { return _taggedResourceService.listByResourceTypeAndId(type, resourceId); } public static List getAutoScalePolicyConditions(long policyId) @@ -1689,7 +1689,7 @@ public class ApiDBUtils { return _accountService.isAdmin(account.getType()); } - public static List listResourceTagViewByResourceUUID(String resourceUUID, TaggedResourceType resourceType){ + public static List listResourceTagViewByResourceUUID(String resourceUUID, ResourceObjectType resourceType){ return _tagJoinDao.listBy(resourceUUID, resourceType); } } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index f4ca112936a..155a563fb5b 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -31,8 +31,6 @@ import java.util.TimeZone; import javax.inject.Inject; -import org.apache.log4j.Logger; - import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.affinity.AffinityGroup; @@ -134,6 +132,8 @@ import org.apache.cloudstack.api.response.VpnUsersResponse; import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.cloudstack.config.Configuration; import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.framework.jobs.AsyncJob; import org.apache.cloudstack.framework.jobs.AsyncJobManager; import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule; @@ -144,6 +144,7 @@ import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.usage.Usage; import org.apache.cloudstack.usage.UsageService; import org.apache.cloudstack.usage.UsageTypes; +import org.apache.log4j.Logger; import com.cloud.api.query.ViewResponseHelper; import com.cloud.api.query.vo.AccountJoinVO; @@ -255,8 +256,9 @@ import com.cloud.projects.ProjectInvitation; import com.cloud.region.ha.GlobalLoadBalancerRule; import com.cloud.server.Criteria; import com.cloud.server.ResourceTag; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.service.ServiceOfferingVO; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.GuestOS; import com.cloud.storage.GuestOSCategoryVO; @@ -281,6 +283,7 @@ import com.cloud.uservm.UserVm; import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; import com.cloud.utils.db.EntityManager; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; import com.cloud.utils.net.NetUtils; import com.cloud.vm.ConsoleProxyVO; @@ -312,6 +315,8 @@ public class ApiResponseHelper implements ResponseGenerator { protected AsyncJobManager _jobMgr; @Inject ConfigurationManager _configMgr; + @Inject + SnapshotDataFactory snapshotfactory; @Override public UserResponse createUserResponse(User user) { @@ -447,8 +452,21 @@ public class ApiResponseHelper implements ResponseGenerator { snapshotResponse.setIntervalType(ApiDBUtils.getSnapshotIntervalTypes(snapshot.getId())); snapshotResponse.setState(snapshot.getState()); + SnapshotInfo snapshotInfo = null; + if (!(snapshot instanceof SnapshotInfo)) { + snapshotInfo = snapshotfactory.getSnapshot(snapshot.getId(), DataStoreRole.Image); + } else { + snapshotInfo = (SnapshotInfo)snapshot; + } + + if (snapshotInfo == null) { + throw new CloudRuntimeException("Unable to find info for image store snapshot with uuid '"+snapshot.getUuid()+"'"); + } + + snapshotResponse.setRevertable(snapshotInfo.isRevertable()); + // set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Snapshot, snapshot.getId()); + List tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.Snapshot, snapshot.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); @@ -701,7 +719,7 @@ public class ApiResponseHelper implements ResponseGenerator { ipResponse.setPortable(ipAddr.isPortable()); //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.PublicIpAddress, ipAddr.getId()); + List tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.PublicIpAddress, ipAddr.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); @@ -741,7 +759,7 @@ public class ApiResponseHelper implements ResponseGenerator { } //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.LoadBalancer, loadBalancer.getId()); + List tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.LoadBalancer, loadBalancer.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); @@ -809,7 +827,7 @@ public class ApiResponseHelper implements ResponseGenerator { for (SummedCapacity capacity : capacities) { CapacityResponse capacityResponse = new CapacityResponse(); capacityResponse.setCapacityType(capacity.getCapacityType()); - capacityResponse.setCapacityUsed(capacity.getUsedCapacity()); + capacityResponse.setCapacityUsed(capacity.getUsedCapacity() + capacity.getReservedCapacity()); if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) { List c = ApiDBUtils.findNonSharedStorageForClusterPodZone(null, pod.getId(), null); capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity()); @@ -846,7 +864,7 @@ public class ApiResponseHelper implements ResponseGenerator { for (SummedCapacity capacity : capacities) { CapacityResponse capacityResponse = new CapacityResponse(); capacityResponse.setCapacityType(capacity.getCapacityType()); - capacityResponse.setCapacityUsed(capacity.getUsedCapacity()); + capacityResponse.setCapacityUsed(capacity.getUsedCapacity() + capacity.getReservedCapacity()); if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) { List c = ApiDBUtils.findNonSharedStorageForClusterPodZone(zoneId, null, null); capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity()); @@ -967,7 +985,7 @@ public class ApiResponseHelper implements ResponseGenerator { for (SummedCapacity capacity : capacities) { CapacityResponse capacityResponse = new CapacityResponse(); capacityResponse.setCapacityType(capacity.getCapacityType()); - capacityResponse.setCapacityUsed(capacity.getUsedCapacity()); + capacityResponse.setCapacityUsed(capacity.getUsedCapacity() + capacity.getReservedCapacity()); if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) { List c = ApiDBUtils.findNonSharedStorageForClusterPodZone(null, null, cluster.getId()); @@ -1029,7 +1047,7 @@ public class ApiResponseHelper implements ResponseGenerator { } // set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.PortForwardingRule, fwRule.getId()); + List tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.PortForwardingRule, fwRule.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); @@ -2290,7 +2308,7 @@ public class ApiResponseHelper implements ResponseGenerator { response.setCanUseForDeploy(ApiDBUtils.canUseForDeploy(network)); // set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Network, network.getId()); + List tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.Network, network.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); @@ -2364,7 +2382,7 @@ public class ApiResponseHelper implements ResponseGenerator { response.setIcmpType(fwRule.getIcmpType()); // set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.FirewallRule, fwRule.getId()); + List tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.FirewallRule, fwRule.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); @@ -2414,7 +2432,7 @@ public class ApiResponseHelper implements ResponseGenerator { } //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.NetworkACL, aclItem.getId()); + List tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.NetworkACL, aclItem.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); @@ -2927,7 +2945,7 @@ public class ApiResponseHelper implements ResponseGenerator { populateOwner(response, vpc); // set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Vpc, vpc.getId()); + List tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.Vpc, vpc.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); @@ -3118,7 +3136,7 @@ public class ApiResponseHelper implements ResponseGenerator { populateDomain(response, result.getDomainId()); // set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.StaticRoute, result.getId()); + List tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.StaticRoute, result.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); @@ -3624,7 +3642,7 @@ public class ApiResponseHelper implements ResponseGenerator { lbResponse.setLbInstances(instanceResponses); //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.LoadBalancer, lb.getId()); + List tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.LoadBalancer, lb.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index b73045d5fce..cb2ecc6ade9 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -44,7 +44,6 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; -import javax.annotation.PostConstruct; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import javax.inject.Inject; @@ -52,37 +51,6 @@ import javax.naming.ConfigurationException; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import org.apache.commons.codec.binary.Base64; -import org.apache.http.ConnectionClosedException; -import org.apache.http.HttpException; -import org.apache.http.HttpRequest; -import org.apache.http.HttpResponse; -import org.apache.http.HttpServerConnection; -import org.apache.http.HttpStatus; -import org.apache.http.NameValuePair; -import org.apache.http.client.utils.URLEncodedUtils; -import org.apache.http.entity.BasicHttpEntity; -import org.apache.http.impl.DefaultHttpResponseFactory; -import org.apache.http.impl.DefaultHttpServerConnection; -import org.apache.http.impl.NoConnectionReuseStrategy; -import org.apache.http.impl.SocketHttpServerConnection; -import org.apache.http.params.BasicHttpParams; -import org.apache.http.params.CoreConnectionPNames; -import org.apache.http.params.CoreProtocolPNames; -import org.apache.http.params.HttpParams; -import org.apache.http.protocol.BasicHttpContext; -import org.apache.http.protocol.BasicHttpProcessor; -import org.apache.http.protocol.HttpContext; -import org.apache.http.protocol.HttpRequestHandler; -import org.apache.http.protocol.HttpRequestHandlerRegistry; -import org.apache.http.protocol.HttpService; -import org.apache.http.protocol.ResponseConnControl; -import org.apache.http.protocol.ResponseContent; -import org.apache.http.protocol.ResponseDate; -import org.apache.http.protocol.ResponseServer; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import org.apache.cloudstack.acl.APIChecker; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiErrorCode; @@ -120,6 +88,36 @@ import org.apache.cloudstack.framework.jobs.AsyncJob; import org.apache.cloudstack.framework.jobs.AsyncJobManager; import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO; import org.apache.cloudstack.managed.context.ManagedContextRunnable; +import org.apache.commons.codec.binary.Base64; +import org.apache.http.ConnectionClosedException; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.HttpServerConnection; +import org.apache.http.HttpStatus; +import org.apache.http.NameValuePair; +import org.apache.http.client.utils.URLEncodedUtils; +import org.apache.http.entity.BasicHttpEntity; +import org.apache.http.impl.DefaultHttpResponseFactory; +import org.apache.http.impl.DefaultHttpServerConnection; +import org.apache.http.impl.NoConnectionReuseStrategy; +import org.apache.http.impl.SocketHttpServerConnection; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.CoreConnectionPNames; +import org.apache.http.params.CoreProtocolPNames; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.BasicHttpProcessor; +import org.apache.http.protocol.HttpContext; +import org.apache.http.protocol.HttpRequestHandler; +import org.apache.http.protocol.HttpRequestHandlerRegistry; +import org.apache.http.protocol.HttpService; +import org.apache.http.protocol.ResponseConnControl; +import org.apache.http.protocol.ResponseContent; +import org.apache.http.protocol.ResponseDate; +import org.apache.http.protocol.ResponseServer; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import com.cloud.api.response.ApiResponseSerializer; import com.cloud.configuration.Config; @@ -149,7 +147,7 @@ import com.cloud.utils.component.PluggableService; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.EntityManager; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.ExceptionProxyObject; @@ -186,11 +184,11 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer @Override public boolean configure(String name, Map params) throws ConfigurationException { - init(); return true; } - public void init() { + @Override + public boolean start() { Integer apiPort = null; // api port, null by default SearchCriteria sc = _configDao.createSearchCriteria(); sc.addAnd("name", SearchCriteria.Op.EQ, Config.IntegrationAPIPort.key()); @@ -245,6 +243,8 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer ListenerThread listenerThread = new ListenerThread(this, apiPort); listenerThread.start(); } + + return true; } // NOTE: handle() only handles over the wire (OTW) requests from integration.api.port 8096 @@ -708,7 +708,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer } } - Transaction txn = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); User user = null; // verify there is a user with this api key diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index b464e9e5cdb..79eb1b4dae7 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -155,7 +155,7 @@ import com.cloud.resource.ResourceManager; import com.cloud.server.Criteria; import com.cloud.server.ResourceMetaDataService; import com.cloud.server.ResourceTag; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.server.TaggedResourceService; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; @@ -2390,22 +2390,8 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { Long domainId = cmd.getDomainId(); Boolean isSystem = cmd.getIsSystem(); String vmTypeStr = cmd.getSystemVmType(); - Map resourceTags = cmd.getResourceTags(); - SearchBuilder sb = _srvOfferingJoinDao.createSearchBuilder(); - if (resourceTags != null && !resourceTags.isEmpty()) { - SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); - for (int count=0; count < resourceTags.size(); count++) { - tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); - tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); - tagSearch.cp(); - } - tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); - sb.groupBy(sb.entity().getId()); - sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); - } - - SearchCriteria sc = sb.create(); + SearchCriteria sc = _srvOfferingJoinDao.createSearchCriteria(); if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN && isSystem) { throw new InvalidParameterValueException("Only ROOT admins can access system's offering"); @@ -2423,6 +2409,27 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } } + if (vmId != null) { + UserVmVO vmInstance = _userVmDao.findById(vmId); + if ((vmInstance == null) || (vmInstance.getRemoved() != null)) { + InvalidParameterValueException ex = new InvalidParameterValueException( + "unable to find a virtual machine with specified id"); + ex.addProxyObject(vmId.toString(), "vmId"); + throw ex; + } + + _accountMgr.checkAccess(caller, null, true, vmInstance); + + ServiceOfferingVO offering = _srvOfferingDao.findByIdIncludingRemoved(vmInstance.getServiceOfferingId()); + sc.addAnd("id", SearchCriteria.Op.NEQ, offering.getId()); + + // Only return offerings with the same Guest IP type and storage + // pool preference + // sc.addAnd("guestIpType", SearchCriteria.Op.EQ, + // offering.getGuestIpType()); + sc.addAnd("useLocalStorage", SearchCriteria.Op.EQ, offering.getUseLocalStorage()); + } + // boolean includePublicOfferings = false; if ((caller.getType() == Account.ACCOUNT_TYPE_NORMAL || caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { @@ -2432,11 +2439,20 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } // find all domain Id up to root domain for this account List domainIds = new ArrayList(); - DomainVO domainRecord = _domainDao.findById(caller.getDomainId()); - if (domainRecord == null) { - s_logger.error("Could not find the domainId for account:" + caller.getAccountName()); - throw new CloudAuthenticationException("Could not find the domainId for account:" - + caller.getAccountName()); + DomainVO domainRecord; + if (vmId != null) { + UserVmVO vmInstance = _userVmDao.findById(vmId); + domainRecord = _domainDao.findById(vmInstance.getDomainId()); + if ( domainRecord == null ){ + s_logger.error("Could not find the domainId for vmId:" + vmId); + throw new CloudAuthenticationException("Could not find the domainId for vmId:" + vmId); + } + } else { + domainRecord = _domainDao.findById(caller.getDomainId()); + if ( domainRecord == null ){ + s_logger.error("Could not find the domainId for account:" + caller.getAccountName()); + throw new CloudAuthenticationException("Could not find the domainId for account:" + caller.getAccountName()); + } } domainIds.add(domainRecord.getId()); while (domainRecord.getParent() != null) { @@ -2466,25 +2482,6 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); sc.addAnd("name", SearchCriteria.Op.SC, ssc); - } else if (vmId != null) { - UserVmVO vmInstance = _userVmDao.findById(vmId); - if ((vmInstance == null) || (vmInstance.getRemoved() != null)) { - InvalidParameterValueException ex = new InvalidParameterValueException( - "unable to find a virtual machine with specified id"); - ex.addProxyObject(vmId.toString(), "vmId"); - throw ex; - } - - _accountMgr.checkAccess(caller, null, true, vmInstance); - - ServiceOfferingVO offering = _srvOfferingDao.findByIdIncludingRemoved(vmInstance.getServiceOfferingId()); - sc.addAnd("id", SearchCriteria.Op.NEQ, offering.getId()); - - // Only return offerings with the same Guest IP type and storage - // pool preference - // sc.addAnd("guestIpType", SearchCriteria.Op.EQ, - // offering.getGuestIpType()); - sc.addAnd("useLocalStorage", SearchCriteria.Op.EQ, offering.getUseLocalStorage()); } if (id != null) { @@ -2504,17 +2501,6 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { if (vmTypeStr != null) { sc.addAnd("vm_type", SearchCriteria.Op.EQ, vmTypeStr); } - - - if (resourceTags != null && !resourceTags.isEmpty()) { - int count = 0; - sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.ServiceOffering.toString()); - for (String key : resourceTags.keySet()) { - sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); - sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), resourceTags.get(key)); - count++; - } - } return _srvOfferingJoinDao.searchAndCount(sc, searchFilter); } @@ -2536,9 +2522,23 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { String keyword = cmd.getKeyword(); String name = cmd.getName(); String networkType = cmd.getNetworkType(); - + Map resourceTags = cmd.getTags(); + + SearchBuilder sb = _dcJoinDao.createSearchBuilder(); + if (resourceTags != null && !resourceTags.isEmpty()) { + SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); + for (int count=0; count < resourceTags.size(); count++) { + tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); + tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); + tagSearch.cp(); + } + tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); + sb.groupBy(sb.entity().getId()); + sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); + } + Filter searchFilter = new Filter(DataCenterJoinVO.class, null, false, cmd.getStartIndex(), cmd.getPageSizeVal()); - SearchCriteria sc = _dcJoinDao.createSearchCriteria(); + SearchCriteria sc = sb.create(); if (networkType != null) { sc.addAnd("networkType", SearchCriteria.Op.EQ, networkType); @@ -2687,6 +2687,16 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } } } + + if (resourceTags != null && !resourceTags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.Zone.toString()); + for (String key : resourceTags.keySet()) { + sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); + sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), resourceTags.get(key)); + count++; + } + } return _dcJoinDao.searchAndCount(sc, searchFilter); } @@ -2936,9 +2946,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { scTag.addAnd("tagKey", SearchCriteria.Op.EQ, key); scTag.addAnd("tagValue", SearchCriteria.Op.EQ, tags.get(key)); if (isIso) { - scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, TaggedResourceType.ISO); + scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, ResourceObjectType.ISO); } else { - scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, TaggedResourceType.Template); + scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, ResourceObjectType.Template); } scc.addOr("tagKey", SearchCriteria.Op.SC, scTag); count++; @@ -3253,39 +3263,39 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { @Override public List listResource(ListResourceDetailsCmd cmd) { String key = cmd.getKey(); - ResourceTag.TaggedResourceType resourceType = cmd.getResourceType(); + ResourceTag.ResourceObjectType resourceType = cmd.getResourceType(); String resourceId = cmd.getResourceId(); - Long id = _taggedResourceMgr.getResourceId(resourceId, resourceType); + long id = _taggedResourceMgr.getResourceId(resourceId, resourceType); List responseList = new ArrayList(); List detailList = new ArrayList(); ResourceDetail requestedDetail = null; - if (resourceType == ResourceTag.TaggedResourceType.Volume) { + if (resourceType == ResourceTag.ResourceObjectType.Volume) { if (key == null) { detailList = _volumeDetailDao.findDetails(id); } else { requestedDetail = _volumeDetailDao.findDetail(id, key); } - } else if (resourceType == ResourceTag.TaggedResourceType.Nic){ + } else if (resourceType == ResourceTag.ResourceObjectType.Nic){ if (key == null) { detailList = _nicDetailDao.findDetails(id); } else { requestedDetail = _nicDetailDao.findDetail(id, key); } - } else if (resourceType == ResourceTag.TaggedResourceType.UserVm){ + } else if (resourceType == ResourceTag.ResourceObjectType.UserVm){ if (key == null) { detailList = _userVmDetailDao.findDetailsList(id); } else { requestedDetail = _userVmDetailDao.findDetail(id, key); } - } else if (resourceType == ResourceTag.TaggedResourceType.Zone){ + } else if (resourceType == ResourceTag.ResourceObjectType.Zone){ if (key == null) { detailList = _dcDetailsDao.findDetailsList(id); } else { requestedDetail = _dcDetailsDao.findDetail(id, key); } - } else if (resourceType == TaggedResourceType.Network){ + } else if (resourceType == ResourceObjectType.Network){ if (key == null) { detailList = _networkDetailsDao.findDetails(id); } else { @@ -3311,7 +3321,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } - protected ResourceDetailResponse createResourceDetailsResponse(long resourceId, String key, String value, ResourceTag.TaggedResourceType type) { + protected ResourceDetailResponse createResourceDetailsResponse(long resourceId, String key, String value, ResourceTag.ResourceObjectType type) { ResourceDetailResponse resourceDetailResponse = new ResourceDetailResponse(); resourceDetailResponse.setResourceId(String.valueOf(resourceId)); resourceDetailResponse.setName(key); diff --git a/server/src/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java index edceb26666c..6e2649e9d0a 100644 --- a/server/src/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java @@ -20,23 +20,23 @@ import java.util.List; import javax.ejb.Local; +import org.apache.cloudstack.api.response.ResourceTagResponse; +import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import com.cloud.api.ApiDBUtils; import com.cloud.api.ApiResponseHelper; import com.cloud.api.query.vo.DataCenterJoinVO; +import com.cloud.api.query.vo.ResourceTagJoinVO; import com.cloud.dc.DataCenter; - -import org.apache.cloudstack.api.response.ZoneResponse; -import org.apache.cloudstack.context.CallContext; - +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.user.Account; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import org.springframework.stereotype.Component; - @Component @Local(value={DataCenterJoinDao.class}) public class DataCenterJoinDaoImpl extends GenericDaoBase implements DataCenterJoinDao { @@ -97,6 +97,14 @@ public class DataCenterJoinDaoImpl extends GenericDaoBase resourceTags = ApiDBUtils.listResourceTagViewByResourceUUID(dataCenter.getUuid(), ResourceObjectType.Zone); + for (ResourceTagJoinVO resourceTag : resourceTags) { + ResourceTagResponse tagResponse = ApiDBUtils.newResourceTagResponse(resourceTag, false); + zoneResponse.addTag(tagResponse); + } + zoneResponse.setObjectName("zone"); return zoneResponse; } diff --git a/server/src/com/cloud/api/query/dao/ResourceTagJoinDao.java b/server/src/com/cloud/api/query/dao/ResourceTagJoinDao.java index 627033c274d..769bc9b1e6e 100644 --- a/server/src/com/cloud/api/query/dao/ResourceTagJoinDao.java +++ b/server/src/com/cloud/api/query/dao/ResourceTagJoinDao.java @@ -22,7 +22,7 @@ import org.apache.cloudstack.api.response.ResourceTagResponse; import com.cloud.api.query.vo.ResourceTagJoinVO; import com.cloud.server.ResourceTag; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.utils.db.GenericDao; public interface ResourceTagJoinDao extends GenericDao { @@ -33,5 +33,5 @@ public interface ResourceTagJoinDao extends GenericDao List searchByIds(Long... ids); - List listBy(String resourceUUID, TaggedResourceType resourceType); + List listBy(String resourceUUID, ResourceObjectType resourceType); } diff --git a/server/src/com/cloud/api/query/dao/ResourceTagJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/ResourceTagJoinDaoImpl.java index f0ddaa6964f..27a76af01c5 100644 --- a/server/src/com/cloud/api/query/dao/ResourceTagJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/ResourceTagJoinDaoImpl.java @@ -30,7 +30,7 @@ import org.springframework.stereotype.Component; import com.cloud.api.ApiResponseHelper; import com.cloud.api.query.vo.ResourceTagJoinVO; import com.cloud.server.ResourceTag; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -95,7 +95,7 @@ public class ResourceTagJoinDaoImpl extends GenericDaoBase listBy(String resourceUUID, TaggedResourceType resourceType) { + public List listBy(String resourceUUID, ResourceObjectType resourceType) { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("uuid", resourceUUID); sc.setParameters("resourceType", resourceType); diff --git a/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java index 8c32be3d13d..17270345f14 100644 --- a/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java @@ -20,16 +20,13 @@ import java.util.List; import javax.ejb.Local; -import org.apache.cloudstack.api.response.ResourceTagResponse; import org.apache.cloudstack.api.response.ServiceOfferingResponse; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.api.ApiDBUtils; -import com.cloud.api.query.vo.ResourceTagJoinVO; import com.cloud.api.query.vo.ServiceOfferingJoinVO; import com.cloud.offering.ServiceOffering; -import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -84,12 +81,6 @@ public class ServiceOfferingJoinDaoImpl extends GenericDaoBase resourceTags = ApiDBUtils.listResourceTagViewByResourceUUID(offering.getUuid(), TaggedResourceType.ServiceOffering); - for (ResourceTagJoinVO resourceTag : resourceTags) { - ResourceTagResponse tagResponse = ApiDBUtils.newResourceTagResponse(resourceTag, false); - offeringResponse.addTag(tagResponse); } return offeringResponse; } diff --git a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java index 7fe3c1d2fcc..799690e45c8 100644 --- a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java @@ -19,8 +19,10 @@ package com.cloud.api.query.dao; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.EnumSet; +import java.util.HashMap; import java.util.Hashtable; import java.util.List; +import java.util.Map; import java.util.Set; import javax.ejb.Local; @@ -45,8 +47,9 @@ import com.cloud.uservm.UserVm; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.vm.VmStats; import com.cloud.vm.VirtualMachine.State; +import com.cloud.vm.VmDetailConstants; +import com.cloud.vm.VmStats; @Component @@ -260,6 +263,14 @@ public class UserVmJoinDaoImpl extends GenericDaoBase implem userVmResponse.addAffinityGroup(resp); } } + + // set resource details map + // only hypervisortoolsversion can be returned to the end user } + if (userVm.getDetailName() != null && userVm.getDetailName().equalsIgnoreCase(VmDetailConstants.HYPERVISOR_TOOLS_VERSION)){ + Map resourceDetails = new HashMap(); + resourceDetails.put(userVm.getDetailName(), userVm.getDetailValue()); + userVmResponse.setDetails(resourceDetails); + } userVmResponse.setObjectName(objectName); if (userVm.isDynamicallyScalable() == null) { diff --git a/server/src/com/cloud/api/query/vo/ProjectJoinVO.java b/server/src/com/cloud/api/query/vo/ProjectJoinVO.java index 77b013183fa..8addabeb1ff 100644 --- a/server/src/com/cloud/api/query/vo/ProjectJoinVO.java +++ b/server/src/com/cloud/api/query/vo/ProjectJoinVO.java @@ -29,7 +29,7 @@ import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; import com.cloud.projects.Project.State; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.utils.db.GenericDao; @Entity @@ -103,7 +103,7 @@ public class ProjectJoinVO extends BaseViewVO implements InternalIdentity, Ident @Column(name="tag_resource_type") @Enumerated(value=EnumType.STRING) - private TaggedResourceType tagResourceType; + private ResourceObjectType tagResourceType; @Column(name="tag_customer") private String tagCustomer; @@ -196,7 +196,7 @@ public class ProjectJoinVO extends BaseViewVO implements InternalIdentity, Ident return tagResourceUuid; } - public TaggedResourceType getTagResourceType() { + public ResourceObjectType getTagResourceType() { return tagResourceType; } diff --git a/server/src/com/cloud/api/query/vo/ResourceTagJoinVO.java b/server/src/com/cloud/api/query/vo/ResourceTagJoinVO.java index a13d107583a..cd94ba5987c 100644 --- a/server/src/com/cloud/api/query/vo/ResourceTagJoinVO.java +++ b/server/src/com/cloud/api/query/vo/ResourceTagJoinVO.java @@ -23,7 +23,7 @@ import javax.persistence.Enumerated; import javax.persistence.Id; import javax.persistence.Table; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; @Entity @Table(name="resource_tag_view") @@ -50,7 +50,7 @@ public class ResourceTagJoinVO extends BaseViewVO implements ControlledViewEntit @Column(name="resource_type") @Enumerated(value=EnumType.STRING) - private TaggedResourceType resourceType; + private ResourceObjectType resourceType; @Column(name="customer") String customer; @@ -171,7 +171,7 @@ public class ResourceTagJoinVO extends BaseViewVO implements ControlledViewEntit return resourceUuid; } - public TaggedResourceType getResourceType() { + public ResourceObjectType getResourceType() { return resourceType; } diff --git a/server/src/com/cloud/api/query/vo/SecurityGroupJoinVO.java b/server/src/com/cloud/api/query/vo/SecurityGroupJoinVO.java index 50b30f30e49..ca1fa85c3ac 100644 --- a/server/src/com/cloud/api/query/vo/SecurityGroupJoinVO.java +++ b/server/src/com/cloud/api/query/vo/SecurityGroupJoinVO.java @@ -24,7 +24,7 @@ import javax.persistence.Id; import javax.persistence.Table; import com.cloud.network.security.SecurityRule.SecurityRuleType; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; @Entity @Table(name="security_group_view") @@ -135,7 +135,7 @@ public class SecurityGroupJoinVO extends BaseViewVO implements ControlledViewEnt @Column(name="tag_resource_type") @Enumerated(value=EnumType.STRING) - private TaggedResourceType tagResourceType; + private ResourceObjectType tagResourceType; @Column(name="tag_customer") private String tagCustomer; @@ -295,7 +295,7 @@ public class SecurityGroupJoinVO extends BaseViewVO implements ControlledViewEnt return tagResourceUuid; } - public TaggedResourceType getTagResourceType() { + public ResourceObjectType getTagResourceType() { return tagResourceType; } diff --git a/server/src/com/cloud/api/query/vo/TemplateJoinVO.java b/server/src/com/cloud/api/query/vo/TemplateJoinVO.java index 4cfdf6ac3f8..ca5963efb63 100644 --- a/server/src/com/cloud/api/query/vo/TemplateJoinVO.java +++ b/server/src/com/cloud/api/query/vo/TemplateJoinVO.java @@ -30,7 +30,7 @@ import javax.persistence.TemporalType; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.storage.ScopeType; import com.cloud.storage.Storage; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; @@ -238,7 +238,7 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name="tag_resource_type") @Enumerated(value=EnumType.STRING) - private TaggedResourceType tagResourceType; + private ResourceObjectType tagResourceType; @Column(name="tag_customer") private String tagCustomer; @@ -369,7 +369,7 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity { return tagResourceUuid; } - public TaggedResourceType getTagResourceType() { + public ResourceObjectType getTagResourceType() { return tagResourceType; } diff --git a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java b/server/src/com/cloud/api/query/vo/UserVmJoinVO.java index c9d5ddcc374..5aae820d810 100644 --- a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java +++ b/server/src/com/cloud/api/query/vo/UserVmJoinVO.java @@ -31,7 +31,7 @@ import javax.persistence.Transient; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Network.GuestType; import com.cloud.network.Networks.TrafficType; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume; import com.cloud.utils.db.Encrypt; @@ -366,7 +366,7 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name="tag_resource_type") @Enumerated(value=EnumType.STRING) - private TaggedResourceType tagResourceType; + private ResourceObjectType tagResourceType; @Column(name="tag_customer") private String tagCustomer; @@ -393,6 +393,12 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name="dynamically_scalable") private boolean isDynamicallyScalable; + + @Column(name="detail_name") + private String detailName; + + @Column(name="detail_value") + private String detailValue; public UserVmJoinVO() { } @@ -792,7 +798,7 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { return tagResourceUuid; } - public TaggedResourceType getTagResourceType() { + public ResourceObjectType getTagResourceType() { return tagResourceType; } @@ -884,4 +890,13 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { public Boolean isDynamicallyScalable() { return isDynamicallyScalable; } + + public String getDetailName() { + return detailName; + } + + + public String getDetailValue() { + return detailValue; + } } diff --git a/server/src/com/cloud/api/query/vo/VolumeJoinVO.java b/server/src/com/cloud/api/query/vo/VolumeJoinVO.java index 066ed94a382..7c03cd7bd21 100644 --- a/server/src/com/cloud/api/query/vo/VolumeJoinVO.java +++ b/server/src/com/cloud/api/query/vo/VolumeJoinVO.java @@ -26,7 +26,7 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.storage.Storage; import com.cloud.storage.Volume; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; @@ -255,7 +255,7 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name="tag_resource_type") @Enumerated(value=EnumType.STRING) - private TaggedResourceType tagResourceType; + private ResourceObjectType tagResourceType; @Column(name="tag_customer") private String tagCustomer; @@ -649,7 +649,7 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity { - public TaggedResourceType getTagResourceType() { + public ResourceObjectType getTagResourceType() { return tagResourceType; } diff --git a/server/src/com/cloud/capacity/CapacityManagerImpl.java b/server/src/com/cloud/capacity/CapacityManagerImpl.java index b28fe201f78..72905a7c0c4 100755 --- a/server/src/com/cloud/capacity/CapacityManagerImpl.java +++ b/server/src/com/cloud/capacity/CapacityManagerImpl.java @@ -28,7 +28,6 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; - import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.Configurable; @@ -61,6 +60,7 @@ import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; import com.cloud.offering.ServiceOffering; +import com.cloud.org.Cluster; import com.cloud.org.Grouping.AllocationState; import com.cloud.resource.ResourceListener; import com.cloud.resource.ResourceManager; @@ -81,6 +81,9 @@ import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.fsm.StateListener; import com.cloud.vm.UserVmDetailVO; import com.cloud.vm.UserVmVO; @@ -170,100 +173,104 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, @DB @Override - public boolean releaseVmCapacity(VirtualMachine vm, boolean moveFromReserved, boolean moveToReservered, Long hostId) { - ServiceOfferingVO svo = _offeringsDao.findById(vm.getServiceOfferingId()); + public boolean releaseVmCapacity(VirtualMachine vm, final boolean moveFromReserved, final boolean moveToReservered, final Long hostId) { + final ServiceOfferingVO svo = _offeringsDao.findById(vm.getServiceOfferingId()); CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_CPU); CapacityVO capacityMemory = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_MEMORY); Long clusterId = null; if (hostId != null) { - HostVO host = _hostDao.findById(hostId); + HostVO host = _hostDao.findById(hostId); clusterId = host.getClusterId(); } if (capacityCpu == null || capacityMemory == null || svo == null) { return false; } - Transaction txn = Transaction.currentTxn(); try { - txn.start(); - - capacityCpu = _capacityDao.lockRow(capacityCpu.getId(), true); - capacityMemory = _capacityDao.lockRow(capacityMemory.getId(), true); - - long usedCpu = capacityCpu.getUsedCapacity(); - long usedMem = capacityMemory.getUsedCapacity(); - long reservedCpu = capacityCpu.getReservedCapacity(); - long reservedMem = capacityMemory.getReservedCapacity(); - long actualTotalCpu = capacityCpu.getTotalCapacity(); - float cpuOvercommitRatio =Float.parseFloat(_clusterDetailsDao.findDetail(clusterId,"cpuOvercommitRatio").getValue()); - float memoryOvercommitRatio = Float.parseFloat(_clusterDetailsDao.findDetail(clusterId,"memoryOvercommitRatio").getValue()); - int vmCPU = svo.getCpu() * svo.getSpeed(); - long vmMem = svo.getRamSize() * 1024L * 1024L; - long actualTotalMem = capacityMemory.getTotalCapacity(); - long totalMem = (long) (actualTotalMem * memoryOvercommitRatio); - long totalCpu = (long) (actualTotalCpu * cpuOvercommitRatio); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Hosts's actual total CPU: " + actualTotalCpu + " and CPU after applying overprovisioning: " + totalCpu); - s_logger.debug("Hosts's actual total RAM: " + actualTotalMem + " and RAM after applying overprovisioning: " + totalMem); - } - - - if (!moveFromReserved) { - /* move resource from used */ - if (usedCpu >= vmCPU) { - capacityCpu.setUsedCapacity(usedCpu - vmCPU); - } - if (usedMem >= vmMem) { - capacityMemory.setUsedCapacity(usedMem - vmMem); - } - - if (moveToReservered) { - if (reservedCpu + vmCPU <= totalCpu) { - capacityCpu.setReservedCapacity(reservedCpu + vmCPU); + final Long clusterIdFinal = clusterId; + final long capacityCpuId = capacityCpu.getId(); + final long capacityMemoryId = capacityMemory.getId(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + CapacityVO capacityCpu = _capacityDao.lockRow(capacityCpuId, true); + CapacityVO capacityMemory = _capacityDao.lockRow(capacityMemoryId, true); + + long usedCpu = capacityCpu.getUsedCapacity(); + long usedMem = capacityMemory.getUsedCapacity(); + long reservedCpu = capacityCpu.getReservedCapacity(); + long reservedMem = capacityMemory.getReservedCapacity(); + long actualTotalCpu = capacityCpu.getTotalCapacity(); + float cpuOvercommitRatio =Float.parseFloat(_clusterDetailsDao.findDetail(clusterIdFinal,"cpuOvercommitRatio").getValue()); + float memoryOvercommitRatio = Float.parseFloat(_clusterDetailsDao.findDetail(clusterIdFinal,"memoryOvercommitRatio").getValue()); + int vmCPU = svo.getCpu() * svo.getSpeed(); + long vmMem = svo.getRamSize() * 1024L * 1024L; + long actualTotalMem = capacityMemory.getTotalCapacity(); + long totalMem = (long) (actualTotalMem * memoryOvercommitRatio); + long totalCpu = (long) (actualTotalCpu * cpuOvercommitRatio); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Hosts's actual total CPU: " + actualTotalCpu + " and CPU after applying overprovisioning: " + totalCpu); + s_logger.debug("Hosts's actual total RAM: " + actualTotalMem + " and RAM after applying overprovisioning: " + totalMem); } - if (reservedMem + vmMem <= totalMem) { - capacityMemory.setReservedCapacity(reservedMem + vmMem); + + + if (!moveFromReserved) { + /* move resource from used */ + if (usedCpu >= vmCPU) { + capacityCpu.setUsedCapacity(usedCpu - vmCPU); + } + if (usedMem >= vmMem) { + capacityMemory.setUsedCapacity(usedMem - vmMem); + } + + if (moveToReservered) { + if (reservedCpu + vmCPU <= totalCpu) { + capacityCpu.setReservedCapacity(reservedCpu + vmCPU); + } + if (reservedMem + vmMem <= totalMem) { + capacityMemory.setReservedCapacity(reservedMem + vmMem); + } + } + } else { + if (reservedCpu >= vmCPU) { + capacityCpu.setReservedCapacity(reservedCpu - vmCPU); + } + if (reservedMem >= vmMem) { + capacityMemory.setReservedCapacity(reservedMem - vmMem); + } } - } - } else { - if (reservedCpu >= vmCPU) { - capacityCpu.setReservedCapacity(reservedCpu - vmCPU); - } - if (reservedMem >= vmMem) { - capacityMemory.setReservedCapacity(reservedMem - vmMem); - } - } - s_logger.debug("release cpu from host: " + hostId + ", old used: " + usedCpu + ",reserved: " + reservedCpu + ", actual total: " - + actualTotalCpu + ", total with overprovisioning: " + totalCpu + "; new used: " + capacityCpu.getUsedCapacity() + ",reserved:" - + capacityCpu.getReservedCapacity() + "; movedfromreserved: " + moveFromReserved + ",moveToReservered" + moveToReservered); + s_logger.debug("release cpu from host: " + hostId + ", old used: " + usedCpu + ",reserved: " + reservedCpu + ", actual total: " + + actualTotalCpu + ", total with overprovisioning: " + totalCpu + "; new used: " + capacityCpu.getUsedCapacity() + ",reserved:" + + capacityCpu.getReservedCapacity() + "; movedfromreserved: " + moveFromReserved + ",moveToReservered" + moveToReservered); - s_logger.debug("release mem from host: " + hostId + ", old used: " + usedMem + ",reserved: " + reservedMem + ", total: " + totalMem - + "; new used: " + capacityMemory.getUsedCapacity() + ",reserved:" + capacityMemory.getReservedCapacity() - + "; movedfromreserved: " + moveFromReserved + ",moveToReservered" + moveToReservered); + s_logger.debug("release mem from host: " + hostId + ", old used: " + usedMem + ",reserved: " + reservedMem + ", total: " + totalMem + + "; new used: " + capacityMemory.getUsedCapacity() + ",reserved:" + capacityMemory.getReservedCapacity() + + "; movedfromreserved: " + moveFromReserved + ",moveToReservered" + moveToReservered); + + _capacityDao.update(capacityCpu.getId(), capacityCpu); + _capacityDao.update(capacityMemory.getId(), capacityMemory); + } + }); - _capacityDao.update(capacityCpu.getId(), capacityCpu); - _capacityDao.update(capacityMemory.getId(), capacityMemory); - txn.commit(); return true; } catch (Exception e) { s_logger.debug("Failed to transit vm's state, due to " + e.getMessage()); - txn.rollback(); return false; } } @DB @Override - public void allocateVmCapacity(VirtualMachine vm, boolean fromLastHost) { + public void allocateVmCapacity(VirtualMachine vm, final boolean fromLastHost) { - long hostId = vm.getHostId(); + final long hostId = vm.getHostId(); HostVO host = _hostDao.findById(hostId); - long clusterId = host.getClusterId(); - float cpuOvercommitRatio = Float.parseFloat(_clusterDetailsDao.findDetail(clusterId, "cpuOvercommitRatio").getValue()); - float memoryOvercommitRatio = Float.parseFloat(_clusterDetailsDao.findDetail(clusterId, "memoryOvercommitRatio").getValue()); + final long clusterId = host.getClusterId(); + final float cpuOvercommitRatio = Float.parseFloat(_clusterDetailsDao.findDetail(clusterId, "cpuOvercommitRatio").getValue()); + final float memoryOvercommitRatio = Float.parseFloat(_clusterDetailsDao.findDetail(clusterId, "memoryOvercommitRatio").getValue()); - ServiceOfferingVO svo = _offeringsDao.findById(vm.getServiceOfferingId()); + final ServiceOfferingVO svo = _offeringsDao.findById(vm.getServiceOfferingId()); CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_CPU); CapacityVO capacityMem = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_MEMORY); @@ -272,74 +279,78 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, return; } - int cpu = svo.getCpu() * svo.getSpeed(); - long ram = svo.getRamSize() * 1024L * 1024L; + final int cpu = svo.getCpu() * svo.getSpeed(); + final long ram = svo.getRamSize() * 1024L * 1024L; - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - capacityCpu = _capacityDao.lockRow(capacityCpu.getId(), true); - capacityMem = _capacityDao.lockRow(capacityMem.getId(), true); + final long capacityCpuId = capacityCpu.getId(); + final long capacityMemId = capacityMem.getId(); - long usedCpu = capacityCpu.getUsedCapacity(); - long usedMem = capacityMem.getUsedCapacity(); - long reservedCpu = capacityCpu.getReservedCapacity(); - long reservedMem = capacityMem.getReservedCapacity(); - long actualTotalCpu = capacityCpu.getTotalCapacity(); - long actualTotalMem = capacityMem.getTotalCapacity(); - long totalCpu = (long) (actualTotalCpu * cpuOvercommitRatio); - long totalMem = (long) (actualTotalMem * memoryOvercommitRatio); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Hosts's actual total CPU: " + actualTotalCpu + " and CPU after applying overprovisioning: " + totalCpu); - } + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + CapacityVO capacityCpu = _capacityDao.lockRow(capacityCpuId, true); + CapacityVO capacityMem = _capacityDao.lockRow(capacityMemId, true); - long freeCpu = totalCpu - (reservedCpu + usedCpu); - long freeMem = totalMem - (reservedMem + usedMem); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("We are allocating VM, increasing the used capacity of this host:" + hostId); - s_logger.debug("Current Used CPU: " + usedCpu + " , Free CPU:" + freeCpu + " ,Requested CPU: " + cpu); - s_logger.debug("Current Used RAM: " + usedMem + " , Free RAM:" + freeMem + " ,Requested RAM: " + ram); - } - capacityCpu.setUsedCapacity(usedCpu + cpu); - capacityMem.setUsedCapacity(usedMem + ram); - - if (fromLastHost) { - /* alloc from reserved */ - if (s_logger.isDebugEnabled()) { - s_logger.debug("We are allocating VM to the last host again, so adjusting the reserved capacity if it is not less than required"); - s_logger.debug("Reserved CPU: " + reservedCpu + " , Requested CPU: " + cpu); - s_logger.debug("Reserved RAM: " + reservedMem + " , Requested RAM: " + ram); - } - if (reservedCpu >= cpu && reservedMem >= ram) { - capacityCpu.setReservedCapacity(reservedCpu - cpu); - capacityMem.setReservedCapacity(reservedMem - ram); - } - } else { - /* alloc from free resource */ - if (!((reservedCpu + usedCpu + cpu <= totalCpu) && (reservedMem + usedMem + ram <= totalMem))) { + long usedCpu = capacityCpu.getUsedCapacity(); + long usedMem = capacityMem.getUsedCapacity(); + long reservedCpu = capacityCpu.getReservedCapacity(); + long reservedMem = capacityMem.getReservedCapacity(); + long actualTotalCpu = capacityCpu.getTotalCapacity(); + long actualTotalMem = capacityMem.getTotalCapacity(); + long totalCpu = (long) (actualTotalCpu * cpuOvercommitRatio); + long totalMem = (long) (actualTotalMem * memoryOvercommitRatio); if (s_logger.isDebugEnabled()) { - s_logger.debug("Host doesnt seem to have enough free capacity, but increasing the used capacity anyways, since the VM is already starting on this host "); + s_logger.debug("Hosts's actual total CPU: " + actualTotalCpu + " and CPU after applying overprovisioning: " + totalCpu); } + + long freeCpu = totalCpu - (reservedCpu + usedCpu); + long freeMem = totalMem - (reservedMem + usedMem); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("We are allocating VM, increasing the used capacity of this host:" + hostId); + s_logger.debug("Current Used CPU: " + usedCpu + " , Free CPU:" + freeCpu + " ,Requested CPU: " + cpu); + s_logger.debug("Current Used RAM: " + usedMem + " , Free RAM:" + freeMem + " ,Requested RAM: " + ram); + } + capacityCpu.setUsedCapacity(usedCpu + cpu); + capacityMem.setUsedCapacity(usedMem + ram); + + if (fromLastHost) { + /* alloc from reserved */ + if (s_logger.isDebugEnabled()) { + s_logger.debug("We are allocating VM to the last host again, so adjusting the reserved capacity if it is not less than required"); + s_logger.debug("Reserved CPU: " + reservedCpu + " , Requested CPU: " + cpu); + s_logger.debug("Reserved RAM: " + reservedMem + " , Requested RAM: " + ram); + } + if (reservedCpu >= cpu && reservedMem >= ram) { + capacityCpu.setReservedCapacity(reservedCpu - cpu); + capacityMem.setReservedCapacity(reservedMem - ram); + } + } else { + /* alloc from free resource */ + if (!((reservedCpu + usedCpu + cpu <= totalCpu) && (reservedMem + usedMem + ram <= totalMem))) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Host doesnt seem to have enough free capacity, but increasing the used capacity anyways, since the VM is already starting on this host "); + } + } + } + + s_logger.debug("CPU STATS after allocation: for host: " + hostId + ", old used: " + usedCpu + ", old reserved: " + reservedCpu + + ", actual total: " + actualTotalCpu + ", total with overprovisioning: " + totalCpu + "; new used:" + + capacityCpu.getUsedCapacity() + ", reserved:" + capacityCpu.getReservedCapacity() + "; requested cpu:" + cpu + + ",alloc_from_last:" + fromLastHost); + + s_logger.debug("RAM STATS after allocation: for host: " + hostId + ", old used: " + usedMem + ", old reserved: " + reservedMem + + ", total: " + totalMem + "; new used: " + capacityMem.getUsedCapacity() + ", reserved: " + capacityMem.getReservedCapacity() + + "; requested mem: " + ram + ",alloc_from_last:" + fromLastHost); + + _capacityDao.update(capacityCpu.getId(), capacityCpu); + _capacityDao.update(capacityMem.getId(), capacityMem); } - } - - s_logger.debug("CPU STATS after allocation: for host: " + hostId + ", old used: " + usedCpu + ", old reserved: " + reservedCpu - + ", actual total: " + actualTotalCpu + ", total with overprovisioning: " + totalCpu + "; new used:" - + capacityCpu.getUsedCapacity() + ", reserved:" + capacityCpu.getReservedCapacity() + "; requested cpu:" + cpu - + ",alloc_from_last:" + fromLastHost); - - s_logger.debug("RAM STATS after allocation: for host: " + hostId + ", old used: " + usedMem + ", old reserved: " + reservedMem - + ", total: " + totalMem + "; new used: " + capacityMem.getUsedCapacity() + ", reserved: " + capacityMem.getReservedCapacity() - + "; requested mem: " + ram + ",alloc_from_last:" + fromLastHost); - - _capacityDao.update(capacityCpu.getId(), capacityCpu); - _capacityDao.update(capacityMem.getId(), capacityMem); - txn.commit(); + }); } catch (Exception e) { - txn.rollback(); + s_logger.error("Exception allocating VM capacity", e); return; } } @@ -512,7 +523,7 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, @DB @Override - public void updateCapacityForHost(Host host){ + public void updateCapacityForHost(final Host host){ // prepare the service offerings List offerings = _offeringsDao.listAllIncludingRemoved(); Map offeringsMap = new HashMap(); @@ -625,36 +636,42 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, s_logger.error("Caught exception while updating cpu/memory capacity for the host " +host.getId(), e); } }else { - Transaction txn = Transaction.currentTxn(); - txn.start(); - CapacityVO capacity = new CapacityVO(host.getId(), - host.getDataCenterId(), host.getPodId(), host.getClusterId(), usedMemory, - host.getTotalMemory(), - CapacityVO.CAPACITY_TYPE_MEMORY); - capacity.setReservedCapacity(reservedMemory); - CapacityState capacityState = CapacityState.Enabled; - if (host.getClusterId() != null) { - cluster = ApiDBUtils.findClusterById(host.getClusterId()); - if (cluster != null) { - capacityState = _configMgr.findClusterAllocationState(cluster) == AllocationState.Disabled ? CapacityState.Disabled - : CapacityState.Enabled; + final long usedMemoryFinal = usedMemory; + final long reservedMemoryFinal = reservedMemory; + final long usedCpuFinal = usedCpu; + final long reservedCpuFinal = reservedCpu; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + CapacityVO capacity = new CapacityVO(host.getId(), + host.getDataCenterId(), host.getPodId(), host.getClusterId(), usedMemoryFinal, + host.getTotalMemory(), + CapacityVO.CAPACITY_TYPE_MEMORY); + capacity.setReservedCapacity(reservedMemoryFinal); + CapacityState capacityState = CapacityState.Enabled; + if (host.getClusterId() != null) { + ClusterVO cluster = ApiDBUtils.findClusterById(host.getClusterId()); + if (cluster != null) { + capacityState = _configMgr.findClusterAllocationState(cluster) == AllocationState.Disabled ? CapacityState.Disabled + : CapacityState.Enabled; + capacity.setCapacityState(capacityState); + } + } + _capacityDao.persist(capacity); + + capacity = new CapacityVO( + host.getId(), + host.getDataCenterId(), + host.getPodId(), + host.getClusterId(), + usedCpuFinal, + host.getCpus().longValue() * host.getSpeed().longValue(), + CapacityVO.CAPACITY_TYPE_CPU); + capacity.setReservedCapacity(reservedCpuFinal); capacity.setCapacityState(capacityState); + _capacityDao.persist(capacity); } - } - _capacityDao.persist(capacity); - - capacity = new CapacityVO( - host.getId(), - host.getDataCenterId(), - host.getPodId(), - host.getClusterId(), - usedCpu, - host.getCpus().longValue() * host.getSpeed().longValue(), - CapacityVO.CAPACITY_TYPE_CPU); - capacity.setReservedCapacity(reservedCpu); - capacity.setCapacityState(capacityState); - _capacityDao.persist(capacity); - txn.commit(); + }); } diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 9d94bbaa481..3fdc3439092 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -151,7 +151,7 @@ public enum Config { ExtractURLExpirationInterval("Advanced", ManagementServer.class, Integer.class, "extract.url.expiration.interval", "14400", "The life of an extract URL after which it is deleted ", null), HostStatsInterval("Advanced", ManagementServer.class, Integer.class, "host.stats.interval", "60000", "The interval (in milliseconds) when host stats are retrieved from agents.", null), HostRetry("Advanced", AgentManager.class, Integer.class, "host.retry", "2", "Number of times to retry hosts for creating a volume", null), - IntegrationAPIPort("Advanced", ManagementServer.class, Integer.class, "integration.api.port", null, "Defaul API port", null), + IntegrationAPIPort("Advanced", ManagementServer.class, Integer.class, "integration.api.port", null, "Default API port", null), InvestigateRetryInterval("Advanced", HighAvailabilityManager.class, Integer.class, "investigate.retry.interval", "60", "Time (in seconds) between VM pings when agent is disconnected", null), MigrateRetryInterval("Advanced", HighAvailabilityManager.class, Integer.class, "migrate.retry.interval", "120", "Time (in seconds) between migration retries", null), RouterCpuMHz("Advanced", NetworkOrchestrationService.class, Integer.class, "router.cpu.mhz", String.valueOf(VpcVirtualNetworkApplianceManager.DEFAULT_ROUTER_CPU_MHZ), "Default CPU speed (MHz) for router VM.", null), @@ -246,6 +246,8 @@ public enum Config { XenHeartBeatInterval("Advanced", ManagementServer.class, Integer.class, "xen.heartbeat.interval", "60", "heartbeat to use when implementing XenServer Self Fencing", null), XenGuestNetwork("Hidden", ManagementServer.class, String.class, "xen.guest.network.device", null, "Specify for guest network name label", null), XenMaxNics("Advanced", AgentManager.class, Integer.class, "xen.nics.max", "7", "Maximum allowed nics for Vms created on Xen", null), + XenPVdriverVersion("Advanced", ManagementServer.class, String.class, "xen.pvdriver.version", "xenserver61", "default Xen PV driver version for registered template, valid value:xenserver56,xenserver61 ", "xenserver56,xenserver61"), + // VMware VmwareUseNexusVSwitch("Network", ManagementServer.class, Boolean.class, "vmware.use.nexus.vswitch", "false", "Enable/Disable Cisco Nexus 1000v vSwitch in VMware environment", null), VmwareUseDVSwitch("Network", ManagementServer.class, Boolean.class, "vmware.use.dvswitch", "false", "Enable/Disable Nexus/Vmware dvSwitch in VMware environment", null), @@ -377,7 +379,8 @@ public enum Config { // object store S3EnableRRS("Advanced", ManagementServer.class, Boolean.class, "s3.rrs.enabled", "false", "enable s3 reduced redundancy storage", null), - S3EnableMultiPartUpload("Advanced", ManagementServer.class, Boolean.class, "s3.multipart.enabled", "true", "enable s3 multipart upload", null), + S3MaxSingleUploadSize("Advanced", ManagementServer.class, Integer.class, "s3.singleupload.max.size", "5", "The maximum size limit for S3 single part upload API(in GB). If it is set to 0, then it means always use multi-part upload to upload object to S3. " + + "If it is set to -1, then it means always use single-part upload to upload object to S3. ", null), // Ldap LdapBasedn("Advanced", ManagementServer.class, String.class, "ldap.basedn", null, "Sets the basedn for LDAP", null), diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 4fda3b152ee..32459bcba22 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -36,7 +36,6 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; - import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroupService; @@ -192,6 +191,10 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionLegacy; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.vm.NicIpAlias; @@ -508,7 +511,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } // Execute all updates in a single transaction - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); txn.start(); if (!_configDao.update(name, category, value)) { @@ -906,7 +909,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati selectSql += " and removed IS NULL"; } - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql); stmt.setLong(1, podId); @@ -992,9 +995,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Override @DB public boolean deletePod(DeletePodCmd cmd) { - Long podId = cmd.getId(); - - Transaction txn = Transaction.currentTxn(); + final Long podId = cmd.getId(); // Make sure the pod exists if (!validPod(podId)) { @@ -1003,50 +1004,52 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati checkIfPodIsDeletable(podId); - HostPodVO pod = _podDao.findById(podId); + final HostPodVO pod = _podDao.findById(podId); - txn.start(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // Delete private ip addresses for the pod if there are any + List privateIps = _privateIpAddressDao.listByPodIdDcId(Long.valueOf(podId), + pod.getDataCenterId()); + if (!privateIps.isEmpty()) { + if (!(_privateIpAddressDao.deleteIpAddressByPod(podId))) { + throw new CloudRuntimeException("Failed to cleanup private ip addresses for pod " + podId); + } + } - // Delete private ip addresses for the pod if there are any - List privateIps = _privateIpAddressDao.listByPodIdDcId(Long.valueOf(podId), - pod.getDataCenterId()); - if (!privateIps.isEmpty()) { - if (!(_privateIpAddressDao.deleteIpAddressByPod(podId))) { - throw new CloudRuntimeException("Failed to cleanup private ip addresses for pod " + podId); + // Delete link local ip addresses for the pod + List localIps = _LinkLocalIpAllocDao.listByPodIdDcId(podId, + pod.getDataCenterId()); + if (!localIps.isEmpty()) { + if (!(_LinkLocalIpAllocDao.deleteIpAddressByPod(podId))) { + throw new CloudRuntimeException("Failed to cleanup private ip addresses for pod " + podId); + } + } + + // Delete vlans associated with the pod + List vlans = _networkModel.listPodVlans(podId); + if (vlans != null && !vlans.isEmpty()) { + for (Vlan vlan : vlans) { + _vlanDao.remove(vlan.getId()); + } + } + + // Delete corresponding capacity records + _capacityDao.removeBy(null, null, podId, null, null); + + // Delete the pod + if (!(_podDao.remove(podId))) { + throw new CloudRuntimeException("Failed to delete pod " + podId); + } + + // remove from dedicated resources + DedicatedResourceVO dr = _dedicatedDao.findByPodId(podId); + if (dr != null) { + _dedicatedDao.remove(dr.getId()); + } } - } - - // Delete link local ip addresses for the pod - List localIps = _LinkLocalIpAllocDao.listByPodIdDcId(podId, - pod.getDataCenterId()); - if (!localIps.isEmpty()) { - if (!(_LinkLocalIpAllocDao.deleteIpAddressByPod(podId))) { - throw new CloudRuntimeException("Failed to cleanup private ip addresses for pod " + podId); - } - } - - // Delete vlans associated with the pod - List vlans = _networkModel.listPodVlans(podId); - if (vlans != null && !vlans.isEmpty()) { - for (Vlan vlan : vlans) { - _vlanDao.remove(vlan.getId()); - } - } - - // Delete corresponding capacity records - _capacityDao.removeBy(null, null, podId, null, null); - - // Delete the pod - if (!(_podDao.remove(podId))) { - throw new CloudRuntimeException("Failed to delete pod " + podId); - } - - // remove from dedicated resources - DedicatedResourceVO dr = _dedicatedDao.findByPodId(podId); - if (dr != null) { - _dedicatedDao.remove(dr.getId()); - } - txn.commit(); + }); return true; } @@ -1059,12 +1062,12 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Override @DB - public Pod editPod(long id, String name, String startIp, String endIp, String gateway, String netmask, + public Pod editPod(final long id, String name, String startIp, String endIp, String gateway, String netmask, String allocationStateStr) { // verify parameters - HostPodVO pod = _podDao.findById(id); - ; + final HostPodVO pod = _podDao.findById(id); + if (pod == null) { throw new InvalidParameterValueException("Unable to find pod by id " + id); } @@ -1146,59 +1149,73 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } // Verify pod's attributes - String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask); + final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask); boolean checkForDuplicates = !oldPodName.equals(name); checkPodAttributes(id, name, pod.getDataCenterId(), gateway, cidr, startIp, endIp, allocationStateStr, checkForDuplicates, false); - Transaction txn = Transaction.currentTxn(); try { - txn.start(); - long zoneId = pod.getDataCenterId(); - if (!allowToDownsize) { - if (leftRangeToAdd != null) { - _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), leftRangeToAdd[0], leftRangeToAdd[1]); + final String[] existingPodIpRangeFinal = existingPodIpRange; + final String[] leftRangeToAddFinal = leftRangeToAdd; + final String[] rightRangeToAddFinal = rightRangeToAdd; + final boolean allowToDownsizeFinal = allowToDownsize; + final String allocationStateStrFinal = allocationStateStr; + final String startIpFinal = startIp; + final String endIpFinal = endIp; + final String nameFinal = name; + final String gatewayFinal = gateway; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + long zoneId = pod.getDataCenterId(); + + String startIp = startIpFinal; + String endIp = endIpFinal; + + if (!allowToDownsizeFinal) { + if (leftRangeToAddFinal != null) { + _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), leftRangeToAddFinal[0], leftRangeToAddFinal[1]); + } + + if (rightRangeToAddFinal != null) { + _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), rightRangeToAddFinal[0], rightRangeToAddFinal[1]); + } + + } else { + // delete the old range + _zoneDao.deletePrivateIpAddressByPod(pod.getId()); + + // add the new one + if (startIp == null) { + startIp = existingPodIpRangeFinal[0]; + } + + if (endIp == null) { + endIp = existingPodIpRangeFinal[1]; + } + + _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), startIp, endIp); + } + + pod.setName(nameFinal); + pod.setDataCenterId(zoneId); + pod.setGateway(gatewayFinal); + pod.setCidrAddress(getCidrAddress(cidr)); + pod.setCidrSize(getCidrSize(cidr)); + + String ipRange = startIp + "-" + endIp; + pod.setDescription(ipRange); + Grouping.AllocationState allocationState = null; + if (allocationStateStrFinal != null && !allocationStateStrFinal.isEmpty()) { + allocationState = Grouping.AllocationState.valueOf(allocationStateStrFinal); + _capacityDao.updateCapacityState(null, pod.getId(), null, null, allocationStateStrFinal); + pod.setAllocationState(allocationState); + } + + _podDao.update(id, pod); } - - if (rightRangeToAdd != null) { - _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), rightRangeToAdd[0], rightRangeToAdd[1]); - } - - } else { - // delete the old range - _zoneDao.deletePrivateIpAddressByPod(pod.getId()); - - // add the new one - if (startIp == null) { - startIp = existingPodIpRange[0]; - } - - if (endIp == null) { - endIp = existingPodIpRange[1]; - } - - _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), startIp, endIp); - } - - pod.setName(name); - pod.setDataCenterId(zoneId); - pod.setGateway(gateway); - pod.setCidrAddress(getCidrAddress(cidr)); - pod.setCidrSize(getCidrSize(cidr)); - - String ipRange = startIp + "-" + endIp; - pod.setDescription(ipRange); - Grouping.AllocationState allocationState = null; - if (allocationStateStr != null && !allocationStateStr.isEmpty()) { - allocationState = Grouping.AllocationState.valueOf(allocationStateStr); - _capacityDao.updateCapacityState(null, pod.getId(), null, null, allocationStateStr); - pod.setAllocationState(allocationState); - } - - _podDao.update(id, pod); - - txn.commit(); + }); } catch (Exception e) { s_logger.error("Unable to edit pod due to " + e.getMessage(), e); throw new CloudRuntimeException("Failed to edit pod. Please contact Cloud Support."); @@ -1221,7 +1238,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Override @DB - public HostPodVO createPod(long userId, String podName, long zoneId, String gateway, String cidr, String startIp, + public HostPodVO createPod(long userId, String podName, final long zoneId, String gateway, String cidr, final String startIp, String endIp, String allocationStateStr, boolean skipGatewayOverlapCheck) { // Check if the zone is valid @@ -1260,31 +1277,33 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati throw new InvalidParameterValueException("Start ip is required parameter"); } - HostPodVO pod = new HostPodVO(podName, zoneId, gateway, cidrAddress, cidrSize, ipRange); + final HostPodVO podFinal = new HostPodVO(podName, zoneId, gateway, cidrAddress, cidrSize, ipRange); Grouping.AllocationState allocationState = null; if (allocationStateStr != null && !allocationStateStr.isEmpty()) { allocationState = Grouping.AllocationState.valueOf(allocationStateStr); - pod.setAllocationState(allocationState); + podFinal.setAllocationState(allocationState); } - Transaction txn = Transaction.currentTxn(); - txn.start(); + final String endIpFinal = endIp; + return Transaction.execute(new TransactionCallback() { + @Override + public HostPodVO doInTransaction(TransactionStatus status) { - pod = _podDao.persist(pod); + HostPodVO pod = _podDao.persist(podFinal); - if (startIp != null) { - _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), startIp, endIp); - } + if (startIp != null) { + _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), startIp, endIpFinal); + } - String[] linkLocalIpRanges = getLinkLocalIPRange(); - if (linkLocalIpRanges != null) { - _zoneDao.addLinkLocalIpAddress(zoneId, pod.getId(), linkLocalIpRanges[0], linkLocalIpRanges[1]); - } + String[] linkLocalIpRanges = getLinkLocalIPRange(); + if (linkLocalIpRanges != null) { + _zoneDao.addLinkLocalIpAddress(zoneId, pod.getId(), linkLocalIpRanges[0], linkLocalIpRanges[1]); + } - txn.commit(); - - return pod; + return pod; + } + }); } @DB @@ -1369,7 +1388,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati selectSql += " AND state != '" + VirtualMachine.State.Expunging.toString() + "'"; } - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql); stmt.setLong(1, zoneId); @@ -1504,11 +1523,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @ActionEvent(eventType = EventTypes.EVENT_ZONE_DELETE, eventDescription = "deleting zone", async = false) public boolean deleteZone(DeleteZoneCmd cmd) { - Transaction txn = Transaction.currentTxn(); - boolean success = false; - Long userId = CallContext.current().getCallingUserId(); - Long zoneId = cmd.getId(); + final Long zoneId = cmd.getId(); if (userId == null) { userId = Long.valueOf(User.UID_SYSTEM); @@ -1521,38 +1537,38 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati checkIfZoneIsDeletable(zoneId); - txn.start(); - - // delete vlans for this zone - List vlans = _vlanDao.listByZone(zoneId); - for (VlanVO vlan : vlans) { - _vlanDao.remove(vlan.getId()); - } - - success = _zoneDao.remove(zoneId); - - if (success) { - // delete all capacity records for the zone - _capacityDao.removeBy(null, zoneId, null, null, null); - // remove from dedicated resources - DedicatedResourceVO dr = _dedicatedDao.findByZoneId(zoneId); - if (dr != null) { - _dedicatedDao.remove(dr.getId()); - // find the group associated and check if there are any more - // resources under that group - List resourcesInGroup = _dedicatedDao.listByAffinityGroupId(dr - .getAffinityGroupId()); - if (resourcesInGroup.isEmpty()) { - // delete the group - _affinityGroupService.deleteAffinityGroup(dr.getAffinityGroupId(), null, null, null); + return Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + // delete vlans for this zone + List vlans = _vlanDao.listByZone(zoneId); + for (VlanVO vlan : vlans) { + _vlanDao.remove(vlan.getId()); } + + boolean success = _zoneDao.remove(zoneId); + + if (success) { + // delete all capacity records for the zone + _capacityDao.removeBy(null, zoneId, null, null, null); + // remove from dedicated resources + DedicatedResourceVO dr = _dedicatedDao.findByZoneId(zoneId); + if (dr != null) { + _dedicatedDao.remove(dr.getId()); + // find the group associated and check if there are any more + // resources under that group + List resourcesInGroup = _dedicatedDao.listByAffinityGroupId(dr + .getAffinityGroupId()); + if (resourcesInGroup.isEmpty()) { + // delete the group + _affinityGroupService.deleteAffinityGroup(dr.getAffinityGroupId(), null, null, null); + } + } + } + + return success; } - } - - txn.commit(); - - return success; - + }); } @Override @@ -1560,7 +1576,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @ActionEvent(eventType = EventTypes.EVENT_ZONE_EDIT, eventDescription = "editing zone", async = false) public DataCenter editZone(UpdateZoneCmd cmd) { // Parameter validation as from execute() method in V1 - Long zoneId = cmd.getId(); + final Long zoneId = cmd.getId(); String zoneName = cmd.getZoneName(); String dns1 = cmd.getDns1(); String dns2 = cmd.getDns2(); @@ -1570,14 +1586,14 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati String internalDns2 = cmd.getInternalDns2(); String guestCidr = cmd.getGuestCidrAddress(); List dnsSearchOrder = cmd.getDnsSearchOrder(); - Boolean isPublic = cmd.isPublic(); - String allocationStateStr = cmd.getAllocationState(); - String dhcpProvider = cmd.getDhcpProvider(); + final Boolean isPublic = cmd.isPublic(); + final String allocationStateStr = cmd.getAllocationState(); + final String dhcpProvider = cmd.getDhcpProvider(); Map detailsMap = cmd.getDetails(); String networkDomain = cmd.getDomain(); Boolean localStorageEnabled = cmd.getLocalStorageEnabled(); - Map newDetails = new HashMap(); + final Map newDetails = new HashMap(); if (detailsMap != null) { Collection zoneDetailsCollection = detailsMap.values(); Iterator iter = zoneDetailsCollection.iterator(); @@ -1611,7 +1627,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati newDetails.put(ZoneConfig.DnsSearchOrder.getName(), StringUtils.join(dnsSearchOrder, ",")); } - DataCenterVO zone = _zoneDao.findById(zoneId); + final DataCenterVO zone = _zoneDao.findById(zoneId); if (zone == null) { throw new InvalidParameterValueException("unable to find zone by id " + zoneId); } @@ -1698,93 +1714,94 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } - Transaction txn = Transaction.currentTxn(); - txn.start(); - - Map updatedDetails = new HashMap(); - _zoneDao.loadDetails(zone); - if (zone.getDetails() != null) { - updatedDetails.putAll(zone.getDetails()); - } - updatedDetails.putAll(newDetails); - zone.setDetails(updatedDetails); - - if (allocationStateStr != null && !allocationStateStr.isEmpty()) { - Grouping.AllocationState allocationState = Grouping.AllocationState.valueOf(allocationStateStr); - - if (allocationState == Grouping.AllocationState.Enabled) { - // check if zone has necessary trafficTypes before enabling - try { - PhysicalNetwork mgmtPhyNetwork; - // zone should have a physical network with management - // traffiType - mgmtPhyNetwork = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, - TrafficType.Management); - if (NetworkType.Advanced == zone.getNetworkType() && !zone.isSecurityGroupEnabled()) { - // advanced zone without SG should have a physical - // network with public Thpe - _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Public); - } - - try { - _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Storage); - } catch (InvalidParameterValueException noStorage) { - PhysicalNetworkTrafficTypeVO mgmtTraffic = _trafficTypeDao.findBy(mgmtPhyNetwork.getId(), - TrafficType.Management); - _networkSvc.addTrafficTypeToPhysicalNetwork(mgmtPhyNetwork.getId(), - TrafficType.Storage.toString(), mgmtTraffic.getXenNetworkLabel(), - mgmtTraffic.getKvmNetworkLabel(), mgmtTraffic.getVmwareNetworkLabel(), - mgmtTraffic.getSimulatorNetworkLabel(), mgmtTraffic.getVlan()); - s_logger.info("No storage traffic type was specified by admin, create default storage traffic on physical network " - + mgmtPhyNetwork.getId() + " with same configure of management traffic type"); - } - } catch (InvalidParameterValueException ex) { - throw new InvalidParameterValueException("Cannot enable this Zone since: " + ex.getMessage()); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + Map updatedDetails = new HashMap(); + _zoneDao.loadDetails(zone); + if (zone.getDetails() != null) { + updatedDetails.putAll(zone.getDetails()); } - } - _capacityDao.updateCapacityState(zone.getId(), null, null, null, allocationStateStr); - zone.setAllocationState(allocationState); - } - - if (dhcpProvider != null) { - zone.setDhcpProvider(dhcpProvider); - } + updatedDetails.putAll(newDetails); + zone.setDetails(updatedDetails); - // update a private zone to public; not vice versa - if (isPublic != null && isPublic) { - zone.setDomainId(null); - zone.setDomain(null); - - // release the dedication for this zone - DedicatedResourceVO resource = _dedicatedDao.findByZoneId(zoneId); - Long resourceId = null; - if (resource != null) { - resourceId = resource.getId(); - if (!_dedicatedDao.remove(resourceId)) { - throw new CloudRuntimeException("Failed to delete dedicated Zone Resource " + resourceId); + if (allocationStateStr != null && !allocationStateStr.isEmpty()) { + Grouping.AllocationState allocationState = Grouping.AllocationState.valueOf(allocationStateStr); + + if (allocationState == Grouping.AllocationState.Enabled) { + // check if zone has necessary trafficTypes before enabling + try { + PhysicalNetwork mgmtPhyNetwork; + // zone should have a physical network with management + // traffiType + mgmtPhyNetwork = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, + TrafficType.Management); + if (NetworkType.Advanced == zone.getNetworkType() && !zone.isSecurityGroupEnabled()) { + // advanced zone without SG should have a physical + // network with public Thpe + _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Public); + } + + try { + _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Storage); + } catch (InvalidParameterValueException noStorage) { + PhysicalNetworkTrafficTypeVO mgmtTraffic = _trafficTypeDao.findBy(mgmtPhyNetwork.getId(), + TrafficType.Management); + _networkSvc.addTrafficTypeToPhysicalNetwork(mgmtPhyNetwork.getId(), + TrafficType.Storage.toString(), mgmtTraffic.getXenNetworkLabel(), + mgmtTraffic.getKvmNetworkLabel(), mgmtTraffic.getVmwareNetworkLabel(), + mgmtTraffic.getSimulatorNetworkLabel(), mgmtTraffic.getVlan()); + s_logger.info("No storage traffic type was specified by admin, create default storage traffic on physical network " + + mgmtPhyNetwork.getId() + " with same configure of management traffic type"); + } + } catch (InvalidParameterValueException ex) { + throw new InvalidParameterValueException("Cannot enable this Zone since: " + ex.getMessage()); + } + } + _capacityDao.updateCapacityState(zone.getId(), null, null, null, allocationStateStr); + zone.setAllocationState(allocationState); } - // find the group associated and check if there are any more - // resources under that group - List resourcesInGroup = _dedicatedDao.listByAffinityGroupId(resource.getAffinityGroupId()); - if (resourcesInGroup.isEmpty()) { - // delete the group - _affinityGroupService.deleteAffinityGroup(resource.getAffinityGroupId(), null, null, null); + + if (dhcpProvider != null) { + zone.setDhcpProvider(dhcpProvider); + } + + // update a private zone to public; not vice versa + if (isPublic != null && isPublic) { + zone.setDomainId(null); + zone.setDomain(null); + + // release the dedication for this zone + DedicatedResourceVO resource = _dedicatedDao.findByZoneId(zoneId); + Long resourceId = null; + if (resource != null) { + resourceId = resource.getId(); + if (!_dedicatedDao.remove(resourceId)) { + throw new CloudRuntimeException("Failed to delete dedicated Zone Resource " + resourceId); + } + // find the group associated and check if there are any more + // resources under that group + List resourcesInGroup = _dedicatedDao.listByAffinityGroupId(resource.getAffinityGroupId()); + if (resourcesInGroup.isEmpty()) { + // delete the group + _affinityGroupService.deleteAffinityGroup(resource.getAffinityGroupId(), null, null, null); + } + } + } + + if (!_zoneDao.update(zoneId, zone)) { + throw new CloudRuntimeException("Failed to edit zone. Please contact Cloud Support."); } } - } + }); - if (!_zoneDao.update(zoneId, zone)) { - throw new CloudRuntimeException("Failed to edit zone. Please contact Cloud Support."); - } - - txn.commit(); return zone; } @Override @DB public DataCenterVO createZone(long userId, String zoneName, String dns1, String dns2, String internalDns1, - String internalDns2, String guestCidr, String domain, Long domainId, NetworkType zoneType, + String internalDns2, String guestCidr, String domain, final Long domainId, NetworkType zoneType, String allocationStateStr, String networkDomain, boolean isSecurityGroupEnabled, boolean isLocalStorageEnabled, String ip6Dns1, String ip6Dns2) { @@ -1809,43 +1826,40 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati byte[] bytes = (zoneName + System.currentTimeMillis()).getBytes(); String zoneToken = UUID.nameUUIDFromBytes(bytes).toString(); - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - // Create the new zone in the database - DataCenterVO zone = new DataCenterVO(zoneName, null, dns1, dns2, internalDns1, internalDns2, guestCidr, - domain, domainId, zoneType, zoneToken, networkDomain, isSecurityGroupEnabled, - isLocalStorageEnabled, - ip6Dns1, ip6Dns2); - if (allocationStateStr != null && !allocationStateStr.isEmpty()) { - Grouping.AllocationState allocationState = Grouping.AllocationState.valueOf(allocationStateStr); - zone.setAllocationState(allocationState); - } else { - // Zone will be disabled since 3.0. Admin should enable it after - // physical network and providers setup. - zone.setAllocationState(Grouping.AllocationState.Disabled); - } - zone = _zoneDao.persist(zone); - if (domainId != null) { - // zone is explicitly dedicated to this domain - // create affinity group associated and dedicate the zone. - AffinityGroup group = createDedicatedAffinityGroup(null, domainId, null); - DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(zone.getId(), null, null, null, - domainId, null, group.getId()); - _dedicatedDao.persist(dedicatedResource); - } - // Create default system networks - createDefaultSystemNetworks(zone.getId()); - txn.commit(); - return zone; - } catch (Exception ex) { - txn.rollback(); - s_logger.warn("Exception: ", ex); - throw new CloudRuntimeException("Fail to create a network"); - } finally { - txn.close(); + // Create the new zone in the database + final DataCenterVO zoneFinal = new DataCenterVO(zoneName, null, dns1, dns2, internalDns1, internalDns2, guestCidr, + domain, domainId, zoneType, zoneToken, networkDomain, isSecurityGroupEnabled, + isLocalStorageEnabled, + ip6Dns1, ip6Dns2); + if (allocationStateStr != null && !allocationStateStr.isEmpty()) { + Grouping.AllocationState allocationState = Grouping.AllocationState.valueOf(allocationStateStr); + zoneFinal.setAllocationState(allocationState); + } else { + // Zone will be disabled since 3.0. Admin should enable it after + // physical network and providers setup. + zoneFinal.setAllocationState(Grouping.AllocationState.Disabled); } + + return Transaction.execute(new TransactionCallback() { + @Override + public DataCenterVO doInTransaction(TransactionStatus status) { + DataCenterVO zone = _zoneDao.persist(zoneFinal); + if (domainId != null) { + // zone is explicitly dedicated to this domain + // create affinity group associated and dedicate the zone. + AffinityGroup group = createDedicatedAffinityGroup(null, domainId, null); + DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(zone.getId(), null, null, null, + domainId, null, group.getId()); + _dedicatedDao.persist(dedicatedResource); + } + + // Create default system networks + createDefaultSystemNetworks(zone.getId()); + + return zone; + } + }); } private AffinityGroup createDedicatedAffinityGroup(String affinityGroupName, Long domainId, Long accountId) { @@ -2662,31 +2676,43 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati if (ipv4) { checkOverlapPrivateIpRange(zoneId, startIP, endIP); } - Transaction txn = Transaction.currentTxn(); - txn.start(); - if ((sameSubnet == null || sameSubnet.first() == false) && (network.getTrafficType()== TrafficType.Guest) && (network.getGuestType() == GuestType.Shared) && (_vlanDao.listVlansByNetworkId(networkId) != null)) { - Map dhcpCapabilities = _networkSvc.getNetworkOfferingServiceCapabilities(_networkOfferingDao.findById(network.getNetworkOfferingId()), Service.Dhcp); - String supportsMultipleSubnets = dhcpCapabilities.get(Capability.DhcpAccrossMultipleSubnets); - if (supportsMultipleSubnets == null || !Boolean.valueOf(supportsMultipleSubnets)) { - throw new InvalidParameterValueException("The Dhcp serivice provider for this network dose not support the dhcp across multiple subnets"); + return commitVlan(zoneId, podId, startIP, endIP, newVlanGateway, newVlanNetmask, vlanId, + forVirtualNetwork, networkId, physicalNetworkId, startIPv6, endIPv6, ip6Gateway, ip6Cidr, vlanOwner, + network, sameSubnet); + } + + private Vlan commitVlan(final Long zoneId, final Long podId, final String startIP, final String endIP, final String newVlanGatewayFinal, + final String newVlanNetmaskFinal, final String vlanId, final Boolean forVirtualNetwork, final Long networkId, final Long physicalNetworkId, + final String startIPv6, final String endIPv6, final String ip6Gateway, final String ip6Cidr, final Account vlanOwner, final Network network, + final Pair> sameSubnet) { + return Transaction.execute(new TransactionCallback() { + @Override + public Vlan doInTransaction(TransactionStatus status) { + String newVlanNetmask = newVlanNetmaskFinal; + String newVlanGateway = newVlanGatewayFinal; + + if ((sameSubnet == null || sameSubnet.first() == false) && (network.getTrafficType()== TrafficType.Guest) && (network.getGuestType() == GuestType.Shared) && (_vlanDao.listVlansByNetworkId(networkId) != null)) { + Map dhcpCapabilities = _networkSvc.getNetworkOfferingServiceCapabilities(_networkOfferingDao.findById(network.getNetworkOfferingId()), Service.Dhcp); + String supportsMultipleSubnets = dhcpCapabilities.get(Capability.DhcpAccrossMultipleSubnets); + if (supportsMultipleSubnets == null || !Boolean.valueOf(supportsMultipleSubnets)) { + throw new InvalidParameterValueException("The Dhcp serivice provider for this network dose not support the dhcp across multiple subnets"); + } + s_logger.info("adding a new subnet to the network " + network.getId()); + } else if (sameSubnet != null) { + // if it is same subnet the user might not send the vlan and the + // netmask details. so we are + // figuring out while validation and setting them here. + newVlanGateway = sameSubnet.second().first(); + newVlanNetmask = sameSubnet.second().second(); + } + Vlan vlan = createVlanAndPublicIpRange(zoneId, networkId, physicalNetworkId, forVirtualNetwork, podId, startIP, + endIP, newVlanGateway, newVlanNetmask, vlanId, vlanOwner, startIPv6, endIPv6, ip6Gateway, ip6Cidr); + // create an entry in the nic_secondary table. This will be the new + // gateway that will be configured on the corresponding routervm. + return vlan; } - s_logger.info("adding a new subnet to the network " + network.getId()); - } else if (sameSubnet != null) { - // if it is same subnet the user might not send the vlan and the - // netmask details. so we are - // figuring out while validation and setting them here. - newVlanGateway = sameSubnet.second().first(); - newVlanNetmask = sameSubnet.second().second(); - } - Vlan vlan = createVlanAndPublicIpRange(zoneId, networkId, physicalNetworkId, forVirtualNetwork, podId, startIP, - endIP, newVlanGateway, newVlanNetmask, vlanId, vlanOwner, startIPv6, endIPv6, ip6Gateway, ip6Cidr); - // create an entry in the nic_secondary table. This will be the new - // gateway that will be configured on the corresponding routervm. - - txn.commit(); - - return vlan; + }); } public NetUtils.supersetOrSubset checkIfSubsetOrSuperset(String newVlanGateway, String newVlanNetmask, VlanVO vlan, String startIP, @@ -2890,7 +2916,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } // Make sure the netmask is valid - if (!NetUtils.isValidIp(vlanNetmask)) { + if (!NetUtils.isValidNetmask(vlanNetmask)) { throw new InvalidParameterValueException("Please specify a valid netmask"); } } @@ -2907,6 +2933,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati if (ipv4) { String newCidr = NetUtils.getCidrFromGatewayAndNetmask(vlanGateway, vlanNetmask); + //Make sure start and end ips are with in the range of cidr calculated for this gateway and netmask { + if(!NetUtils.isIpWithtInCidrRange(vlanGateway, newCidr) || !NetUtils.isIpWithtInCidrRange(startIP, newCidr) || !NetUtils.isIpWithtInCidrRange(endIP, newCidr)) { + throw new InvalidParameterValueException("Please specify a valid IP range or valid netmask or valid gateway"); + } + // Check if the new VLAN's subnet conflicts with the guest network // in // the specified zone (guestCidr is null for basic zone) @@ -2922,6 +2953,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati // Check if there are any errors with the IP range checkPublicIpRangeErrors(zoneId, vlanId, vlanGateway, vlanNetmask, startIP, endIP); + checkConflictsWithPortableIpRange(zoneId, vlanId, vlanGateway, vlanNetmask, startIP, endIP); + // Throw an exception if this subnet overlaps with subnet on other VLAN, // if this is ip range extension, gateway, network mask should be same and ip range should not overlap @@ -3014,52 +3047,62 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } // Everything was fine, so persist the VLAN - Transaction txn = Transaction.currentTxn(); - txn.start(); - - VlanVO vlan = new VlanVO(vlanType, vlanId, vlanGateway, vlanNetmask, zone.getId(), ipRange, networkId, - physicalNetworkId, vlanIp6Gateway, vlanIp6Cidr, ipv6Range); - s_logger.debug("Saving vlan range " + vlan); - vlan = _vlanDao.persist(vlan); - - // IPv6 use a used ip map, is different from ipv4, no need to save - // public ip range - if (ipv4) { - if (!savePublicIPRange(startIP, endIP, zoneId, vlan.getId(), networkId, physicalNetworkId)) { - throw new CloudRuntimeException("Failed to save IPv4 range. Please contact Cloud Support."); - } - } - - if (vlanOwner != null) { - // This VLAN is account-specific, so create an AccountVlanMapVO - // entry - AccountVlanMapVO accountVlanMapVO = new AccountVlanMapVO(vlanOwner.getId(), vlan.getId()); - _accountVlanMapDao.persist(accountVlanMapVO); - - // generate usage event for dedication of every ip address in the - // range - List ips = _publicIpAddressDao.listByVlanId(vlan.getId()); - for (IPAddressVO ip : ips) { - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN, vlanOwner.getId(), ip - .getDataCenterId(), ip.getId(), ip.getAddress().toString(), ip.isSourceNat(), vlan - .getVlanType().toString(), ip.getSystem(), ip.getClass().getName(), ip.getUuid()); - } - // increment resource count for dedicated public ip's - _resourceLimitMgr.incrementResourceCount(vlanOwner.getId(), ResourceType.public_ip, new Long(ips.size())); - } else if (podId != null) { - // This VLAN is pod-wide, so create a PodVlanMapVO entry - PodVlanMapVO podVlanMapVO = new PodVlanMapVO(podId, vlan.getId()); - _podVlanMapDao.persist(podVlanMapVO); - } - - txn.commit(); + VlanVO vlan = commitVlanAndIpRange(zoneId, networkId, physicalNetworkId, podId, startIP, endIP, vlanGateway, + vlanNetmask, vlanId, vlanOwner, vlanIp6Gateway, vlanIp6Cidr, ipv4, zone, vlanType, ipv6Range, ipRange); return vlan; } + private VlanVO commitVlanAndIpRange(final long zoneId, final long networkId, final long physicalNetworkId, final Long podId, + final String startIP, final String endIP, final String vlanGateway, final String vlanNetmask, final String vlanId, final Account vlanOwner, + final String vlanIp6Gateway, final String vlanIp6Cidr, final boolean ipv4, final DataCenterVO zone, final VlanType vlanType, + final String ipv6Range, final String ipRange) { + return Transaction.execute(new TransactionCallback() { + @Override + public VlanVO doInTransaction(TransactionStatus status) { + VlanVO vlan = new VlanVO(vlanType, vlanId, vlanGateway, vlanNetmask, zone.getId(), ipRange, networkId, + physicalNetworkId, vlanIp6Gateway, vlanIp6Cidr, ipv6Range); + s_logger.debug("Saving vlan range " + vlan); + vlan = _vlanDao.persist(vlan); + + // IPv6 use a used ip map, is different from ipv4, no need to save + // public ip range + if (ipv4) { + if (!savePublicIPRange(startIP, endIP, zoneId, vlan.getId(), networkId, physicalNetworkId)) { + throw new CloudRuntimeException("Failed to save IPv4 range. Please contact Cloud Support."); + } + } + + if (vlanOwner != null) { + // This VLAN is account-specific, so create an AccountVlanMapVO + // entry + AccountVlanMapVO accountVlanMapVO = new AccountVlanMapVO(vlanOwner.getId(), vlan.getId()); + _accountVlanMapDao.persist(accountVlanMapVO); + + // generate usage event for dedication of every ip address in the + // range + List ips = _publicIpAddressDao.listByVlanId(vlan.getId()); + for (IPAddressVO ip : ips) { + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN, vlanOwner.getId(), ip + .getDataCenterId(), ip.getId(), ip.getAddress().toString(), ip.isSourceNat(), vlan + .getVlanType().toString(), ip.getSystem(), ip.getClass().getName(), ip.getUuid()); + } + // increment resource count for dedicated public ip's + _resourceLimitMgr.incrementResourceCount(vlanOwner.getId(), ResourceType.public_ip, new Long(ips.size())); + } else if (podId != null) { + // This VLAN is pod-wide, so create a PodVlanMapVO entry + PodVlanMapVO podVlanMapVO = new PodVlanMapVO(podId, vlan.getId()); + _podVlanMapDao.persist(podVlanMapVO); + } + return vlan; + } + }); + + } + @Override @DB - public boolean deleteVlanAndPublicIpRange(long userId, long vlanDbId, Account caller) { + public boolean deleteVlanAndPublicIpRange(long userId, final long vlanDbId, Account caller) { VlanVO vlanRange = _vlanDao.findById(vlanDbId); if (vlanRange == null) { throw new InvalidParameterValueException("Please specify a valid IP range id."); @@ -3146,12 +3189,13 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } - - Transaction txn = Transaction.currentTxn(); - txn.start(); - _publicIpAddressDao.deletePublicIPRange(vlanDbId); - _vlanDao.expunge(vlanDbId); - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + _publicIpAddressDao.deletePublicIPRange(vlanDbId); + _vlanDao.expunge(vlanDbId); + } + }); return true; } @@ -3229,15 +3273,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } - Transaction txn = Transaction.currentTxn(); - txn.start(); - // Create an AccountVlanMapVO entry AccountVlanMapVO accountVlanMapVO = new AccountVlanMapVO(vlanOwner.getId(), vlan.getId()); _accountVlanMapDao.persist(accountVlanMapVO); - txn.commit(); - // generate usage event for dedication of every ip address in the range for (IPAddressVO ip : ips) { UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN, vlanOwner.getId(), ip.getDataCenterId(), @@ -3332,16 +3371,20 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } @DB - protected boolean savePublicIPRange(String startIP, String endIP, long zoneId, long vlanDbId, long sourceNetworkid, - long physicalNetworkId) { - long startIPLong = NetUtils.ip2Long(startIP); - long endIPLong = NetUtils.ip2Long(endIP); - Transaction txn = Transaction.currentTxn(); - txn.start(); - IPRangeConfig config = new IPRangeConfig(); - List problemIps = config.savePublicIPRange(txn, startIPLong, endIPLong, zoneId, vlanDbId, - sourceNetworkid, physicalNetworkId); - txn.commit(); + protected boolean savePublicIPRange(String startIP, String endIP, final long zoneId, final long vlanDbId, final long sourceNetworkid, + final long physicalNetworkId) { + final long startIPLong = NetUtils.ip2Long(startIP); + final long endIPLong = NetUtils.ip2Long(endIP); + + List problemIps = Transaction.execute(new TransactionCallback>() { + @Override + public List doInTransaction(TransactionStatus status) { + IPRangeConfig config = new IPRangeConfig(); + return config.savePublicIPRange(TransactionLegacy.currentTxn(), startIPLong, endIPLong, zoneId, vlanDbId, + sourceNetworkid, physicalNetworkId); + } + }); + return problemIps != null && problemIps.size() == 0; } @@ -3382,6 +3425,26 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } + private void checkConflictsWithPortableIpRange(long zoneId, String vlanId, String vlanGateway, String vlanNetmask, + String startIP, String endIP) { + // check and throw exception if there is portable IP range that overlaps with public ip range being configured + if (checkOverlapPortableIpRange(_regionDao.getRegionId(), startIP, endIP)) { + throw new InvalidParameterValueException("Ip range: " + startIP + "-" + endIP + + " overlaps with a portable" + " IP range already configured in the region " + _regionDao.getRegionId()); + } + + // verify and throw exception if the VLAN Id is used by any portable IP range + List existingPortableIPRanges = _portableIpRangeDao.listByRegionId(_regionDao.getRegionId()); + if (existingPortableIPRanges != null && !existingPortableIPRanges.isEmpty()) { + for (PortableIpRangeVO portableIpRange : existingPortableIPRanges) { + if (portableIpRange.getVlanTag().equalsIgnoreCase(vlanId)) { + throw new InvalidParameterValueException("The VLAN tag " + vlanId + + " is already being used for portable ip range in this region"); + } + } + } + } + private String getCidrAddress(String cidr) { String[] cidrPair = cidr.split("\\/"); return cidrPair[0]; @@ -3619,6 +3682,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati Map detailsStr = cmd.getDetails(); Boolean egressDefaultPolicy = cmd.getEgressDefaultPolicy(); Integer maxconn = null; + boolean enableKeepAlive = false; // Verify traffic type for (TrafficType tType : TrafficType.values()) { @@ -3780,6 +3844,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati maxconn=Integer.parseInt(_configDao.getValue(Config.NetworkLBHaproxyMaxConn.key())); } } + if(cmd.getKeepAliveEnabled() != null && cmd.getKeepAliveEnabled()) { + enableKeepAlive = true; + } // validate the Source NAT service capabilities specified in the network // offering @@ -3838,7 +3905,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati NetworkOffering offering = createNetworkOffering(name, displayText, trafficType, tags, specifyVlan, availability, networkRate, serviceProviderMap, false, guestType, false, serviceOfferingId, conserveMode, serviceCapabilityMap, - specifyIpRanges, isPersistent, details, egressDefaultPolicy, maxconn); + specifyIpRanges, isPersistent, details, egressDefaultPolicy, maxconn, enableKeepAlive); CallContext.current().setEventDetails(" Id: " + offering.getId() + " Name: " + name); return offering; } @@ -3957,10 +4024,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @DB public NetworkOfferingVO createNetworkOffering(String name, String displayText, TrafficType trafficType, String tags, boolean specifyVlan, Availability availability, Integer networkRate, - Map> serviceProviderMap, boolean isDefault, Network.GuestType type, + final Map> serviceProviderMap, boolean isDefault, Network.GuestType type, boolean systemOnly, Long serviceOfferingId, boolean conserveMode, Map> serviceCapabilityMap, boolean specifyIpRanges, boolean isPersistent, - Map details, boolean egressDefaultPolicy, Integer maxconn) { + final Map details, boolean egressDefaultPolicy, final Integer maxconn, final boolean enableKeepAlive) { String multicastRateStr = _configDao.getValue("multicast.throttling.rate"); int multicastRate = ((multicastRateStr == null) ? 10 : Integer.parseInt(multicastRateStr)); @@ -4100,13 +4167,13 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati publicLb = true; } - NetworkOfferingVO offering = new NetworkOfferingVO(name, displayText, trafficType, systemOnly, specifyVlan, + final NetworkOfferingVO offeringFinal = new NetworkOfferingVO(name, displayText, trafficType, systemOnly, specifyVlan, networkRate, multicastRate, isDefault, availability, tags, type, conserveMode, dedicatedLb, sharedSourceNat, redundantRouter, elasticIp, elasticLb, specifyIpRanges, inline, isPersistent, associatePublicIp, publicLb, internalLb, egressDefaultPolicy); if (serviceOfferingId != null) { - offering.setServiceOfferingId(serviceOfferingId); + offeringFinal.setServiceOfferingId(serviceOfferingId); } // validate the details @@ -4114,46 +4181,50 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati validateNtwkOffDetails(details, serviceProviderMap); } - Transaction txn = Transaction.currentTxn(); - txn.start(); - // 1) create network offering object - s_logger.debug("Adding network offering " + offering); - offering.setConcurrentConnections(maxconn); - offering = _networkOfferingDao.persist(offering, details); - // 2) populate services and providers - if (serviceProviderMap != null) { - for (Network.Service service : serviceProviderMap.keySet()) { - Set providers = serviceProviderMap.get(service); - if (providers != null && !providers.isEmpty()) { - boolean vpcOff = false; - for (Network.Provider provider : providers) { - if (provider == Provider.VPCVirtualRouter) { - vpcOff = true; + return Transaction.execute(new TransactionCallback() { + @Override + public NetworkOfferingVO doInTransaction(TransactionStatus status) { + NetworkOfferingVO offering = offeringFinal; + + // 1) create network offering object + s_logger.debug("Adding network offering " + offering); + offering.setConcurrentConnections(maxconn); + offering.setKeepAliveEnabled(enableKeepAlive); + offering = _networkOfferingDao.persist(offering, details); + // 2) populate services and providers + if (serviceProviderMap != null) { + for (Network.Service service : serviceProviderMap.keySet()) { + Set providers = serviceProviderMap.get(service); + if (providers != null && !providers.isEmpty()) { + boolean vpcOff = false; + for (Network.Provider provider : providers) { + if (provider == Provider.VPCVirtualRouter) { + vpcOff = true; + } + NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(offering.getId(), + service, provider); + _ntwkOffServiceMapDao.persist(offService); + s_logger.trace("Added service for the network offering: " + offService + " with provider " + + provider.getName()); + } + + if (vpcOff) { + List supportedSvcs = new ArrayList(); + supportedSvcs.addAll(serviceProviderMap.keySet()); + _vpcMgr.validateNtwkOffForVpc(offering, supportedSvcs); + } + } else { + NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(offering.getId(), service, + null); + _ntwkOffServiceMapDao.persist(offService); + s_logger.trace("Added service for the network offering: " + offService + " with null provider"); } - NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(offering.getId(), - service, provider); - _ntwkOffServiceMapDao.persist(offService); - s_logger.trace("Added service for the network offering: " + offService + " with provider " - + provider.getName()); } - - if (vpcOff) { - List supportedSvcs = new ArrayList(); - supportedSvcs.addAll(serviceProviderMap.keySet()); - _vpcMgr.validateNtwkOffForVpc(offering, supportedSvcs); - } - } else { - NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(offering.getId(), service, - null); - _ntwkOffServiceMapDao.persist(offService); - s_logger.trace("Added service for the network offering: " + offService + " with null provider"); } + + return offering; } - } - - txn.commit(); - - return offering; + }); } protected void validateNtwkOffDetails(Map details, Map> serviceProviderMap) { @@ -4680,27 +4751,29 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Override @DB - public boolean releaseAccountSpecificVirtualRanges(long accountId) { - List maps = _accountVlanMapDao.listAccountVlanMapsByAccount(accountId); - boolean result = true; + public boolean releaseAccountSpecificVirtualRanges(final long accountId) { + final List maps = _accountVlanMapDao.listAccountVlanMapsByAccount(accountId); if (maps != null && !maps.isEmpty()) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - for (AccountVlanMapVO map : maps) { - if (!releasePublicIpRange(map.getVlanDbId(), _accountMgr.getSystemUser().getId(), - _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM))) { - result = false; - } - } - if (result) { - txn.commit(); - } else { - s_logger.error("Failed to release account specific virtual ip ranges for account id=" + accountId); + try { + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + for (AccountVlanMapVO map : maps) { + if (!releasePublicIpRange(map.getVlanDbId(), _accountMgr.getSystemUser().getId(), + _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM))) { + throw new CloudRuntimeException("Failed to release account specific virtual ip ranges for account id=" + accountId); + } + } + } + }); + } catch ( CloudRuntimeException e ) { + s_logger.error(e); + return false; } } else { s_logger.trace("Account id=" + accountId + " has no account specific virtual ip ranges, nothing to release"); } - return result; + return true; } @Override @@ -4771,14 +4844,14 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @ActionEvent(eventType = EventTypes.EVENT_PORTABLE_IP_RANGE_CREATE, eventDescription = "creating portable ip range", async = false) public PortableIpRange createPortableIpRange(CreatePortableIpRangeCmd cmd) throws ConcurrentOperationException { - Integer regionId = cmd.getRegionId(); - String startIP = cmd.getStartIp(); - String endIP = cmd.getEndIp(); - String gateway = cmd.getGateway(); - String netmask = cmd.getNetmask(); + final Integer regionId = cmd.getRegionId(); + final String startIP = cmd.getStartIp(); + final String endIP = cmd.getEndIp(); + final String gateway = cmd.getGateway(); + final String netmask = cmd.getNetmask(); String vlanId = cmd.getVlan(); - RegionVO region = _regionDao.findById(regionId); + final RegionVO region = _regionDao.findById(regionId); if (region == null) { throw new InvalidParameterValueException("Invalid region ID: " + regionId); } @@ -4809,41 +4882,48 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati throw new InvalidParameterValueException("Invalid vlan id " + vlanId); } - // check if there is zone vlan with same id List zones= _zoneDao.listAllZones(); if (zones != null && !zones.isEmpty()) { for (DataCenterVO zone: zones) { + // check if there is zone vlan with same id if (_vlanDao.findByZoneAndVlanId(zone.getId(), vlanId) != null) throw new InvalidParameterValueException("Found a VLAN id " + vlanId + " already existing in" + " zone " + zone.getUuid() + " that conflicts with VLAN id of the portable ip range being configured"); + //check if there is a public ip range that overlaps with portable ip range being created + checkOverlapPublicIpRange(zone.getId(), startIP, endIP); } } } GlobalLock portableIpLock = GlobalLock.getInternLock("PortablePublicIpRange"); portableIpLock.lock(5); - Transaction txn = Transaction.currentTxn(); - txn.start(); + try { + final String vlanIdFinal = vlanId; + return Transaction.execute(new TransactionCallback() { + @Override + public PortableIpRangeVO doInTransaction(TransactionStatus status) { + PortableIpRangeVO portableIpRange = new PortableIpRangeVO(regionId, vlanIdFinal, gateway, netmask, startIP, endIP); + portableIpRange = _portableIpRangeDao.persist(portableIpRange); - PortableIpRangeVO portableIpRange = new PortableIpRangeVO(regionId, vlanId, gateway, netmask, startIP, endIP); - portableIpRange = _portableIpRangeDao.persist(portableIpRange); + long startIpLong = NetUtils.ip2Long(startIP); + long endIpLong = NetUtils.ip2Long(endIP); + while (startIpLong <= endIpLong) { + PortableIpVO portableIP = new PortableIpVO(regionId, portableIpRange.getId(), vlanIdFinal, gateway, netmask, + NetUtils.long2Ip(startIpLong)); + _portableIpDao.persist(portableIP); + startIpLong++; + } - long startIpLong = NetUtils.ip2Long(startIP); - long endIpLong = NetUtils.ip2Long(endIP); - while (startIpLong <= endIpLong) { - PortableIpVO portableIP = new PortableIpVO(regionId, portableIpRange.getId(), vlanId, gateway, netmask, - NetUtils.long2Ip(startIpLong)); - _portableIpDao.persist(portableIP); - startIpLong++; + // implicitly enable portable IP service for the region + region.setPortableipEnabled(true); + _regionDao.update(region.getId(), region); + + return portableIpRange; + } + }); + } finally { + portableIpLock.unlock(); } - - // implicitly enable portable IP service for the region - region.setPortableipEnabled(true); - _regionDao.update(region.getId(), region); - - txn.commit(); - portableIpLock.unlock(); - return portableIpRange; } @Override @@ -4921,6 +5001,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati long newEndIp = NetUtils.ip2Long(newEndIpStr); List existingPortableIPRanges = _portableIpRangeDao.listByRegionId(regionId); + + if (existingPortableIPRanges == null || existingPortableIPRanges.isEmpty()) { + return false; + } + for (PortableIpRangeVO portableIpRange : existingPortableIPRanges) { String ipRangeStr = portableIpRange.getIpRange(); String[] range = ipRangeStr.split("-"); diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 030a31fb5e6..e55477a3f56 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -118,6 +118,8 @@ import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.QueryBuilder; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.events.SubscriptionMgr; @@ -569,10 +571,10 @@ VirtualMachineGuru, SystemVmLoadScanHandler, ResourceStateAdapter { } catch (ResourceUnavailableException e) { s_logger.warn("Exception while trying to start console proxy", e); return null; - } catch (CloudRuntimeException e) { + } catch (ConcurrentOperationException e) { s_logger.warn("Runtime Exception while trying to start console proxy", e); return null; - } catch (ConcurrentOperationException e) { + } catch (CloudRuntimeException e) { s_logger.warn("Runtime Exception while trying to start console proxy", e); return null; } catch (OperationTimedoutException e) { @@ -1049,25 +1051,24 @@ VirtualMachineGuru, SystemVmLoadScanHandler, ResourceStateAdapter { @Override @DB - public void setManagementState(ConsoleProxyManagementState state) { - Transaction txn = Transaction.currentTxn(); + public void setManagementState(final ConsoleProxyManagementState state) { try { - txn.start(); - - ConsoleProxyManagementState lastState = getManagementState(); + final ConsoleProxyManagementState lastState = getManagementState(); if (lastState == null) { - txn.commit(); return; } if (lastState != state) { - _configDao.update(Config.ConsoleProxyManagementLastState.key(), Config.ConsoleProxyManagementLastState.getCategory(), lastState.toString()); - _configDao.update(Config.ConsoleProxyManagementState.key(), Config.ConsoleProxyManagementState.getCategory(), state.toString()); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + _configDao.update(Config.ConsoleProxyManagementLastState.key(), Config.ConsoleProxyManagementLastState.getCategory(), lastState.toString()); + _configDao.update(Config.ConsoleProxyManagementState.key(), Config.ConsoleProxyManagementState.getCategory(), state.toString()); + } + }); } - - txn.commit(); } catch (Throwable e) { - txn.rollback(); + s_logger.error("Failed to set managment state", e); } } @@ -1090,23 +1091,18 @@ VirtualMachineGuru, SystemVmLoadScanHandler, ResourceStateAdapter { @Override @DB public void resumeLastManagementState() { - Transaction txn = Transaction.currentTxn(); try { - txn.start(); ConsoleProxyManagementState state = getManagementState(); ConsoleProxyManagementState lastState = getLastManagementState(); if (lastState == null) { - txn.commit(); return; } if (lastState != state) { _configDao.update(Config.ConsoleProxyManagementState.key(), Config.ConsoleProxyManagementState.getCategory(), lastState.toString()); } - - txn.commit(); } catch (Throwable e) { - txn.rollback(); + s_logger.error("Failed to resume last management state", e); } } diff --git a/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java index 675ff2505bb..ef161338a1c 100755 --- a/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java +++ b/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java @@ -70,6 +70,9 @@ public class StaticConsoleProxyManager extends AgentBasedConsoleProxyManager imp private String _ip = null; + public StaticConsoleProxyManager() { + + } @Override protected HostVO findHost(VMInstanceVO vm) { diff --git a/server/src/com/cloud/dc/dao/DedicatedResourceDaoImpl.java b/server/src/com/cloud/dc/dao/DedicatedResourceDaoImpl.java index 1936b85015e..3902847c4f9 100644 --- a/server/src/com/cloud/dc/dao/DedicatedResourceDaoImpl.java +++ b/server/src/com/cloud/dc/dao/DedicatedResourceDaoImpl.java @@ -29,6 +29,7 @@ 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.TransactionLegacy; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; @@ -338,7 +339,7 @@ public class DedicatedResourceDaoImpl extends GenericDaoBase() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + final PlannerHostReservationVO lockedEntry = _plannerHostReserveDao.lockRow(id, true); + if (lockedEntry == null) { + s_logger.error("Unable to lock the host entry for reservation, host: " + hostId); return false; } + // check before updating + if (lockedEntry.getResourceUsage() == null) { + lockedEntry.setResourceUsage(resourceUsageRequired); + _plannerHostReserveDao.persist(lockedEntry); + return true; + } else { + // someone updated it earlier. check if we can still use it + if (lockedEntry.getResourceUsage() == resourceUsageRequired) { + return true; + } else { + s_logger.debug("Cannot use this host for usage: " + resourceUsageRequired + + ", since this host has been reserved for planner usage : " + hostResourceTypeFinal); + return false; + } + } } - } finally { - txn.commit(); - } + }); + } } @@ -600,7 +602,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } @DB - public boolean checkHostReservationRelease(Long hostId) { + public boolean checkHostReservationRelease(final Long hostId) { if (hostId != null) { PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId); @@ -662,26 +664,26 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy s_logger.debug("Host has no VMs associated, releasing the planner reservation for host " + hostId); } - long id = reservationEntry.getId(); - final Transaction txn = Transaction.currentTxn(); + final long id = reservationEntry.getId(); - try { - txn.start(); + return Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + final PlannerHostReservationVO lockedEntry = _plannerHostReserveDao.lockRow(id, true); + if (lockedEntry == null) { + s_logger.error("Unable to lock the host entry for reservation, host: " + hostId); + return false; + } + // check before updating + if (lockedEntry.getResourceUsage() != null) { + lockedEntry.setResourceUsage(null); + _plannerHostReserveDao.persist(lockedEntry); + return true; + } - final PlannerHostReservationVO lockedEntry = _plannerHostReserveDao.lockRow(id, true); - if (lockedEntry == null) { - s_logger.error("Unable to lock the host entry for reservation, host: " + hostId); return false; } - // check before updating - if (lockedEntry.getResourceUsage() != null) { - lockedEntry.setResourceUsage(null); - _plannerHostReserveDao.persist(lockedEntry); - return true; - } - } finally { - txn.commit(); - } + }); } } @@ -932,15 +934,36 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy if (!allocatorAvoidOutput.shouldAvoid(host)) { // there's some host in the cluster that is not yet in avoid set avoidAllHosts = false; + break; } } - List allPoolsInCluster = _storagePoolDao.findPoolsByTags(clusterVO.getDataCenterId(), - clusterVO.getPodId(), clusterVO.getId(), null); - for (StoragePoolVO pool : allPoolsInCluster) { - if (!allocatorAvoidOutput.shouldAvoid(pool)) { - // there's some pool in the cluster that is not yet in avoid set - avoidAllPools = false; + // Cluster can be put in avoid set in following scenarios: + // 1. If storage allocators haven't put any pools in avoid set means either no pools in cluster + // or pools not suitable for the allocators to handle. + // 2. If all 'shared' or 'local' pools are in avoid set + if (allocatorAvoidOutput.getPoolsToAvoid() != null && !allocatorAvoidOutput.getPoolsToAvoid().isEmpty()) { + // check shared pools + List allPoolsInCluster = _storagePoolDao.findPoolsByTags(clusterVO.getDataCenterId(), + clusterVO.getPodId(), clusterVO.getId(), null); + for (StoragePoolVO pool : allPoolsInCluster) { + if (!allocatorAvoidOutput.shouldAvoid(pool)) { + // there's some pool in the cluster that is not yet in avoid set + avoidAllPools = false; + break; + } + } + if (avoidAllPools) { + // check local pools + List allLocalPoolsInCluster = _storagePoolDao.findLocalStoragePoolsByTags(clusterVO.getDataCenterId(), + clusterVO.getPodId(), clusterVO.getId(), null); + for (StoragePoolVO pool : allLocalPoolsInCluster) { + if (!allocatorAvoidOutput.shouldAvoid(pool)) { + // there's some pool in the cluster that is not yet in avoid set + avoidAllPools = false; + break; + } + } } } @@ -1230,50 +1253,51 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy @DB @Override - public String finalizeReservation(DeployDestination plannedDestination, - VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids) + public String finalizeReservation(final DeployDestination plannedDestination, + final VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids) throws InsufficientServerCapacityException, AffinityConflictException { - VirtualMachine vm = vmProfile.getVirtualMachine(); - long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId()); + final VirtualMachine vm = vmProfile.getVirtualMachine(); + final long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId()); - boolean saveReservation = true; - final Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - if (vmGroupCount > 0) { - List groupIds = _affinityGroupVMMapDao.listAffinityGroupIdsByVmId(vm.getId()); - SearchCriteria criteria = _affinityGroupDao.createSearchCriteria(); - criteria.addAnd("id", SearchCriteria.Op.IN, groupIds.toArray(new Object[groupIds.size()])); - List groups = _affinityGroupDao.lockRows(criteria, null, true); + return Transaction.execute(new TransactionCallback() { + @Override + public String doInTransaction(TransactionStatus status) { + boolean saveReservation = true; - for (AffinityGroupProcessor processor : _affinityProcessors) { - if (!processor.check(vmProfile, plannedDestination)) { - saveReservation = false; - break; + if (vmGroupCount > 0) { + List groupIds = _affinityGroupVMMapDao.listAffinityGroupIdsByVmId(vm.getId()); + SearchCriteria criteria = _affinityGroupDao.createSearchCriteria(); + criteria.addAnd("id", SearchCriteria.Op.IN, groupIds.toArray(new Object[groupIds.size()])); + List groups = _affinityGroupDao.lockRows(criteria, null, true); + + for (AffinityGroupProcessor processor : _affinityProcessors) { + if (!processor.check(vmProfile, plannedDestination)) { + saveReservation = false; + break; + } } } - } - if (saveReservation) { - VMReservationVO vmReservation = new VMReservationVO(vm.getId(), plannedDestination.getDataCenter() - .getId(), plannedDestination.getPod().getId(), plannedDestination.getCluster().getId(), - plannedDestination.getHost().getId()); - Map volumeReservationMap = new HashMap(); + if (saveReservation) { + VMReservationVO vmReservation = new VMReservationVO(vm.getId(), plannedDestination.getDataCenter() + .getId(), plannedDestination.getPod().getId(), plannedDestination.getCluster().getId(), + plannedDestination.getHost().getId()); + Map volumeReservationMap = new HashMap(); - if (vm.getHypervisorType() != HypervisorType.BareMetal) { - for (Volume vo : plannedDestination.getStorageForDisks().keySet()) { - volumeReservationMap.put(vo.getId(), plannedDestination.getStorageForDisks().get(vo).getId()); + if (vm.getHypervisorType() != HypervisorType.BareMetal) { + for (Volume vo : plannedDestination.getStorageForDisks().keySet()) { + volumeReservationMap.put(vo.getId(), plannedDestination.getStorageForDisks().get(vo).getId()); + } + vmReservation.setVolumeReservation(volumeReservationMap); } - vmReservation.setVolumeReservation(volumeReservationMap); + _reservationDao.persist(vmReservation); + return vmReservation.getUuid(); } - _reservationDao.persist(vmReservation); - return vmReservation.getUuid(); + + return null; } - } finally { - txn.commit(); - } - return null; + }); } @Override diff --git a/server/src/com/cloud/event/ActionEventInterceptor.java b/server/src/com/cloud/event/ActionEventInterceptor.java index 83965120883..1820b346fbf 100644 --- a/server/src/com/cloud/event/ActionEventInterceptor.java +++ b/server/src/com/cloud/event/ActionEventInterceptor.java @@ -20,14 +20,45 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; import org.apache.cloudstack.context.CallContext; import com.cloud.utils.component.ComponentMethodInterceptor; -public class ActionEventInterceptor implements ComponentMethodInterceptor { +public class ActionEventInterceptor implements ComponentMethodInterceptor, MethodInterceptor { public ActionEventInterceptor() { } + + @Override + public Object invoke(MethodInvocation invocation) throws Throwable { + Method m = invocation.getMethod(); + Object target = invocation.getThis(); + + if ( getActionEvents(m).size() == 0 ) { + /* Look for annotation on impl class */ + m = target.getClass().getMethod(m.getName(), m.getParameterTypes()); + } + + Object interceptorData = null; + + boolean success = true; + try { + interceptorData = interceptStart(m, target); + + Object result = invocation.proceed(); + success = true; + + return result; + } finally { + if ( success ) { + interceptComplete(m, target, interceptorData); + } else { + interceptException(m, target, interceptorData); + } + } + } @Override public Object interceptStart(Method method, Object target) { diff --git a/server/src/com/cloud/ha/HighAvailabilityManagerExtImpl.java b/server/src/com/cloud/ha/HighAvailabilityManagerExtImpl.java index 1107a7a031d..801e7dac572 100644 --- a/server/src/com/cloud/ha/HighAvailabilityManagerExtImpl.java +++ b/server/src/com/cloud/ha/HighAvailabilityManagerExtImpl.java @@ -24,14 +24,13 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Component; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.managed.context.ManagedContextRunnable; import com.cloud.alert.AlertManager; import com.cloud.usage.dao.UsageJobDao; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Local(value={HighAvailabilityManager.class}) public class HighAvailabilityManagerExtImpl extends HighAvailabilityManagerImpl { @@ -74,7 +73,7 @@ public class HighAvailabilityManagerExtImpl extends HighAvailabilityManagerImpl try { boolean isRunning = false; - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); try { Date lastHeartbeat = _usageJobDao.getLastHeartbeat(); if (lastHeartbeat != null) { @@ -91,7 +90,7 @@ public class HighAvailabilityManagerExtImpl extends HighAvailabilityManagerImpl txn.close(); // switch back to VMOPS db - Transaction swap = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy swap = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); swap.close(); } diff --git a/server/src/com/cloud/ha/dao/HighAvailabilityDaoImpl.java b/server/src/com/cloud/ha/dao/HighAvailabilityDaoImpl.java index 83a71b80299..d800483b472 100644 --- a/server/src/com/cloud/ha/dao/HighAvailabilityDaoImpl.java +++ b/server/src/com/cloud/ha/dao/HighAvailabilityDaoImpl.java @@ -33,6 +33,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -130,7 +131,7 @@ public class HighAvailabilityDaoImpl extends GenericDaoBase impl @Override public HaWorkVO take(final long serverId) { - final Transaction txn = Transaction.currentTxn(); + final TransactionLegacy txn = TransactionLegacy.currentTxn(); try { final SearchCriteria sc = TBASearch.create(); sc.setParameters("time", System.currentTimeMillis() >> 10); diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java index 2ee6364b231..a52833405a5 100644 --- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java @@ -39,12 +39,14 @@ import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.NicSecondaryIpDao; import com.cloud.vm.dao.VMInstanceDao; +import com.cloud.vm.dao.UserVmDetailsDao; public abstract class HypervisorGuruBase extends AdapterBase implements HypervisorGuru { @Inject VMTemplateDetailsDao _templateDetailsDao; @Inject NicDao _nicDao; @Inject VMInstanceDao _virtualMachineDao; + @Inject UserVmDetailsDao _userVmDetailsDao; @Inject NicSecondaryIpDao _nicSecIpDao; @Inject ConfigurationServer _configServer; @@ -113,14 +115,10 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis to.setArch("x86_64"); } - long templateId = vm.getTemplateId(); - Map details = _templateDetailsDao.findDetails(templateId); - assert(details != null); - Map detailsInVm = vm.getDetails(); + Map detailsInVm = _userVmDetailsDao.findDetails(vm.getId()); if(detailsInVm != null) { - details.putAll(detailsInVm); + to.setDetails(detailsInVm); } - to.setDetails(details); // Workaround to make sure the TO has the UUID we need for Niciri integration VMInstanceVO vmInstance = _virtualMachineDao.findById(to.getId()); // check if XStools/VMWare tools are present in the VM and dynamic scaling feature is enabled (per zone/global) diff --git a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java b/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java index 5481ebb8c44..4159a8006ee 100644 --- a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java +++ b/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java @@ -16,150 +16,67 @@ // under the License. package com.cloud.metadata; -import java.util.HashMap; import java.util.Map; import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import com.cloud.dc.DcDetailVO; -import com.cloud.dc.dao.DataCenterDao; -import com.cloud.dc.dao.DcDetailsDao; -import com.cloud.network.dao.NetworkDetailVO; -import com.cloud.network.dao.NetworkDetailsDao; -import com.cloud.server.ResourceMetaDataService; -import com.cloud.storage.VolumeDetailVO; -import com.cloud.storage.dao.VolumeDetailsDao; -import com.cloud.vm.NicDetailVO; -import com.cloud.vm.UserVmDetailVO; -import com.cloud.vm.dao.NicDao; -import com.cloud.vm.dao.NicDetailDao; -import com.cloud.vm.dao.UserVmDetailsDao; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.api.query.dao.ResourceTagJoinDao; +import com.cloud.dc.DcDetailVO; +import com.cloud.dc.dao.DcDetailsDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.network.dao.FirewallRulesDao; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.LoadBalancerDao; -import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.RemoteAccessVpnDao; -import com.cloud.network.rules.dao.PortForwardingRulesDao; -import com.cloud.network.security.dao.SecurityGroupDao; -import com.cloud.network.vpc.dao.StaticRouteDao; -import com.cloud.network.vpc.dao.VpcDao; -import com.cloud.projects.dao.ProjectDao; -import com.cloud.server.ResourceTag; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.network.dao.NetworkDetailVO; +import com.cloud.network.dao.NetworkDetailsDao; +import com.cloud.server.ResourceMetaDataService; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.server.TaggedResourceService; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VolumeDao; -import com.cloud.tags.dao.ResourceTagDao; -import com.cloud.user.AccountManager; -import com.cloud.user.DomainManager; +import com.cloud.service.ServiceOfferingDetailsVO; +import com.cloud.service.dao.ServiceOfferingDetailsDao; +import com.cloud.storage.VolumeDetailVO; +import com.cloud.storage.dao.VMTemplateDetailsDao; +import com.cloud.storage.dao.VolumeDetailsDao; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; -import com.cloud.utils.db.GenericDao; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionStatus; import com.cloud.uuididentity.dao.IdentityDao; -import com.cloud.vm.dao.UserVmDao; -import com.cloud.vm.snapshot.dao.VMSnapshotDao; +import com.cloud.vm.NicDetailVO; +import com.cloud.vm.dao.NicDetailDao; +import com.cloud.vm.dao.UserVmDetailsDao; @Component @Local(value = { ResourceMetaDataService.class, ResourceMetaDataManager.class }) public class ResourceMetaDataManagerImpl extends ManagerBase implements ResourceMetaDataService, ResourceMetaDataManager { public static final Logger s_logger = Logger.getLogger(ResourceMetaDataManagerImpl.class); - - - private static Map> _daoMap= - new HashMap>(); @Inject - AccountManager _accountMgr; - @Inject - ResourceTagDao _resourceTagDao; - @Inject - ResourceTagJoinDao _resourceTagJoinDao; - @Inject - IdentityDao _identityDao; - @Inject - DomainManager _domainMgr; - @Inject - UserVmDao _userVmDao; - @Inject - VolumeDao _volumeDao; - @Inject - VMTemplateDao _templateDao; - @Inject - SnapshotDao _snapshotDao; - @Inject - NetworkDao _networkDao; - @Inject - DataCenterDao _dataCenterDao; - @Inject - LoadBalancerDao _lbDao; - @Inject - PortForwardingRulesDao _pfDao; - @Inject - FirewallRulesDao _firewallDao; - @Inject - SecurityGroupDao _securityGroupDao; - @Inject - RemoteAccessVpnDao _vpnDao; - @Inject - IPAddressDao _publicIpDao; - @Inject - ProjectDao _projectDao; - @Inject - VpcDao _vpcDao; - @Inject - StaticRouteDao _staticRouteDao; - @Inject - VMSnapshotDao _vmSnapshotDao; - @Inject - protected VolumeDetailsDao _volumeDetailDao; + VolumeDetailsDao _volumeDetailDao; @Inject NicDetailDao _nicDetailDao; @Inject UserVmDetailsDao _userVmDetailDao; @Inject - NicDao _nicDao; - @Inject DcDetailsDao _dcDetailsDao; @Inject NetworkDetailsDao _networkDetailsDao; @Inject TaggedResourceService _taggedResourceMgr; @Inject - UserVmDetailsDao _userVmDetail; + VMTemplateDetailsDao _templateDetailsDao; + @Inject + UserVmDetailsDao _userVmDetailsDao; + @Inject + ServiceOfferingDetailsDao _serviceOfferingDetailsDao; + @Override public boolean configure(String name, Map params) throws ConfigurationException { - - _daoMap.put(TaggedResourceType.UserVm, _userVmDao); - _daoMap.put(TaggedResourceType.Volume, _volumeDao); - _daoMap.put(TaggedResourceType.Template, _templateDao); - _daoMap.put(TaggedResourceType.ISO, _templateDao); - _daoMap.put(TaggedResourceType.Snapshot, _snapshotDao); - _daoMap.put(TaggedResourceType.Network, _networkDao); - _daoMap.put(TaggedResourceType.LoadBalancer, _lbDao); - _daoMap.put(TaggedResourceType.PortForwardingRule, _pfDao); - _daoMap.put(TaggedResourceType.FirewallRule, _firewallDao); - _daoMap.put(TaggedResourceType.SecurityGroup, _securityGroupDao); - _daoMap.put(TaggedResourceType.PublicIpAddress, _publicIpDao); - _daoMap.put(TaggedResourceType.Project, _projectDao); - _daoMap.put(TaggedResourceType.Vpc, _vpcDao); - _daoMap.put(TaggedResourceType.NetworkACL, _firewallDao); - _daoMap.put(TaggedResourceType.Nic, _nicDao); - _daoMap.put(TaggedResourceType.StaticRoute, _staticRouteDao); - _daoMap.put(TaggedResourceType.VMSnapshot, _vmSnapshotDao); - _daoMap.put(TaggedResourceType.RemoteAccessVpn, _vpnDao); - _daoMap.put(TaggedResourceType.Zone, _dataCenterDao); return true; } @@ -172,92 +89,80 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource public boolean stop() { return true; } - - - - - @Override - public TaggedResourceType getResourceType(String resourceTypeStr) { - - for (TaggedResourceType type : ResourceTag.TaggedResourceType.values()) { - if (type.toString().equalsIgnoreCase(resourceTypeStr)) { - return type; - } - } - throw new InvalidParameterValueException("Invalid resource type " + resourceTypeStr); - } + @Override @DB @ActionEvent(eventType = EventTypes.EVENT_RESOURCE_DETAILS_CREATE, eventDescription = "creating resource meta data") - public boolean addResourceMetaData(String resourceId, TaggedResourceType resourceType, Map details){ + public boolean addResourceMetaData(final String resourceId, final ResourceObjectType resourceType, final Map details){ + return Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + for (String key : details.keySet()) { + String value = details.get(key); - Transaction txn = Transaction.currentTxn(); - txn.start(); + if (value == null || value.isEmpty()) { + throw new InvalidParameterValueException("Value for the key " + key + " is either null or empty"); + } + + if (!resourceType.resourceMetadataSupport()) { + throw new InvalidParameterValueException("The resource type " + resourceType + " doesn't support metadata (resource details)"); + } - for (String key : details.keySet()) { - Long id = _taggedResourceMgr.getResourceId(resourceId, resourceType); - - //check if object exists - if (_daoMap.get(resourceType).findById(id) == null) { - throw new InvalidParameterValueException("Unable to find resource by id " + resourceId + - " and type " + resourceType); + long id = _taggedResourceMgr.getResourceId(resourceId, resourceType); + // TODO - Have a better design here. + if(resourceType == ResourceObjectType.Volume){ + VolumeDetailVO v = new VolumeDetailVO(id, key, value); + _volumeDetailDao.persist(v); + } else if (resourceType == ResourceObjectType.Nic){ + NicDetailVO n = new NicDetailVO(id, key, value); + _nicDetailDao.persist(n); + } else if (resourceType == ResourceObjectType.Zone){ + DcDetailVO dataCenterDetail = new DcDetailVO(id, key, value); + _dcDetailsDao.persist(dataCenterDetail); + } else if (resourceType == ResourceObjectType.Network){ + NetworkDetailVO networkDetail = new NetworkDetailVO(id, key, value); + _networkDetailsDao.persist(networkDetail); + } else if (resourceType == ResourceObjectType.UserVm) { + _userVmDetailsDao.addVmDetail(id, key, value); + } else if (resourceType == ResourceObjectType.Template) { + _templateDetailsDao.addTemplateDetail(id, key, value); + } else if (resourceType == ResourceObjectType.ServiceOffering) { + ServiceOfferingDetailsVO entity = new ServiceOfferingDetailsVO(id, key, value); + _serviceOfferingDetailsDao.persist(entity); + } } - - String value = details.get(key); - - if (value == null || value.isEmpty()) { - throw new InvalidParameterValueException("Value for the key " + key + " is either null or empty"); - } - - // TODO - Have a better design here. - if(resourceType == TaggedResourceType.Volume){ - VolumeDetailVO v = new VolumeDetailVO(id, key, value); - _volumeDetailDao.persist(v); - } else if (resourceType == TaggedResourceType.Nic){ - NicDetailVO n = new NicDetailVO(id, key, value); - _nicDetailDao.persist(n); - }else if (resourceType == TaggedResourceType.UserVm){ - UserVmDetailVO userVmDetail = new UserVmDetailVO(id, key, value); - _userVmDetailDao.persist(userVmDetail); - } else if (resourceType == TaggedResourceType.Zone){ - DcDetailVO dataCenterDetail = new DcDetailVO(id, key, value); - _dcDetailsDao.persist(dataCenterDetail); - } else if (resourceType == TaggedResourceType.Network){ - NetworkDetailVO networkDetail = new NetworkDetailVO(id, key, value); - _networkDetailsDao.persist(networkDetail); - } else { - throw new InvalidParameterValueException("The resource type " + resourceType + " is not supported by the API yet"); - } - - } - - txn.commit(); - - return true; + + + return true; + } + }); } @Override @DB @ActionEvent(eventType = EventTypes.EVENT_RESOURCE_DETAILS_DELETE, eventDescription = "deleting resource meta data") - public boolean deleteResourceMetaData(String resourceId, TaggedResourceType resourceType, String key){ + public boolean deleteResourceMetaData(String resourceId, ResourceObjectType resourceType, String key){ - Long id = _taggedResourceMgr.getResourceId(resourceId, resourceType); - // TODO - Have a better design here. - if(resourceType == TaggedResourceType.Volume){ - _volumeDetailDao.removeDetails(id, key); - } else if(resourceType == TaggedResourceType.Nic){ - _nicDetailDao.removeDetails(id, key); - } else if(resourceType == TaggedResourceType.UserVm){ - _userVmDetailDao.removeDetails(id, key); - } else if (resourceType == TaggedResourceType.Zone){ - _dcDetailsDao.removeDetails(id, key); - } else if (resourceType == TaggedResourceType.Network){ - _networkDetailsDao.removeDetails(id, key); - } else{ + long id = _taggedResourceMgr.getResourceId(resourceId, resourceType); + + if (!resourceType.resourceMetadataSupport()) { throw new InvalidParameterValueException("The resource type " + resourceType + " is not supported by the API yet"); } + + // TODO - Have a better design here. + if (resourceType == ResourceObjectType.Volume){ + _volumeDetailDao.removeDetails(id, key); + } else if (resourceType == ResourceObjectType.Nic){ + _nicDetailDao.removeDetails(id, key); + } else if (resourceType == ResourceObjectType.UserVm) { + _userVmDetailsDao.removeDetails(id, key); + } else if (resourceType == ResourceObjectType.Template) { + _templateDetailsDao.removeDetails(id, key); + } else if (resourceType == ResourceObjectType.Zone){ + _dcDetailsDao.removeDetails(id, key); + } return true; } diff --git a/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java b/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java index 00dd25c4a86..cd3532e837d 100644 --- a/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java +++ b/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java @@ -81,8 +81,9 @@ import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.exception.ExecutionException; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.NicVO; import com.cloud.vm.dao.DomainRouterDao; @@ -288,12 +289,19 @@ public class ExternalDeviceUsageManagerImpl extends ManagerBase implements Exter newCurrentBytesReceived += bytesSentAndReceived[1]; } - UserStatisticsVO userStats; - final Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - userStats = _userStatsDao.lock(accountId, zone.getId(), networkId, publicIp, externalLoadBalancer.getId(), externalLoadBalancer.getType().toString()); + commitStats(networkId, externalLoadBalancer, accountId, publicIp, zone, statsEntryIdentifier, + newCurrentBytesSent, newCurrentBytesReceived); + } + } + private void commitStats(final long networkId, final HostVO externalLoadBalancer, final long accountId, final String publicIp, + final DataCenterVO zone, final String statsEntryIdentifier, final long newCurrentBytesSent, final long newCurrentBytesReceived) { + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + UserStatisticsVO userStats; + userStats = _userStatsDao.lock(accountId, zone.getId(), networkId, publicIp, externalLoadBalancer.getId(), externalLoadBalancer.getType().toString()); + if (userStats != null) { long oldNetBytesSent = userStats.getNetBytesSent(); long oldNetBytesReceived = userStats.getNetBytesReceived(); @@ -301,19 +309,19 @@ public class ExternalDeviceUsageManagerImpl extends ManagerBase implements Exter long oldCurrentBytesReceived = userStats.getCurrentBytesReceived(); String warning = "Received an external network stats byte count that was less than the stored value. Zone ID: " + userStats.getDataCenterId() + ", account ID: " + userStats.getAccountId() + "."; - + userStats.setCurrentBytesSent(newCurrentBytesSent); if (oldCurrentBytesSent > newCurrentBytesSent) { s_logger.warn(warning + "Stored bytes sent: " + oldCurrentBytesSent + ", new bytes sent: " + newCurrentBytesSent + "."); userStats.setNetBytesSent(oldNetBytesSent + oldCurrentBytesSent); } - + userStats.setCurrentBytesReceived(newCurrentBytesReceived); if (oldCurrentBytesReceived > newCurrentBytesReceived) { s_logger.warn(warning + "Stored bytes received: " + oldCurrentBytesReceived + ", new bytes received: " + newCurrentBytesReceived + "."); userStats.setNetBytesReceived(oldNetBytesReceived + oldCurrentBytesReceived); } - + if (_userStatsDao.update(userStats.getId(), userStats)) { s_logger.debug("Successfully updated stats for " + statsEntryIdentifier); } else { @@ -322,13 +330,8 @@ public class ExternalDeviceUsageManagerImpl extends ManagerBase implements Exter } else { s_logger.warn("Unable to find user stats entry for " + statsEntryIdentifier); } - - txn.commit(); - } catch (final Exception e) { - txn.rollback(); - throw new CloudRuntimeException("Problem getting stats after reboot/stop ", e); } - } + }); } protected class ExternalDeviceNetworkUsageTask extends ManagedContextRunnable { @@ -601,78 +604,78 @@ public class ExternalDeviceUsageManagerImpl extends ManagerBase implements Exter * Stats entries are created for source NAT IP addresses, static NAT rules, port forwarding rules, and load * balancing rules */ - private boolean manageStatsEntries(boolean create, long accountId, long zoneId, Network network, - HostVO externalFirewall, ExternalNetworkResourceUsageAnswer firewallAnswer, - HostVO externalLoadBalancer, ExternalNetworkResourceUsageAnswer lbAnswer) { - String accountErrorMsg = "Failed to update external network stats entry. Details: account ID = " + accountId; - Transaction txn = Transaction.open(Transaction.CLOUD_DB); + private boolean manageStatsEntries(final boolean create, final long accountId, final long zoneId, final Network network, + final HostVO externalFirewall, final ExternalNetworkResourceUsageAnswer firewallAnswer, + final HostVO externalLoadBalancer, final ExternalNetworkResourceUsageAnswer lbAnswer) { + final String accountErrorMsg = "Failed to update external network stats entry. Details: account ID = " + accountId; try { - txn.start(); - String networkErrorMsg = accountErrorMsg + ", network ID = " + network.getId(); - - boolean sharedSourceNat = false; - Map sourceNatCapabilities = _networkModel.getNetworkServiceCapabilities(network.getId(), Network.Service.SourceNat); - if (sourceNatCapabilities != null) { - String supportedSourceNatTypes = sourceNatCapabilities.get(Network.Capability.SupportedSourceNatTypes).toLowerCase(); - if (supportedSourceNatTypes.contains("zone")) { - sharedSourceNat = true; - } - } - - if (externalFirewall != null && firewallAnswer != null) { - if (!sharedSourceNat) { - // Manage the entry for this network's source NAT IP address - List sourceNatIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), true); - if (sourceNatIps.size() == 1) { - String publicIp = sourceNatIps.get(0).getAddress().addr(); - if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalFirewall.getId(), firewallAnswer, false)) { - throw new ExecutionException(networkErrorMsg + ", source NAT IP = " + publicIp); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + String networkErrorMsg = accountErrorMsg + ", network ID = " + network.getId(); + + boolean sharedSourceNat = false; + Map sourceNatCapabilities = _networkModel.getNetworkServiceCapabilities(network.getId(), Network.Service.SourceNat); + if (sourceNatCapabilities != null) { + String supportedSourceNatTypes = sourceNatCapabilities.get(Network.Capability.SupportedSourceNatTypes).toLowerCase(); + if (supportedSourceNatTypes.contains("zone")) { + sharedSourceNat = true; } } - - // Manage one entry for each static NAT rule in this network - List staticNatIps = _ipAddressDao.listStaticNatPublicIps(network.getId()); - for (IPAddressVO staticNatIp : staticNatIps) { - String publicIp = staticNatIp.getAddress().addr(); - if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalFirewall.getId(), firewallAnswer, false)) { - throw new ExecutionException(networkErrorMsg + ", static NAT rule public IP = " + publicIp); + + if (externalFirewall != null && firewallAnswer != null) { + if (!sharedSourceNat) { + // Manage the entry for this network's source NAT IP address + List sourceNatIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), true); + if (sourceNatIps.size() == 1) { + String publicIp = sourceNatIps.get(0).getAddress().addr(); + if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalFirewall.getId(), firewallAnswer, false)) { + throw new CloudRuntimeException(networkErrorMsg + ", source NAT IP = " + publicIp); + } + } + + // Manage one entry for each static NAT rule in this network + List staticNatIps = _ipAddressDao.listStaticNatPublicIps(network.getId()); + for (IPAddressVO staticNatIp : staticNatIps) { + String publicIp = staticNatIp.getAddress().addr(); + if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalFirewall.getId(), firewallAnswer, false)) { + throw new CloudRuntimeException(networkErrorMsg + ", static NAT rule public IP = " + publicIp); + } + } + + // Manage one entry for each port forwarding rule in this network + List portForwardingRules = _portForwardingRulesDao.listByNetwork(network.getId()); + for (PortForwardingRuleVO portForwardingRule : portForwardingRules) { + String publicIp = _networkModel.getIp(portForwardingRule.getSourceIpAddressId()).getAddress().addr(); + if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalFirewall.getId(), firewallAnswer, false)) { + throw new CloudRuntimeException(networkErrorMsg + ", port forwarding rule public IP = " + publicIp); + } + } + } else { + // Manage the account-wide entry for the external firewall + if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), null, externalFirewall.getId(), firewallAnswer, false)) { + throw new CloudRuntimeException(networkErrorMsg); + } } } - - // Manage one entry for each port forwarding rule in this network - List portForwardingRules = _portForwardingRulesDao.listByNetwork(network.getId()); - for (PortForwardingRuleVO portForwardingRule : portForwardingRules) { - String publicIp = _networkModel.getIp(portForwardingRule.getSourceIpAddressId()).getAddress().addr(); - if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalFirewall.getId(), firewallAnswer, false)) { - throw new ExecutionException(networkErrorMsg + ", port forwarding rule public IP = " + publicIp); + + // If an external load balancer is added, manage one entry for each load balancing rule in this network + if (externalLoadBalancer != null && lbAnswer != null) { + boolean inline = _networkModel.isNetworkInlineMode(network); + List loadBalancers = _loadBalancerDao.listByNetworkIdAndScheme(network.getId(), Scheme.Public); + for (LoadBalancerVO loadBalancer : loadBalancers) { + String publicIp = _networkModel.getIp(loadBalancer.getSourceIpAddressId()).getAddress().addr(); + if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalLoadBalancer.getId(), lbAnswer, inline)) { + throw new CloudRuntimeException(networkErrorMsg + ", load balancing rule public IP = " + publicIp); + } } } - } else { - // Manage the account-wide entry for the external firewall - if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), null, externalFirewall.getId(), firewallAnswer, false)) { - throw new ExecutionException(networkErrorMsg); - } } - } - - // If an external load balancer is added, manage one entry for each load balancing rule in this network - if (externalLoadBalancer != null && lbAnswer != null) { - boolean inline = _networkModel.isNetworkInlineMode(network); - List loadBalancers = _loadBalancerDao.listByNetworkIdAndScheme(network.getId(), Scheme.Public); - for (LoadBalancerVO loadBalancer : loadBalancers) { - String publicIp = _networkModel.getIp(loadBalancer.getSourceIpAddressId()).getAddress().addr(); - if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalLoadBalancer.getId(), lbAnswer, inline)) { - throw new ExecutionException(networkErrorMsg + ", load balancing rule public IP = " + publicIp); - } - } - } - return txn.commit(); + }); + return true; } catch (Exception e) { s_logger.warn("Exception: ", e); - txn.rollback(); return false; - } finally { - txn.close(); } } } diff --git a/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java index 629bef5eca1..32744ef187a 100644 --- a/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java +++ b/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java @@ -26,7 +26,6 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; - import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.response.ExternalFirewallResponse; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -108,6 +107,8 @@ import com.cloud.utils.component.AdapterBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.utils.net.UrlUtil; @@ -159,7 +160,7 @@ public abstract class ExternalFirewallDeviceManagerImpl extends AdapterBase impl @Override @DB - public ExternalFirewallDeviceVO addExternalFirewall(long physicalNetworkId, String url, String username, String password, String deviceName, ServerResource resource) { + public ExternalFirewallDeviceVO addExternalFirewall(long physicalNetworkId, String url, String username, String password, final String deviceName, ServerResource resource) { String guid; PhysicalNetworkVO pNetwork = null; NetworkDevice ntwkDevice = NetworkDevice.getNetworkDevice(deviceName); @@ -176,7 +177,7 @@ public abstract class ExternalFirewallDeviceManagerImpl extends AdapterBase impl } zoneId = pNetwork.getDataCenterId(); - PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(), ntwkDevice.getNetworkServiceProvder()); + final PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(), ntwkDevice.getNetworkServiceProvder()); if (ntwkSvcProvider == null ) { throw new CloudRuntimeException("Network Service Provider: " + ntwkDevice.getNetworkServiceProvder() + " is not enabled in the physical network: " + physicalNetworkId + "to add this device" ); @@ -204,7 +205,7 @@ public abstract class ExternalFirewallDeviceManagerImpl extends AdapterBase impl hostDetails.put("username", username); hostDetails.put("password", password); hostDetails.put("deviceName", deviceName); - Map configParams = new HashMap(); + final Map configParams = new HashMap(); UrlUtil.parseQueryParameters(uri.getQuery(), false, configParams); hostDetails.putAll(configParams); @@ -215,27 +216,29 @@ public abstract class ExternalFirewallDeviceManagerImpl extends AdapterBase impl throw new CloudRuntimeException(e.getMessage()); } - Host externalFirewall = _resourceMgr.addHost(zoneId, resource, Host.Type.ExternalFirewall, hostDetails); + final Host externalFirewall = _resourceMgr.addHost(zoneId, resource, Host.Type.ExternalFirewall, hostDetails); if (externalFirewall != null) { - Transaction txn = Transaction.currentTxn(); - txn.start(); + final PhysicalNetworkVO pNetworkFinal = pNetwork; + return Transaction.execute(new TransactionCallback() { + @Override + public ExternalFirewallDeviceVO doInTransaction(TransactionStatus status) { + boolean dedicatedUse = (configParams.get(ApiConstants.FIREWALL_DEVICE_DEDICATED) != null) ? Boolean.parseBoolean(configParams.get(ApiConstants.FIREWALL_DEVICE_DEDICATED)) : false; + long capacity = NumbersUtil.parseLong(configParams.get(ApiConstants.FIREWALL_DEVICE_CAPACITY), 0); + if (capacity == 0) { + capacity = _defaultFwCapacity; + } - boolean dedicatedUse = (configParams.get(ApiConstants.FIREWALL_DEVICE_DEDICATED) != null) ? Boolean.parseBoolean(configParams.get(ApiConstants.FIREWALL_DEVICE_DEDICATED)) : false; - long capacity = NumbersUtil.parseLong(configParams.get(ApiConstants.FIREWALL_DEVICE_CAPACITY), 0); - if (capacity == 0) { - capacity = _defaultFwCapacity; - } + ExternalFirewallDeviceVO fwDevice = new ExternalFirewallDeviceVO(externalFirewall.getId(), pNetworkFinal.getId(), ntwkSvcProvider.getProviderName(), + deviceName, capacity, dedicatedUse); - ExternalFirewallDeviceVO fwDevice = new ExternalFirewallDeviceVO(externalFirewall.getId(), pNetwork.getId(), ntwkSvcProvider.getProviderName(), - deviceName, capacity, dedicatedUse); + _externalFirewallDeviceDao.persist(fwDevice); - _externalFirewallDeviceDao.persist(fwDevice); + DetailVO hostDetail = new DetailVO(externalFirewall.getId(), ApiConstants.FIREWALL_DEVICE_ID, String.valueOf(fwDevice.getId())); + _hostDetailDao.persist(hostDetail); - DetailVO hostDetail = new DetailVO(externalFirewall.getId(), ApiConstants.FIREWALL_DEVICE_ID, String.valueOf(fwDevice.getId())); - _hostDetailDao.persist(hostDetail); - - txn.commit(); - return fwDevice; + return fwDevice; + } + }); } else { return null; } @@ -343,7 +346,6 @@ public abstract class ExternalFirewallDeviceManagerImpl extends AdapterBase impl @DB protected boolean freeFirewallForNetwork(Network network) { - Transaction txn = Transaction.currentTxn(); GlobalLock deviceMapLock = GlobalLock.getInternLock("NetworkFirewallDeviceMap"); try { if (deviceMapLock.lock(120)) { @@ -353,7 +355,6 @@ public abstract class ExternalFirewallDeviceManagerImpl extends AdapterBase impl _networkExternalFirewallDao.remove(fwDeviceForNetwork.getId()); } } catch (Exception exception) { - txn.rollback(); s_logger.error("Failed to release firewall device for the network" + network.getId() + " due to " + exception.getMessage()); return false; } finally { @@ -363,7 +364,6 @@ public abstract class ExternalFirewallDeviceManagerImpl extends AdapterBase impl } finally { deviceMapLock.releaseRef(); } - txn.commit(); return true; } diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java index dd4893030fe..6ca40c01e98 100644 --- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java +++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java @@ -27,7 +27,6 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; - import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.response.ExternalLoadBalancerResponse; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -118,6 +117,9 @@ import com.cloud.utils.component.AdapterBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackWithException; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.utils.net.UrlUtil; @@ -196,11 +198,11 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase @Override @DB public ExternalLoadBalancerDeviceVO addExternalLoadBalancer(long physicalNetworkId, String url, - String username, String password, String deviceName, ServerResource resource, boolean gslbProvider, - String gslbSitePublicIp, String gslbSitePrivateIp) { + String username, String password, final String deviceName, ServerResource resource, final boolean gslbProvider, + final String gslbSitePublicIp, final String gslbSitePrivateIp) { PhysicalNetworkVO pNetwork = null; - NetworkDevice ntwkDevice = NetworkDevice.getNetworkDevice(deviceName); + final NetworkDevice ntwkDevice = NetworkDevice.getNetworkDevice(deviceName); long zoneId; if ((ntwkDevice == null) || (url == null) || (username == null) || (resource == null) || (password == null)) { @@ -258,39 +260,41 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase UrlUtil.parseQueryParameters(uri.getQuery(), false, configParams); hostDetails.putAll(configParams); - Transaction txn = Transaction.currentTxn(); try { resource.configure(hostName, hostDetails); - Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.ExternalLoadBalancer, hostDetails); + final Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.ExternalLoadBalancer, hostDetails); if (host != null) { - boolean dedicatedUse = (configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED) != null) ? Boolean.parseBoolean(configParams + final boolean dedicatedUse = (configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED) != null) ? Boolean.parseBoolean(configParams .get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED)) : false; long capacity = NumbersUtil.parseLong(configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_CAPACITY), 0); if (capacity == 0) { capacity = _defaultLbCapacity; } - ExternalLoadBalancerDeviceVO lbDeviceVO; - txn.start(); - lbDeviceVO = new ExternalLoadBalancerDeviceVO(host.getId(), pNetwork.getId(), ntwkDevice.getNetworkServiceProvder(), - deviceName, capacity, dedicatedUse, gslbProvider); - if (gslbProvider) { - lbDeviceVO.setGslbSitePublicIP(gslbSitePublicIp); - lbDeviceVO.setGslbSitePrivateIP(gslbSitePrivateIp); - } - _externalLoadBalancerDeviceDao.persist(lbDeviceVO); - DetailVO hostDetail = new DetailVO(host.getId(), ApiConstants.LOAD_BALANCER_DEVICE_ID, String.valueOf(lbDeviceVO.getId())); - _hostDetailDao.persist(hostDetail); + final long capacityFinal = capacity; + final PhysicalNetworkVO pNetworkFinal = pNetwork; + return Transaction.execute(new TransactionCallback() { + @Override + public ExternalLoadBalancerDeviceVO doInTransaction(TransactionStatus status) { + ExternalLoadBalancerDeviceVO lbDeviceVO = new ExternalLoadBalancerDeviceVO(host.getId(), pNetworkFinal.getId(), ntwkDevice.getNetworkServiceProvder(), + deviceName, capacityFinal, dedicatedUse, gslbProvider); + if (gslbProvider) { + lbDeviceVO.setGslbSitePublicIP(gslbSitePublicIp); + lbDeviceVO.setGslbSitePrivateIP(gslbSitePrivateIp); + } + _externalLoadBalancerDeviceDao.persist(lbDeviceVO); + DetailVO hostDetail = new DetailVO(host.getId(), ApiConstants.LOAD_BALANCER_DEVICE_ID, String.valueOf(lbDeviceVO.getId())); + _hostDetailDao.persist(hostDetail); - txn.commit(); - return lbDeviceVO; + return lbDeviceVO; + } + }); } else { throw new CloudRuntimeException("Failed to add load balancer device due to internal error."); } } catch (ConfigurationException e) { - txn.rollback(); throw new CloudRuntimeException(e.getMessage()); } } @@ -402,7 +406,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase } @DB - protected ExternalLoadBalancerDeviceVO allocateLoadBalancerForNetwork(Network guestConfig) throws InsufficientCapacityException { + protected ExternalLoadBalancerDeviceVO allocateLoadBalancerForNetwork(final Network guestConfig) throws InsufficientCapacityException { boolean retry = true; boolean tryLbProvisioning = false; ExternalLoadBalancerDeviceVO lbDevice = null; @@ -412,34 +416,33 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase while (retry) { GlobalLock deviceMapLock = GlobalLock.getInternLock("LoadBalancerAllocLock"); - Transaction txn = Transaction.currentTxn(); try { if (deviceMapLock.lock(120)) { try { - boolean dedicatedLB = offering.getDedicatedLB(); // does network offering supports a dedicated -// load balancer? - long lbDeviceId; + final boolean dedicatedLB = offering.getDedicatedLB(); // does network offering supports a dedicated load balancer? - txn.start(); try { - // FIXME: should the device allocation be done during network implement phase or do a - // lazy allocation when first rule for the network is configured?? - - // find a load balancer device for this network as per the network offering - lbDevice = findSuitableLoadBalancerForNetwork(guestConfig, dedicatedLB); - lbDeviceId = lbDevice.getId(); - - // persist the load balancer device id that will be used for this network. Once a network - // is implemented on a LB device then later on all rules will be programmed on to same -// device - NetworkExternalLoadBalancerVO networkLB = new NetworkExternalLoadBalancerVO(guestConfig.getId(), lbDeviceId); - _networkExternalLBDao.persist(networkLB); - - // mark device to be either dedicated or shared use - lbDevice.setAllocationState(dedicatedLB ? LBDeviceAllocationState.Dedicated : LBDeviceAllocationState.Shared); - _externalLoadBalancerDeviceDao.update(lbDeviceId, lbDevice); - - txn.commit(); + lbDevice = Transaction.execute(new TransactionCallbackWithException() { + @Override + public ExternalLoadBalancerDeviceVO doInTransaction(TransactionStatus status) throws InsufficientCapacityException { + // FIXME: should the device allocation be done during network implement phase or do a + // lazy allocation when first rule for the network is configured?? + + // find a load balancer device for this network as per the network offering + ExternalLoadBalancerDeviceVO lbDevice = findSuitableLoadBalancerForNetwork(guestConfig, dedicatedLB); + long lbDeviceId = lbDevice.getId(); + + // persist the load balancer device id that will be used for this network. Once a network + // is implemented on a LB device then later on all rules will be programmed on to same device + NetworkExternalLoadBalancerVO networkLB = new NetworkExternalLoadBalancerVO(guestConfig.getId(), lbDeviceId); + _networkExternalLBDao.persist(networkLB); + + // mark device to be either dedicated or shared use + lbDevice.setAllocationState(dedicatedLB ? LBDeviceAllocationState.Dedicated : LBDeviceAllocationState.Shared); + _externalLoadBalancerDeviceDao.update(lbDeviceId, lbDevice); + return lbDevice; + } + }); // allocated load balancer for the network, so skip retry tryLbProvisioning = false; @@ -448,28 +451,22 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase // if already attempted to provision load balancer then throw out of capacity exception, if (tryLbProvisioning) { retry = false; - // TODO: throwing warning instead of error for now as its possible another provider can -// service this network + // TODO: throwing warning instead of error for now as its possible another provider can service this network s_logger.warn("There are no load balancer device with the capacity for implementing this network"); throw exception; } else { - tryLbProvisioning = true; // if possible provision a LB appliance in to the physical -// network + tryLbProvisioning = true; // if possible provision a LB appliance in to the physical network } } } finally { deviceMapLock.unlock(); - if (lbDevice == null) { - txn.rollback(); - } } } } finally { deviceMapLock.releaseRef(); } - // there are no LB devices or there is no free capacity on the devices in the physical network so provision -// a new LB appliance + // there are no LB devices or there is no free capacity on the devices in the physical network so provision a new LB appliance if (tryLbProvisioning) { // check if LB appliance can be dynamically provisioned List providerLbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, @@ -477,8 +474,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase if ((providerLbDevices != null) && (!providerLbDevices.isEmpty())) { for (ExternalLoadBalancerDeviceVO lbProviderDevice : providerLbDevices) { if (lbProviderDevice.getState() == LBDeviceState.Enabled) { - // acquire a private IP from the data center which will be used as management IP of -// provisioned LB appliance, + // acquire a private IP from the data center which will be used as management IP of provisioned LB appliance, DataCenterIpAddressVO dcPrivateIp = _dcDao.allocatePrivateIpAddress(guestConfig.getDataCenterId(), lbProviderDevice.getUuid()); if (dcPrivateIp == null) { throw new InsufficientNetworkCapacityException("failed to acquire a priavate IP in the zone " + guestConfig.getDataCenterId() + @@ -509,13 +505,11 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase String publicIf = createLbAnswer.getPublicInterface(); String privateIf = createLbAnswer.getPrivateInterface(); - // we have provisioned load balancer so add the appliance as cloudstack provisioned external -// load balancer + // we have provisioned load balancer so add the appliance as cloudstack provisioned external load balancer String dedicatedLb = offering.getDedicatedLB() ? "true" : "false"; String capacity = Long.toString(lbProviderDevice.getCapacity()); - // acquire a public IP to associate with lb appliance (used as subnet IP to make the -// appliance part of private network) + // acquire a public IP to associate with lb appliance (used as subnet IP to make the appliance part of private network) PublicIp publicIp = _ipAddrMgr.assignPublicIpAddress(guestConfig.getDataCenterId(), null, _accountMgr.getSystemAccount(), @@ -542,8 +536,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase } if (lbAppliance != null) { - // mark the load balancer as cloudstack managed and set parent host id on which lb -// appliance is provisioned + // mark the load balancer as cloudstack managed and set parent host id on which lb appliance is provisioned ExternalLoadBalancerDeviceVO managedLb = _externalLoadBalancerDeviceDao.findById(lbAppliance.getId()); managedLb.setIsManagedDevice(true); managedLb.setParentHostId(lbProviderDevice.getHostId()); @@ -557,8 +550,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase if (answer == null || !answer.getResult()) { s_logger.warn("Failed to destroy load balancer appliance created"); } else { - // release the public & private IP back to dc pool, as the load balancer -// appliance is now destroyed + // release the public & private IP back to dc pool, as the load balancer appliance is now destroyed _dcDao.releasePrivateIpAddress(lbIP, guestConfig.getDataCenterId(), null); _ipAddrMgr.disassociatePublicIpAddress(publicIp.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount()); } @@ -656,34 +648,40 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase } @DB - protected boolean freeLoadBalancerForNetwork(Network guestConfig) { - Transaction txn = Transaction.currentTxn(); + protected boolean freeLoadBalancerForNetwork(final Network guestConfig) { GlobalLock deviceMapLock = GlobalLock.getInternLock("LoadBalancerAllocLock"); try { if (deviceMapLock.lock(120)) { - txn.start(); - // since network is shutdown remove the network mapping to the load balancer device - NetworkExternalLoadBalancerVO networkLBDevice = _networkExternalLBDao.findByNetworkId(guestConfig.getId()); - long lbDeviceId = networkLBDevice.getExternalLBDeviceId(); - _networkExternalLBDao.remove(networkLBDevice.getId()); + ExternalLoadBalancerDeviceVO lbDevice = Transaction.execute(new TransactionCallback() { + @Override + public ExternalLoadBalancerDeviceVO doInTransaction(TransactionStatus status) { + // since network is shutdown remove the network mapping to the load balancer device + NetworkExternalLoadBalancerVO networkLBDevice = _networkExternalLBDao.findByNetworkId(guestConfig.getId()); + long lbDeviceId = networkLBDevice.getExternalLBDeviceId(); + _networkExternalLBDao.remove(networkLBDevice.getId()); - List ntwksMapped = _networkExternalLBDao.listByLoadBalancerDeviceId(networkLBDevice.getExternalLBDeviceId()); - ExternalLoadBalancerDeviceVO lbDevice = _externalLoadBalancerDeviceDao.findById(lbDeviceId); - boolean lbInUse = !(ntwksMapped == null || ntwksMapped.isEmpty()); - boolean lbCloudManaged = lbDevice.getIsManagedDevice(); + List ntwksMapped = _networkExternalLBDao.listByLoadBalancerDeviceId(networkLBDevice.getExternalLBDeviceId()); + ExternalLoadBalancerDeviceVO lbDevice = _externalLoadBalancerDeviceDao.findById(lbDeviceId); + boolean lbInUse = !(ntwksMapped == null || ntwksMapped.isEmpty()); + boolean lbCloudManaged = lbDevice.getIsManagedDevice(); - if (!lbInUse && !lbCloudManaged) { - // this is the last network mapped to the load balancer device so set device allocation state to be -// free - lbDevice.setAllocationState(LBDeviceAllocationState.Free); - _externalLoadBalancerDeviceDao.update(lbDevice.getId(), lbDevice); - } + if (!lbInUse && !lbCloudManaged) { + // this is the last network mapped to the load balancer device so set device allocation state to be free + lbDevice.setAllocationState(LBDeviceAllocationState.Free); + _externalLoadBalancerDeviceDao.update(lbDevice.getId(), lbDevice); + } - // commit the changes before sending agent command to destroy cloudstack managed LB - txn.commit(); + // commit the changes before sending agent command to destroy cloudstack managed LB + if (!lbInUse && lbCloudManaged) { + return lbDevice; + } else { + return null; + } + } + }); - if (!lbInUse && lbCloudManaged) { + if (lbDevice != null) { // send DestroyLoadBalancerApplianceCommand to the host where load balancer appliance is provisioned Host lbHost = _hostDao.findById(lbDevice.getHostId()); String lbIP = lbHost.getPrivateIpAddress(); @@ -723,7 +721,6 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase return false; } } catch (Exception exception) { - txn.rollback(); s_logger.error("Failed to release load balancer device for the network" + guestConfig.getId() + " due to " + exception.getMessage()); } finally { deviceMapLock.releaseRef(); diff --git a/server/src/com/cloud/network/IpAddressManagerImpl.java b/server/src/com/cloud/network/IpAddressManagerImpl.java index 74f316bb12c..8619ae178cd 100644 --- a/server/src/com/cloud/network/IpAddressManagerImpl.java +++ b/server/src/com/cloud/network/IpAddressManagerImpl.java @@ -29,7 +29,6 @@ import java.util.UUID; import javax.inject.Inject; import org.apache.log4j.Logger; - import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.context.CallContext; @@ -133,17 +132,24 @@ import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; import com.cloud.utils.Journal; import com.cloud.utils.Pair; +import com.cloud.utils.Ternary; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.EntityManager; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GlobalLock; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionCallbackWithException; import com.cloud.utils.db.JoinBuilder.JoinType; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.exception.ExceptionUtil; import com.cloud.utils.net.Ip; import com.cloud.utils.net.NetUtils; import com.cloud.vm.Nic; @@ -609,28 +615,30 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @DB @Override - public boolean releasePortableIpAddress(long addrId) { - Transaction txn = Transaction.currentTxn(); - GlobalLock portableIpLock = GlobalLock.getInternLock("PortablePublicIpRange"); + public boolean releasePortableIpAddress(final long addrId) { + final GlobalLock portableIpLock = GlobalLock.getInternLock("PortablePublicIpRange"); - txn.start(); try { - portableIpLock.lock(5); - IPAddressVO ip = _ipAddressDao.findById(addrId); + return Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + portableIpLock.lock(5); + IPAddressVO ip = _ipAddressDao.findById(addrId); - // unassign portable IP - PortableIpVO portableIp = _portableIpDao.findByIpAddress(ip.getAddress().addr()); - _portableIpDao.unassignIpAddress(portableIp.getId()); + // unassign portable IP + PortableIpVO portableIp = _portableIpDao.findByIpAddress(ip.getAddress().addr()); + _portableIpDao.unassignIpAddress(portableIp.getId()); - // removed the provisioned vlan - VlanVO vlan = _vlanDao.findById(ip.getVlanId()); - _vlanDao.remove(vlan.getId()); + // removed the provisioned vlan + VlanVO vlan = _vlanDao.findById(ip.getVlanId()); + _vlanDao.remove(vlan.getId()); - // remove the provisioned public ip address - _ipAddressDao.remove(ip.getId()); + // remove the provisioned public ip address + _ipAddressDao.remove(ip.getId()); - txn.commit(); - return true; + return true; + } + }); } finally { portableIpLock.releaseRef(); } @@ -649,135 +657,138 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage } @DB - public PublicIp fetchNewPublicIp(long dcId, Long podId, List vlanDbIds, Account owner, VlanType vlanUse, Long guestNetworkId, boolean sourceNat, boolean assign, - String requestedIp, boolean isSystem, Long vpcId) throws InsufficientAddressCapacityException { - StringBuilder errorMessage = new StringBuilder("Unable to get ip adress in "); - boolean fetchFromDedicatedRange = false; - List dedicatedVlanDbIds = new ArrayList(); - List nonDedicatedVlanDbIds = new ArrayList(); + public PublicIp fetchNewPublicIp(final long dcId, final Long podId, final List vlanDbIds, final Account owner, final VlanType vlanUse, final Long guestNetworkId, final boolean sourceNat, final boolean assign, + final String requestedIp, final boolean isSystem, final Long vpcId) throws InsufficientAddressCapacityException { + IPAddressVO addr = Transaction.execute(new TransactionCallbackWithException() { + @Override + public IPAddressVO doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException { + StringBuilder errorMessage = new StringBuilder("Unable to get ip adress in "); + boolean fetchFromDedicatedRange = false; + List dedicatedVlanDbIds = new ArrayList(); + List nonDedicatedVlanDbIds = new ArrayList(); - Transaction txn = Transaction.currentTxn(); - txn.start(); - SearchCriteria sc = null; - if (podId != null) { - sc = AssignIpAddressFromPodVlanSearch.create(); - sc.setJoinParameters("podVlanMapSB", "podId", podId); - errorMessage.append(" pod id=" + podId); - } else { - sc = AssignIpAddressSearch.create(); - errorMessage.append(" zone id=" + dcId); - } + SearchCriteria sc = null; + if (podId != null) { + sc = AssignIpAddressFromPodVlanSearch.create(); + sc.setJoinParameters("podVlanMapSB", "podId", podId); + errorMessage.append(" pod id=" + podId); + } else { + sc = AssignIpAddressSearch.create(); + errorMessage.append(" zone id=" + dcId); + } - // If owner has dedicated Public IP ranges, fetch IP from the dedicated range - // Otherwise fetch IP from the system pool - List maps = _accountVlanMapDao.listAccountVlanMapsByAccount(owner.getId()); - for (AccountVlanMapVO map : maps) { - if (vlanDbIds == null || vlanDbIds.contains(map.getVlanDbId())) - dedicatedVlanDbIds.add(map.getVlanDbId()); - } - List nonDedicatedVlans = _vlanDao.listZoneWideNonDedicatedVlans(dcId); - for (VlanVO nonDedicatedVlan : nonDedicatedVlans) { - if (vlanDbIds == null || vlanDbIds.contains(nonDedicatedVlan.getId())) - nonDedicatedVlanDbIds.add(nonDedicatedVlan.getId()); - } - if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) { - fetchFromDedicatedRange = true; - sc.setParameters("vlanId", dedicatedVlanDbIds.toArray()); - errorMessage.append(", vlanId id=" + dedicatedVlanDbIds.toArray()); - } else if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) { - sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray()); - errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray()); - } else { - if (podId != null) { - InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId); - ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid()); - throw ex; + // If owner has dedicated Public IP ranges, fetch IP from the dedicated range + // Otherwise fetch IP from the system pool + List maps = _accountVlanMapDao.listAccountVlanMapsByAccount(owner.getId()); + for (AccountVlanMapVO map : maps) { + if (vlanDbIds == null || vlanDbIds.contains(map.getVlanDbId())) + dedicatedVlanDbIds.add(map.getVlanDbId()); + } + List nonDedicatedVlans = _vlanDao.listZoneWideNonDedicatedVlans(dcId); + for (VlanVO nonDedicatedVlan : nonDedicatedVlans) { + if (vlanDbIds == null || vlanDbIds.contains(nonDedicatedVlan.getId())) + nonDedicatedVlanDbIds.add(nonDedicatedVlan.getId()); + } + if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) { + fetchFromDedicatedRange = true; + sc.setParameters("vlanId", dedicatedVlanDbIds.toArray()); + errorMessage.append(", vlanId id=" + dedicatedVlanDbIds.toArray()); + } else if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) { + sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray()); + errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray()); + } else { + if (podId != null) { + InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId); + ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid()); + throw ex; + } + s_logger.warn(errorMessage.toString()); + InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId); + ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid()); + throw ex; + } + + sc.setParameters("dc", dcId); + + DataCenter zone = _entityMgr.findById(DataCenter.class, dcId); + + // for direct network take ip addresses only from the vlans belonging to the network + if (vlanUse == VlanType.DirectAttached) { + sc.setJoinParameters("vlan", "networkId", guestNetworkId); + errorMessage.append(", network id=" + guestNetworkId); + } + sc.setJoinParameters("vlan", "type", vlanUse); + + if (requestedIp != null) { + sc.addAnd("address", SearchCriteria.Op.EQ, requestedIp); + errorMessage.append(": requested ip " + requestedIp + " is not available"); + } + + Filter filter = new Filter(IPAddressVO.class, "vlanId", true, 0l, 1l); + + List addrs = _ipAddressDao.lockRows(sc, filter, true); + + // If all the dedicated IPs of the owner are in use fetch an IP from the system pool + if (addrs.size() == 0 && fetchFromDedicatedRange) { + // Verify if account is allowed to acquire IPs from the system + boolean useSystemIps = UseSystemPublicIps.valueIn(owner.getId()); + if (useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) { + fetchFromDedicatedRange = false; + sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray()); + errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray()); + addrs = _ipAddressDao.lockRows(sc, filter, true); + } + } + + if (addrs.size() == 0) { + if (podId != null) { + InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId); + // for now, we hardcode the table names, but we should ideally do a lookup for the tablename from the VO object. + ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid()); + throw ex; + } + s_logger.warn(errorMessage.toString()); + InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId); + ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid()); + throw ex; + } + + assert (addrs.size() == 1) : "Return size is incorrect: " + addrs.size(); + + if (!fetchFromDedicatedRange) { + // Check that the maximum number of public IPs for the given accountId will not be exceeded + try { + _resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip); + } catch (ResourceAllocationException ex) { + s_logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + owner); + throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded."); + } + } + + IPAddressVO addr = addrs.get(0); + addr.setSourceNat(sourceNat); + addr.setAllocatedTime(new Date()); + addr.setAllocatedInDomainId(owner.getDomainId()); + addr.setAllocatedToAccountId(owner.getId()); + addr.setSystem(isSystem); + + if (assign) { + markPublicIpAsAllocated(addr); + } else { + addr.setState(IpAddress.State.Allocating); + } + addr.setState(assign ? IpAddress.State.Allocated : IpAddress.State.Allocating); + + if (vlanUse != VlanType.DirectAttached) { + addr.setAssociatedWithNetworkId(guestNetworkId); + addr.setVpcId(vpcId); + } + + _ipAddressDao.update(addr.getId(), addr); + + return addr; } - s_logger.warn(errorMessage.toString()); - InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId); - ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid()); - throw ex; - } - - sc.setParameters("dc", dcId); - - DataCenter zone = _entityMgr.findById(DataCenter.class, dcId); - - // for direct network take ip addresses only from the vlans belonging to the network - if (vlanUse == VlanType.DirectAttached) { - sc.setJoinParameters("vlan", "networkId", guestNetworkId); - errorMessage.append(", network id=" + guestNetworkId); - } - sc.setJoinParameters("vlan", "type", vlanUse); - - if (requestedIp != null) { - sc.addAnd("address", SearchCriteria.Op.EQ, requestedIp); - errorMessage.append(": requested ip " + requestedIp + " is not available"); - } - - Filter filter = new Filter(IPAddressVO.class, "vlanId", true, 0l, 1l); - - List addrs = _ipAddressDao.lockRows(sc, filter, true); - - // If all the dedicated IPs of the owner are in use fetch an IP from the system pool - if (addrs.size() == 0 && fetchFromDedicatedRange) { - // Verify if account is allowed to acquire IPs from the system - boolean useSystemIps = UseSystemPublicIps.valueIn(owner.getId()); - if (useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) { - fetchFromDedicatedRange = false; - sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray()); - errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray()); - addrs = _ipAddressDao.lockRows(sc, filter, true); - } - } - - if (addrs.size() == 0) { - if (podId != null) { - InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId); - // for now, we hardcode the table names, but we should ideally do a lookup for the tablename from the VO object. - ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid()); - throw ex; - } - s_logger.warn(errorMessage.toString()); - InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId); - ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid()); - throw ex; - } - - assert (addrs.size() == 1) : "Return size is incorrect: " + addrs.size(); - - if (!fetchFromDedicatedRange) { - // Check that the maximum number of public IPs for the given accountId will not be exceeded - try { - _resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip); - } catch (ResourceAllocationException ex) { - s_logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + owner); - throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded."); - } - } - - IPAddressVO addr = addrs.get(0); - addr.setSourceNat(sourceNat); - addr.setAllocatedTime(new Date()); - addr.setAllocatedInDomainId(owner.getDomainId()); - addr.setAllocatedToAccountId(owner.getId()); - addr.setSystem(isSystem); - - if (assign) { - markPublicIpAsAllocated(addr); - } else { - addr.setState(IpAddress.State.Allocating); - } - addr.setState(assign ? IpAddress.State.Allocated : IpAddress.State.Allocating); - - if (vlanUse != VlanType.DirectAttached) { - addr.setAssociatedWithNetworkId(guestNetworkId); - addr.setVpcId(vpcId); - } - - _ipAddressDao.update(addr.getId(), addr); - - txn.commit(); + }); if (vlanUse == VlanType.VirtualNetwork) { _firewallMgr.addSystemFirewallRules(addr, owner); @@ -788,44 +799,43 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @DB @Override - public void markPublicIpAsAllocated(IPAddressVO addr) { + public void markPublicIpAsAllocated(final IPAddressVO addr) { assert (addr.getState() == IpAddress.State.Allocating || addr.getState() == IpAddress.State.Free) : "Unable to transition from state " + addr.getState() + " to " + IpAddress.State.Allocated; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + Account owner = _accountMgr.getAccount(addr.getAllocatedToAccountId()); - Transaction txn = Transaction.currentTxn(); + addr.setState(IpAddress.State.Allocated); + _ipAddressDao.update(addr.getId(), addr); - Account owner = _accountMgr.getAccount(addr.getAllocatedToAccountId()); + // Save usage event + if (owner.getAccountId() != Account.ACCOUNT_ID_SYSTEM) { + VlanVO vlan = _vlanDao.findById(addr.getVlanId()); - txn.start(); - addr.setState(IpAddress.State.Allocated); - _ipAddressDao.update(addr.getId(), addr); + String guestType = vlan.getVlanType().toString(); - // Save usage event - if (owner.getAccountId() != Account.ACCOUNT_ID_SYSTEM) { - VlanVO vlan = _vlanDao.findById(addr.getVlanId()); + if (!isIpDedicated(addr)) { + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN, + owner.getId(), + addr.getDataCenterId(), + addr.getId(), + addr.getAddress().toString(), + addr.isSourceNat(), + guestType, + addr.getSystem(), + addr.getClass().getName(), + addr.getUuid()); + } - String guestType = vlan.getVlanType().toString(); - - if (!isIpDedicated(addr)) { - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN, - owner.getId(), - addr.getDataCenterId(), - addr.getId(), - addr.getAddress().toString(), - addr.isSourceNat(), - guestType, - addr.getSystem(), - addr.getClass().getName(), - addr.getUuid()); + if (updateIpResourceCount(addr)) { + _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.public_ip); + } + } } - - if (updateIpResourceCount(addr)) { - _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.public_ip); - } - } - - txn.commit(); + }); } private boolean isIpDedicated(IPAddressVO addr) { @@ -855,35 +865,38 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @DB @Override - public PublicIp assignDedicateIpAddress(Account owner, Long guestNtwkId, Long vpcId, long dcId, boolean isSourceNat) throws ConcurrentOperationException, + public PublicIp assignDedicateIpAddress(Account owner, final Long guestNtwkId, final Long vpcId, final long dcId, final boolean isSourceNat) throws ConcurrentOperationException, InsufficientAddressCapacityException { - long ownerId = owner.getId(); + final long ownerId = owner.getId(); PublicIp ip = null; - Transaction txn = Transaction.currentTxn(); try { - txn.start(); + ip = Transaction.execute(new TransactionCallbackWithException() { + @Override + public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException { + Account owner = _accountDao.acquireInLockTable(ownerId); - owner = _accountDao.acquireInLockTable(ownerId); + if (owner == null) { + // this ownerId comes from owner or type Account. See the class "AccountVO" and the annotations in that class + // to get the table name and field name that is queried to fill this ownerid. + ConcurrentOperationException ex = new ConcurrentOperationException("Unable to lock account"); + throw ex; + } + if (s_logger.isDebugEnabled()) { + s_logger.debug("lock account " + ownerId + " is acquired"); + } - if (owner == null) { - // this ownerId comes from owner or type Account. See the class "AccountVO" and the annotations in that class - // to get the table name and field name that is queried to fill this ownerid. - ConcurrentOperationException ex = new ConcurrentOperationException("Unable to lock account"); - throw ex; - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("lock account " + ownerId + " is acquired"); - } + PublicIp ip = fetchNewPublicIp(dcId, null, null, owner, VlanType.VirtualNetwork, guestNtwkId, isSourceNat, false, null, false, vpcId); + IPAddressVO publicIp = ip.ip(); - ip = fetchNewPublicIp(dcId, null, null, owner, VlanType.VirtualNetwork, guestNtwkId, isSourceNat, false, null, false, vpcId); - IPAddressVO publicIp = ip.ip(); + markPublicIpAsAllocated(publicIp); + _ipAddressDao.update(publicIp.getId(), publicIp); - markPublicIpAsAllocated(publicIp); - _ipAddressDao.update(publicIp.getId(), publicIp); + return ip; + } + }); - txn.commit(); return ip; } finally { if (owner != null) { @@ -894,7 +907,6 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage _accountDao.releaseFromLockTable(ownerId); } if (ip == null) { - txn.rollback(); s_logger.error("Unable to get source nat ip address for account " + ownerId); } } @@ -977,11 +989,11 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @DB @Override - public IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, long callerUserId, DataCenter zone) throws ConcurrentOperationException, + public IpAddress allocateIp(final Account ipOwner, final boolean isSystem, Account caller, long callerUserId, final DataCenter zone) throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException { - VlanType vlanType = VlanType.VirtualNetwork; - boolean assign = false; + final VlanType vlanType = VlanType.VirtualNetwork; + final boolean assign = false; if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) { // zone is of type DataCenter. See DataCenterVO.java. @@ -992,7 +1004,6 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage PublicIp ip = null; - Transaction txn = Transaction.currentTxn(); Account accountToLock = null; try { if (s_logger.isDebugEnabled()) { @@ -1008,21 +1019,25 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage s_logger.debug("Associate IP address lock acquired"); } - txn.start(); + ip = Transaction.execute(new TransactionCallbackWithException() { + @Override + public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException { + PublicIp ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, false, assign, null, isSystem, null); - ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, false, assign, null, isSystem, null); + if (ip == null) { + InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zone.getId()); + ex.addProxyObject(ApiDBUtils.findZoneById(zone.getId()).getUuid()); + throw ex; + } + CallContext.current().setEventDetails("Ip Id: " + ip.getId()); + Ip ipAddress = ip.getAddress(); - if (ip == null) { - InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zone.getId()); - ex.addProxyObject(ApiDBUtils.findZoneById(zone.getId()).getUuid()); - throw ex; - } - CallContext.current().setEventDetails("Ip Id: " + ip.getId()); - Ip ipAddress = ip.getAddress(); + s_logger.debug("Got " + ipAddress + " to assign for account " + ipOwner.getId() + " in zone " + zone.getId()); - s_logger.debug("Got " + ipAddress + " to assign for account " + ipOwner.getId() + " in zone " + zone.getId()); + return ip; + } + }); - txn.commit(); } finally { if (accountToLock != null) { if (s_logger.isDebugEnabled()) { @@ -1037,75 +1052,77 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @Override @DB - public IpAddress allocatePortableIp(Account ipOwner, Account caller, long dcId, Long networkId, Long vpcID) throws ConcurrentOperationException, ResourceAllocationException, + public IpAddress allocatePortableIp(final Account ipOwner, Account caller, final long dcId, final Long networkId, final Long vpcID) throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException { - Transaction txn = Transaction.currentTxn(); GlobalLock portableIpLock = GlobalLock.getInternLock("PortablePublicIpRange"); - PortableIpVO allocatedPortableIp; IPAddressVO ipaddr; try { portableIpLock.lock(5); - txn.start(); + ipaddr = Transaction.execute(new TransactionCallbackWithException() { + @Override + public IPAddressVO doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException { + PortableIpVO allocatedPortableIp; - List portableIpVOs = _portableIpDao.listByRegionIdAndState(1, PortableIp.State.Free); - if (portableIpVOs == null || portableIpVOs.isEmpty()) { - InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available portable IP addresses", Region.class, new Long(1)); - throw ex; - } + List portableIpVOs = _portableIpDao.listByRegionIdAndState(1, PortableIp.State.Free); + if (portableIpVOs == null || portableIpVOs.isEmpty()) { + InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available portable IP addresses", Region.class, new Long(1)); + throw ex; + } + + // allocate first portable IP to the user + allocatedPortableIp = portableIpVOs.get(0); + allocatedPortableIp.setAllocatedTime(new Date()); + allocatedPortableIp.setAllocatedToAccountId(ipOwner.getAccountId()); + allocatedPortableIp.setAllocatedInDomainId(ipOwner.getDomainId()); + allocatedPortableIp.setState(PortableIp.State.Allocated); + _portableIpDao.update(allocatedPortableIp.getId(), allocatedPortableIp); + + // To make portable IP available as a zone level resource we need to emulate portable IP's (which are + // provisioned at region level) as public IP provisioned in a zone. user_ip_address and vlan combo give the + // identity of a public IP in zone. Create entry for portable ip in these tables. + + // provision portable IP range VLAN into the zone + long physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(dcId, TrafficType.Public).getId(); + Network network = _networkModel.getSystemNetworkByZoneAndTrafficType(dcId, TrafficType.Public); + String range = allocatedPortableIp.getAddress() + "-" + allocatedPortableIp.getAddress(); + VlanVO vlan = new VlanVO(VlanType.VirtualNetwork, + allocatedPortableIp.getVlan(), + allocatedPortableIp.getGateway(), + allocatedPortableIp.getNetmask(), + dcId, + range, + network.getId(), + physicalNetworkId, + null, + null, + null); + vlan = _vlanDao.persist(vlan); - // allocate first portable IP to the user - allocatedPortableIp = portableIpVOs.get(0); - allocatedPortableIp.setAllocatedTime(new Date()); - allocatedPortableIp.setAllocatedToAccountId(ipOwner.getAccountId()); - allocatedPortableIp.setAllocatedInDomainId(ipOwner.getDomainId()); - allocatedPortableIp.setState(PortableIp.State.Allocated); - _portableIpDao.update(allocatedPortableIp.getId(), allocatedPortableIp); + // provision the portable IP in to user_ip_address table + IPAddressVO ipaddr = new IPAddressVO(new Ip(allocatedPortableIp.getAddress()), dcId, networkId, vpcID, physicalNetworkId, network.getId(), vlan.getId(), true); + ipaddr.setState(State.Allocated); + ipaddr.setAllocatedTime(new Date()); + ipaddr.setAllocatedInDomainId(ipOwner.getDomainId()); + ipaddr.setAllocatedToAccountId(ipOwner.getId()); + ipaddr = _ipAddressDao.persist(ipaddr); - // To make portable IP available as a zone level resource we need to emulate portable IP's (which are - // provisioned at region level) as public IP provisioned in a zone. user_ip_address and vlan combo give the - // identity of a public IP in zone. Create entry for portable ip in these tables. - - // provision portable IP range VLAN into the zone - long physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(dcId, TrafficType.Public).getId(); - Network network = _networkModel.getSystemNetworkByZoneAndTrafficType(dcId, TrafficType.Public); - String range = allocatedPortableIp.getAddress() + "-" + allocatedPortableIp.getAddress(); - VlanVO vlan = new VlanVO(VlanType.VirtualNetwork, - allocatedPortableIp.getVlan(), - allocatedPortableIp.getGateway(), - allocatedPortableIp.getNetmask(), - dcId, - range, - network.getId(), - physicalNetworkId, - null, - null, - null); - vlan = _vlanDao.persist(vlan); - - // provision the portable IP in to user_ip_address table - ipaddr = new IPAddressVO(new Ip(allocatedPortableIp.getAddress()), dcId, networkId, vpcID, physicalNetworkId, network.getId(), vlan.getId(), true); - ipaddr.setState(State.Allocated); - ipaddr.setAllocatedTime(new Date()); - ipaddr.setAllocatedInDomainId(ipOwner.getDomainId()); - ipaddr.setAllocatedToAccountId(ipOwner.getId()); - ipaddr = _ipAddressDao.persist(ipaddr); - - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_PORTABLE_IP_ASSIGN, - ipaddr.getId(), - ipaddr.getDataCenterId(), - ipaddr.getId(), - ipaddr.getAddress().toString(), - ipaddr.isSourceNat(), - null, - ipaddr.getSystem(), - ipaddr.getClass().getName(), - ipaddr.getUuid()); - - txn.commit(); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_PORTABLE_IP_ASSIGN, + ipaddr.getId(), + ipaddr.getDataCenterId(), + ipaddr.getId(), + ipaddr.getAddress().toString(), + ipaddr.isSourceNat(), + null, + ipaddr.getSystem(), + ipaddr.getClass().getName(), + ipaddr.getUuid()); + return ipaddr; + } + }); } finally { portableIpLock.unlock(); } @@ -1392,7 +1409,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @DB @Override - public void transferPortableIP(long ipAddrId, long currentNetworkId, long newNetworkId) throws ResourceAllocationException, ResourceUnavailableException, + public void transferPortableIP(final long ipAddrId, long currentNetworkId, long newNetworkId) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException { Network srcNetwork = _networksDao.findById(currentNetworkId); @@ -1400,18 +1417,16 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage throw new InvalidParameterValueException("Invalid source network id " + currentNetworkId + " is given"); } - Network dstNetwork = _networksDao.findById(newNetworkId); + final Network dstNetwork = _networksDao.findById(newNetworkId); if (dstNetwork == null) { throw new InvalidParameterValueException("Invalid source network id " + newNetworkId + " is given"); } - IPAddressVO ip = _ipAddressDao.findById(ipAddrId); + final IPAddressVO ip = _ipAddressDao.findById(ipAddrId); if (ip == null) { throw new InvalidParameterValueException("Invalid portable ip address id is given"); } - Transaction txn = Transaction.currentTxn(); - assert (isPortableIpTransferableFromNetwork(ipAddrId, currentNetworkId)); // disassociate portable IP with current network/VPC network @@ -1424,39 +1439,42 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage // If portable IP need to be transferred across the zones, then mark the entry corresponding to portable ip // in user_ip_address and vlan tables so as to emulate portable IP as provisioned in destination data center if (srcNetwork.getDataCenterId() != dstNetwork.getDataCenterId()) { - txn.start(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + long physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(dstNetwork.getDataCenterId(), TrafficType.Public).getId(); + long publicNetworkId = _networkModel.getSystemNetworkByZoneAndTrafficType(dstNetwork.getDataCenterId(), TrafficType.Public).getId(); - long physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(dstNetwork.getDataCenterId(), TrafficType.Public).getId(); - long publicNetworkId = _networkModel.getSystemNetworkByZoneAndTrafficType(dstNetwork.getDataCenterId(), TrafficType.Public).getId(); + ip.setDataCenterId(dstNetwork.getDataCenterId()); + ip.setPhysicalNetworkId(physicalNetworkId); + ip.setSourceNetworkId(publicNetworkId); + _ipAddressDao.update(ipAddrId, ip); - ip.setDataCenterId(dstNetwork.getDataCenterId()); - ip.setPhysicalNetworkId(physicalNetworkId); - ip.setSourceNetworkId(publicNetworkId); - _ipAddressDao.update(ipAddrId, ip); - - VlanVO vlan = _vlanDao.findById(ip.getVlanId()); - vlan.setPhysicalNetworkId(physicalNetworkId); - vlan.setNetworkId(publicNetworkId); - vlan.setDataCenterId(dstNetwork.getDataCenterId()); - _vlanDao.update(ip.getVlanId(), vlan); - - txn.commit(); + VlanVO vlan = _vlanDao.findById(ip.getVlanId()); + vlan.setPhysicalNetworkId(physicalNetworkId); + vlan.setNetworkId(publicNetworkId); + vlan.setDataCenterId(dstNetwork.getDataCenterId()); + _vlanDao.update(ip.getVlanId(), vlan); + } + }); } // associate portable IP with new network/VPC network associatePortableIPToGuestNetwork(ipAddrId, newNetworkId, false); - txn.start(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + if (dstNetwork.getVpcId() != null) { + ip.setVpcId(dstNetwork.getVpcId()); + } else { + ip.setVpcId(null); + } - if (dstNetwork.getVpcId() != null) { - ip.setVpcId(dstNetwork.getVpcId()); - } else { - ip.setVpcId(null); - } + _ipAddressDao.update(ipAddrId, ip); + } + }); - _ipAddressDao.update(ipAddrId, ip); - - txn.commit(); // trigger an action event for the transfer of portable IP across the networks, so that external entities // monitoring for this event can initiate the route advertisement for the availability of IP from the zoe @@ -1474,106 +1492,121 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @Override @DB - public boolean associateIpAddressListToAccount(long userId, long accountId, long zoneId, Long vlanId, Network guestNetwork) throws InsufficientCapacityException, + public boolean associateIpAddressListToAccount(long userId, final long accountId, final long zoneId, final Long vlanId, final Network guestNetworkFinal) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, ResourceAllocationException { - Account owner = _accountMgr.getActiveAccountById(accountId); - boolean createNetwork = false; + final Account owner = _accountMgr.getActiveAccountById(accountId); - if (guestNetwork != null && guestNetwork.getTrafficType() != TrafficType.Guest) { - throw new InvalidParameterValueException("Network " + guestNetwork + " is not of a type " + TrafficType.Guest); + if (guestNetworkFinal != null && guestNetworkFinal.getTrafficType() != TrafficType.Guest) { + throw new InvalidParameterValueException("Network " + guestNetworkFinal + " is not of a type " + TrafficType.Guest); } - Transaction txn = Transaction.currentTxn(); - txn.start(); + Ternary, Network> pair = null; + try { + pair = Transaction.execute(new TransactionCallbackWithException, Network>,Exception>() { + @Override + public Ternary, Network> doInTransaction(TransactionStatus status) throws InsufficientCapacityException, ResourceAllocationException { + boolean createNetwork = false; + Network guestNetwork = guestNetworkFinal; - if (guestNetwork == null) { - List networks = getIsolatedNetworksWithSourceNATOwnedByAccountInZone(zoneId, owner); - if (networks.size() == 0) { - createNetwork = true; - } else if (networks.size() == 1) { - guestNetwork = networks.get(0); - } else { - throw new InvalidParameterValueException("Error, more than 1 Guest Isolated Networks with SourceNAT " - + "service enabled found for this account, cannot assosiate the IP range, please provide the network ID"); - } - } - - // create new Virtual network (Isolated with SourceNAT) for the user if it doesn't exist - List requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false); - if (requiredOfferings.size() < 1) { - throw new CloudRuntimeException("Unable to find network offering with availability=" + Availability.Required + - " to automatically create the network as part of createVlanIpRange"); - } - if (createNetwork) { - if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) { - long physicalNetworkId = _networkModel.findPhysicalNetworkId(zoneId, requiredOfferings.get(0).getTags(), requiredOfferings.get(0).getTrafficType()); - // Validate physical network - PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); - if (physicalNetwork == null) { - throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: " + requiredOfferings.get(0).getTags()); + if (guestNetwork == null) { + List networks = getIsolatedNetworksWithSourceNATOwnedByAccountInZone(zoneId, owner); + if (networks.size() == 0) { + createNetwork = true; + } else if (networks.size() == 1) { + guestNetwork = networks.get(0); + } else { + throw new InvalidParameterValueException("Error, more than 1 Guest Isolated Networks with SourceNAT " + + "service enabled found for this account, cannot assosiate the IP range, please provide the network ID"); + } + } + + // create new Virtual network (Isolated with SourceNAT) for the user if it doesn't exist + List requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false); + if (requiredOfferings.size() < 1) { + throw new CloudRuntimeException("Unable to find network offering with availability=" + Availability.Required + + " to automatically create the network as part of createVlanIpRange"); + } + if (createNetwork) { + if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) { + long physicalNetworkId = _networkModel.findPhysicalNetworkId(zoneId, requiredOfferings.get(0).getTags(), requiredOfferings.get(0).getTrafficType()); + // Validate physical network + PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); + if (physicalNetwork == null) { + throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: " + requiredOfferings.get(0).getTags()); + } + + s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId() + + " as a part of createVlanIpRange process"); + guestNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), + owner.getAccountName() + "-network", + owner.getAccountName() + "-network", + null, + null, + null, + null, + owner, + null, + physicalNetwork, + zoneId, + ACLType.Account, + null, + null, + null, + null, + true, + null); + if (guestNetwork == null) { + s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId); + throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT " + + "service enabled as a part of createVlanIpRange, for the account " + accountId + "in zone " + zoneId); + } + } else { + throw new CloudRuntimeException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled); + } + } + + // Check if there is a source nat ip address for this account; if not - we have to allocate one + boolean allocateSourceNat = false; + List sourceNat = _ipAddressDao.listByAssociatedNetwork(guestNetwork.getId(), true); + if (sourceNat.isEmpty()) { + allocateSourceNat = true; + } + + // update all ips with a network id, mark them as allocated and update resourceCount/usage + List ips = _ipAddressDao.listByVlanId(vlanId); + boolean isSourceNatAllocated = false; + for (IPAddressVO addr : ips) { + if (addr.getState() != State.Allocated) { + if (!isSourceNatAllocated && allocateSourceNat) { + addr.setSourceNat(true); + isSourceNatAllocated = true; + } else { + addr.setSourceNat(false); + } + addr.setAssociatedWithNetworkId(guestNetwork.getId()); + addr.setVpcId(guestNetwork.getVpcId()); + addr.setAllocatedTime(new Date()); + addr.setAllocatedInDomainId(owner.getDomainId()); + addr.setAllocatedToAccountId(owner.getId()); + addr.setSystem(false); + addr.setState(IpAddress.State.Allocating); + markPublicIpAsAllocated(addr); + } + } + return new Ternary, Network>(createNetwork, requiredOfferings, guestNetwork); } - - s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId() + - " as a part of createVlanIpRange process"); - guestNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), - owner.getAccountName() + "-network", - owner.getAccountName() + "-network", - null, - null, - null, - null, - owner, - null, - physicalNetwork, - zoneId, - ACLType.Account, - null, - null, - null, - null, - true, - null); - if (guestNetwork == null) { - s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId); - throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT " + - "service enabled as a part of createVlanIpRange, for the account " + accountId + "in zone " + zoneId); - } - } else { - throw new CloudRuntimeException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled); - } + }); + } catch (Exception e1) { + ExceptionUtil.rethrowRuntime(e1); + ExceptionUtil.rethrow(e1, InsufficientCapacityException.class); + ExceptionUtil.rethrow(e1, ResourceAllocationException.class); + throw new IllegalStateException(e1); } - // Check if there is a source nat ip address for this account; if not - we have to allocate one - boolean allocateSourceNat = false; - List sourceNat = _ipAddressDao.listByAssociatedNetwork(guestNetwork.getId(), true); - if (sourceNat.isEmpty()) { - allocateSourceNat = true; - } - - // update all ips with a network id, mark them as allocated and update resourceCount/usage - List ips = _ipAddressDao.listByVlanId(vlanId); - boolean isSourceNatAllocated = false; - for (IPAddressVO addr : ips) { - if (addr.getState() != State.Allocated) { - if (!isSourceNatAllocated && allocateSourceNat) { - addr.setSourceNat(true); - isSourceNatAllocated = true; - } else { - addr.setSourceNat(false); - } - addr.setAssociatedWithNetworkId(guestNetwork.getId()); - addr.setVpcId(guestNetwork.getVpcId()); - addr.setAllocatedTime(new Date()); - addr.setAllocatedInDomainId(owner.getDomainId()); - addr.setAllocatedToAccountId(owner.getId()); - addr.setSystem(false); - addr.setState(IpAddress.State.Allocating); - markPublicIpAsAllocated(addr); - } - } - - txn.commit(); - + boolean createNetwork = pair.first(); + List requiredOfferings = pair.second(); + Network guestNetwork = pair.third(); + // if the network offering has persistent set to true, implement the network if (createNetwork && requiredOfferings.get(0).getIsPersistent()) { DataCenter zone = _dcDao.findById(zoneId); @@ -1602,10 +1635,8 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @DB @Override - public IPAddressVO markIpAsUnavailable(long addrId) { - Transaction txn = Transaction.currentTxn(); - - IPAddressVO ip = _ipAddressDao.findById(addrId); + public IPAddressVO markIpAsUnavailable(final long addrId) { + final IPAddressVO ip = _ipAddressDao.findById(addrId); if (ip.getAllocatedToAccountId() == null && ip.getAllocatedTime() == null) { s_logger.trace("Ip address id=" + addrId + " is already released"); @@ -1613,35 +1644,36 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage } if (ip.getState() != State.Releasing) { - txn.start(); + return Transaction.execute(new TransactionCallback() { + @Override + public IPAddressVO doInTransaction(TransactionStatus status) { + if (updateIpResourceCount(ip)) { + _resourceLimitMgr.decrementResourceCount(_ipAddressDao.findById(addrId).getAllocatedToAccountId(), ResourceType.public_ip); + } - if (updateIpResourceCount(ip)) { - _resourceLimitMgr.decrementResourceCount(_ipAddressDao.findById(addrId).getAllocatedToAccountId(), ResourceType.public_ip); - } + // Save usage event + if (ip.getAllocatedToAccountId() != null && ip.getAllocatedToAccountId() != Account.ACCOUNT_ID_SYSTEM) { + VlanVO vlan = _vlanDao.findById(ip.getVlanId()); - // Save usage event - if (ip.getAllocatedToAccountId() != null && ip.getAllocatedToAccountId() != Account.ACCOUNT_ID_SYSTEM) { - VlanVO vlan = _vlanDao.findById(ip.getVlanId()); - - String guestType = vlan.getVlanType().toString(); - if (!isIpDedicated(ip)) { - String eventType = ip.isPortable() ? EventTypes.EVENT_PORTABLE_IP_RELEASE : EventTypes.EVENT_NET_IP_RELEASE; - UsageEventUtils.publishUsageEvent(eventType, - ip.getAllocatedToAccountId(), - ip.getDataCenterId(), - addrId, - ip.getAddress().addr(), - ip.isSourceNat(), - guestType, - ip.getSystem(), - ip.getClass().getName(), - ip.getUuid()); + String guestType = vlan.getVlanType().toString(); + if (!isIpDedicated(ip)) { + String eventType = ip.isPortable() ? EventTypes.EVENT_PORTABLE_IP_RELEASE : EventTypes.EVENT_NET_IP_RELEASE; + UsageEventUtils.publishUsageEvent(eventType, + ip.getAllocatedToAccountId(), + ip.getDataCenterId(), + addrId, + ip.getAddress().addr(), + ip.isSourceNat(), + guestType, + ip.getSystem(), + ip.getClass().getName(), + ip.getUuid()); + } + } + + return _ipAddressDao.markAsUnavailable(addrId); } - } - - ip = _ipAddressDao.markAsUnavailable(addrId); - - txn.commit(); + }); } return ip; @@ -1826,73 +1858,73 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @Override @DB - public void allocateDirectIp(NicProfile nic, DataCenter dc, VirtualMachineProfile vm, Network network, String requestedIpv4, String requestedIpv6) + public void allocateDirectIp(final NicProfile nic, final DataCenter dc, final VirtualMachineProfile vm, final Network network, final String requestedIpv4, final String requestedIpv6) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { - //This method allocates direct ip for the Shared network in Advance zones - boolean ipv4 = false; + Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientAddressCapacityException { + //This method allocates direct ip for the Shared network in Advance zones + boolean ipv4 = false; - Transaction txn = Transaction.currentTxn(); - txn.start(); + if (network.getGateway() != null) { + if (nic.getIp4Address() == null) { + ipv4 = true; + PublicIp ip = null; - if (network.getGateway() != null) { - if (nic.getIp4Address() == null) { - ipv4 = true; - PublicIp ip = null; + //Get ip address from the placeholder and don't allocate a new one + if (requestedIpv4 != null && vm.getType() == VirtualMachine.Type.DomainRouter) { + Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, null); + if (placeholderNic != null) { + IPAddressVO userIp = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), placeholderNic.getIp4Address()); + ip = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId())); + s_logger.debug("Nic got an ip address " + placeholderNic.getIp4Address() + " stored in placeholder nic for the network " + network); + } + } - //Get ip address from the placeholder and don't allocate a new one - if (requestedIpv4 != null && vm.getType() == VirtualMachine.Type.DomainRouter) { - Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, null); - if (placeholderNic != null) { - IPAddressVO userIp = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), placeholderNic.getIp4Address()); - ip = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId())); - s_logger.debug("Nic got an ip address " + placeholderNic.getIp4Address() + " stored in placeholder nic for the network " + network); + if (ip == null) { + ip = assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.DirectAttached, network.getId(), requestedIpv4, false); + } + + nic.setIp4Address(ip.getAddress().toString()); + nic.setGateway(ip.getGateway()); + nic.setNetmask(ip.getNetmask()); + nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); + //nic.setBroadcastType(BroadcastDomainType.Vlan); + //nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag())); + nic.setBroadcastType(network.getBroadcastDomainType()); + nic.setBroadcastUri(network.getBroadcastUri()); + nic.setFormat(AddressFormat.Ip4); + nic.setReservationId(String.valueOf(ip.getVlanTag())); + nic.setMacAddress(ip.getMacAddress()); } + nic.setDns1(dc.getDns1()); + nic.setDns2(dc.getDns2()); } - if (ip == null) { - ip = assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.DirectAttached, network.getId(), requestedIpv4, false); - } - - nic.setIp4Address(ip.getAddress().toString()); - nic.setGateway(ip.getGateway()); - nic.setNetmask(ip.getNetmask()); - nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); - //nic.setBroadcastType(BroadcastDomainType.Vlan); - //nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag())); - nic.setBroadcastType(network.getBroadcastDomainType()); - nic.setBroadcastUri(network.getBroadcastUri()); - nic.setFormat(AddressFormat.Ip4); - nic.setReservationId(String.valueOf(ip.getVlanTag())); - nic.setMacAddress(ip.getMacAddress()); - } - nic.setDns1(dc.getDns1()); - nic.setDns2(dc.getDns2()); - } - - //FIXME - get ipv6 address from the placeholder if it's stored there - if (network.getIp6Gateway() != null) { - if (nic.getIp6Address() == null) { - UserIpv6Address ip = _ipv6Mgr.assignDirectIp6Address(dc.getId(), vm.getOwner(), network.getId(), requestedIpv6); - Vlan vlan = _vlanDao.findById(ip.getVlanId()); - nic.setIp6Address(ip.getAddress().toString()); - nic.setIp6Gateway(vlan.getIp6Gateway()); - nic.setIp6Cidr(vlan.getIp6Cidr()); - if (ipv4) { - nic.setFormat(AddressFormat.DualStack); - } else { - nic.setIsolationUri(IsolationType.Vlan.toUri(vlan.getVlanTag())); - nic.setBroadcastType(BroadcastDomainType.Vlan); - nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlan.getVlanTag())); - nic.setFormat(AddressFormat.Ip6); - nic.setReservationId(String.valueOf(vlan.getVlanTag())); - nic.setMacAddress(ip.getMacAddress()); + //FIXME - get ipv6 address from the placeholder if it's stored there + if (network.getIp6Gateway() != null) { + if (nic.getIp6Address() == null) { + UserIpv6Address ip = _ipv6Mgr.assignDirectIp6Address(dc.getId(), vm.getOwner(), network.getId(), requestedIpv6); + Vlan vlan = _vlanDao.findById(ip.getVlanId()); + nic.setIp6Address(ip.getAddress().toString()); + nic.setIp6Gateway(vlan.getIp6Gateway()); + nic.setIp6Cidr(vlan.getIp6Cidr()); + if (ipv4) { + nic.setFormat(AddressFormat.DualStack); + } else { + nic.setIsolationUri(IsolationType.Vlan.toUri(vlan.getVlanTag())); + nic.setBroadcastType(BroadcastDomainType.Vlan); + nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlan.getVlanTag())); + nic.setFormat(AddressFormat.Ip6); + nic.setReservationId(String.valueOf(vlan.getVlanTag())); + nic.setMacAddress(ip.getMacAddress()); + } + } + nic.setIp6Dns1(dc.getIp6Dns1()); + nic.setIp6Dns2(dc.getIp6Dns2()); } } - nic.setIp6Dns1(dc.getIp6Dns1()); - nic.setIp6Dns2(dc.getIp6Dns2()); - } - - txn.commit(); + }); } @Override diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index 61c070a86c4..cf419f37ad1 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -41,7 +41,6 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; - import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd; @@ -137,7 +136,7 @@ import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; import com.cloud.org.Grouping; import com.cloud.projects.Project; import com.cloud.projects.ProjectManager; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; @@ -159,9 +158,15 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionCallbackWithException; +import com.cloud.utils.db.TransactionLegacy; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.exception.ExceptionUtil; import com.cloud.utils.net.NetUtils; import com.cloud.vm.Nic; import com.cloud.vm.NicSecondaryIp; @@ -635,11 +640,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { @Override - public NicSecondaryIp allocateSecondaryGuestIP (Account ipOwner, long zoneId, Long nicId, Long networkId, String requestedIp) throws InsufficientAddressCapacityException { + public NicSecondaryIp allocateSecondaryGuestIP (Account ipOwner, long zoneId, final Long nicId, final Long networkId, String requestedIp) throws InsufficientAddressCapacityException { - Long accountId = null; - Long domainId = null; - Long vmId = null; String ipaddr = null; if (networkId == null) { @@ -649,7 +651,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { Account caller = CallContext.current().getCallingAccount(); //check whether the nic belongs to user vm. - NicVO nicVO = _nicDao.findById(nicId); + final NicVO nicVO = _nicDao.findById(nicId); if (nicVO == null) { throw new InvalidParameterValueException("There is no nic for the " + nicId); } @@ -670,8 +672,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (network == null) { throw new InvalidParameterValueException("Invalid network id is given"); } - accountId = ipOwner.getAccountId(); - domainId = ipOwner.getDomainId(); + final Long accountId = ipOwner.getAccountId(); + final Long domainId = ipOwner.getDomainId(); // Validate network offering NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(network.getNetworkOfferingId()); @@ -716,26 +718,29 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { return null; } - NicSecondaryIpVO secondaryIpVO; if (ipaddr != null) { // we got the ip addr so up the nics table and secodary ip - Transaction txn = Transaction.currentTxn(); - txn.start(); + final String addrFinal = ipaddr; + long id = Transaction.execute(new TransactionCallback() { + @Override + public Long doInTransaction(TransactionStatus status) { + boolean nicSecondaryIpSet = nicVO.getSecondaryIp(); + if (!nicSecondaryIpSet) { + nicVO.setSecondaryIp(true); + // commit when previously set ?? + s_logger.debug("Setting nics table ..."); + _nicDao.update(nicId, nicVO); + } + + s_logger.debug("Setting nic_secondary_ip table ..."); + Long vmId = nicVO.getInstanceId(); + NicSecondaryIpVO secondaryIpVO = new NicSecondaryIpVO(nicId, addrFinal, vmId, accountId, domainId, networkId); + _nicSecondaryIpDao.persist(secondaryIpVO); + return secondaryIpVO.getId(); + } + }); - boolean nicSecondaryIpSet = nicVO.getSecondaryIp(); - if (!nicSecondaryIpSet) { - nicVO.setSecondaryIp(true); - // commit when previously set ?? - s_logger.debug("Setting nics table ..."); - _nicDao.update(nicId, nicVO); - } - - s_logger.debug("Setting nic_secondary_ip table ..."); - vmId = nicVO.getInstanceId(); - secondaryIpVO = new NicSecondaryIpVO(nicId, ipaddr, vmId, accountId, domainId, networkId); - _nicSecondaryIpDao.persist(secondaryIpVO); - txn.commit(); - return getNicSecondaryIp(secondaryIpVO.getId()); + return getNicSecondaryIp(id); } else { return null; } @@ -805,13 +810,15 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { throw new InvalidParameterValueException("Can' remove the ip " + secondaryIp + "is associate with static NAT rule public IP address id " + publicIpVO.getId()); } } else if (dc.getNetworkType() == NetworkType.Basic || ntwkOff.getGuestType() == Network.GuestType.Shared) { - IPAddressVO ip = _ipAddressDao.findByIpAndNetworkId(secIpVO.getNetworkId(), secIpVO.getIp4Address()); + final IPAddressVO ip = _ipAddressDao.findByIpAndNetworkId(secIpVO.getNetworkId(), secIpVO.getIp4Address()); if (ip != null) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - _ipAddrMgr.markIpAsUnavailable(ip.getId()); - _ipAddressDao.unassignIpAddress(ip.getId()); - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + _ipAddrMgr.markIpAsUnavailable(ip.getId()); + _ipAddressDao.unassignIpAddress(ip.getId()); + } + }); } } else { throw new InvalidParameterValueException("Not supported for this network now"); @@ -821,22 +828,24 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { return success; } - boolean removeNicSecondaryIP(NicSecondaryIpVO ipVO, boolean lastIp) { - Transaction txn = Transaction.currentTxn(); - long nicId = ipVO.getNicId(); - NicVO nic = _nicDao.findById(nicId); + boolean removeNicSecondaryIP(final NicSecondaryIpVO ipVO, final boolean lastIp) { + final long nicId = ipVO.getNicId(); + final NicVO nic = _nicDao.findById(nicId); - txn.start(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + if (lastIp) { + nic.setSecondaryIp(false); + s_logger.debug("Setting nics secondary ip to false ..."); + _nicDao.update(nicId, nic); + } - if (lastIp) { - nic.setSecondaryIp(false); - s_logger.debug("Setting nics secondary ip to false ..."); - _nicDao.update(nicId, nic); - } + s_logger.debug("Revoving nic secondary ip entry ..."); + _nicSecondaryIpDao.remove(ipVO.getId()); + } + }); - s_logger.debug("Revoving nic secondary ip entry ..."); - _nicSecondaryIpDao.remove(ipVO.getId()); - txn.commit(); return true; } @@ -1255,67 +1264,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { throw ex; } - Transaction txn = Transaction.currentTxn(); - txn.start(); - - Long sharedDomainId = null; - if (isDomainSpecific) { - if (domainId != null) { - sharedDomainId = domainId; - } else { - sharedDomainId = _domainMgr.getDomain(Domain.ROOT_DOMAIN).getId(); - subdomainAccess = true; - } - } - - // default owner to system if network has aclType=Domain - if (aclType == ACLType.Domain) { - owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); - } - - //Create guest network - Network network = null; - if (vpcId != null) { - if (!_configMgr.isOfferingForVpc(ntwkOff)){ - throw new InvalidParameterValueException("Network offering can't be used for VPC networks"); - } - - if(aclId != null){ - NetworkACL acl = _networkACLDao.findById(aclId); - if(acl == null){ - throw new InvalidParameterValueException("Unable to find specified NetworkACL"); - } - - if(aclId != NetworkACL.DEFAULT_DENY && aclId != NetworkACL.DEFAULT_ALLOW) { - //ACL is not default DENY/ALLOW - // ACL should be associated with a VPC - if(!vpcId.equals(acl.getVpcId())){ - throw new InvalidParameterValueException("ACL: "+aclId+" do not belong to the VPC"); - } - } - } - network = _vpcMgr.createVpcGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, - networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, aclId, caller, displayNetwork); - } else { - if (_configMgr.isOfferingForVpc(ntwkOff)){ - throw new InvalidParameterValueException("Network offering can be used for VPC networks only"); - } - if (ntwkOff.getInternalLb()) { - throw new InvalidParameterValueException("Internal Lb can be enabled on vpc networks only"); - } - - network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, - networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, - ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan); - } - - if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN && createVlan) { - // Create vlan ip range - _configMgr.createVlanAndPublicIpRange(pNtwk.getDataCenterId(), network.getId(), physicalNetworkId, - false, null, startIP, endIP, gateway, netmask, vlanId, null, startIPv6, endIPv6, ip6Gateway, ip6Cidr); - } - - txn.commit(); + Network network = commitNetwork(networkOfferingId, gateway, startIP, endIP, netmask, networkDomain, vlanId, + name, displayText, caller, physicalNetworkId, zoneId, domainId, isDomainSpecific, subdomainAccess, + vpcId, startIPv6, endIPv6, ip6Gateway, ip6Cidr, displayNetwork, aclId, isolatedPvlan, ntwkOff, pNtwk, + aclType, owner, cidr, createVlan); // if the network offering has persistent set to true, implement the network if ( ntwkOff.getIsPersistent() ) { @@ -1344,6 +1296,87 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { return network; } + private Network commitNetwork(final Long networkOfferingId, final String gateway, final String startIP, final String endIP, final String netmask, + final String networkDomain, final String vlanId, final String name, final String displayText, final Account caller, + final Long physicalNetworkId, final Long zoneId, final Long domainId, final boolean isDomainSpecific, final Boolean subdomainAccessFinal, + final Long vpcId, final String startIPv6, final String endIPv6, final String ip6Gateway, final String ip6Cidr, final Boolean displayNetwork, + final Long aclId, final String isolatedPvlan, final NetworkOfferingVO ntwkOff, final PhysicalNetwork pNtwk, final ACLType aclType, + final Account ownerFinal, final String cidr, final boolean createVlan) throws InsufficientCapacityException, + ResourceAllocationException { + try { + return Transaction.execute(new TransactionCallbackWithException() { + @Override + public Network doInTransaction(TransactionStatus status) throws InsufficientCapacityException, ResourceAllocationException { + Account owner = ownerFinal; + Boolean subdomainAccess = subdomainAccessFinal; + + Long sharedDomainId = null; + if (isDomainSpecific) { + if (domainId != null) { + sharedDomainId = domainId; + } else { + sharedDomainId = _domainMgr.getDomain(Domain.ROOT_DOMAIN).getId(); + subdomainAccess = true; + } + } + + // default owner to system if network has aclType=Domain + if (aclType == ACLType.Domain) { + owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); + } + + //Create guest network + Network network = null; + if (vpcId != null) { + if (!_configMgr.isOfferingForVpc(ntwkOff)){ + throw new InvalidParameterValueException("Network offering can't be used for VPC networks"); + } + + if(aclId != null){ + NetworkACL acl = _networkACLDao.findById(aclId); + if(acl == null){ + throw new InvalidParameterValueException("Unable to find specified NetworkACL"); + } + + if(aclId != NetworkACL.DEFAULT_DENY && aclId != NetworkACL.DEFAULT_ALLOW) { + //ACL is not default DENY/ALLOW + // ACL should be associated with a VPC + if(!vpcId.equals(acl.getVpcId())){ + throw new InvalidParameterValueException("ACL: "+aclId+" do not belong to the VPC"); + } + } + } + network = _vpcMgr.createVpcGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, + networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, aclId, caller, displayNetwork); + } else { + if (_configMgr.isOfferingForVpc(ntwkOff)){ + throw new InvalidParameterValueException("Network offering can be used for VPC networks only"); + } + if (ntwkOff.getInternalLb()) { + throw new InvalidParameterValueException("Internal Lb can be enabled on vpc networks only"); + } + + network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, + networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, + ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan); + } + + if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN && createVlan) { + // Create vlan ip range + _configMgr.createVlanAndPublicIpRange(pNtwk.getDataCenterId(), network.getId(), physicalNetworkId, + false, null, startIP, endIP, gateway, netmask, vlanId, null, startIPv6, endIPv6, ip6Gateway, ip6Cidr); + } + return network; + } + }); + } catch (Exception e) { + ExceptionUtil.rethrowRuntime(e); + ExceptionUtil.rethrow(e, InsufficientCapacityException.class); + ExceptionUtil.rethrow(e, ResourceAllocationException.class); + throw new IllegalStateException(e); + } + } + @Override public List searchForNetworks(ListNetworksCmd cmd) { Long id = cmd.getId(); @@ -1638,7 +1671,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (tags != null && !tags.isEmpty()) { int count = 0; - sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.Network.toString()); + sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.Network.toString()); for (String key : tags.keySet()) { sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); @@ -1915,13 +1948,13 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { @Override @DB @ActionEvent(eventType = EventTypes.EVENT_NETWORK_UPDATE, eventDescription = "updating network", async = true) - public Network updateGuestNetwork(long networkId, String name, String displayText, Account callerAccount, - User callerUser, String domainSuffix, Long networkOfferingId, Boolean changeCidr, String guestVmCidr, Boolean displayNetwork) { + public Network updateGuestNetwork(final long networkId, String name, String displayText, Account callerAccount, + User callerUser, String domainSuffix, final Long networkOfferingId, Boolean changeCidr, String guestVmCidr, Boolean displayNetwork) { boolean restartNetwork = false; // verify input parameters - NetworkVO network = _networksDao.findById(networkId); + final NetworkVO network = _networksDao.findById(networkId); if (network == null) { // see NetworkVO.java InvalidParameterValueException ex = new InvalidParameterValueException("Specified network id doesn't exist in the system"); @@ -1975,7 +2008,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { boolean networkOfferingChanged = false; - long oldNetworkOfferingId = network.getNetworkOfferingId(); + final long oldNetworkOfferingId = network.getNetworkOfferingId(); NetworkOffering oldNtwkOff = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId); NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId); if (networkOfferingId != null) { @@ -2024,10 +2057,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } } - Map newSvcProviders = new HashMap(); - if (networkOfferingChanged) { - newSvcProviders = _networkMgr.finalizeServicesAndProvidersForNetwork(_entityMgr.findById(NetworkOffering.class, networkOfferingId), network.getPhysicalNetworkId()); - } + final Map newSvcProviders = networkOfferingChanged ? _networkMgr.finalizeServicesAndProvidersForNetwork(_entityMgr.findById(NetworkOffering.class, networkOfferingId), network.getPhysicalNetworkId()) + : new HashMap(); // don't allow to modify network domain if the service is not supported if (domainSuffix != null) { @@ -2201,29 +2232,31 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (networkOfferingId != null) { if (networkOfferingChanged) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - network.setNetworkOfferingId(networkOfferingId); - _networksDao.update(networkId, network, newSvcProviders); - // get all nics using this network - // log remove usage events for old offering - // log assign usage events for new offering - List nics = _nicDao.listByNetworkId(networkId); - for (NicVO nic : nics) { - long vmId = nic.getInstanceId(); - VMInstanceVO vm = _vmDao.findById(vmId); - if (vm == null) { - s_logger.error("Vm for nic " + nic.getId() + " not found with Vm Id:" + vmId); - continue; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + network.setNetworkOfferingId(networkOfferingId); + _networksDao.update(networkId, network, newSvcProviders); + // get all nics using this network + // log remove usage events for old offering + // log assign usage events for new offering + List nics = _nicDao.listByNetworkId(networkId); + for (NicVO nic : nics) { + long vmId = nic.getInstanceId(); + VMInstanceVO vm = _vmDao.findById(vmId); + if (vm == null) { + s_logger.error("Vm for nic " + nic.getId() + " not found with Vm Id:" + vmId); + continue; + } + long isDefault = (nic.isDefaultNic()) ? 1 : 0; + String nicIdString = Long.toString(nic.getId()); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vm.getAccountId(), vm.getDataCenterId(), + vm.getId(), nicIdString, oldNetworkOfferingId, null, isDefault, VirtualMachine.class.getName(), vm.getUuid()); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(), vm.getDataCenterId(), + vm.getId(), nicIdString, networkOfferingId, null, isDefault, VirtualMachine.class.getName(), vm.getUuid()); + } } - long isDefault = (nic.isDefaultNic()) ? 1 : 0; - String nicIdString = Long.toString(nic.getId()); - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vm.getAccountId(), vm.getDataCenterId(), - vm.getId(), nicIdString, oldNetworkOfferingId, null, isDefault, VirtualMachine.class.getName(), vm.getUuid()); - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(), vm.getDataCenterId(), - vm.getId(), nicIdString, networkOfferingId, null, isDefault, VirtualMachine.class.getName(), vm.getUuid()); - } - txn.commit(); + }); } else { network.setNetworkOfferingId(networkOfferingId); _networksDao.update(networkId, network, _networkMgr.finalizeServicesAndProvidersForNetwork(_entityMgr.findById(NetworkOffering.class, networkOfferingId), network.getPhysicalNetworkId())); @@ -2379,8 +2412,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { @Override @DB @ActionEvent(eventType = EventTypes.EVENT_PHYSICAL_NETWORK_CREATE, eventDescription = "Creating Physical Network", create = true) - public PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, List - isolationMethods, String broadcastDomainRangeStr, Long domainId, List tags, String name) { + public PhysicalNetwork createPhysicalNetwork(final Long zoneId, final String vnetRange, final String networkSpeed, final List + isolationMethods, String broadcastDomainRangeStr, final Long domainId, final List tags, final String name) { // Check if zone exists if (zoneId == null) { @@ -2445,39 +2478,42 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } } - Transaction txn = Transaction.currentTxn(); try { - txn.start(); - // Create the new physical network in the database - long id = _physicalNetworkDao.getNextInSequence(Long.class, "id"); - PhysicalNetworkVO pNetwork = new PhysicalNetworkVO(id, zoneId, vnetRange, networkSpeed, domainId, broadcastDomainRange, name); - pNetwork.setTags(tags); - pNetwork.setIsolationMethods(isolationMethods); + final BroadcastDomainRange broadcastDomainRangeFinal = broadcastDomainRange; + return Transaction.execute(new TransactionCallback() { + @Override + public PhysicalNetworkVO doInTransaction(TransactionStatus status) { + // Create the new physical network in the database + long id = _physicalNetworkDao.getNextInSequence(Long.class, "id"); + PhysicalNetworkVO pNetwork = new PhysicalNetworkVO(id, zoneId, vnetRange, networkSpeed, domainId, broadcastDomainRangeFinal, name); + pNetwork.setTags(tags); + pNetwork.setIsolationMethods(isolationMethods); - pNetwork = _physicalNetworkDao.persist(pNetwork); + pNetwork = _physicalNetworkDao.persist(pNetwork); - // Add vnet entries for the new zone if zone type is Advanced - if (vnetRange != null) { - addOrRemoveVnets(vnetRange.split(","), pNetwork); - } + // Add vnet entries for the new zone if zone type is Advanced + if (vnetRange != null) { + addOrRemoveVnets(vnetRange.split(","), pNetwork); + } - // add VirtualRouter as the default network service provider - addDefaultVirtualRouterToPhysicalNetwork(pNetwork.getId()); + // add VirtualRouter as the default network service provider + addDefaultVirtualRouterToPhysicalNetwork(pNetwork.getId()); - // add security group provider to the physical network - addDefaultSecurityGroupProviderToPhysicalNetwork(pNetwork.getId()); + // add security group provider to the physical network + addDefaultSecurityGroupProviderToPhysicalNetwork(pNetwork.getId()); - // add VPCVirtualRouter as the defualt network service provider - addDefaultVpcVirtualRouterToPhysicalNetwork(pNetwork.getId()); + // add VPCVirtualRouter as the defualt network service provider + addDefaultVpcVirtualRouterToPhysicalNetwork(pNetwork.getId()); - // add baremetal as the defualt network service provider - addDefaultBaremetalProvidersToPhysicalNetwork(pNetwork.getId()); + // add baremetal as the defualt network service provider + addDefaultBaremetalProvidersToPhysicalNetwork(pNetwork.getId()); - //Add Internal Load Balancer element as a default network service provider - addDefaultInternalLbProviderToPhysicalNetwork(pNetwork.getId()); - - txn.commit(); - return pNetwork; + //Add Internal Load Balancer element as a default network service provider + addDefaultInternalLbProviderToPhysicalNetwork(pNetwork.getId()); + + return pNetwork; + } + }); } catch (Exception ex) { s_logger.warn("Exception: ", ex); throw new CloudRuntimeException("Fail to create a physical network"); @@ -2568,7 +2604,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } @DB - public void addOrRemoveVnets(String [] listOfRanges, PhysicalNetworkVO network) { + public void addOrRemoveVnets(String [] listOfRanges, final PhysicalNetworkVO network) { List addVnets = null; List removeVnets =null; HashSet tempVnets = new HashSet(); @@ -2611,22 +2647,27 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } network.setVnet(comaSeperatedStingOfVnetRanges); - Transaction txn = Transaction.currentTxn(); - txn.start(); - if (addVnets != null) { - s_logger.debug("Adding vnet range " + addVnets.toString()+ " for the physicalNetwork id= " + network.getId() + " and zone id=" + network.getDataCenterId() - + " as a part of updatePhysicalNetwork call"); - //add vnet takes a list of strings to be added. each string is a vnet. - _dcDao.addVnet(network.getDataCenterId(), network.getId(), addVnets); - } - if (removeVnets != null) { - s_logger.debug("removing vnet range " + removeVnets.toString()+ " for the physicalNetwork id= " + network.getId() + " and zone id=" + network.getDataCenterId() - + " as a part of updatePhysicalNetwork call"); - //deleteVnets takes a list of strings to be removed. each string is a vnet. - _datacneter_vnet.deleteVnets(txn, network.getDataCenterId(), network.getId(), removeVnets); - } - _physicalNetworkDao.update(network.getId(), network); - txn.commit(); + final List addVnetsFinal = addVnets; + final List removeVnetsFinal = removeVnets; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + if (addVnetsFinal != null) { + s_logger.debug("Adding vnet range " + addVnetsFinal.toString()+ " for the physicalNetwork id= " + network.getId() + " and zone id=" + network.getDataCenterId() + + " as a part of updatePhysicalNetwork call"); + //add vnet takes a list of strings to be added. each string is a vnet. + _dcDao.addVnet(network.getDataCenterId(), network.getId(), addVnetsFinal); + } + if (removeVnetsFinal != null) { + s_logger.debug("removing vnet range " + removeVnetsFinal.toString()+ " for the physicalNetwork id= " + network.getId() + " and zone id=" + network.getDataCenterId() + + " as a part of updatePhysicalNetwork call"); + //deleteVnets takes a list of strings to be removed. each string is a vnet. + _datacneter_vnet.deleteVnets(TransactionLegacy.currentTxn(), network.getDataCenterId(), network.getId(), removeVnetsFinal); + } + _physicalNetworkDao.update(network.getId(), network); + } + }); + _physicalNetworkDao.releaseFromLockTable(network.getId()); } } @@ -2771,7 +2812,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { @Override @ActionEvent(eventType = EventTypes.EVENT_PHYSICAL_NETWORK_DELETE, eventDescription = "deleting physical network", async = true) @DB - public boolean deletePhysicalNetwork(Long physicalNetworkId) { + public boolean deletePhysicalNetwork(final Long physicalNetworkId) { // verify input parameters PhysicalNetworkVO pNetwork = _physicalNetworkDao.findById(physicalNetworkId); @@ -2783,48 +2824,47 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { checkIfPhysicalNetworkIsDeletable(physicalNetworkId); - Transaction txn = Transaction.currentTxn(); - txn.start(); - // delete vlans for this zone - List vlans = _vlanDao.listVlansByPhysicalNetworkId(physicalNetworkId); - for (VlanVO vlan : vlans) { - _vlanDao.remove(vlan.getId()); - } - - // Delete networks - List networks = _networksDao.listByPhysicalNetwork(physicalNetworkId); - if (networks != null && !networks.isEmpty()) { - for (NetworkVO network : networks) { - _networksDao.remove(network.getId()); + return Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + // delete vlans for this zone + List vlans = _vlanDao.listVlansByPhysicalNetworkId(physicalNetworkId); + for (VlanVO vlan : vlans) { + _vlanDao.remove(vlan.getId()); + } + + // Delete networks + List networks = _networksDao.listByPhysicalNetwork(physicalNetworkId); + if (networks != null && !networks.isEmpty()) { + for (NetworkVO network : networks) { + _networksDao.remove(network.getId()); + } + } + + // delete vnets + _dcDao.deleteVnet(physicalNetworkId); + + // delete service providers + List providers = _pNSPDao.listBy(physicalNetworkId); + + for(PhysicalNetworkServiceProviderVO provider : providers){ + try { + deleteNetworkServiceProvider(provider.getId()); + }catch (ResourceUnavailableException e) { + s_logger.warn("Unable to complete destroy of the physical network provider: " + provider.getProviderName() + ", id: "+ provider.getId(), e); + return false; + } catch (ConcurrentOperationException e) { + s_logger.warn("Unable to complete destroy of the physical network provider: " + provider.getProviderName() + ", id: "+ provider.getId(), e); + return false; + } + } + + // delete traffic types + _pNTrafficTypeDao.deleteTrafficTypes(physicalNetworkId); + + return _physicalNetworkDao.remove(physicalNetworkId); } - } - - // delete vnets - _dcDao.deleteVnet(physicalNetworkId); - - // delete service providers - List providers = _pNSPDao.listBy(physicalNetworkId); - - for(PhysicalNetworkServiceProviderVO provider : providers){ - try { - deleteNetworkServiceProvider(provider.getId()); - }catch (ResourceUnavailableException e) { - s_logger.warn("Unable to complete destroy of the physical network provider: " + provider.getProviderName() + ", id: "+ provider.getId(), e); - return false; - } catch (ConcurrentOperationException e) { - s_logger.warn("Unable to complete destroy of the physical network provider: " + provider.getProviderName() + ", id: "+ provider.getId(), e); - return false; - } - } - - // delete traffic types - _pNTrafficTypeDao.deleteTrafficTypes(physicalNetworkId); - - boolean success = _physicalNetworkDao.remove(physicalNetworkId); - - txn.commit(); - - return success; + }); } @DB @@ -2882,7 +2922,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { selectSql += " AND taken IS NOT NULL"; } - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql); stmt.setLong(1, physicalNetworkId); @@ -3045,12 +3085,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { accountGuestVlanMapVO.setGuestVlanRange(updatedVlanRange); _accountGuestVlanMapDao.update(guestVlanMapId, accountGuestVlanMapVO); } else { - Transaction txn = Transaction.currentTxn(); - txn.start(); accountGuestVlanMapVO = new AccountGuestVlanMapVO(vlanOwner.getAccountId(), physicalNetworkId); accountGuestVlanMapVO.setGuestVlanRange(startVlan + "-" + endVlan); _accountGuestVlanMapDao.persist(accountGuestVlanMapVO); - txn.commit(); } // For every guest vlan set the corresponding account guest vlan map id List finaVlanTokens = getVlanFromRange(accountGuestVlanMapVO.getGuestVlanRange()); @@ -3276,9 +3313,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { services = new ArrayList(element.getCapabilities().keySet()); } - Transaction txn = Transaction.currentTxn(); try { - txn.start(); // Create the new physical network in the database PhysicalNetworkServiceProviderVO nsp = new PhysicalNetworkServiceProviderVO(physicalNetworkId, providerName); // set enabled services @@ -3289,7 +3324,6 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } nsp = _pNSPDao.persist(nsp); - txn.commit(); return nsp; } catch (Exception ex) { s_logger.warn("Exception: ", ex); @@ -3537,9 +3571,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } } - Transaction txn = Transaction.currentTxn(); try { - txn.start(); // Create the new traffic type in the database if (xenLabel == null) { xenLabel = getDefaultXenNetworkLabel(trafficType); @@ -3547,7 +3579,6 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { PhysicalNetworkTrafficTypeVO pNetworktrafficType = new PhysicalNetworkTrafficTypeVO(physicalNetworkId, trafficType, xenLabel, kvmLabel, vmwareLabel, simulatorLabel, vlan); pNetworktrafficType = _pNTrafficTypeDao.persist(pNetworktrafficType); - txn.commit(); return pNetworktrafficType; } catch (Exception ex) { s_logger.warn("Exception: ", ex); @@ -3809,11 +3840,11 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { @Override @DB - public Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, - String broadcastUriString, String startIp, String endIp, String gateway, String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat, Long networkOfferingId) + public Network createPrivateNetwork(final String networkName, final String displayText, long physicalNetworkId, + String broadcastUriString, final String startIp, String endIp, final String gateway, String netmask, final long networkOwnerId, final Long vpcId, final Boolean sourceNat, final Long networkOfferingId) throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException { - Account owner = _accountMgr.getAccount(networkOwnerId); + final Account owner = _accountMgr.getAccount(networkOwnerId); // Get system network offering NetworkOfferingVO ntwkOff = null; @@ -3827,7 +3858,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } // Validate physical network - PhysicalNetwork pNtwk = _physicalNetworkDao.findById(physicalNetworkId); + final PhysicalNetwork pNtwk = _physicalNetworkDao.findById(physicalNetworkId); if (pNtwk == null) { InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a physical network" + " having the given id"); @@ -3846,7 +3877,6 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { throw new InvalidParameterValueException("Invalid format for the endIp address parameter"); } - String cidr = null; if (!NetUtils.isValidIp(gateway)) { throw new InvalidParameterValueException("Invalid gateway"); } @@ -3854,10 +3884,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { throw new InvalidParameterValueException("Invalid netmask"); } - cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask); + final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask); URI uri = BroadcastDomainType.fromString(broadcastUriString); - String uriString = uri.toString(); + final String uriString = uri.toString(); BroadcastDomainType tiep = BroadcastDomainType.getSchemeValue(uri); // numeric vlan or vlan uri are ok for now // TODO make a test for any supported scheme @@ -3866,49 +3896,58 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { throw new InvalidParameterValueException("unsupported type of broadcastUri specified: " + broadcastUriString); } - Transaction txn = Transaction.currentTxn(); - txn.start(); - - //lock datacenter as we need to get mac address seq from there - DataCenterVO dc = _dcDao.lockRow(pNtwk.getDataCenterId(), true); - - //check if we need to create guest network - Network privateNetwork = _networksDao.getPrivateNetwork(uriString, cidr, - networkOwnerId, pNtwk.getDataCenterId(), networkOfferingId); - if (privateNetwork == null) { - //create Guest network - privateNetwork = _networkMgr.createGuestNetwork(ntwkOff.getId(), networkName, displayText, gateway, cidr, uriString, - null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null, vpcId, null, null, true, null); - s_logger.debug("Created private network " + privateNetwork); - } else { - s_logger.debug("Private network already exists: " + privateNetwork); - //Do not allow multiple private gateways with same Vlan within a VPC - if(vpcId.equals(privateNetwork.getVpcId())){ - throw new InvalidParameterValueException("Private network for the vlan: " + uriString + " and cidr "+ cidr +" already exists " + - "for Vpc "+vpcId+" in zone " + _entityMgr.findById(DataCenter.class, pNtwk.getDataCenterId()).getName()); - } + final NetworkOfferingVO ntwkOffFinal = ntwkOff; + try { + return Transaction.execute(new TransactionCallbackWithException() { + @Override + public Network doInTransaction(TransactionStatus status) throws ResourceAllocationException, InsufficientCapacityException { + //lock datacenter as we need to get mac address seq from there + DataCenterVO dc = _dcDao.lockRow(pNtwk.getDataCenterId(), true); + + //check if we need to create guest network + Network privateNetwork = _networksDao.getPrivateNetwork(uriString, cidr, + networkOwnerId, pNtwk.getDataCenterId(), networkOfferingId); + if (privateNetwork == null) { + //create Guest network + privateNetwork = _networkMgr.createGuestNetwork(ntwkOffFinal.getId(), networkName, displayText, gateway, cidr, uriString, + null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null, vpcId, null, null, true, null); + s_logger.debug("Created private network " + privateNetwork); + } else { + s_logger.debug("Private network already exists: " + privateNetwork); + //Do not allow multiple private gateways with same Vlan within a VPC + if(vpcId.equals(privateNetwork.getVpcId())){ + throw new InvalidParameterValueException("Private network for the vlan: " + uriString + " and cidr "+ cidr +" already exists " + + "for Vpc "+vpcId+" in zone " + _entityMgr.findById(DataCenter.class, pNtwk.getDataCenterId()).getName()); + } + } + + //add entry to private_ip_address table + PrivateIpVO privateIp = _privateIpDao.findByIpAndSourceNetworkIdAndVpcId(privateNetwork.getId(), startIp, vpcId); + if (privateIp != null) { + throw new InvalidParameterValueException("Private ip address " + startIp + " already used for private gateway" + + " in zone " + _entityMgr.findById(DataCenter.class, pNtwk.getDataCenterId()).getName()); + } + + Long mac = dc.getMacAddress(); + Long nextMac = mac + 1; + dc.setMacAddress(nextMac); + + privateIp = new PrivateIpVO(startIp, privateNetwork.getId(), nextMac, vpcId, sourceNat); + _privateIpDao.persist(privateIp); + + _dcDao.update(dc.getId(), dc); + + s_logger.debug("Private network " + privateNetwork + " is created"); + + return privateNetwork; + } + }); + } catch (Exception e) { + ExceptionUtil.rethrowRuntime(e); + ExceptionUtil.rethrow(e, ResourceAllocationException.class); + ExceptionUtil.rethrow(e, InsufficientCapacityException.class); + throw new IllegalStateException(e); } - - //add entry to private_ip_address table - PrivateIpVO privateIp = _privateIpDao.findByIpAndSourceNetworkIdAndVpcId(privateNetwork.getId(), startIp, vpcId); - if (privateIp != null) { - throw new InvalidParameterValueException("Private ip address " + startIp + " already used for private gateway" + - " in zone " + _entityMgr.findById(DataCenter.class, pNtwk.getDataCenterId()).getName()); - } - - Long mac = dc.getMacAddress(); - Long nextMac = mac + 1; - dc.setMacAddress(nextMac); - - privateIp = new PrivateIpVO(startIp, privateNetwork.getId(), nextMac, vpcId, sourceNat); - _privateIpDao.persist(privateIp); - - _dcDao.update(dc.getId(), dc); - - txn.commit(); - s_logger.debug("Private network " + privateNetwork + " is created"); - - return privateNetwork; } diff --git a/server/src/com/cloud/network/NetworkUsageManagerImpl.java b/server/src/com/cloud/network/NetworkUsageManagerImpl.java index 41c1bc2912b..0f2feb07b91 100755 --- a/server/src/com/cloud/network/NetworkUsageManagerImpl.java +++ b/server/src/com/cloud/network/NetworkUsageManagerImpl.java @@ -88,6 +88,8 @@ import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; @@ -290,11 +292,11 @@ public class NetworkUsageManagerImpl extends ManagerBase implements NetworkUsage return false; } - private boolean collectDirectNetworkUsage(HostVO host){ + private boolean collectDirectNetworkUsage(final HostVO host){ s_logger.debug("Direct Network Usage stats collector is running..."); - long zoneId = host.getDataCenterId(); - DetailVO lastCollectDetail = _detailsDao.findDetail(host.getId(),"last_collection"); + final long zoneId = host.getDataCenterId(); + final DetailVO lastCollectDetail = _detailsDao.findDetail(host.getId(),"last_collection"); if(lastCollectDetail == null){ s_logger.warn("Last collection time not available. Skipping direct usage collection for Traffic Monitor: "+host.getId()); return false; @@ -309,7 +311,7 @@ public class NetworkUsageManagerImpl extends ManagerBase implements NetworkUsage // This coule be made configurable rightNow.add(Calendar.HOUR_OF_DAY, -2); - Date now = rightNow.getTime(); + final Date now = rightNow.getTime(); if(lastCollection.after(now)){ s_logger.debug("Current time is less than 2 hours after last collection time : " + lastCollection.toString() + ". Skipping direct network usage collection"); @@ -361,7 +363,7 @@ public class NetworkUsageManagerImpl extends ManagerBase implements NetworkUsage } - List collectedStats = new ArrayList(); + final List collectedStats = new ArrayList(); //Get usage for Ips which were assigned for the entire duration if(fullDurationIpUsage.size() > 0){ @@ -431,28 +433,26 @@ public class NetworkUsageManagerImpl extends ManagerBase implements NetworkUsage return false; } //Persist all the stats and last_collection time in a single transaction - Transaction txn = Transaction.open(Transaction.CLOUD_DB); - try { - txn.start(); - for(UserStatisticsVO stat : collectedStats){ - UserStatisticsVO stats = _statsDao.lock(stat.getAccountId(), stat.getDataCenterId(), 0L, null, host.getId(), "DirectNetwork"); - if (stats == null) { - stats = new UserStatisticsVO(stat.getAccountId(), zoneId, null, host.getId(), "DirectNetwork", 0L); - stats.setCurrentBytesSent(stat.getCurrentBytesSent()); - stats.setCurrentBytesReceived(stat.getCurrentBytesReceived()); - _statsDao.persist(stats); - } else { - stats.setCurrentBytesSent(stats.getCurrentBytesSent() + stat.getCurrentBytesSent()); - stats.setCurrentBytesReceived(stats.getCurrentBytesReceived() + stat.getCurrentBytesReceived()); - _statsDao.update(stats.getId(), stats); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + for(UserStatisticsVO stat : collectedStats){ + UserStatisticsVO stats = _statsDao.lock(stat.getAccountId(), stat.getDataCenterId(), 0L, null, host.getId(), "DirectNetwork"); + if (stats == null) { + stats = new UserStatisticsVO(stat.getAccountId(), zoneId, null, host.getId(), "DirectNetwork", 0L); + stats.setCurrentBytesSent(stat.getCurrentBytesSent()); + stats.setCurrentBytesReceived(stat.getCurrentBytesReceived()); + _statsDao.persist(stats); + } else { + stats.setCurrentBytesSent(stats.getCurrentBytesSent() + stat.getCurrentBytesSent()); + stats.setCurrentBytesReceived(stats.getCurrentBytesReceived() + stat.getCurrentBytesReceived()); + _statsDao.update(stats.getId(), stats); + } } + lastCollectDetail.setValue(""+now.getTime()); + _detailsDao.update(lastCollectDetail.getId(), lastCollectDetail); } - lastCollectDetail.setValue(""+now.getTime()); - _detailsDao.update(lastCollectDetail.getId(), lastCollectDetail); - txn.commit(); - } finally { - txn.close(); - } + }); return true; } diff --git a/server/src/com/cloud/network/PortProfileManagerImpl.java b/server/src/com/cloud/network/PortProfileManagerImpl.java index f17ee6f45b6..c731597925f 100644 --- a/server/src/com/cloud/network/PortProfileManagerImpl.java +++ b/server/src/com/cloud/network/PortProfileManagerImpl.java @@ -55,18 +55,7 @@ public class PortProfileManagerImpl { // Else, go ahead and create the port profile. PortProfileVO portProfileObj = new PortProfileVO(portProfName, vsmId, vlanId, pType, bType); - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - _portProfileDao.persist(portProfileObj); - txn.commit(); - } catch (Exception e) { - txn.rollback(); - throw new CloudRuntimeException(e.getMessage()); - } - - // Return the PortProfileVO object created. - return portProfileObj; + return _portProfileDao.persist(portProfileObj); } @DB @@ -95,18 +84,7 @@ public class PortProfileManagerImpl { // Else, go ahead and create the port profile. portProfileObj = new PortProfileVO(portProfName, vsmId, lowVlanId, highVlanId, pType, bType); - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - _portProfileDao.persist(portProfileObj); - txn.commit(); - } catch (Exception e) { - txn.rollback(); - throw new CloudRuntimeException(e.getMessage()); - } - - // Return the PortProfileVO object created. - return portProfileObj; + return _portProfileDao.persist(portProfileObj); } @DB @@ -121,16 +99,7 @@ public class PortProfileManagerImpl { // TODO: Should we be putting any checks here before removing // the port profile record from the db? - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - // Remove the VSM entry in CiscoNexusVSMDeviceVO's table. - _portProfileDao.remove(portProfileId); - txn.commit(); - } catch (Exception e) { - s_logger.info("Caught exception when trying to delete Port Profile record.." + e.getMessage()); - throw new CloudRuntimeException("Failed to delete Port Profile"); - } - return true; + // Remove the VSM entry in CiscoNexusVSMDeviceVO's table. + return _portProfileDao.remove(portProfileId); } } \ No newline at end of file diff --git a/server/src/com/cloud/network/StorageNetworkManagerImpl.java b/server/src/com/cloud/network/StorageNetworkManagerImpl.java index c0cb2894fc0..4719a42e8be 100755 --- a/server/src/com/cloud/network/StorageNetworkManagerImpl.java +++ b/server/src/com/cloud/network/StorageNetworkManagerImpl.java @@ -26,7 +26,6 @@ import javax.inject.Inject; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; - import org.apache.cloudstack.api.command.admin.network.CreateStorageNetworkIpRangeCmd; import org.apache.cloudstack.api.command.admin.network.DeleteStorageNetworkIpRangeCmd; import org.apache.cloudstack.api.command.admin.network.ListStorageNetworkIpRangeCmd; @@ -46,8 +45,12 @@ import com.cloud.network.dao.NetworkVO; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.QueryBuilder; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionCallbackWithException; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.vm.SecondaryStorageVmVO; @@ -93,7 +96,7 @@ public class StorageNetworkManagerImpl extends ManagerBase implements StorageNet } } - private void createStorageIpEntires(Transaction txn, long rangeId, String startIp, String endIp, long zoneId) throws SQLException { + private void createStorageIpEntires(TransactionLegacy txn, long rangeId, String startIp, String endIp, long zoneId) throws SQLException { long startIPLong = NetUtils.ip2Long(startIp); long endIPLong = NetUtils.ip2Long(endIp); String insertSql = "INSERT INTO `cloud`.`op_dc_storage_network_ip_address` (range_id, ip_address, mac_address, taken) VALUES (?, ?, (select mac_address from `cloud`.`data_center` where id=?), ?)"; @@ -120,11 +123,11 @@ public class StorageNetworkManagerImpl extends ManagerBase implements StorageNet @Override @DB public StorageNetworkIpRange updateIpRange(UpdateStorageNetworkIpRangeCmd cmd) { - Integer vlan = cmd.getVlan(); - Long rangeId = cmd.getId(); + final Integer vlan = cmd.getVlan(); + final Long rangeId = cmd.getId(); String startIp = cmd.getStartIp(); String endIp = cmd.getEndIp(); - String netmask = cmd.getNetmask(); + final String netmask = cmd.getNetmask(); if (netmask != null && !NetUtils.isValidNetmask(netmask)) { throw new CloudRuntimeException("Invalid netmask:" + netmask); @@ -147,45 +150,50 @@ public class StorageNetworkManagerImpl extends ManagerBase implements StorageNet checkOverlapStorageIpRange(podId, startIp, endIp); } - Transaction txn = Transaction.currentTxn(); - txn.start(); - try { - range = _sNwIpRangeDao.acquireInLockTable(range.getId()); - if (range == null) { - throw new CloudRuntimeException("Cannot acquire lock on storage ip range " + rangeId); + final String startIpFinal = startIp; + final String endIpFinal = endIp; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + StorageNetworkIpRangeVO range = null; + try { + range = _sNwIpRangeDao.acquireInLockTable(rangeId); + if (range == null) { + throw new CloudRuntimeException("Cannot acquire lock on storage ip range " + rangeId); + } + StorageNetworkIpRangeVO vo = _sNwIpRangeDao.createForUpdate(); + if (vlan != null) { + vo.setVlan(vlan); + } + if (startIpFinal != null) { + vo.setStartIp(startIpFinal); + } + if (endIpFinal != null) { + vo.setEndIp(endIpFinal); + } + if (netmask != null) { + vo.setNetmask(netmask); + } + _sNwIpRangeDao.update(rangeId, vo); + } finally { + if (range != null) { + _sNwIpRangeDao.releaseFromLockTable(range.getId()); + } + } } - StorageNetworkIpRangeVO vo = _sNwIpRangeDao.createForUpdate(); - if (vlan != null) { - vo.setVlan(vlan); - } - if (startIp != null) { - vo.setStartIp(startIp); - } - if (endIp != null) { - vo.setEndIp(endIp); - } - if (netmask != null) { - vo.setNetmask(netmask); - } - _sNwIpRangeDao.update(rangeId, vo); - } finally { - if (range != null) { - _sNwIpRangeDao.releaseFromLockTable(range.getId()); - } - } - txn.commit(); + }); return _sNwIpRangeDao.findById(rangeId); } @Override @DB - public StorageNetworkIpRange createIpRange(CreateStorageNetworkIpRangeCmd cmd) throws SQLException { - Long podId = cmd.getPodId(); - String startIp = cmd.getStartIp(); + public StorageNetworkIpRange createIpRange(final CreateStorageNetworkIpRangeCmd cmd) throws SQLException { + final Long podId = cmd.getPodId(); + final String startIp = cmd.getStartIp(); String endIp = cmd.getEndIp(); - Integer vlan = cmd.getVlan(); - String netmask = cmd.getNetmask(); + final Integer vlan = cmd.getVlan(); + final String netmask = cmd.getNetmask(); if (endIp == null) { endIp = startIp; @@ -199,7 +207,7 @@ public class StorageNetworkManagerImpl extends ManagerBase implements StorageNet if (pod == null) { throw new CloudRuntimeException("Cannot find pod " + podId); } - Long zoneId = pod.getDataCenterId(); + final Long zoneId = pod.getDataCenterId(); List nws = _networkDao.listByZoneAndTrafficType(zoneId, TrafficType.Storage); if (nws.size() == 0) { @@ -208,34 +216,35 @@ public class StorageNetworkManagerImpl extends ManagerBase implements StorageNet if (nws.size() > 1) { throw new CloudRuntimeException("Find more than one storage network in zone " + zoneId + "," + nws.size() + " found"); } - NetworkVO nw = nws.get(0); + final NetworkVO nw = nws.get(0); checkOverlapPrivateIpRange(podId, startIp, endIp); checkOverlapStorageIpRange(podId, startIp, endIp); - Transaction txn = Transaction.currentTxn(); StorageNetworkIpRangeVO range = null; - txn.start(); - range = new StorageNetworkIpRangeVO(zoneId, podId, nw.getId(), startIp, endIp, vlan, netmask, cmd.getGateWay()); - _sNwIpRangeDao.persist(range); - try { - createStorageIpEntires(txn, range.getId(), startIp, endIp, zoneId); - } catch (SQLException e) { - txn.rollback(); - StringBuilder err = new StringBuilder(); - err.append("Create storage network range failed."); - err.append("startIp=" + startIp); - err.append("endIp=" + endIp); - err.append("netmask=" + netmask); - err.append("zoneId=" + zoneId); - s_logger.debug(err.toString(), e); - throw e; - } + final String endIpFinal = endIp; + return Transaction.execute(new TransactionCallbackWithException() { + @Override + public StorageNetworkIpRangeVO doInTransaction(TransactionStatus status) throws SQLException { + StorageNetworkIpRangeVO range = new StorageNetworkIpRangeVO(zoneId, podId, nw.getId(), startIp, endIpFinal, vlan, netmask, cmd.getGateWay()); + _sNwIpRangeDao.persist(range); + try { + createStorageIpEntires(TransactionLegacy.currentTxn(), range.getId(), startIp, endIpFinal, zoneId); + } catch (SQLException e) { + StringBuilder err = new StringBuilder(); + err.append("Create storage network range failed."); + err.append("startIp=" + startIp); + err.append("endIp=" + endIpFinal); + err.append("netmask=" + netmask); + err.append("zoneId=" + zoneId); + s_logger.debug(err.toString(), e); + throw e; + } - txn.commit(); - - return range; + return range; + } + }); } private String getInUseIpAddress(long rangeId) { @@ -251,7 +260,7 @@ public class StorageNetworkManagerImpl extends ManagerBase implements StorageNet @Override @DB public void deleteIpRange(DeleteStorageNetworkIpRangeCmd cmd) { - long rangeId = cmd.getId(); + final long rangeId = cmd.getId(); StorageNetworkIpRangeVO range = _sNwIpRangeDao.findById(rangeId); if (range == null) { throw new CloudRuntimeException("Can not find storage network ip range " + rangeId); @@ -261,26 +270,30 @@ public class StorageNetworkManagerImpl extends ManagerBase implements StorageNet throw new CloudRuntimeException(getInUseIpAddress(rangeId)); } - final Transaction txn = Transaction.currentTxn(); - txn.start(); - try { - range = _sNwIpRangeDao.acquireInLockTable(rangeId); - if (range == null) { - String msg = "Unable to acquire lock on storage network ip range id=" + rangeId + ", delete failed"; - s_logger.warn(msg); - throw new CloudRuntimeException(msg); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + StorageNetworkIpRangeVO range = null; + try { + range = _sNwIpRangeDao.acquireInLockTable(rangeId); + if (range == null) { + String msg = "Unable to acquire lock on storage network ip range id=" + rangeId + ", delete failed"; + s_logger.warn(msg); + throw new CloudRuntimeException(msg); + } + /* + * entries in op_dc_storage_network_ip_address will be deleted automatically due to + * fk_storage_ip_address__range_id constraint key + */ + _sNwIpRangeDao.remove(rangeId); + } finally { + if (range != null) { + _sNwIpRangeDao.releaseFromLockTable(rangeId); + } + } } - /* - * entries in op_dc_storage_network_ip_address will be deleted automatically due to - * fk_storage_ip_address__range_id constraint key - */ - _sNwIpRangeDao.remove(rangeId); - } finally { - if (range != null) { - _sNwIpRangeDao.releaseFromLockTable(rangeId); - } - } - txn.commit(); + }); + } @Override diff --git a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java index 859211bd572..58a90bb1116 100644 --- a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java +++ b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java @@ -95,8 +95,10 @@ import com.cloud.utils.db.GenericDao; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.TransactionCallback; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.net.NetUtils; @Local(value = { AutoScaleService.class, AutoScaleManager.class }) @@ -428,9 +430,9 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale } @DB - protected AutoScalePolicyVO checkValidityAndPersist(AutoScalePolicyVO autoScalePolicyVO, List conditionIds) { - int duration = autoScalePolicyVO.getDuration(); - int quietTime = autoScalePolicyVO.getQuietTime(); + protected AutoScalePolicyVO checkValidityAndPersist(final AutoScalePolicyVO autoScalePolicyVOFinal, final List conditionIds) { + final int duration = autoScalePolicyVOFinal.getDuration(); + final int quietTime = autoScalePolicyVOFinal.getQuietTime(); if (duration < 0) { throw new InvalidParameterValueException("duration is an invalid value: " + duration); @@ -440,48 +442,49 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale throw new InvalidParameterValueException("quiettime is an invalid value: " + quietTime); } - final Transaction txn = Transaction.currentTxn(); - txn.start(); - - autoScalePolicyVO = _autoScalePolicyDao.persist(autoScalePolicyVO); - - if (conditionIds != null) { - SearchBuilder conditionsSearch = _conditionDao.createSearchBuilder(); - conditionsSearch.and("ids", conditionsSearch.entity().getId(), Op.IN); - conditionsSearch.done(); - SearchCriteria sc = conditionsSearch.create(); - - sc.setParameters("ids", conditionIds.toArray(new Object[0])); - List conditions = _conditionDao.search(sc, null); - - ControlledEntity[] sameOwnerEntities = conditions.toArray(new ControlledEntity[conditions.size() + 1]); - sameOwnerEntities[sameOwnerEntities.length - 1] = autoScalePolicyVO; - _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, sameOwnerEntities); - - if (conditionIds.size() != conditions.size()) { - // TODO report the condition id which could not be found - throw new InvalidParameterValueException("Unable to find the condition specified"); - } - - ArrayList counterIds = new ArrayList(); - for (ConditionVO condition : conditions) { - if (counterIds.contains(condition.getCounterid())) { - throw new InvalidParameterValueException("atleast two conditions in the conditionids have the same counter. It is not right to apply two different conditions for the same counter"); + return Transaction.execute(new TransactionCallback() { + @Override + public AutoScalePolicyVO doInTransaction(TransactionStatus status) { + AutoScalePolicyVO autoScalePolicyVO = _autoScalePolicyDao.persist(autoScalePolicyVOFinal); + + if (conditionIds != null) { + SearchBuilder conditionsSearch = _conditionDao.createSearchBuilder(); + conditionsSearch.and("ids", conditionsSearch.entity().getId(), Op.IN); + conditionsSearch.done(); + SearchCriteria sc = conditionsSearch.create(); + + sc.setParameters("ids", conditionIds.toArray(new Object[0])); + List conditions = _conditionDao.search(sc, null); + + ControlledEntity[] sameOwnerEntities = conditions.toArray(new ControlledEntity[conditions.size() + 1]); + sameOwnerEntities[sameOwnerEntities.length - 1] = autoScalePolicyVO; + _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, sameOwnerEntities); + + if (conditionIds.size() != conditions.size()) { + // TODO report the condition id which could not be found + throw new InvalidParameterValueException("Unable to find the condition specified"); + } + + ArrayList counterIds = new ArrayList(); + for (ConditionVO condition : conditions) { + if (counterIds.contains(condition.getCounterid())) { + throw new InvalidParameterValueException("atleast two conditions in the conditionids have the same counter. It is not right to apply two different conditions for the same counter"); + } + counterIds.add(condition.getCounterid()); + } + + /* For update case remove the existing mappings and create fresh ones */ + _autoScalePolicyConditionMapDao.removeByAutoScalePolicyId(autoScalePolicyVO.getId()); + + for (Long conditionId : conditionIds) { + AutoScalePolicyConditionMapVO policyConditionMapVO = new AutoScalePolicyConditionMapVO(autoScalePolicyVO.getId(), conditionId); + _autoScalePolicyConditionMapDao.persist(policyConditionMapVO); + } } - counterIds.add(condition.getCounterid()); + + return autoScalePolicyVO; } - - /* For update case remove the existing mappings and create fresh ones */ - _autoScalePolicyConditionMapDao.removeByAutoScalePolicyId(autoScalePolicyVO.getId()); - - for (Long conditionId : conditionIds) { - AutoScalePolicyConditionMapVO policyConditionMapVO = new AutoScalePolicyConditionMapVO(autoScalePolicyVO.getId(), conditionId); - _autoScalePolicyConditionMapDao.persist(policyConditionMapVO); - } - } - - txn.commit(); - return autoScalePolicyVO; + }); } @Override @@ -511,7 +514,7 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale @Override @DB @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEPOLICY_DELETE, eventDescription = "deleting autoscale policy") - public boolean deleteAutoScalePolicy(long id) { + public boolean deleteAutoScalePolicy(final long id) { /* Check if entity is in database */ getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Policy", id, _autoScalePolicyDao); @@ -519,23 +522,25 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale throw new InvalidParameterValueException("Cannot delete AutoScale Policy when it is in use by one or more AutoScale Vm Groups"); } - Transaction txn = Transaction.currentTxn(); - txn.start(); + return Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + boolean success = true; + success = _autoScalePolicyDao.remove(id); + if (!success) { + s_logger.warn("Failed to remove AutoScale Policy db object"); + return false; + } + success = _autoScalePolicyConditionMapDao.removeByAutoScalePolicyId(id); + if (!success) { + s_logger.warn("Failed to remove AutoScale Policy Condition mappings"); + return false; + } + s_logger.info("Successfully deleted autoscale policy id : " + id); - boolean success = true; - success = _autoScalePolicyDao.remove(id); - if (!success) { - s_logger.warn("Failed to remove AutoScale Policy db object"); - return false; - } - success = _autoScalePolicyConditionMapDao.removeByAutoScalePolicyId(id); - if (!success) { - s_logger.warn("Failed to remove AutoScale Policy Condition mappings"); - return false; - } - txn.commit(); - s_logger.info("Successfully deleted autoscale policy id : " + id); - return true; // successful + return success; + } + }); } public void checkCallerAccess(String accountName, Long domainId) @@ -745,7 +750,7 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale @Override @DB @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_DELETE, eventDescription = "deleting autoscale vm group") - public boolean deleteAutoScaleVmGroup(long id) { + public boolean deleteAutoScaleVmGroup(final long id) { AutoScaleVmGroupVO autoScaleVmGroupVO = getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Group", id, _autoScaleVmGroupDao); if (autoScaleVmGroupVO.getState().equals(AutoScaleVmGroup.State_New)) { @@ -769,24 +774,27 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale } } - Transaction txn = Transaction.currentTxn(); - txn.start(); - success = _autoScaleVmGroupDao.remove(id); + return Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + boolean success = _autoScaleVmGroupDao.remove(id); + + if (!success) { + s_logger.warn("Failed to remove AutoScale Group db object"); + return false; + } + + success = _autoScaleVmGroupPolicyMapDao.removeByGroupId(id); + if (!success) { + s_logger.warn("Failed to remove AutoScale Group Policy mappings"); + return false; + } + + s_logger.info("Successfully deleted autoscale vm group id : " + id); + return success; // Successfull + } + }); - if (!success) { - s_logger.warn("Failed to remove AutoScale Group db object"); - return false; - } - - success = _autoScaleVmGroupPolicyMapDao.removeByGroupId(id); - if (!success) { - s_logger.warn("Failed to remove AutoScale Group Policy mappings"); - return false; - } - - txn.commit(); - s_logger.info("Successfully deleted autoscale vm group id : " + id); - return success; // Successfull } @Override @@ -831,13 +839,13 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale } @DB - protected AutoScaleVmGroupVO checkValidityAndPersist(AutoScaleVmGroupVO vmGroup, List passedScaleUpPolicyIds, List passedScaleDownPolicyIds) { + protected AutoScaleVmGroupVO checkValidityAndPersist(final AutoScaleVmGroupVO vmGroup, final List passedScaleUpPolicyIds, final List passedScaleDownPolicyIds) { int minMembers = vmGroup.getMinMembers(); int maxMembers = vmGroup.getMaxMembers(); int interval = vmGroup.getInterval(); List counters = new ArrayList(); List policies = new ArrayList(); - List policyIds = new ArrayList(); + final List policyIds = new ArrayList(); List currentScaleUpPolicyIds = new ArrayList(); List currentScaleDownPolicyIds = new ArrayList(); if (vmGroup.getCreated() != null) { @@ -887,20 +895,23 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale sameOwnerEntities[sameOwnerEntities.length - 1] = profileVO; _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, sameOwnerEntities); - final Transaction txn = Transaction.currentTxn(); - txn.start(); - vmGroup = _autoScaleVmGroupDao.persist(vmGroup); + return Transaction.execute(new TransactionCallback() { + @Override + public AutoScaleVmGroupVO doInTransaction(TransactionStatus status) { + AutoScaleVmGroupVO vmGroupNew = _autoScaleVmGroupDao.persist(vmGroup); + + if (passedScaleUpPolicyIds != null || passedScaleDownPolicyIds != null) { + _autoScaleVmGroupPolicyMapDao.removeByGroupId(vmGroupNew.getId()); + + for (Long policyId : policyIds) { + _autoScaleVmGroupPolicyMapDao.persist(new AutoScaleVmGroupPolicyMapVO(vmGroupNew.getId(), policyId)); + } + } - if (passedScaleUpPolicyIds != null || passedScaleDownPolicyIds != null) { - _autoScaleVmGroupPolicyMapDao.removeByGroupId(vmGroup.getId()); - - for (Long policyId : policyIds) { - _autoScaleVmGroupPolicyMapDao.persist(new AutoScaleVmGroupPolicyMapVO(vmGroup.getId(), policyId)); + return vmGroupNew; } - } - txn.commit(); + }); - return vmGroup; } @Override diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index eb53db6be8e..503ce74d5e0 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -404,7 +404,9 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public boolean startVpn(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException { + public boolean startVpn(RemoteAccessVpn vpn) throws ResourceUnavailableException { + Network network = _networksDao.findById(vpn.getNetworkId()); + if (canHandle(network, Service.Vpn)) { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { @@ -420,7 +422,9 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public boolean stopVpn(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException { + public boolean stopVpn(RemoteAccessVpn vpn) throws ResourceUnavailableException { + Network network = _networksDao.findById(vpn.getNetworkId()); + if (canHandle(network, Service.Vpn)) { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { diff --git a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java index c86476e2957..bd9ead0b26a 100644 --- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java +++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java @@ -29,7 +29,6 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; - import org.apache.cloudstack.api.command.user.firewall.ListEgressFirewallRulesCmd; import org.apache.cloudstack.api.command.user.firewall.ListFirewallRulesCmd; import org.apache.cloudstack.context.CallContext; @@ -75,7 +74,7 @@ import com.cloud.network.rules.StaticNat; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.network.vpc.VpcManager; import com.cloud.projects.Project.ListProjectResourcesCriteria; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; @@ -89,6 +88,9 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionCallbackWithException; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; @@ -181,9 +183,9 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService, } @DB - protected FirewallRule createFirewallRule(Long ipAddrId, Account caller, String xId, Integer portStart, - Integer portEnd, String protocol, List sourceCidrList, Integer icmpCode, Integer icmpType, - Long relatedRuleId, FirewallRule.FirewallRuleType type, Long networkId, FirewallRule.TrafficType trafficType) throws NetworkRuleConflictException { + protected FirewallRule createFirewallRule(final Long ipAddrId, Account caller, final String xId, final Integer portStart, + final Integer portEnd, final String protocol, final List sourceCidrList, final Integer icmpCode, final Integer icmpType, + final Long relatedRuleId, final FirewallRule.FirewallRuleType type, final Long networkId, final FirewallRule.TrafficType trafficType) throws NetworkRuleConflictException { IPAddressVO ipAddress = null; if (ipAddrId != null){ @@ -222,25 +224,27 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService, domainId = network.getDomainId(); } - Transaction txn = Transaction.currentTxn(); - txn.start(); - - FirewallRuleVO newRule = new FirewallRuleVO(xId, ipAddrId, portStart, portEnd, protocol.toLowerCase(), networkId, - accountId, domainId, Purpose.Firewall, sourceCidrList, icmpCode, icmpType, relatedRuleId, trafficType); - newRule.setType(type); - newRule = _firewallDao.persist(newRule); - - if (type == FirewallRuleType.User) - detectRulesConflict(newRule); - - if (!_firewallDao.setStateToAdd(newRule)) { - throw new CloudRuntimeException("Unable to update the state to add for " + newRule); - } - CallContext.current().setEventDetails("Rule Id: " + newRule.getId()); - - txn.commit(); - - return newRule; + final Long accountIdFinal = accountId; + final Long domainIdFinal = domainId; + return Transaction.execute(new TransactionCallbackWithException() { + @Override + public FirewallRuleVO doInTransaction(TransactionStatus status) throws NetworkRuleConflictException { + FirewallRuleVO newRule = new FirewallRuleVO(xId, ipAddrId, portStart, portEnd, protocol.toLowerCase(), networkId, + accountIdFinal, domainIdFinal, Purpose.Firewall, sourceCidrList, icmpCode, icmpType, relatedRuleId, trafficType); + newRule.setType(type); + newRule = _firewallDao.persist(newRule); + + if (type == FirewallRuleType.User) + detectRulesConflict(newRule); + + if (!_firewallDao.setStateToAdd(newRule)) { + throw new CloudRuntimeException("Unable to update the state to add for " + newRule); + } + CallContext.current().setEventDetails("Rule Id: " + newRule.getId()); + + return newRule; + } + }); } @Override @@ -304,7 +308,7 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService, if (tags != null && !tags.isEmpty()) { int count = 0; - sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.FirewallRule.toString()); + sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.FirewallRule.toString()); for (String key : tags.keySet()) { sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); @@ -724,33 +728,34 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService, @Override @DB - public void revokeRule(FirewallRuleVO rule, Account caller, long userId, boolean needUsageEvent) { + public void revokeRule(final FirewallRuleVO rule, Account caller, long userId, final boolean needUsageEvent) { if (caller != null) { _accountMgr.checkAccess(caller, null, true, rule); } - Transaction txn = Transaction.currentTxn(); - boolean generateUsageEvent = false; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + boolean generateUsageEvent = false; - txn.start(); - if (rule.getState() == State.Staged) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Found a rule that is still in stage state so just removing it: " + rule); + if (rule.getState() == State.Staged) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Found a rule that is still in stage state so just removing it: " + rule); + } + removeRule(rule); + generateUsageEvent = true; + } else if (rule.getState() == State.Add || rule.getState() == State.Active) { + rule.setState(State.Revoke); + _firewallDao.update(rule.getId(), rule); + generateUsageEvent = true; + } + + if (generateUsageEvent && needUsageEvent) { + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_DELETE, rule.getAccountId(), 0, rule.getId(), + null, rule.getClass().getName(), rule.getUuid()); + } } - removeRule(rule); - generateUsageEvent = true; - } else if (rule.getState() == State.Add || rule.getState() == State.Active) { - rule.setState(State.Revoke); - _firewallDao.update(rule.getId(), rule); - generateUsageEvent = true; - } - - if (generateUsageEvent && needUsageEvent) { - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_DELETE, rule.getAccountId(), 0, rule.getId(), - null, rule.getClass().getName(), rule.getUuid()); - } - - txn.commit(); + }); } @Override diff --git a/server/src/com/cloud/network/guru/DirectNetworkGuru.java b/server/src/com/cloud/network/guru/DirectNetworkGuru.java index 55da113a148..801d252ef81 100755 --- a/server/src/com/cloud/network/guru/DirectNetworkGuru.java +++ b/server/src/com/cloud/network/guru/DirectNetworkGuru.java @@ -22,7 +22,6 @@ import javax.ejb.Local; import javax.inject.Inject; import org.apache.log4j.Logger; - import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import com.cloud.dc.DataCenter; @@ -33,6 +32,7 @@ import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientVirtualNetworkCapcityException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.network.IpAddressManager; @@ -56,6 +56,11 @@ import com.cloud.user.Account; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionCallbackWithException; +import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn; +import com.cloud.utils.db.TransactionStatus; +import com.cloud.utils.exception.ExceptionUtil; import com.cloud.vm.Nic; import com.cloud.vm.Nic.ReservationStrategy; import com.cloud.vm.NicProfile; @@ -228,22 +233,30 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru { } @DB - protected void allocateDirectIp(NicProfile nic, Network network, VirtualMachineProfile vm, DataCenter dc, String requestedIp4Addr, String requestedIp6Addr) + protected void allocateDirectIp(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final DataCenter dc, final String requestedIp4Addr, final String requestedIp6Addr) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { - - Transaction txn = Transaction.currentTxn(); - txn.start(); - _ipAddrMgr.allocateDirectIp(nic, dc, vm, network, requestedIp4Addr, requestedIp6Addr); - //save the placeholder nic if the vm is the Virtual router - if (vm.getType() == VirtualMachine.Type.DomainRouter) { - Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, null); - if (placeholderNic == null) { - s_logger.debug("Saving placeholder nic with ip4 address " + nic.getIp4Address() + " and ipv6 address " + nic.getIp6Address() + " for the network " + network); - _networkMgr.savePlaceholderNic(network, nic.getIp4Address(), nic.getIp6Address(), VirtualMachine.Type.DomainRouter); - } + + try { + Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { + _ipAddrMgr.allocateDirectIp(nic, dc, vm, network, requestedIp4Addr, requestedIp6Addr); + //save the placeholder nic if the vm is the Virtual router + if (vm.getType() == VirtualMachine.Type.DomainRouter) { + Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, null); + if (placeholderNic == null) { + s_logger.debug("Saving placeholder nic with ip4 address " + nic.getIp4Address() + " and ipv6 address " + nic.getIp6Address() + " for the network " + network); + _networkMgr.savePlaceholderNic(network, nic.getIp4Address(), nic.getIp6Address(), VirtualMachine.Type.DomainRouter); + } + } + } + }); + } catch (InsufficientCapacityException e) { + ExceptionUtil.rethrow(e, InsufficientVirtualNetworkCapcityException.class); + ExceptionUtil.rethrow(e, InsufficientAddressCapacityException.class); + throw new IllegalStateException(e); } - txn.commit(); } @Override @@ -257,37 +270,37 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru { } @Override @DB - public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) { + public void deallocate(final Network network, final NicProfile nic, VirtualMachineProfile vm) { if (s_logger.isDebugEnabled()) { s_logger.debug("Deallocate network: networkId: " + nic.getNetworkId() + ", ip: " + nic.getIp4Address()); } if (nic.getIp4Address() != null) { - IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIp4Address()); + final IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIp4Address()); if (ip != null) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - - // if the ip address a part of placeholder, don't release it - Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, null); - if (placeholderNic != null && placeholderNic.getIp4Address().equalsIgnoreCase(ip.getAddress().addr())) { - s_logger.debug("Not releasing direct ip " + ip.getId() +" yet as its ip is saved in the placeholder"); - } else { - _ipAddrMgr.markIpAsUnavailable(ip.getId()); - _ipAddressDao.unassignIpAddress(ip.getId()); - } - - //unassign nic secondary ip address - s_logger.debug("remove nic " + nic.getId() + " secondary ip "); - List nicSecIps = null; - nicSecIps = _nicSecondaryIpDao.getSecondaryIpAddressesForNic(nic.getId()); - for (String secIp: nicSecIps) { - IPAddressVO pubIp = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), secIp); - _ipAddrMgr.markIpAsUnavailable(pubIp.getId()); - _ipAddressDao.unassignIpAddress(pubIp.getId()); - } - - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // if the ip address a part of placeholder, don't release it + Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, null); + if (placeholderNic != null && placeholderNic.getIp4Address().equalsIgnoreCase(ip.getAddress().addr())) { + s_logger.debug("Not releasing direct ip " + ip.getId() +" yet as its ip is saved in the placeholder"); + } else { + _ipAddrMgr.markIpAsUnavailable(ip.getId()); + _ipAddressDao.unassignIpAddress(ip.getId()); + } + + //unassign nic secondary ip address + s_logger.debug("remove nic " + nic.getId() + " secondary ip "); + List nicSecIps = null; + nicSecIps = _nicSecondaryIpDao.getSecondaryIpAddressesForNic(nic.getId()); + for (String secIp: nicSecIps) { + IPAddressVO pubIp = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), secIp); + _ipAddrMgr.markIpAsUnavailable(pubIp.getId()); + _ipAddressDao.unassignIpAddress(pubIp.getId()); + } + } + }); } } @@ -305,21 +318,23 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru { @DB public boolean trash(Network network, NetworkOffering offering) { //Have to remove all placeholder nics - List nics = _nicDao.listPlaceholderNicsByNetworkId(network.getId()); - Transaction txn = Transaction.currentTxn(); - txn.start(); - for (Nic nic : nics) { - if (nic.getIp4Address() != null) { - s_logger.debug("Releasing ip " + nic.getIp4Address() + " of placeholder nic " + nic); - IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIp4Address()); - _ipAddrMgr.markIpAsUnavailable(ip.getId()); - _ipAddressDao.unassignIpAddress(ip.getId()); - s_logger.debug("Removing placeholder nic " + nic); - _nicDao.remove(nic.getId()); + final List nics = _nicDao.listPlaceholderNicsByNetworkId(network.getId()); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + for (Nic nic : nics) { + if (nic.getIp4Address() != null) { + s_logger.debug("Releasing ip " + nic.getIp4Address() + " of placeholder nic " + nic); + IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIp4Address()); + _ipAddrMgr.markIpAsUnavailable(ip.getId()); + _ipAddressDao.unassignIpAddress(ip.getId()); + s_logger.debug("Removing placeholder nic " + nic); + _nicDao.remove(nic.getId()); + } + } } - } - - txn.commit(); + }); + return true; } diff --git a/server/src/com/cloud/network/guru/DirectPodBasedNetworkGuru.java b/server/src/com/cloud/network/guru/DirectPodBasedNetworkGuru.java index 31bc021ff73..053a786e67b 100755 --- a/server/src/com/cloud/network/guru/DirectPodBasedNetworkGuru.java +++ b/server/src/com/cloud/network/guru/DirectPodBasedNetworkGuru.java @@ -23,7 +23,6 @@ import javax.ejb.Local; import javax.inject.Inject; import org.apache.log4j.Logger; - import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import com.cloud.configuration.ZoneConfig; @@ -53,6 +52,9 @@ import com.cloud.offering.NetworkOffering; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.Nic; import com.cloud.vm.Nic.ReservationStrategy; @@ -133,18 +135,18 @@ public class DirectPodBasedNetworkGuru extends DirectNetworkGuru { getNewIp = true; } else { // we need to get a new ip address if we try to deploy a vm in a different pod - IPAddressVO ipVO = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), oldIp); + final IPAddressVO ipVO = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), oldIp); if (ipVO != null) { PodVlanMapVO mapVO = _podVlanDao.listPodVlanMapsByVlan(ipVO.getVlanId()); if (mapVO.getPodId() != dest.getPod().getId()) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - - //release the old ip here - _ipAddrMgr.markIpAsUnavailable(ipVO.getId()); - _ipAddressDao.unassignIpAddress(ipVO.getId()); - - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + //release the old ip here + _ipAddrMgr.markIpAsUnavailable(ipVO.getId()); + _ipAddressDao.unassignIpAddress(ipVO.getId()); + } + }); nic.setIp4Address(null); getNewIp = true; @@ -163,54 +165,55 @@ public class DirectPodBasedNetworkGuru extends DirectNetworkGuru { } @DB - protected void getIp(NicProfile nic, Pod pod, VirtualMachineProfile vm, Network network) throws InsufficientVirtualNetworkCapcityException, + protected void getIp(final NicProfile nic, final Pod pod, final VirtualMachineProfile vm, final Network network) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException { - DataCenter dc = _dcDao.findById(pod.getDataCenterId()); + final DataCenter dc = _dcDao.findById(pod.getDataCenterId()); if (nic.getIp4Address() == null) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - - PublicIp ip = null; - List podRefs = _podVlanDao.listPodVlanMapsByPod(pod.getId()); - String podRangeGateway = null; - if (!podRefs.isEmpty()) { - podRangeGateway = _vlanDao.findById(podRefs.get(0).getVlanDbId()).getVlanGateway(); - } - //Get ip address from the placeholder and don't allocate a new one - if (vm.getType() == VirtualMachine.Type.DomainRouter) { - Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, pod.getId()); - if (placeholderNic != null) { - IPAddressVO userIp = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), placeholderNic.getIp4Address()); - ip = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId())); - s_logger.debug("Nic got an ip address " + placeholderNic.getIp4Address() + " stored in placeholder nic for the network " + network + " and gateway " + podRangeGateway); + Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientAddressCapacityException { + PublicIp ip = null; + List podRefs = _podVlanDao.listPodVlanMapsByPod(pod.getId()); + String podRangeGateway = null; + if (!podRefs.isEmpty()) { + podRangeGateway = _vlanDao.findById(podRefs.get(0).getVlanDbId()).getVlanGateway(); + } + //Get ip address from the placeholder and don't allocate a new one + if (vm.getType() == VirtualMachine.Type.DomainRouter) { + Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, pod.getId()); + if (placeholderNic != null) { + IPAddressVO userIp = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), placeholderNic.getIp4Address()); + ip = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId())); + s_logger.debug("Nic got an ip address " + placeholderNic.getIp4Address() + " stored in placeholder nic for the network " + network + " and gateway " + podRangeGateway); + } + } + + if (ip == null) { + ip = _ipAddrMgr.assignPublicIpAddress(dc.getId(), pod.getId(), vm.getOwner(), VlanType.DirectAttached, network.getId(), null, false); + } + + nic.setIp4Address(ip.getAddress().toString()); + nic.setFormat(AddressFormat.Ip4); + nic.setGateway(ip.getGateway()); + nic.setNetmask(ip.getNetmask()); + if (ip.getVlanTag() != null && ip.getVlanTag().equalsIgnoreCase(Vlan.UNTAGGED)) { + nic.setIsolationUri(IsolationType.Ec2.toUri(Vlan.UNTAGGED)); + nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(Vlan.UNTAGGED)); + nic.setBroadcastType(BroadcastDomainType.Native); + } + nic.setReservationId(String.valueOf(ip.getVlanTag())); + nic.setMacAddress(ip.getMacAddress()); + + //save the placeholder nic if the vm is the Virtual router + if (vm.getType() == VirtualMachine.Type.DomainRouter) { + Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, pod.getId()); + if (placeholderNic == null) { + s_logger.debug("Saving placeholder nic with ip4 address " + nic.getIp4Address() + " for the network " + network); + _networkMgr.savePlaceholderNic(network, nic.getIp4Address(), null, VirtualMachine.Type.DomainRouter); + } + } } - } - - if (ip == null) { - ip = _ipAddrMgr.assignPublicIpAddress(dc.getId(), pod.getId(), vm.getOwner(), VlanType.DirectAttached, network.getId(), null, false); - } - - nic.setIp4Address(ip.getAddress().toString()); - nic.setFormat(AddressFormat.Ip4); - nic.setGateway(ip.getGateway()); - nic.setNetmask(ip.getNetmask()); - if (ip.getVlanTag() != null && ip.getVlanTag().equalsIgnoreCase(Vlan.UNTAGGED)) { - nic.setIsolationUri(IsolationType.Ec2.toUri(Vlan.UNTAGGED)); - nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(Vlan.UNTAGGED)); - nic.setBroadcastType(BroadcastDomainType.Native); - } - nic.setReservationId(String.valueOf(ip.getVlanTag())); - nic.setMacAddress(ip.getMacAddress()); - - //save the placeholder nic if the vm is the Virtual router - if (vm.getType() == VirtualMachine.Type.DomainRouter) { - Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, pod.getId()); - if (placeholderNic == null) { - s_logger.debug("Saving placeholder nic with ip4 address " + nic.getIp4Address() + " for the network " + network); - _networkMgr.savePlaceholderNic(network, nic.getIp4Address(), null, VirtualMachine.Type.DomainRouter); - } - } - txn.commit(); + }); } nic.setDns1(dc.getDns1()); nic.setDns2(dc.getDns2()); diff --git a/server/src/com/cloud/network/guru/GuestNetworkGuru.java b/server/src/com/cloud/network/guru/GuestNetworkGuru.java index 20b0ce5b86a..85728c22fbb 100755 --- a/server/src/com/cloud/network/guru/GuestNetworkGuru.java +++ b/server/src/com/cloud/network/guru/GuestNetworkGuru.java @@ -24,7 +24,6 @@ import javax.ejb.Local; import javax.inject.Inject; import org.apache.log4j.Logger; - import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.ConfigKey; @@ -70,6 +69,8 @@ import com.cloud.utils.Pair; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.vm.Nic.ReservationStrategy; @@ -223,13 +224,15 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur s_logger.debug("Deallocate network: networkId: " + nic.getNetworkId() + ", ip: " + nic.getIp4Address()); } - IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIp4Address()); + final IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIp4Address()); if (ip != null) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - _ipAddrMgr.markIpAsUnavailable(ip.getId()); - _ipAddressDao.unassignIpAddress(ip.getId()); - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + _ipAddrMgr.markIpAsUnavailable(ip.getId()); + _ipAddressDao.unassignIpAddress(ip.getId()); + } + }); } nic.deallocate(); } diff --git a/server/src/com/cloud/network/guru/PublicNetworkGuru.java b/server/src/com/cloud/network/guru/PublicNetworkGuru.java index f82e22e8dde..6fed1a6ff7e 100755 --- a/server/src/com/cloud/network/guru/PublicNetworkGuru.java +++ b/server/src/com/cloud/network/guru/PublicNetworkGuru.java @@ -20,7 +20,6 @@ import javax.ejb.Local; import javax.inject.Inject; import org.apache.log4j.Logger; - import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import com.cloud.dc.DataCenter; @@ -50,6 +49,8 @@ import com.cloud.user.Account; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.Nic.ReservationStrategy; import com.cloud.vm.NicProfile; @@ -192,16 +193,15 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { s_logger.debug("public network deallocate network: networkId: " + nic.getNetworkId() + ", ip: " + nic.getIp4Address()); } - IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIp4Address()); + final IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIp4Address()); if (ip != null && nic.getReservationStrategy() != ReservationStrategy.Managed) { - - Transaction txn = Transaction.currentTxn(); - txn.start(); - - _ipAddrMgr.markIpAsUnavailable(ip.getId()); - _ipAddressDao.unassignIpAddress(ip.getId()); - - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + _ipAddrMgr.markIpAsUnavailable(ip.getId()); + _ipAddressDao.unassignIpAddress(ip.getId()); + } + }); } nic.deallocate(); diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index c685ee3e40b..d49f309e577 100755 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -130,7 +130,7 @@ import com.cloud.network.rules.StickinessPolicy; import com.cloud.network.vpc.VpcManager; import com.cloud.offering.NetworkOffering; import com.cloud.projects.Project.ListProjectResourcesCriteria; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.tags.ResourceTagVO; @@ -152,6 +152,10 @@ import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionCallbackWithException; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; import com.cloud.utils.net.NetUtils; @@ -379,11 +383,11 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements @Override @DB - public boolean configureLbAutoScaleVmGroup(long vmGroupid, String currentState) throws ResourceUnavailableException { - AutoScaleVmGroupVO vmGroup = _autoScaleVmGroupDao.findById(vmGroupid); + public boolean configureLbAutoScaleVmGroup(final long vmGroupid, String currentState) throws ResourceUnavailableException { + final AutoScaleVmGroupVO vmGroup = _autoScaleVmGroupDao.findById(vmGroupid); boolean success = false; - LoadBalancerVO loadBalancer = _lbDao.findById(vmGroup.getLoadBalancerId()); + final LoadBalancerVO loadBalancer = _lbDao.findById(vmGroup.getLoadBalancerId()); FirewallRule.State backupState = loadBalancer.getState(); @@ -416,14 +420,17 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements if (success) { if (vmGroup.getState().equals(AutoScaleVmGroup.State_New)) { - Transaction.currentTxn().start(); - loadBalancer.setState(FirewallRule.State.Active); - s_logger.debug("LB rule " + loadBalancer.getId() + " state is set to Active"); - _lbDao.persist(loadBalancer); - vmGroup.setState(AutoScaleVmGroup.State_Enabled); - _autoScaleVmGroupDao.persist(vmGroup); - s_logger.debug("LB Auto Scale Vm Group with Id: " + vmGroupid + " is set to Enabled state."); - Transaction.currentTxn().commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + loadBalancer.setState(FirewallRule.State.Active); + s_logger.debug("LB rule " + loadBalancer.getId() + " state is set to Active"); + _lbDao.persist(loadBalancer); + vmGroup.setState(AutoScaleVmGroup.State_Enabled); + _autoScaleVmGroupDao.persist(vmGroup); + s_logger.debug("LB Auto Scale Vm Group with Id: " + vmGroupid + " is set to Enabled state."); + } + }); } s_logger.info("Successfully configured LB Autoscale Vm Group with Id: " + vmGroupid); } @@ -813,7 +820,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements throw new InvalidParameterException("Invalid Load balancer : " + healthCheckPolicy.getLoadBalancerId() + " for HealthCheck policy id: " + healthCheckPolicyId); } - long loadBalancerId = loadBalancer.getId(); + final long loadBalancerId = loadBalancer.getId(); FirewallRule.State backupState = loadBalancer.getState(); _accountMgr.checkAccess(caller.getCallingAccount(), null, true, loadBalancer); @@ -830,17 +837,19 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements + ", healthCheckpolicyID " + healthCheckPolicyId); // removing the state of services set by the monitor. - List maps = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId); + final List maps = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId); if (maps != null) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - s_logger.debug("Resetting health state policy for services in loadbalancing rule id : " - + loadBalancerId); - for (LoadBalancerVMMapVO map : maps) { - map.setState(null); - _lb2VmMapDao.persist(map); - } - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + s_logger.debug("Resetting health state policy for services in loadbalancing rule id : " + + loadBalancerId); + for (LoadBalancerVMMapVO map : maps) { + map.setState(null); + _lb2VmMapDao.persist(map); + } + } + }); } try { @@ -957,7 +966,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements CallContext ctx = CallContext.current(); Account caller = ctx.getCallingAccount(); - LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId); + final LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId); if (loadBalancer == null) { throw new InvalidParameterValueException("Failed to assign to load balancer " + loadBalancerId + ", the load balancer was not found."); @@ -969,7 +978,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements mappedInstanceIds.add(Long.valueOf(mappedInstance.getInstanceId())); } - List vmsToAdd = new ArrayList(); + final List vmsToAdd = new ArrayList(); if (instanceIds == null || instanceIds.isEmpty()) { s_logger.warn("List of vms to assign to the lb, is empty"); @@ -1022,13 +1031,16 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements vmsToAdd.add(vm); } - Transaction txn = Transaction.currentTxn(); - txn.start(); - for (UserVm vm : vmsToAdd) { - LoadBalancerVMMapVO map = new LoadBalancerVMMapVO(loadBalancer.getId(), vm.getId(), false); - map = _lb2VmMapDao.persist(map); - } - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + for (UserVm vm : vmsToAdd) { + LoadBalancerVMMapVO map = new LoadBalancerVMMapVO(loadBalancer.getId(), vm.getId(), false); + map = _lb2VmMapDao.persist(map); + } + } + }); + if (_autoScaleVmGroupDao.isAutoScaleLoadBalancer(loadBalancerId)) { // For autoscaled loadbalancer, the rules need not be applied, // meaning the call need not reach the resource layer. @@ -1044,13 +1056,15 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements success = true; } catch (ResourceUnavailableException e) { if (isRollBackAllowedForProvider(loadBalancer)) { - List vmInstanceIds = new ArrayList(); - txn = Transaction.currentTxn(); - txn.start(); - for (UserVm vm : vmsToAdd) { - vmInstanceIds.add(vm.getId()); - } - txn.commit(); + final List vmInstanceIds = new ArrayList(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + for (UserVm vm : vmsToAdd) { + vmInstanceIds.add(vm.getId()); + } + } + }); if (!vmInstanceIds.isEmpty()) { _lb2VmMapDao.remove(loadBalancer.getId(), vmInstanceIds, null); s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " while attaching VM: " @@ -1203,49 +1217,52 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } @DB - public boolean deleteLoadBalancerRule(long loadBalancerId, boolean apply, Account caller, long callerUserId, + public boolean deleteLoadBalancerRule(final long loadBalancerId, boolean apply, Account caller, long callerUserId, boolean rollBack) { - LoadBalancerVO lb = _lbDao.findById(loadBalancerId); - Transaction txn = Transaction.currentTxn(); - boolean generateUsageEvent = false; - boolean success = true; + final LoadBalancerVO lb = _lbDao.findById(loadBalancerId); FirewallRule.State backupState = lb.getState(); - txn.start(); - if (lb.getState() == FirewallRule.State.Staged) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Found a rule that is still in stage state so just removing it: " + lb); + List backupMaps = Transaction.execute(new TransactionCallback>() { + @Override + public List doInTransaction(TransactionStatus status) { + boolean generateUsageEvent = false; + + if (lb.getState() == FirewallRule.State.Staged) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Found a rule that is still in stage state so just removing it: " + lb); + } + generateUsageEvent = true; + } else if (lb.getState() == FirewallRule.State.Add || lb.getState() == FirewallRule.State.Active) { + lb.setState(FirewallRule.State.Revoke); + _lbDao.persist(lb); + generateUsageEvent = true; + } + List backupMaps = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId); + List maps = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId); + if (maps != null) { + for (LoadBalancerVMMapVO map : maps) { + map.setRevoke(true); + _lb2VmMapDao.persist(map); + s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", vmId " + + map.getInstanceId()); + } + } + + List hcPolicies = _lb2healthcheckDao.listByLoadBalancerId(loadBalancerId); + for (LBHealthCheckPolicyVO lbHealthCheck : hcPolicies) { + lbHealthCheck.setRevoke(true); + _lb2healthcheckDao.persist(lbHealthCheck); + } + + if (generateUsageEvent) { + // Generate usage event right after all rules were marked for revoke + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_DELETE, lb.getAccountId(), 0, lb.getId(), + null, LoadBalancingRule.class.getName(), lb.getUuid()); + } + + return backupMaps; } - generateUsageEvent = true; - } else if (lb.getState() == FirewallRule.State.Add || lb.getState() == FirewallRule.State.Active) { - lb.setState(FirewallRule.State.Revoke); - _lbDao.persist(lb); - generateUsageEvent = true; - } - List backupMaps = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId); - List maps = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId); - if (maps != null) { - for (LoadBalancerVMMapVO map : maps) { - map.setRevoke(true); - _lb2VmMapDao.persist(map); - s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", vmId " - + map.getInstanceId()); - } - } - - List hcPolicies = _lb2healthcheckDao.listByLoadBalancerId(loadBalancerId); - for (LBHealthCheckPolicyVO lbHealthCheck : hcPolicies) { - lbHealthCheck.setRevoke(true); - _lb2healthcheckDao.persist(lbHealthCheck); - } - - if (generateUsageEvent) { - // Generate usage event right after all rules were marked for revoke - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_DELETE, lb.getAccountId(), 0, lb.getId(), - null, LoadBalancingRule.class.getName(), lb.getUuid()); - } - - txn.commit(); + }); // gather external network usage stats for this lb rule NetworkVO network = _networkDao.findById(lb.getNetworkId()); @@ -1283,7 +1300,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements if (relatedRule != null) { s_logger.warn("Unable to remove firewall rule id=" + lb.getId() + " as it has related firewall rule id=" + relatedRule.getId() + "; leaving it in Revoke state"); - success = false; + return false; } else { _firewallMgr.removeRule(lb); } @@ -1293,11 +1310,9 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements // Bug CS-15411 opened to document this // _elbMgr.handleDeleteLoadBalancerRule(lb, callerUserId, caller); - if (success) { - s_logger.debug("Load balancer with id " + lb.getId() + " is removed successfully"); - } - - return success; + s_logger.debug("Load balancer with id " + lb.getId() + " is removed successfully"); + + return true; } @Override @@ -1392,8 +1407,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements @DB @Override - public LoadBalancer createPublicLoadBalancer(String xId, String name, String description, - int srcPort, int destPort, long sourceIpId, String protocol, String algorithm, boolean openFirewall, CallContext caller) + public LoadBalancer createPublicLoadBalancer(final String xId, final String name, final String description, + final int srcPort, final int destPort, final long sourceIpId, final String protocol, final String algorithm, final boolean openFirewall, final CallContext caller) throws NetworkRuleConflictException { if (!NetUtils.isValidPort(destPort)) { @@ -1404,7 +1419,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements throw new InvalidParameterValueException("Invalid algorithm: " + algorithm); } - IPAddressVO ipAddr = _ipAddressDao.findById(sourceIpId); + final IPAddressVO ipAddr = _ipAddressDao.findById(sourceIpId); // make sure ip address exists if (ipAddr == null || !ipAddr.readyToUse()) { InvalidParameterValueException ex = new InvalidParameterValueException( @@ -1426,7 +1441,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements _accountMgr.checkAccess(caller.getCallingAccount(), null, true, ipAddr); - Long networkId = ipAddr.getAssociatedWithNetworkId(); + final Long networkId = ipAddr.getAssociatedWithNetworkId(); if (networkId == null) { InvalidParameterValueException ex = new InvalidParameterValueException( "Unable to create load balancer rule ; specified sourceip id is not associated with any network"); @@ -1440,61 +1455,60 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements _firewallMgr.validateFirewallRule(caller.getCallingAccount(), ipAddr, srcPort, srcPort, protocol, Purpose.LoadBalancing, FirewallRuleType.User, networkId, null); - LoadBalancerVO newRule = new LoadBalancerVO(xId, name, description, - sourceIpId, srcPort, destPort, algorithm, - networkId, ipAddr.getAllocatedToAccountId(), ipAddr.getAllocatedInDomainId()); - // verify rule is supported by Lb provider of the network - Ip sourceIp = getSourceIp(newRule); - LoadBalancingRule loadBalancing = new LoadBalancingRule(newRule, new ArrayList(), - new ArrayList(), new ArrayList(), sourceIp); - if (!validateLbRule(loadBalancing)) { - throw new InvalidParameterValueException("LB service provider cannot support this rule"); - } + return Transaction.execute(new TransactionCallbackWithException() { + @Override + public LoadBalancerVO doInTransaction(TransactionStatus status) throws NetworkRuleConflictException { + LoadBalancerVO newRule = new LoadBalancerVO(xId, name, description, + sourceIpId, srcPort, destPort, algorithm, + networkId, ipAddr.getAllocatedToAccountId(), ipAddr.getAllocatedInDomainId()); - Transaction txn = Transaction.currentTxn(); - txn.start(); + // verify rule is supported by Lb provider of the network + Ip sourceIp = getSourceIp(newRule); + LoadBalancingRule loadBalancing = new LoadBalancingRule(newRule, new ArrayList(), + new ArrayList(), new ArrayList(), sourceIp); + if (!validateLbRule(loadBalancing)) { + throw new InvalidParameterValueException("LB service provider cannot support this rule"); + } + + newRule = _lbDao.persist(newRule); - newRule = _lbDao.persist(newRule); - - //create rule for all CIDRs - if (openFirewall) { - _firewallMgr.createRuleForAllCidrs(sourceIpId, caller.getCallingAccount(), srcPort, - srcPort, protocol, null, null, newRule.getId(), networkId); - } - - boolean success = true; - - try { - _firewallMgr.detectRulesConflict(newRule); - if (!_firewallDao.setStateToAdd(newRule)) { - throw new CloudRuntimeException("Unable to update the state to add for " + newRule); + //create rule for all CIDRs + if (openFirewall) { + _firewallMgr.createRuleForAllCidrs(sourceIpId, caller.getCallingAccount(), srcPort, + srcPort, protocol, null, null, newRule.getId(), networkId); + } + + boolean success = true; + + try { + _firewallMgr.detectRulesConflict(newRule); + if (!_firewallDao.setStateToAdd(newRule)) { + throw new CloudRuntimeException("Unable to update the state to add for " + newRule); + } + s_logger.debug("Load balancer " + newRule.getId() + " for Ip address id=" + sourceIpId + ", public port " + + srcPort + ", private port " + destPort + " is added successfully."); + CallContext.current().setEventDetails("Load balancer Id: " + newRule.getId()); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_CREATE, ipAddr.getAllocatedToAccountId(), + ipAddr.getDataCenterId(), newRule.getId(), null, LoadBalancingRule.class.getName(), + newRule.getUuid()); + + return newRule; + } catch (Exception e) { + success = false; + if (e instanceof NetworkRuleConflictException) { + throw (NetworkRuleConflictException) e; + } + throw new CloudRuntimeException("Unable to add rule for ip address id=" + newRule.getSourceIpAddressId(), e); + } finally { + if (!success && newRule != null) { + _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false); + removeLBRule(newRule); + } + } } - s_logger.debug("Load balancer " + newRule.getId() + " for Ip address id=" + sourceIpId + ", public port " - + srcPort + ", private port " + destPort + " is added successfully."); - CallContext.current().setEventDetails("Load balancer Id: " + newRule.getId()); - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_CREATE, ipAddr.getAllocatedToAccountId(), - ipAddr.getDataCenterId(), newRule.getId(), null, LoadBalancingRule.class.getName(), - newRule.getUuid()); - txn.commit(); + }); - return newRule; - } catch (Exception e) { - success = false; - if (e instanceof NetworkRuleConflictException) { - throw (NetworkRuleConflictException) e; - } - throw new CloudRuntimeException("Unable to add rule for ip address id=" + newRule.getSourceIpAddressId(), e); - } finally { - if (!success && newRule != null) { - - txn.start(); - _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false); - removeLBRule(newRule); - - txn.commit(); - } - } } @Override @@ -1583,7 +1597,6 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements @DB protected boolean applyLoadBalancerRules(List lbs, boolean updateRulesInDB) throws ResourceUnavailableException { - Transaction txn = Transaction.currentTxn(); List rules = new ArrayList(); for (LoadBalancerVO lb : lbs) { rules.add(getLoadBalancerRuleToApply(lb)); @@ -1595,57 +1608,63 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } if (updateRulesInDB) { - for (LoadBalancerVO lb : lbs) { - boolean checkForReleaseElasticIp = false; - txn.start(); - if (lb.getState() == FirewallRule.State.Revoke) { - removeLBRule(lb); - s_logger.debug("LB " + lb.getId() + " is successfully removed"); - checkForReleaseElasticIp = true; - } else if (lb.getState() == FirewallRule.State.Add) { - lb.setState(FirewallRule.State.Active); - s_logger.debug("LB rule " + lb.getId() + " state is set to Active"); - _lbDao.persist(lb); - } + for (final LoadBalancerVO lb : lbs) { + boolean checkForReleaseElasticIp = Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + boolean checkForReleaseElasticIp = false; - // remove LB-Vm mappings that were state to revoke - List lbVmMaps = _lb2VmMapDao.listByLoadBalancerId(lb.getId(), true); - List instanceIds = new ArrayList(); + if (lb.getState() == FirewallRule.State.Revoke) { + removeLBRule(lb); + s_logger.debug("LB " + lb.getId() + " is successfully removed"); + checkForReleaseElasticIp = true; + } else if (lb.getState() == FirewallRule.State.Add) { + lb.setState(FirewallRule.State.Active); + s_logger.debug("LB rule " + lb.getId() + " state is set to Active"); + _lbDao.persist(lb); + } + + // remove LB-Vm mappings that were state to revoke + List lbVmMaps = _lb2VmMapDao.listByLoadBalancerId(lb.getId(), true); + List instanceIds = new ArrayList(); + + for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) { + instanceIds.add(lbVmMap.getInstanceId()); + } + + if (!instanceIds.isEmpty()) { + _lb2VmMapDao.remove(lb.getId(), instanceIds, null); + s_logger.debug("Load balancer rule id " + lb.getId() + " is removed for vms " + instanceIds); + } + + if (_lb2VmMapDao.listByLoadBalancerId(lb.getId()).isEmpty()) { + lb.setState(FirewallRule.State.Add); + _lbDao.persist(lb); + s_logger.debug("LB rule " + lb.getId() + + " state is set to Add as there are no more active LB-VM mappings"); + } + + // remove LB-Stickiness policy mapping that were state to revoke + List stickinesspolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId( + lb.getId(), true); + if (!stickinesspolicies.isEmpty()) { + _lb2stickinesspoliciesDao.remove(lb.getId(), true); + s_logger.debug("Load balancer rule id " + lb.getId() + " is removed stickiness policies"); + } + + // remove LB-HealthCheck policy mapping that were state to + // revoke + List healthCheckpolicies = _lb2healthcheckDao.listByLoadBalancerId(lb.getId(), + true); + if (!healthCheckpolicies.isEmpty()) { + _lb2healthcheckDao.remove(lb.getId(), true); + s_logger.debug("Load balancer rule id " + lb.getId() + " is removed health check monitors policies"); + } + + return checkForReleaseElasticIp; + } + }); - for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) { - instanceIds.add(lbVmMap.getInstanceId()); - } - - if (!instanceIds.isEmpty()) { - _lb2VmMapDao.remove(lb.getId(), instanceIds, null); - s_logger.debug("Load balancer rule id " + lb.getId() + " is removed for vms " + instanceIds); - } - - if (_lb2VmMapDao.listByLoadBalancerId(lb.getId()).isEmpty()) { - lb.setState(FirewallRule.State.Add); - _lbDao.persist(lb); - s_logger.debug("LB rule " + lb.getId() - + " state is set to Add as there are no more active LB-VM mappings"); - } - - // remove LB-Stickiness policy mapping that were state to revoke - List stickinesspolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId( - lb.getId(), true); - if (!stickinesspolicies.isEmpty()) { - _lb2stickinesspoliciesDao.remove(lb.getId(), true); - s_logger.debug("Load balancer rule id " + lb.getId() + " is removed stickiness policies"); - } - - // remove LB-HealthCheck policy mapping that were state to - // revoke - List healthCheckpolicies = _lb2healthcheckDao.listByLoadBalancerId(lb.getId(), - true); - if (!healthCheckpolicies.isEmpty()) { - _lb2healthcheckDao.remove(lb.getId(), true); - s_logger.debug("Load balancer rule id " + lb.getId() + " is removed health check monitors policies"); - } - - txn.commit(); if (checkForReleaseElasticIp && lb.getSourceIpAddressId() != null) { boolean success = true; long count = _firewallDao.countRulesByIpId(lb.getSourceIpAddressId()); @@ -2036,7 +2055,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements if (tags != null && !tags.isEmpty()) { int count = 0; - sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.LoadBalancer.toString()); + sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.LoadBalancer.toString()); for (String key : tags.keySet()) { sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 5ea75604ebe..5b9d84e4d04 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -230,6 +230,8 @@ import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; import com.cloud.utils.net.MacAddress; @@ -578,34 +580,30 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V @DB public void processStopOrRebootAnswer(final DomainRouterVO router, Answer answer) { - final Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - //FIXME!!! - UserStats command should grab bytesSent/Received for all guest interfaces of the VR - List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); - for (Long guestNtwkId : routerGuestNtwkIds) { - final UserStatisticsVO userStats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterId(), - guestNtwkId, null, router.getId(), router.getType().toString()); - if (userStats != null) { - final long currentBytesRcvd = userStats.getCurrentBytesReceived(); - userStats.setCurrentBytesReceived(0); - userStats.setNetBytesReceived(userStats.getNetBytesReceived() + currentBytesRcvd); - - final long currentBytesSent = userStats.getCurrentBytesSent(); - userStats.setCurrentBytesSent(0); - userStats.setNetBytesSent(userStats.getNetBytesSent() + currentBytesSent); - _userStatsDao.update(userStats.getId(), userStats); - s_logger.debug("Successfully updated user statistics as a part of domR " + router + " reboot/stop"); - } else { - s_logger.warn("User stats were not created for account " + router.getAccountId() + " and dc " + router.getDataCenterId()); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + //FIXME!!! - UserStats command should grab bytesSent/Received for all guest interfaces of the VR + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + for (Long guestNtwkId : routerGuestNtwkIds) { + final UserStatisticsVO userStats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterId(), + guestNtwkId, null, router.getId(), router.getType().toString()); + if (userStats != null) { + final long currentBytesRcvd = userStats.getCurrentBytesReceived(); + userStats.setCurrentBytesReceived(0); + userStats.setNetBytesReceived(userStats.getNetBytesReceived() + currentBytesRcvd); + + final long currentBytesSent = userStats.getCurrentBytesSent(); + userStats.setCurrentBytesSent(0); + userStats.setNetBytesSent(userStats.getNetBytesSent() + currentBytesSent); + _userStatsDao.update(userStats.getId(), userStats); + s_logger.debug("Successfully updated user statistics as a part of domR " + router + " reboot/stop"); + } else { + s_logger.warn("User stats were not created for account " + router.getAccountId() + " and dc " + router.getDataCenterId()); + } + } } - } - - txn.commit(); - } catch (final Exception e) { - txn.rollback(); - throw new CloudRuntimeException("Problem updating stats after reboot/stop ", e); - } + }); } @Override @ActionEvent(eventType = EventTypes.EVENT_ROUTER_REBOOT, eventDescription = "rebooting router Vm", async = true) @@ -862,21 +860,21 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V final List routers = _routerDao.listByStateAndNetworkType(State.Running, GuestType.Isolated, mgmtSrvrId); s_logger.debug("Found " + routers.size() + " running routers. "); - for (DomainRouterVO router : routers) { + for (final DomainRouterVO router : routers) { String privateIP = router.getPrivateIpAddress(); if (privateIP != null) { - boolean forVpc = router.getVpcId() != null; + final boolean forVpc = router.getVpcId() != null; List routerNics = _nicDao.listByVmId(router.getId()); - for (Nic routerNic : routerNics) { - Network network = _networkModel.getNetwork(routerNic.getNetworkId()); + for (final Nic routerNic : routerNics) { + final Network network = _networkModel.getNetwork(routerNic.getNetworkId()); //Send network usage command for public nic in VPC VR //Send network usage command for isolated guest nic of non VPC VR if ((forVpc && network.getTrafficType() == TrafficType.Public) || (!forVpc && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Isolated)) { final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), forVpc, routerNic.getIp4Address()); - String routerType = router.getType().toString(); - UserStatisticsVO previousStats = _userStatsDao.findBy(router.getAccountId(), + final String routerType = router.getType().toString(); + final UserStatisticsVO previousStats = _userStatsDao.findBy(router.getAccountId(), router.getDataCenterId(), network.getId(), (forVpc ? routerNic.getIp4Address() : null), router.getId(), routerType); NetworkUsageAnswer answer = null; try { @@ -891,62 +889,63 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V s_logger.warn("Error while collecting network stats from router: " + router.getInstanceName() + " from host: " + router.getHostId() + "; details: " + answer.getDetails()); continue; } - Transaction txn = Transaction.open(Transaction.CLOUD_DB); try { if ((answer.getBytesReceived() == 0) && (answer.getBytesSent() == 0)) { s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics"); continue; } - txn.start(); - UserStatisticsVO stats = _userStatsDao.lock(router.getAccountId(), - router.getDataCenterId(), network.getId(), (forVpc ? routerNic.getIp4Address() : null), router.getId(), routerType); - if (stats == null) { - s_logger.warn("unable to find stats for account: " + router.getAccountId()); - continue; - } - - if (previousStats != null - && ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived()) - || (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))) { - s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + - "Ignoring current answer. Router: " + answer.getRouterName() + " Rcvd: " + - answer.getBytesReceived() + "Sent: " + answer.getBytesSent()); - continue; - } - - if (stats.getCurrentBytesReceived() > answer.getBytesReceived()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Received # of bytes that's less than the last one. " + - "Assuming something went wrong and persisting it. Router: " + - answer.getRouterName() + " Reported: " + answer.getBytesReceived() - + " Stored: " + stats.getCurrentBytesReceived()); + final NetworkUsageAnswer answerFinal = answer; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + UserStatisticsVO stats = _userStatsDao.lock(router.getAccountId(), + router.getDataCenterId(), network.getId(), (forVpc ? routerNic.getIp4Address() : null), router.getId(), routerType); + if (stats == null) { + s_logger.warn("unable to find stats for account: " + router.getAccountId()); + return; + } + + if (previousStats != null + && ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived()) + || (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))) { + s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + + "Ignoring current answer. Router: " + answerFinal.getRouterName() + " Rcvd: " + + answerFinal.getBytesReceived() + "Sent: " + answerFinal.getBytesSent()); + return; + } + + if (stats.getCurrentBytesReceived() > answerFinal.getBytesReceived()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Received # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Router: " + + answerFinal.getRouterName() + " Reported: " + answerFinal.getBytesReceived() + + " Stored: " + stats.getCurrentBytesReceived()); + } + stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); + } + stats.setCurrentBytesReceived(answerFinal.getBytesReceived()); + if (stats.getCurrentBytesSent() > answerFinal.getBytesSent()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Received # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Router: " + + answerFinal.getRouterName() + " Reported: " + answerFinal.getBytesSent() + + " Stored: " + stats.getCurrentBytesSent()); + } + stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); + } + stats.setCurrentBytesSent(answerFinal.getBytesSent()); + if (! _dailyOrHourly) { + //update agg bytes + stats.setAggBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); + stats.setAggBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); + } + _userStatsDao.update(stats.getId(), stats); } - stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); - } - stats.setCurrentBytesReceived(answer.getBytesReceived()); - if (stats.getCurrentBytesSent() > answer.getBytesSent()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Received # of bytes that's less than the last one. " + - "Assuming something went wrong and persisting it. Router: " + - answer.getRouterName() + " Reported: " + answer.getBytesSent() - + " Stored: " + stats.getCurrentBytesSent()); - } - stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); - } - stats.setCurrentBytesSent(answer.getBytesSent()); - if (! _dailyOrHourly) { - //update agg bytes - stats.setAggBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); - stats.setAggBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); - } - _userStatsDao.update(stats.getId(), stats); - txn.commit(); + }); + } catch (Exception e) { - txn.rollback(); s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + " Rx: " + answer.getBytesReceived() + "; Tx: " + answer.getBytesSent()); - } finally { - txn.close(); } } } @@ -977,30 +976,30 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V scanLock.unlock(); return; } - Transaction txn = Transaction.open(Transaction.CLOUD_DB); try { - txn.start(); - //get all stats with delta > 0 - List updatedStats = _userStatsDao.listUpdatedStats(); - Date updatedTime = new Date(); - for(UserStatisticsVO stat : updatedStats){ - //update agg bytes - stat.setAggBytesReceived(stat.getCurrentBytesReceived() + stat.getNetBytesReceived()); - stat.setAggBytesSent(stat.getCurrentBytesSent() + stat.getNetBytesSent()); - _userStatsDao.update(stat.getId(), stat); - //insert into op_user_stats_log - UserStatsLogVO statsLog = new UserStatsLogVO(stat.getId(), stat.getNetBytesReceived(), stat.getNetBytesSent(), stat.getCurrentBytesReceived(), - stat.getCurrentBytesSent(), stat.getAggBytesReceived(), stat.getAggBytesSent(), updatedTime); - _userStatsLogDao.persist(statsLog); - } - s_logger.debug("Successfully updated aggregate network stats"); - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + //get all stats with delta > 0 + List updatedStats = _userStatsDao.listUpdatedStats(); + Date updatedTime = new Date(); + for(UserStatisticsVO stat : updatedStats){ + //update agg bytes + stat.setAggBytesReceived(stat.getCurrentBytesReceived() + stat.getNetBytesReceived()); + stat.setAggBytesSent(stat.getCurrentBytesSent() + stat.getNetBytesSent()); + _userStatsDao.update(stat.getId(), stat); + //insert into op_user_stats_log + UserStatsLogVO statsLog = new UserStatsLogVO(stat.getId(), stat.getNetBytesReceived(), stat.getNetBytesSent(), stat.getCurrentBytesReceived(), + stat.getCurrentBytesSent(), stat.getAggBytesReceived(), stat.getAggBytesSent(), updatedTime); + _userStatsLogDao.persist(statsLog); + } + s_logger.debug("Successfully updated aggregate network stats"); + } + }); } catch (Exception e){ - txn.rollback(); s_logger.debug("Failed to update aggregate network stats", e); } finally { scanLock.unlock(); - txn.close(); } } } catch (Exception e){ @@ -1137,17 +1136,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } } if (updated) { - Transaction txn = Transaction.open(Transaction.CLOUD_DB); - try { - txn.start(); - _routerDao.update(router.getId(), router); - txn.commit(); - } catch (Exception e) { - txn.rollback(); - s_logger.warn("Unable to update router status for account: " + router.getAccountId()); - } finally { - txn.close(); - } + _routerDao.update(router.getId(), router); } RedundantState currState = router.getRedundantState(); if (prevState != currState) { @@ -1412,6 +1401,26 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V throw new CloudRuntimeException(errMsg); } + private void checkAndResetPriorityOfRedundantRouter(List routers) { + boolean allStopped = true; + for (DomainRouterVO router : routers) { + if (!router.getIsRedundantRouter() || router.getState() != VirtualMachine.State.Stopped) { + allStopped = false; + break; + } + } + if (!allStopped) { + return; + } + + for (DomainRouterVO router : routers) { + // getUpdatedPriority() would update the value later + router.setPriority(0); + router.setIsPriorityBumpUp(false); + _routerDao.update(router.getId(), router); + } + } + @DB protected List findOrDeployVirtualRouterInGuestNetwork(Network guestNetwork, DeployDestination dest, Account owner, boolean isRedundant, Map params) throws ConcurrentOperationException, @@ -1482,6 +1491,10 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V int routerCount = 1; if (isRedundant) { routerCount = 2; + //Check current redundant routers, if possible(all routers are stopped), reset the priority + if (routers.size() != 0) { + checkAndResetPriorityOfRedundantRouter(routers); + } } // If old network is redundant but new is single router, then routers.size() = 2 but routerCount = 1 @@ -2459,7 +2472,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V s_logger.debug("Found " + vpns.size() + " vpn(s) to apply as a part of domR " + router + " start."); if (!vpns.isEmpty()) { for (RemoteAccessVpn vpn : vpns) { - createApplyVpnCommands(vpn, router, cmds); + createApplyVpnCommands(true, vpn, router, cmds); } } @@ -2661,7 +2674,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } Commands cmds = new Commands(Command.OnError.Stop); - createApplyVpnCommands(vpn, router, cmds); + createApplyVpnCommands(true, vpn, router, cmds); try { _agentMgr.send(router.getHostId(), cmds); @@ -2705,19 +2718,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V for (VirtualRouter router : routers) { if (router.getState() == State.Running) { Commands cmds = new Commands(Command.OnError.Continue); - IpAddress ip = _networkModel.getIp(vpn.getServerAddressId()); - - RemoteAccessVpnCfgCommand removeVpnCmd = new RemoteAccessVpnCfgCommand(false, ip.getAddress().addr(), - vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey()); - removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(network.getId(), router.getId())); - removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - - DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId()); - removeVpnCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - - cmds.addCommand(removeVpnCmd); - + createApplyVpnCommands(false, vpn, router, cmds); result = result && sendCommandsToRouter(router, cmds); } else if (router.getState() == State.Stopped) { s_logger.debug("Router " + router + " is in Stopped state, not sending deleteRemoteAccessVpn command to it"); @@ -2847,12 +2848,15 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V configDnsMasq(router, network, cmds); boolean result = sendCommandsToRouter(router, cmds); if (result == false) { - NicIpAliasVO ipAliasVO = _nicIpAliasDao.findByInstanceIdAndNetworkId(network.getId(), router.getId()); - Transaction txn = Transaction.currentTxn(); - txn.start(); - _nicIpAliasDao.expunge(ipAliasVO.getId()); - _ipAddressDao.unassignIpAddress(routerPublicIP.getId()); - txn.commit(); + final NicIpAliasVO ipAliasVO = _nicIpAliasDao.findByInstanceIdAndNetworkId(network.getId(), router.getId()); + final PublicIp routerPublicIPFinal = routerPublicIP; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + _nicIpAliasDao.expunge(ipAliasVO.getId()); + _ipAddressDao.unassignIpAddress(routerPublicIPFinal.getId()); + } + }); throw new CloudRuntimeException("failed to configure ip alias on the router as a part of dhcp config"); } } @@ -2877,7 +2881,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } Commands cmds = new Commands(Command.OnError.Continue); - List revokedIpAliasVOs = _nicIpAliasDao.listByNetworkIdAndState(network.getId(), NicIpAlias.state.revoked); + final List revokedIpAliasVOs = _nicIpAliasDao.listByNetworkIdAndState(network.getId(), NicIpAlias.state.revoked); s_logger.debug("Found" + revokedIpAliasVOs.size() + "ip Aliases to revoke on the router as a part of dhcp configuration"); List revokedIpAliasTOs = new ArrayList(); for (NicIpAliasVO revokedAliasVO : revokedIpAliasVOs) { @@ -2893,12 +2897,14 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V configDnsMasq(router, network, cmds); boolean result = sendCommandsToRouter(router, cmds); if (result) { - Transaction txn= Transaction.currentTxn(); - txn.start(); - for (NicIpAliasVO revokedAliasVO : revokedIpAliasVOs) { - _nicIpAliasDao.expunge(revokedAliasVO.getId()); - } - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + for (NicIpAliasVO revokedAliasVO : revokedIpAliasVOs) { + _nicIpAliasDao.expunge(revokedAliasVO.getId()); + } + } + }); return true; } } @@ -3018,6 +3024,28 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V }); } + protected void createApplyVpnUsersCommand(List users, VirtualRouter router, Commands cmds) + { + List addUsers = new ArrayList(); + List removeUsers = new ArrayList(); + for (VpnUser user : users) { + if (user.getState() == VpnUser.State.Add || user.getState() == VpnUser.State.Active) { + addUsers.add(user); + } else if (user.getState() == VpnUser.State.Revoke) { + removeUsers.add(user); + } + } + + VpnUsersCfgCommand cmd = new VpnUsersCfgCommand(addUsers, removeUsers); + cmd.setAccessDetail(NetworkElementCommand.ACCOUNT_ID, String.valueOf(router.getAccountId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + + cmds.addCommand("users", cmd); + } + @Override //FIXME add partial success and STOP state support public String[] applyVpnUsers(Network network, List users, List routers) throws ResourceUnavailableException { @@ -3037,27 +3065,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } Commands cmds = new Commands(Command.OnError.Continue); - List addUsers = new ArrayList(); - List removeUsers = new ArrayList(); - for (VpnUser user : users) { - if (user.getState() == VpnUser.State.Add || user.getState() == VpnUser.State.Active) { - addUsers.add(user); - } else if (user.getState() == VpnUser.State.Revoke) { - removeUsers.add(user); - } - } - - VpnUsersCfgCommand cmd = new VpnUsersCfgCommand(addUsers, removeUsers); - cmd.setAccessDetail(NetworkElementCommand.ACCOUNT_ID, String.valueOf(router.getAccountId())); - cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_CIDR, network.getCidr()); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(network.getId(), router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId()); - cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - - cmds.addCommand(cmd); - + createApplyVpnUsersCommand(users, router, cmds); // Currently we receive just one answer from the agent. In the future we have to parse individual answers and set // results accordingly @@ -3314,9 +3322,10 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V else { maxconn = offering.getConcurrentConnections().toString(); } + LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs, routerPublicIp, getRouterIpInNetwork(guestNetworkId, router.getId()), router.getPrivateIpAddress(), - _itMgr.toNicTO(nicProfile, router.getHypervisorType()), router.getVpcId(), maxconn); + _itMgr.toNicTO(nicProfile, router.getHypervisorType()), router.getVpcId(), maxconn, offering.isKeepAliveEnabled()); cmd.lbStatsVisibility = _configDao.getValue(Config.NetworkLBHaproxyStatsVisbility.key()); cmd.lbStatsUri = _configDao.getValue(Config.NetworkLBHaproxyStatsUri.key()); @@ -3333,34 +3342,20 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } - private void createApplyVpnCommands(RemoteAccessVpn vpn, VirtualRouter router, Commands cmds) { + protected void createApplyVpnCommands(boolean isCreate, RemoteAccessVpn vpn, VirtualRouter router, Commands cmds) { List vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId()); - List addUsers = new ArrayList(); - List removeUsers = new ArrayList(); - for (VpnUser user : vpnUsers) { - if (user.getState() == VpnUser.State.Add) { - addUsers.add(user); - } else if (user.getState() == VpnUser.State.Revoke) { - removeUsers.add(user); - } - } - VpnUsersCfgCommand addUsersCmd = new VpnUsersCfgCommand(addUsers, removeUsers); - addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(vpn.getNetworkId(), router.getId())); - addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + createApplyVpnUsersCommand(vpnUsers, router, cmds); IpAddress ip = _networkModel.getIp(vpn.getServerAddressId()); - RemoteAccessVpnCfgCommand startVpnCmd = new RemoteAccessVpnCfgCommand(true, ip.getAddress().addr(), + RemoteAccessVpnCfgCommand startVpnCmd = new RemoteAccessVpnCfgCommand(isCreate, ip.getAddress().addr(), vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey()); startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(vpn.getNetworkId(), router.getId())); startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId()); startVpnCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - cmds.addCommand("users", addUsersCmd); cmds.addCommand("startVpn", startVpnCmd); } @@ -3966,7 +3961,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V public void prepareStop(VirtualMachineProfile profile){ //Collect network usage before stopping Vm - DomainRouterVO router = _routerDao.findById(profile.getVirtualMachine().getId()); + final DomainRouterVO router = _routerDao.findById(profile.getVirtualMachine().getId()); if(router == null){ return; } @@ -3974,17 +3969,17 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V String privateIP = router.getPrivateIpAddress(); if (privateIP != null) { - boolean forVpc = router.getVpcId() != null; + final boolean forVpc = router.getVpcId() != null; List routerNics = _nicDao.listByVmId(router.getId()); - for (Nic routerNic : routerNics) { - Network network = _networkModel.getNetwork(routerNic.getNetworkId()); + for (final Nic routerNic : routerNics) { + final Network network = _networkModel.getNetwork(routerNic.getNetworkId()); //Send network usage command for public nic in VPC VR //Send network usage command for isolated guest nic of non VPC VR if ((forVpc && network.getTrafficType() == TrafficType.Public) || (!forVpc && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Isolated)) { final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), forVpc, routerNic.getIp4Address()); - String routerType = router.getType().toString(); - UserStatisticsVO previousStats = _userStatsDao.findBy(router.getAccountId(), + final String routerType = router.getType().toString(); + final UserStatisticsVO previousStats = _userStatsDao.findBy(router.getAccountId(), router.getDataCenterId(), network.getId(), (forVpc ? routerNic.getIp4Address() : null), router.getId(), routerType); NetworkUsageAnswer answer = null; try { @@ -3999,62 +3994,63 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V s_logger.warn("Error while collecting network stats from router: " + router.getInstanceName() + " from host: " + router.getHostId() + "; details: " + answer.getDetails()); continue; } - Transaction txn = Transaction.open(Transaction.CLOUD_DB); try { if ((answer.getBytesReceived() == 0) && (answer.getBytesSent() == 0)) { s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics"); continue; } - txn.start(); - UserStatisticsVO stats = _userStatsDao.lock(router.getAccountId(), - router.getDataCenterId(), network.getId(), (forVpc ? routerNic.getIp4Address() : null), router.getId(), routerType); - if (stats == null) { - s_logger.warn("unable to find stats for account: " + router.getAccountId()); - continue; - } - - if (previousStats != null - && ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived()) - || (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))){ - s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + - "Ignoring current answer. Router: " + answer.getRouterName() + " Rcvd: " + - answer.getBytesReceived() + "Sent: " + answer.getBytesSent()); - continue; - } - - if (stats.getCurrentBytesReceived() > answer.getBytesReceived()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Received # of bytes that's less than the last one. " + - "Assuming something went wrong and persisting it. Router: " + - answer.getRouterName() + " Reported: " + answer.getBytesReceived() - + " Stored: " + stats.getCurrentBytesReceived()); + + final NetworkUsageAnswer answerFinal = answer; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + UserStatisticsVO stats = _userStatsDao.lock(router.getAccountId(), + router.getDataCenterId(), network.getId(), (forVpc ? routerNic.getIp4Address() : null), router.getId(), routerType); + if (stats == null) { + s_logger.warn("unable to find stats for account: " + router.getAccountId()); + return; + } + + if (previousStats != null + && ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived()) + || (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))){ + s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + + "Ignoring current answer. Router: " + answerFinal.getRouterName() + " Rcvd: " + + answerFinal.getBytesReceived() + "Sent: " + answerFinal.getBytesSent()); + return; + } + + if (stats.getCurrentBytesReceived() > answerFinal.getBytesReceived()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Received # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Router: " + + answerFinal.getRouterName() + " Reported: " + answerFinal.getBytesReceived() + + " Stored: " + stats.getCurrentBytesReceived()); + } + stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); + } + stats.setCurrentBytesReceived(answerFinal.getBytesReceived()); + if (stats.getCurrentBytesSent() > answerFinal.getBytesSent()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Received # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Router: " + + answerFinal.getRouterName() + " Reported: " + answerFinal.getBytesSent() + + " Stored: " + stats.getCurrentBytesSent()); + } + stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); + } + stats.setCurrentBytesSent(answerFinal.getBytesSent()); + if (! _dailyOrHourly) { + //update agg bytes + stats.setAggBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); + stats.setAggBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); + } + _userStatsDao.update(stats.getId(), stats); } - stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); - } - stats.setCurrentBytesReceived(answer.getBytesReceived()); - if (stats.getCurrentBytesSent() > answer.getBytesSent()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Received # of bytes that's less than the last one. " + - "Assuming something went wrong and persisting it. Router: " + - answer.getRouterName() + " Reported: " + answer.getBytesSent() - + " Stored: " + stats.getCurrentBytesSent()); - } - stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); - } - stats.setCurrentBytesSent(answer.getBytesSent()); - if (! _dailyOrHourly) { - //update agg bytes - stats.setAggBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); - stats.setAggBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); - } - _userStatsDao.update(stats.getId(), stats); - txn.commit(); + }); } catch (Exception e) { - txn.rollback(); s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + " Rx: " + answer.getBytesReceived() + "; Tx: " + answer.getBytesSent()); - } finally { - txn.close(); } } } diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index 6e326b0f652..2ea10211cce 100755 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -26,7 +26,6 @@ import javax.ejb.Local; import javax.inject.Inject; import org.apache.log4j.Logger; - import org.apache.cloudstack.api.command.user.firewall.ListPortForwardingRulesCmd; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -60,7 +59,7 @@ import com.cloud.network.vpc.VpcManager; import com.cloud.network.vpc.VpcService; import com.cloud.offering.NetworkOffering; import com.cloud.projects.Project.ListProjectResourcesCriteria; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; @@ -76,8 +75,12 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionCallbackWithException; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; import com.cloud.utils.net.NetUtils; @@ -197,12 +200,12 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules @Override @DB @ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "creating forwarding rule", create = true) - public PortForwardingRule createPortForwardingRule(PortForwardingRule rule, Long vmId, Ip vmIp, boolean openFirewall) + public PortForwardingRule createPortForwardingRule(final PortForwardingRule rule, final Long vmId, Ip vmIp, final boolean openFirewall) throws NetworkRuleConflictException { CallContext ctx = CallContext.current(); - Account caller = ctx.getCallingAccount(); + final Account caller = ctx.getCallingAccount(); - Long ipAddrId = rule.getSourceIpAddressId(); + final Long ipAddrId = rule.getSourceIpAddressId(); IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId); @@ -213,7 +216,7 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + " has static nat enabled"); } - Long networkId = rule.getNetworkId(); + final Long networkId = rule.getNetworkId(); Network network = _networkModel.getNetwork(networkId); //associate ip address to network (if needed) boolean performedIpAssoc = false; @@ -245,8 +248,8 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules _firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), Purpose.PortForwarding, FirewallRuleType.User, networkId, rule.getTrafficType()); - Long accountId = ipAddress.getAllocatedToAccountId(); - Long domainId = ipAddress.getAllocatedInDomainId(); + final Long accountId = ipAddress.getAllocatedToAccountId(); + final Long domainId = ipAddress.getAllocatedInDomainId(); // start port can't be bigger than end port if (rule.getDestinationPortStart() > rule.getDestinationPortEnd()) { @@ -308,46 +311,48 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules } } - Transaction txn = Transaction.currentTxn(); - txn.start(); - - PortForwardingRuleVO newRule = new PortForwardingRuleVO(rule.getXid(), rule.getSourceIpAddressId(), - rule.getSourcePortStart(), rule.getSourcePortEnd(), dstIp, rule.getDestinationPortStart(), - rule.getDestinationPortEnd(), rule.getProtocol().toLowerCase(), networkId, accountId, domainId, vmId); - newRule = _portForwardingDao.persist(newRule); - - // create firewallRule for 0.0.0.0/0 cidr - if (openFirewall) { - _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), - rule.getProtocol(), null, null, newRule.getId(), networkId); - } - - try { - _firewallMgr.detectRulesConflict(newRule); - if (!_firewallDao.setStateToAdd(newRule)) { - throw new CloudRuntimeException("Unable to update the state to add for " + newRule); - } - CallContext.current().setEventDetails("Rule Id: " + newRule.getId()); - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), - ipAddress.getDataCenterId(), newRule.getId(), null, PortForwardingRule.class.getName(), - newRule.getUuid()); - txn.commit(); - return newRule; - } catch (Exception e) { - if (newRule != null) { - txn.start(); - // no need to apply the rule as it wasn't programmed on the backend yet - _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false); - removePFRule(newRule); - txn.commit(); + final Ip dstIpFinal = dstIp; + final IPAddressVO ipAddressFinal = ipAddress; + return Transaction.execute(new TransactionCallbackWithException() { + @Override + public PortForwardingRuleVO doInTransaction(TransactionStatus status) throws NetworkRuleConflictException { + PortForwardingRuleVO newRule = new PortForwardingRuleVO(rule.getXid(), rule.getSourceIpAddressId(), + rule.getSourcePortStart(), rule.getSourcePortEnd(), dstIpFinal, rule.getDestinationPortStart(), + rule.getDestinationPortEnd(), rule.getProtocol().toLowerCase(), networkId, accountId, domainId, vmId); + newRule = _portForwardingDao.persist(newRule); + + // create firewallRule for 0.0.0.0/0 cidr + if (openFirewall) { + _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), + rule.getProtocol(), null, null, newRule.getId(), networkId); + } + + try { + _firewallMgr.detectRulesConflict(newRule); + if (!_firewallDao.setStateToAdd(newRule)) { + throw new CloudRuntimeException("Unable to update the state to add for " + newRule); + } + CallContext.current().setEventDetails("Rule Id: " + newRule.getId()); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), + ipAddressFinal.getDataCenterId(), newRule.getId(), null, PortForwardingRule.class.getName(), + newRule.getUuid()); + return newRule; + } catch (Exception e) { + if (newRule != null) { + // no need to apply the rule as it wasn't programmed on the backend yet + _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false); + removePFRule(newRule); + } + + if (e instanceof NetworkRuleConflictException) { + throw (NetworkRuleConflictException) e; + } + + throw new CloudRuntimeException("Unable to add rule for the ip id=" + ipAddrId, e); + } } + }); - if (e instanceof NetworkRuleConflictException) { - throw (NetworkRuleConflictException) e; - } - - throw new CloudRuntimeException("Unable to add rule for the ip id=" + ipAddrId, e); - } } finally { // release ip address if ipassoc was perfored if (performedIpAssoc) { @@ -361,10 +366,10 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules @Override @DB @ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "creating static nat rule", create = true) - public StaticNatRule createStaticNatRule(StaticNatRule rule, boolean openFirewall) throws NetworkRuleConflictException { - Account caller = CallContext.current().getCallingAccount(); + public StaticNatRule createStaticNatRule(final StaticNatRule rule, final boolean openFirewall) throws NetworkRuleConflictException { + final Account caller = CallContext.current().getCallingAccount(); - Long ipAddrId = rule.getSourceIpAddressId(); + final Long ipAddrId = rule.getSourceIpAddressId(); IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId); @@ -377,9 +382,9 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules _firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), Purpose.StaticNat, FirewallRuleType.User,null, rule.getTrafficType() ); - Long networkId = ipAddress.getAssociatedWithNetworkId(); - Long accountId = ipAddress.getAllocatedToAccountId(); - Long domainId = ipAddress.getAllocatedInDomainId(); + final Long networkId = ipAddress.getAssociatedWithNetworkId(); + final Long accountId = ipAddress.getAllocatedToAccountId(); + final Long domainId = ipAddress.getAllocatedInDomainId(); _networkModel.checkIpForService(ipAddress, Service.StaticNat, null); @@ -390,48 +395,48 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules } //String dstIp = _networkModel.getIpInNetwork(ipAddress.getAssociatedWithVmId(), networkId); - String dstIp = ipAddress.getVmIp(); - Transaction txn = Transaction.currentTxn(); - txn.start(); + final String dstIp = ipAddress.getVmIp(); + return Transaction.execute(new TransactionCallbackWithException() { + @Override + public StaticNatRule doInTransaction(TransactionStatus status) throws NetworkRuleConflictException { - FirewallRuleVO newRule = new FirewallRuleVO(rule.getXid(), rule.getSourceIpAddressId(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol().toLowerCase(), - networkId, accountId, domainId, rule.getPurpose(), null, null, null, null, null); + FirewallRuleVO newRule = new FirewallRuleVO(rule.getXid(), rule.getSourceIpAddressId(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol().toLowerCase(), + networkId, accountId, domainId, rule.getPurpose(), null, null, null, null, null); - newRule = _firewallDao.persist(newRule); + newRule = _firewallDao.persist(newRule); - // create firewallRule for 0.0.0.0/0 cidr - if (openFirewall) { - _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), null, null, newRule.getId(), networkId); - } + // create firewallRule for 0.0.0.0/0 cidr + if (openFirewall) { + _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), null, null, newRule.getId(), networkId); + } - try { - _firewallMgr.detectRulesConflict(newRule); - if (!_firewallDao.setStateToAdd(newRule)) { - throw new CloudRuntimeException("Unable to update the state to add for " + newRule); + try { + _firewallMgr.detectRulesConflict(newRule); + if (!_firewallDao.setStateToAdd(newRule)) { + throw new CloudRuntimeException("Unable to update the state to add for " + newRule); + } + CallContext.current().setEventDetails("Rule Id: " + newRule.getId()); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), 0, newRule.getId(), + null, FirewallRule.class.getName(), newRule.getUuid()); + + StaticNatRule staticNatRule = new StaticNatRuleImpl(newRule, dstIp); + + return staticNatRule; + } catch (Exception e) { + if (newRule != null) { + // no need to apply the rule as it wasn't programmed on the backend yet + _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false); + _firewallMgr.removeRule(newRule); + } + + if (e instanceof NetworkRuleConflictException) { + throw (NetworkRuleConflictException) e; + } + throw new CloudRuntimeException("Unable to add static nat rule for the ip id=" + newRule.getSourceIpAddressId(), e); + } } - CallContext.current().setEventDetails("Rule Id: " + newRule.getId()); - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), 0, newRule.getId(), - null, FirewallRule.class.getName(), newRule.getUuid()); + }); - txn.commit(); - StaticNatRule staticNatRule = new StaticNatRuleImpl(newRule, dstIp); - - return staticNatRule; - } catch (Exception e) { - - if (newRule != null) { - txn.start(); - // no need to apply the rule as it wasn't programmed on the backend yet - _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false); - _firewallMgr.removeRule(newRule); - txn.commit(); - } - - if (e instanceof NetworkRuleConflictException) { - throw (NetworkRuleConflictException) e; - } - throw new CloudRuntimeException("Unable to add static nat rule for the ip id=" + newRule.getSourceIpAddressId(), e); - } } @Override @@ -826,7 +831,7 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules if (tags != null && !tags.isEmpty()) { int count = 0; - sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.PortForwardingRule.toString()); + sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.PortForwardingRule.toString()); for (String key : tags.keySet()) { sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); @@ -1146,23 +1151,25 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules @Override @DB - public FirewallRuleVO[] reservePorts(IpAddress ip, String protocol, FirewallRule.Purpose purpose, - boolean openFirewall, Account caller, int... ports) throws NetworkRuleConflictException { - FirewallRuleVO[] rules = new FirewallRuleVO[ports.length]; + public FirewallRuleVO[] reservePorts(final IpAddress ip, final String protocol, final FirewallRule.Purpose purpose, + final boolean openFirewall, final Account caller, final int... ports) throws NetworkRuleConflictException { + final FirewallRuleVO[] rules = new FirewallRuleVO[ports.length]; - Transaction txn = Transaction.currentTxn(); - txn.start(); - for (int i = 0; i < ports.length; i++) { - - rules[i] = new FirewallRuleVO(null, ip.getId(), ports[i], protocol, ip.getAssociatedWithNetworkId(), ip.getAllocatedToAccountId(), ip.getAllocatedInDomainId(), purpose, null, null, null, null); - rules[i] = _firewallDao.persist(rules[i]); - - if (openFirewall) { - _firewallMgr.createRuleForAllCidrs(ip.getId(), caller, ports[i], ports[i], protocol, null, null, - rules[i].getId(), ip.getAssociatedWithNetworkId()); + Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) throws NetworkRuleConflictException { + for (int i = 0; i < ports.length; i++) { + + rules[i] = new FirewallRuleVO(null, ip.getId(), ports[i], protocol, ip.getAssociatedWithNetworkId(), ip.getAllocatedToAccountId(), ip.getAllocatedInDomainId(), purpose, null, null, null, null); + rules[i] = _firewallDao.persist(rules[i]); + + if (openFirewall) { + _firewallMgr.createRuleForAllCidrs(ip.getId(), caller, ports[i], ports[i], protocol, null, null, + rules[i].getId(), ip.getAssociatedWithNetworkId()); + } + } } - } - txn.commit(); + }); boolean success = false; try { @@ -1173,12 +1180,14 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules return rules; } finally { if (!success) { - txn.start(); - - for (FirewallRuleVO newRule : rules) { - _firewallMgr.removeRule(newRule); - } - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + for (FirewallRuleVO newRule : rules) { + _firewallMgr.removeRule(newRule); + } + } + }); } } } diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java index 8b2db9dde90..c7b6e1eb3f7 100755 --- a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java +++ b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.ConcurrentModificationException; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -34,6 +35,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import javax.ejb.ConcurrentAccessException; import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; @@ -96,6 +98,10 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionCallbackWithException; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.StateListener; import com.cloud.utils.net.NetUtils; @@ -191,12 +197,7 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro @Override protected void runInContext() { try { - Transaction txn = Transaction.open("SG Work"); - try { - work(); - } finally { - txn.close("SG Work"); - } + work(); } catch (Throwable th) { try { s_logger.error("Problem with SG work", th); @@ -204,24 +205,15 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro } } } - - WorkerThread() { - - } } public class CleanupThread extends ManagedContextRunnable { @Override protected void runInContext() { try { - Transaction txn = Transaction.open("SG Cleanup"); - try { - cleanupFinishedWork(); - cleanupUnfinishedWork(); - //processScheduledWork(); - } finally { - txn.close("SG Cleanup"); - } + cleanupFinishedWork(); + cleanupUnfinishedWork(); + //processScheduledWork(); } catch (Throwable th) { try { s_logger.error("Problem with SG Cleanup", th); @@ -229,10 +221,6 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro } } } - - CleanupThread() { - - } } public static class PortAndProto implements Comparable { @@ -400,7 +388,7 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro } @DB - public void scheduleRulesetUpdateToHosts(List affectedVms, boolean updateSeqno, Long delayMs) { + public void scheduleRulesetUpdateToHosts(final List affectedVms, final boolean updateSeqno, Long delayMs) { if (affectedVms.size() == 0) { return; } @@ -422,39 +410,43 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro if (s_logger.isTraceEnabled()) { s_logger.trace("Security Group Mgr: acquired global work lock"); } - Transaction txn = Transaction.currentTxn(); + try { - txn.start(); - for (Long vmId : affectedVms) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Security Group Mgr: scheduling ruleset update for " + vmId); - } - VmRulesetLogVO log = null; - SecurityGroupWorkVO work = null; - - log = _rulesetLogDao.findByVmId(vmId); - if (log == null) { - log = new VmRulesetLogVO(vmId); - log = _rulesetLogDao.persist(log); - } - - if (log != null && updateSeqno) { - log.incrLogsequence(); - _rulesetLogDao.update(log.getId(), log); - } - work = _workDao.findByVmIdStep(vmId, Step.Scheduled); - if (work == null) { - work = new SecurityGroupWorkVO(vmId, null, null, SecurityGroupWork.Step.Scheduled, null); - work = _workDao.persist(work); - if (s_logger.isTraceEnabled()) { - s_logger.trace("Security Group Mgr: created new work item for " + vmId + "; id = " + work.getId()); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + for (Long vmId : affectedVms) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("Security Group Mgr: scheduling ruleset update for " + vmId); + } + VmRulesetLogVO log = null; + SecurityGroupWorkVO work = null; + + log = _rulesetLogDao.findByVmId(vmId); + if (log == null) { + log = new VmRulesetLogVO(vmId); + log = _rulesetLogDao.persist(log); + } + + if (log != null && updateSeqno) { + log.incrLogsequence(); + _rulesetLogDao.update(log.getId(), log); + } + work = _workDao.findByVmIdStep(vmId, Step.Scheduled); + if (work == null) { + work = new SecurityGroupWorkVO(vmId, null, null, SecurityGroupWork.Step.Scheduled, null); + work = _workDao.persist(work); + if (s_logger.isTraceEnabled()) { + s_logger.trace("Security Group Mgr: created new work item for " + vmId + "; id = " + work.getId()); + } + } + + work.setLogsequenceNumber(log.getLogsequence()); + _workDao.update(work.getId(), work); } } + }); - work.setLogsequenceNumber(log.getLogsequence()); - _workDao.update(work.getId(), work); - } - txn.commit(); for (Long vmId : affectedVms) { _executorPool.schedule(new WorkerThread(), delayMs, TimeUnit.MILLISECONDS); } @@ -595,7 +587,7 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro return authorizeSecurityGroupRule(securityGroupId,protocol,startPort,endPort,icmpType,icmpCode,cidrList,groupList,SecurityRuleType.IngressRule); } - private List authorizeSecurityGroupRule(Long securityGroupId,String protocol,Integer startPort,Integer endPort,Integer icmpType,Integer icmpCode,List cidrList,Map groupList,SecurityRuleType ruleType) { + private List authorizeSecurityGroupRule(final Long securityGroupId, String protocol,Integer startPort,Integer endPort,Integer icmpType,Integer icmpCode,final List cidrList,Map groupList, final SecurityRuleType ruleType) { Integer startPortOrType = null; Integer endPortOrCode = null; @@ -713,66 +705,71 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro } } - final Transaction txn = Transaction.currentTxn(); final Set authorizedGroups2 = new TreeSet(new SecurityGroupVOComparator()); authorizedGroups2.addAll(authorizedGroups); // Ensure we don't re-lock the same row - txn.start(); - // Prevents other threads/management servers from creating duplicate security rules - securityGroup = _securityGroupDao.acquireInLockTable(securityGroupId); - if (securityGroup == null) { - s_logger.warn("Could not acquire lock on network security group: id= " + securityGroupId); - return null; - } - List newRules = new ArrayList(); - try { - for (final SecurityGroupVO ngVO : authorizedGroups2) { - final Long ngId = ngVO.getId(); - // Don't delete the referenced group from under us - if (ngVO.getId() != securityGroup.getId()) { - final SecurityGroupVO tmpGrp = _securityGroupDao.lockRow(ngId, false); - if (tmpGrp == null) { - s_logger.warn("Failed to acquire lock on security group: " + ngId); - txn.rollback(); - return null; + final Integer startPortOrTypeFinal = startPortOrType; + final Integer endPortOrCodeFinal = endPortOrCode; + final String protocolFinal = protocol; + return Transaction.execute(new TransactionCallback>() { + @Override + public List doInTransaction(TransactionStatus status) { + // Prevents other threads/management servers from creating duplicate security rules + SecurityGroup securityGroup = _securityGroupDao.acquireInLockTable(securityGroupId); + if (securityGroup == null) { + s_logger.warn("Could not acquire lock on network security group: id= " + securityGroupId); + return null; + } + List newRules = new ArrayList(); + try { + for (final SecurityGroupVO ngVO : authorizedGroups2) { + final Long ngId = ngVO.getId(); + // Don't delete the referenced group from under us + if (ngVO.getId() != securityGroup.getId()) { + final SecurityGroupVO tmpGrp = _securityGroupDao.lockRow(ngId, false); + if (tmpGrp == null) { + s_logger.warn("Failed to acquire lock on security group: " + ngId); + throw new ConcurrentAccessException("Failed to acquire lock on security group: " + ngId); + } + } + SecurityGroupRuleVO securityGroupRule = _securityGroupRuleDao.findByProtoPortsAndAllowedGroupId(securityGroup.getId(), protocolFinal, startPortOrTypeFinal, endPortOrCodeFinal, ngVO.getId()); + if ((securityGroupRule != null) && (securityGroupRule.getRuleType() == ruleType)) { + continue; // rule already exists. + } + securityGroupRule = new SecurityGroupRuleVO(ruleType, securityGroup.getId(), startPortOrTypeFinal, endPortOrCodeFinal, protocolFinal, ngVO.getId()); + securityGroupRule = _securityGroupRuleDao.persist(securityGroupRule); + newRules.add(securityGroupRule); + } + if (cidrList != null) { + for (String cidr : cidrList) { + SecurityGroupRuleVO securityGroupRule = _securityGroupRuleDao.findByProtoPortsAndCidr(securityGroup.getId(), protocolFinal, startPortOrTypeFinal, endPortOrCodeFinal, cidr); + if ((securityGroupRule != null) && (securityGroupRule.getRuleType() == ruleType)) { + continue; + } + securityGroupRule = new SecurityGroupRuleVO(ruleType, securityGroup.getId(), startPortOrTypeFinal, endPortOrCodeFinal, protocolFinal, cidr); + securityGroupRule = _securityGroupRuleDao.persist(securityGroupRule); + newRules.add(securityGroupRule); + } + } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Added " + newRules.size() + " rules to security group " + securityGroup.getName()); + } + final ArrayList affectedVms = new ArrayList(); + affectedVms.addAll(_securityGroupVMMapDao.listVmIdsBySecurityGroup(securityGroup.getId())); + scheduleRulesetUpdateToHosts(affectedVms, true, null); + return newRules; + } catch (Exception e) { + s_logger.warn("Exception caught when adding security group rules ", e); + throw new CloudRuntimeException("Exception caught when adding security group rules", e); + } finally { + if (securityGroup != null) { + _securityGroupDao.releaseFromLockTable(securityGroup.getId()); } } - SecurityGroupRuleVO securityGroupRule = _securityGroupRuleDao.findByProtoPortsAndAllowedGroupId(securityGroup.getId(), protocol, startPortOrType, endPortOrCode, ngVO.getId()); - if ((securityGroupRule != null) && (securityGroupRule.getRuleType() == ruleType)) { - continue; // rule already exists. - } - securityGroupRule = new SecurityGroupRuleVO(ruleType, securityGroup.getId(), startPortOrType, endPortOrCode, protocol, ngVO.getId()); - securityGroupRule = _securityGroupRuleDao.persist(securityGroupRule); - newRules.add(securityGroupRule); } - if (cidrList != null) { - for (String cidr : cidrList) { - SecurityGroupRuleVO securityGroupRule = _securityGroupRuleDao.findByProtoPortsAndCidr(securityGroup.getId(), protocol, startPortOrType, endPortOrCode, cidr); - if ((securityGroupRule != null) && (securityGroupRule.getRuleType() == ruleType)) { - continue; - } - securityGroupRule = new SecurityGroupRuleVO(ruleType, securityGroup.getId(), startPortOrType, endPortOrCode, protocol, cidr); - securityGroupRule = _securityGroupRuleDao.persist(securityGroupRule); - newRules.add(securityGroupRule); - } - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Added " + newRules.size() + " rules to security group " + securityGroup.getName()); - } - txn.commit(); - final ArrayList affectedVms = new ArrayList(); - affectedVms.addAll(_securityGroupVMMapDao.listVmIdsBySecurityGroup(securityGroup.getId())); - scheduleRulesetUpdateToHosts(affectedVms, true, null); - return newRules; - } catch (Exception e) { - s_logger.warn("Exception caught when adding security group rules ", e); - throw new CloudRuntimeException("Exception caught when adding security group rules", e); - } finally { - if (securityGroup != null) { - _securityGroupDao.releaseFromLockTable(securityGroup.getId()); - } - } + }); + } @Override @@ -792,11 +789,11 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro return revokeSecurityGroupRule(id, SecurityRuleType.IngressRule); } - private boolean revokeSecurityGroupRule(Long id, SecurityRuleType type) { + private boolean revokeSecurityGroupRule(final Long id, SecurityRuleType type) { // input validation Account caller = CallContext.current().getCallingAccount(); - SecurityGroupRuleVO rule = _securityGroupRuleDao.findById(id); + final SecurityGroupRuleVO rule = _securityGroupRuleDao.findById(id); if (rule == null) { s_logger.debug("Unable to find security rule with id " + id); throw new InvalidParameterValueException("Unable to find security rule with id " + id); @@ -812,36 +809,37 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro SecurityGroup securityGroup = _securityGroupDao.findById(rule.getSecurityGroupId()); _accountMgr.checkAccess(caller, null, true, securityGroup); - SecurityGroupVO groupHandle = null; - final Transaction txn = Transaction.currentTxn(); + return Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + SecurityGroupVO groupHandle = null; - try { - txn.start(); - // acquire lock on parent group (preserving this logic) - groupHandle = _securityGroupDao.acquireInLockTable(rule.getSecurityGroupId()); - if (groupHandle == null) { - s_logger.warn("Could not acquire lock on security group id: " + rule.getSecurityGroupId()); - return false; + try { + // acquire lock on parent group (preserving this logic) + groupHandle = _securityGroupDao.acquireInLockTable(rule.getSecurityGroupId()); + if (groupHandle == null) { + s_logger.warn("Could not acquire lock on security group id: " + rule.getSecurityGroupId()); + return false; + } + + _securityGroupRuleDao.remove(id); + s_logger.debug("revokeSecurityGroupRule succeeded for security rule id: " + id); + + final ArrayList affectedVms = new ArrayList(); + affectedVms.addAll(_securityGroupVMMapDao.listVmIdsBySecurityGroup(groupHandle.getId())); + scheduleRulesetUpdateToHosts(affectedVms, true, null); + + return true; + } catch (Exception e) { + s_logger.warn("Exception caught when deleting security rules ", e); + throw new CloudRuntimeException("Exception caught when deleting security rules", e); + } finally { + if (groupHandle != null) { + _securityGroupDao.releaseFromLockTable(groupHandle.getId()); + } + } } - - _securityGroupRuleDao.remove(id); - s_logger.debug("revokeSecurityGroupRule succeeded for security rule id: " + id); - - final ArrayList affectedVms = new ArrayList(); - affectedVms.addAll(_securityGroupVMMapDao.listVmIdsBySecurityGroup(groupHandle.getId())); - scheduleRulesetUpdateToHosts(affectedVms, true, null); - - return true; - } catch (Exception e) { - s_logger.warn("Exception caught when deleting security rules ", e); - throw new CloudRuntimeException("Exception caught when deleting security rules", e); - } finally { - if (groupHandle != null) { - _securityGroupDao.releaseFromLockTable(groupHandle.getId()); - } - txn.commit(); - } - + }); } @Override @@ -939,7 +937,7 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro } return; } - Long userVmId = work.getInstanceId(); + final Long userVmId = work.getInstanceId(); if (work.getStep() == Step.Done) { if (s_logger.isDebugEnabled()) { s_logger.debug("Security Group work: found a job in done state, rescheduling for vm: " + userVmId); @@ -949,68 +947,73 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro scheduleRulesetUpdateToHosts(affectedVms, false, _timeBetweenCleanups*1000l); return; } - UserVm vm = null; - Long seqnum = null; s_logger.debug("Working on " + work); - final Transaction txn = Transaction.currentTxn(); - txn.start(); - boolean locked = false; - try { - vm = _userVMDao.acquireInLockTable(work.getInstanceId()); - if (vm == null) { - vm = _userVMDao.findById(work.getInstanceId()); - if (vm == null) { - s_logger.info("VM " + work.getInstanceId() + " is removed"); - locked = true; - return; - } - s_logger.warn("Unable to acquire lock on vm id=" + userVmId); - return; - } - locked = true; - Long agentId = null; - VmRulesetLogVO log = _rulesetLogDao.findByVmId(userVmId); - if (log == null) { - s_logger.warn("Cannot find log record for vm id=" + userVmId); - return; - } - seqnum = log.getLogsequence(); - if (vm != null && vm.getState() == State.Running) { - Map> ingressRules = generateRulesForVM(userVmId, SecurityRuleType.IngressRule); - Map> egressRules = generateRulesForVM(userVmId, SecurityRuleType.EgressRule); - agentId = vm.getHostId(); - if (agentId != null) { - // get nic secondary ip address - String privateIp = vm.getPrivateIpAddress(); - NicVO nic = _nicDao.findByIp4AddressAndVmId(privateIp, vm.getId()); - List nicSecIps = null; - if (nic != null) { - if (nic.getSecondaryIp()) { - //get secondary ips of the vm - long networkId = nic.getNetworkId(); - nicSecIps = _nicSecIpDao.getSecondaryIpAddressesForNic(nic.getId()); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + UserVm vm = null; + Long seqnum = null; + + boolean locked = false; + try { + vm = _userVMDao.acquireInLockTable(work.getInstanceId()); + if (vm == null) { + vm = _userVMDao.findById(work.getInstanceId()); + if (vm == null) { + s_logger.info("VM " + work.getInstanceId() + " is removed"); + locked = true; + return; + } + s_logger.warn("Unable to acquire lock on vm id=" + userVmId); + return; + } + locked = true; + Long agentId = null; + VmRulesetLogVO log = _rulesetLogDao.findByVmId(userVmId); + if (log == null) { + s_logger.warn("Cannot find log record for vm id=" + userVmId); + return; + } + seqnum = log.getLogsequence(); + + if (vm != null && vm.getState() == State.Running) { + Map> ingressRules = generateRulesForVM(userVmId, SecurityRuleType.IngressRule); + Map> egressRules = generateRulesForVM(userVmId, SecurityRuleType.EgressRule); + agentId = vm.getHostId(); + if (agentId != null) { + // get nic secondary ip address + String privateIp = vm.getPrivateIpAddress(); + NicVO nic = _nicDao.findByIp4AddressAndVmId(privateIp, vm.getId()); + List nicSecIps = null; + if (nic != null) { + if (nic.getSecondaryIp()) { + //get secondary ips of the vm + long networkId = nic.getNetworkId(); + nicSecIps = _nicSecIpDao.getSecondaryIpAddressesForNic(nic.getId()); + } + } + SecurityGroupRulesCmd cmd = generateRulesetCmd( vm.getInstanceName(), vm.getPrivateIpAddress(), vm.getPrivateMacAddress(), vm.getId(), generateRulesetSignature(ingressRules, egressRules), seqnum, + ingressRules, egressRules, nicSecIps); + Commands cmds = new Commands(cmd); + try { + _agentMgr.send(agentId, cmds, _answerListener); + } catch (AgentUnavailableException e) { + s_logger.debug("Unable to send ingress rules updates for vm: " + userVmId + "(agentid=" + agentId + ")"); + _workDao.updateStep(work.getInstanceId(), seqnum, Step.Done); + } + } } - SecurityGroupRulesCmd cmd = generateRulesetCmd( vm.getInstanceName(), vm.getPrivateIpAddress(), vm.getPrivateMacAddress(), vm.getId(), generateRulesetSignature(ingressRules, egressRules), seqnum, - ingressRules, egressRules, nicSecIps); - Commands cmds = new Commands(cmd); - try { - _agentMgr.send(agentId, cmds, _answerListener); - } catch (AgentUnavailableException e) { - s_logger.debug("Unable to send ingress rules updates for vm: " + userVmId + "(agentid=" + agentId + ")"); - _workDao.updateStep(work.getInstanceId(), seqnum, Step.Done); + } finally { + if (locked) { + _userVMDao.releaseFromLockTable(userVmId); + _workDao.updateStep(work.getId(), Step.Done); } - } } - } finally { - if (locked) { - _userVMDao.releaseFromLockTable(userVmId); - _workDao.updateStep(work.getId(), Step.Done); - } - txn.commit(); - } + }); + } @Override @@ -1021,41 +1024,40 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro return false; } if (groups != null && !groups.isEmpty()) { - - final Transaction txn = Transaction.currentTxn(); - txn.start(); - UserVm userVm = _userVMDao.acquireInLockTable(userVmId); // ensures that duplicate entries are not created. - List sgs = new ArrayList(); - for (Long sgId : groups) { - sgs.add(_securityGroupDao.findById(sgId)); - } - final Set uniqueGroups = new TreeSet(new SecurityGroupVOComparator()); - uniqueGroups.addAll(sgs); - if (userVm == null) { - s_logger.warn("Failed to acquire lock on user vm id=" + userVmId); - } - try { - for (SecurityGroupVO securityGroup : uniqueGroups) { - // don't let the group be deleted from under us. - SecurityGroupVO ngrpLock = _securityGroupDao.lockRow(securityGroup.getId(), false); - if (ngrpLock == null) { - s_logger.warn("Failed to acquire lock on network group id=" + securityGroup.getId() + " name=" + securityGroup.getName()); - txn.rollback(); - return false; + return Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + UserVm userVm = _userVMDao.acquireInLockTable(userVmId); // ensures that duplicate entries are not created. + List sgs = new ArrayList(); + for (Long sgId : groups) { + sgs.add(_securityGroupDao.findById(sgId)); } - if (_securityGroupVMMapDao.findByVmIdGroupId(userVmId, securityGroup.getId()) == null) { - SecurityGroupVMMapVO groupVmMapVO = new SecurityGroupVMMapVO(securityGroup.getId(), userVmId); - _securityGroupVMMapDao.persist(groupVmMapVO); + final Set uniqueGroups = new TreeSet(new SecurityGroupVOComparator()); + uniqueGroups.addAll(sgs); + if (userVm == null) { + s_logger.warn("Failed to acquire lock on user vm id=" + userVmId); + } + try { + for (SecurityGroupVO securityGroup : uniqueGroups) { + // don't let the group be deleted from under us. + SecurityGroupVO ngrpLock = _securityGroupDao.lockRow(securityGroup.getId(), false); + if (ngrpLock == null) { + s_logger.warn("Failed to acquire lock on network group id=" + securityGroup.getId() + " name=" + securityGroup.getName()); + throw new ConcurrentModificationException("Failed to acquire lock on network group id=" + securityGroup.getId() + " name=" + securityGroup.getName()); + } + if (_securityGroupVMMapDao.findByVmIdGroupId(userVmId, securityGroup.getId()) == null) { + SecurityGroupVMMapVO groupVmMapVO = new SecurityGroupVMMapVO(securityGroup.getId(), userVmId); + _securityGroupVMMapDao.persist(groupVmMapVO); + } + } + return true; + } finally { + if (userVm != null) { + _userVMDao.releaseFromLockTable(userVmId); + } } } - txn.commit(); - return true; - } finally { - if (userVm != null) { - _userVMDao.releaseFromLockTable(userVmId); - } - } - + }); } return false; @@ -1063,22 +1065,24 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro @Override @DB - public void removeInstanceFromGroups(long userVmId) { + public void removeInstanceFromGroups(final long userVmId) { if (_securityGroupVMMapDao.countSGForVm(userVmId) < 1) { s_logger.trace("No security groups found for vm id=" + userVmId + ", returning"); return; } - final Transaction txn = Transaction.currentTxn(); - txn.start(); - UserVm userVm = _userVMDao.acquireInLockTable(userVmId); // ensures that duplicate entries are not created in - // addInstance - if (userVm == null) { - s_logger.warn("Failed to acquire lock on user vm id=" + userVmId); - } - int n = _securityGroupVMMapDao.deleteVM(userVmId); - s_logger.info("Disassociated " + n + " network groups " + " from uservm " + userVmId); - _userVMDao.releaseFromLockTable(userVmId); - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + UserVm userVm = _userVMDao.acquireInLockTable(userVmId); // ensures that duplicate entries are not created in + // addInstance + if (userVm == null) { + s_logger.warn("Failed to acquire lock on user vm id=" + userVmId); + } + int n = _securityGroupVMMapDao.deleteVM(userVmId); + s_logger.info("Disassociated " + n + " network groups " + " from uservm " + userVmId); + _userVMDao.releaseFromLockTable(userVmId); + } + }); s_logger.debug("Security group mappings are removed successfully for vm id=" + userVmId); } @@ -1086,7 +1090,7 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro @Override @ActionEvent(eventType = EventTypes.EVENT_SECURITY_GROUP_DELETE, eventDescription = "deleting security group") public boolean deleteSecurityGroup(DeleteSecurityGroupCmd cmd) throws ResourceInUseException { - Long groupId = cmd.getId(); + final Long groupId = cmd.getId(); Account caller = CallContext.current().getCallingAccount(); SecurityGroupVO group = _securityGroupDao.findById(groupId); @@ -1097,32 +1101,34 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro // check permissions _accountMgr.checkAccess(caller, null, true, group); - final Transaction txn = Transaction.currentTxn(); - txn.start(); + return Transaction.execute(new TransactionCallbackWithException() { + @Override + public Boolean doInTransaction(TransactionStatus status) throws ResourceInUseException { + SecurityGroupVO group = _securityGroupDao.lockRow(groupId, true); + if (group == null) { + throw new InvalidParameterValueException("Unable to find security group by id " + groupId); + } + + if (group.getName().equalsIgnoreCase(SecurityGroupManager.DEFAULT_GROUP_NAME)) { + throw new InvalidParameterValueException("The network group default is reserved"); + } + + List allowingRules = _securityGroupRuleDao.listByAllowedSecurityGroupId(groupId); + List securityGroupVmMap = _securityGroupVMMapDao.listBySecurityGroup(groupId); + if (!allowingRules.isEmpty()) { + throw new ResourceInUseException("Cannot delete group when there are security rules that allow this group"); + } else if (!securityGroupVmMap.isEmpty()) { + throw new ResourceInUseException("Cannot delete group when it's in use by virtual machines"); + } + + _securityGroupDao.expunge(groupId); - group = _securityGroupDao.lockRow(groupId, true); - if (group == null) { - throw new InvalidParameterValueException("Unable to find security group by id " + groupId); - } + s_logger.debug("Deleted security group id=" + groupId); + + return true; + } + }); - if (group.getName().equalsIgnoreCase(SecurityGroupManager.DEFAULT_GROUP_NAME)) { - throw new InvalidParameterValueException("The network group default is reserved"); - } - - List allowingRules = _securityGroupRuleDao.listByAllowedSecurityGroupId(groupId); - List securityGroupVmMap = _securityGroupVMMapDao.listBySecurityGroup(groupId); - if (!allowingRules.isEmpty()) { - throw new ResourceInUseException("Cannot delete group when there are security rules that allow this group"); - } else if (!securityGroupVmMap.isEmpty()) { - throw new ResourceInUseException("Cannot delete group when it's in use by virtual machines"); - } - - _securityGroupDao.expunge(groupId); - txn.commit(); - - s_logger.debug("Deleted security group id=" + groupId); - - return true; } diff --git a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java index 9923db56461..30d39e06b91 100644 --- a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java +++ b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java @@ -23,7 +23,6 @@ import javax.ejb.Local; import javax.inject.Inject; import org.apache.log4j.Logger; - import org.apache.cloudstack.context.CallContext; import com.cloud.configuration.ConfigurationManager; @@ -48,6 +47,8 @@ import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.EntityManager; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; @@ -214,30 +215,35 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana @Override @DB @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_ITEM_CREATE, eventDescription = "creating network ACL Item", create = true) - public NetworkACLItem createNetworkACLItem(Integer portStart, Integer portEnd, String protocol, List sourceCidrList, - Integer icmpCode, Integer icmpType, NetworkACLItem.TrafficType trafficType, Long aclId, - String action, Integer number) { - NetworkACLItem.Action ruleAction = NetworkACLItem.Action.Allow; - if("deny".equalsIgnoreCase(action)){ - ruleAction = NetworkACLItem.Action.Deny; - } + public NetworkACLItem createNetworkACLItem(final Integer portStart, final Integer portEnd, final String protocol, final List sourceCidrList, + final Integer icmpCode, final Integer icmpType, final NetworkACLItem.TrafficType trafficType, final Long aclId, + final String action, Integer number) { // If number is null, set it to currentMax + 1 (for backward compatibility) if(number == null){ number = _networkACLItemDao.getMaxNumberByACL(aclId) + 1; } - Transaction txn = Transaction.currentTxn(); - txn.start(); + final Integer numberFinal = number; + NetworkACLItemVO newRule = Transaction.execute(new TransactionCallback() { + @Override + public NetworkACLItemVO doInTransaction(TransactionStatus status) { + NetworkACLItem.Action ruleAction = NetworkACLItem.Action.Allow; + if("deny".equalsIgnoreCase(action)){ + ruleAction = NetworkACLItem.Action.Deny; + } - NetworkACLItemVO newRule = new NetworkACLItemVO(portStart, portEnd, protocol.toLowerCase(), aclId, sourceCidrList, icmpCode, icmpType, trafficType, ruleAction, number); - newRule = _networkACLItemDao.persist(newRule); + NetworkACLItemVO newRule = new NetworkACLItemVO(portStart, portEnd, protocol.toLowerCase(), aclId, sourceCidrList, icmpCode, icmpType, trafficType, ruleAction, numberFinal); + newRule = _networkACLItemDao.persist(newRule); - if (!_networkACLItemDao.setStateToAdd(newRule)) { - throw new CloudRuntimeException("Unable to update the state to add for " + newRule); - } - CallContext.current().setEventDetails("ACL Item Id: " + newRule.getId()); + if (!_networkACLItemDao.setStateToAdd(newRule)) { + throw new CloudRuntimeException("Unable to update the state to add for " + newRule); + } + CallContext.current().setEventDetails("ACL Item Id: " + newRule.getId()); + + return newRule; + } + }); - txn.commit(); return getNetworkACLItem(newRule.getId()); } diff --git a/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java b/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java index 50dd8e30741..d12e57701cc 100644 --- a/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java +++ b/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java @@ -43,7 +43,7 @@ import com.cloud.network.dao.NetworkVO; import com.cloud.network.vpc.dao.NetworkACLDao; import com.cloud.network.vpc.dao.VpcGatewayDao; import com.cloud.projects.Project.ListProjectResourcesCriteria; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; @@ -484,7 +484,7 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ if (tags != null && !tags.isEmpty()) { int count = 0; - sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.NetworkACL.toString()); + sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.NetworkACL.toString()); for (String key : tags.keySet()) { sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 651e82c6d21..6e0b54d9b9a 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -99,7 +99,7 @@ import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; import com.cloud.org.Grouping; import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.server.ConfigurationServer; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; @@ -118,9 +118,15 @@ import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionCallbackWithException; +import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.exception.ExceptionUtil; import com.cloud.utils.net.NetUtils; import com.cloud.vm.ReservationContext; import com.cloud.vm.ReservationContextImpl; @@ -206,50 +212,50 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis @DB public boolean configure(String name, Map params) throws ConfigurationException { //configure default vpc offering - Transaction txn = Transaction.currentTxn(); - txn.start(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCOfferingName) == null) { + s_logger.debug("Creating default VPC offering " + VpcOffering.defaultVPCOfferingName); + + Map> svcProviderMap = new HashMap>(); + Set defaultProviders = new HashSet(); + defaultProviders.add(Provider.VPCVirtualRouter); + for (Service svc : getSupportedServices()) { + if (svc == Service.Lb) { + Set lbProviders = new HashSet(); + lbProviders.add(Provider.VPCVirtualRouter); + lbProviders.add(Provider.InternalLbVm); + svcProviderMap.put(svc, lbProviders); + } else { + svcProviderMap.put(svc, defaultProviders); + } + } + createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap, + true, State.Enabled); + } - if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCOfferingName) == null) { - s_logger.debug("Creating default VPC offering " + VpcOffering.defaultVPCOfferingName); - - Map> svcProviderMap = new HashMap>(); - Set defaultProviders = new HashSet(); - defaultProviders.add(Provider.VPCVirtualRouter); - for (Service svc : getSupportedServices()) { - if (svc == Service.Lb) { - Set lbProviders = new HashSet(); - lbProviders.add(Provider.VPCVirtualRouter); - lbProviders.add(Provider.InternalLbVm); - svcProviderMap.put(svc, lbProviders); - } else { - svcProviderMap.put(svc, defaultProviders); + //configure default vpc offering with Netscaler as LB Provider + if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCNSOfferingName ) == null) { + s_logger.debug("Creating default VPC offering with Netscaler as LB Provider" + VpcOffering.defaultVPCNSOfferingName); + Map> svcProviderMap = new HashMap>(); + Set defaultProviders = new HashSet(); + defaultProviders.add(Provider.VPCVirtualRouter); + for (Service svc : getSupportedServices()) { + if (svc == Service.Lb) { + Set lbProviders = new HashSet(); + lbProviders.add(Provider.Netscaler); + lbProviders.add(Provider.InternalLbVm); + svcProviderMap.put(svc, lbProviders); + } else { + svcProviderMap.put(svc, defaultProviders); + } + } + createVpcOffering(VpcOffering.defaultVPCNSOfferingName, VpcOffering.defaultVPCNSOfferingName, + svcProviderMap, false, State.Enabled); } } - createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap, - true, State.Enabled); - } - - //configure default vpc offering with Netscaler as LB Provider - if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCNSOfferingName ) == null) { - s_logger.debug("Creating default VPC offering with Netscaler as LB Provider" + VpcOffering.defaultVPCNSOfferingName); - Map> svcProviderMap = new HashMap>(); - Set defaultProviders = new HashSet(); - defaultProviders.add(Provider.VPCVirtualRouter); - for (Service svc : getSupportedServices()) { - if (svc == Service.Lb) { - Set lbProviders = new HashSet(); - lbProviders.add(Provider.Netscaler); - lbProviders.add(Provider.InternalLbVm); - svcProviderMap.put(svc, lbProviders); - } else { - svcProviderMap.put(svc, defaultProviders); - } - } - createVpcOffering(VpcOffering.defaultVPCNSOfferingName, VpcOffering.defaultVPCNSOfferingName, - svcProviderMap, false, State.Enabled); - } - - txn.commit(); + }); Map configs = _configDao.getConfiguration(params); String value = configs.get(Config.VpcCleanupInterval.key()); @@ -375,36 +381,38 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis @DB - protected VpcOffering createVpcOffering(String name, String displayText, Map> svcProviderMap, boolean isDefault, State state) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - // create vpc offering object - VpcOfferingVO offering = new VpcOfferingVO(name, displayText, isDefault, null); - - if (state != null) { - offering.setState(state); - } - s_logger.debug("Adding vpc offering " + offering); - offering = _vpcOffDao.persist(offering); - // populate services and providers - if (svcProviderMap != null) { - for (Network.Service service : svcProviderMap.keySet()) { - Set providers = svcProviderMap.get(service); - if (providers != null && !providers.isEmpty()) { - for (Network.Provider provider : providers) { - VpcOfferingServiceMapVO offService = new VpcOfferingServiceMapVO(offering.getId(), service, provider); - _vpcOffSvcMapDao.persist(offService); - s_logger.trace("Added service for the vpc offering: " + offService + " with provider " + provider.getName()); - } - } else { - throw new InvalidParameterValueException("Provider is missing for the VPC offering service " + service.getName()); - } - } - } - txn.commit(); + protected VpcOffering createVpcOffering(final String name, final String displayText, final Map> svcProviderMap, final boolean isDefault, final State state) { + return Transaction.execute(new TransactionCallback() { + @Override + public VpcOffering doInTransaction(TransactionStatus status) { + // create vpc offering object + VpcOfferingVO offering = new VpcOfferingVO(name, displayText, isDefault, null); - return offering; + if (state != null) { + offering.setState(state); + } + s_logger.debug("Adding vpc offering " + offering); + offering = _vpcOffDao.persist(offering); + // populate services and providers + if (svcProviderMap != null) { + for (Network.Service service : svcProviderMap.keySet()) { + Set providers = svcProviderMap.get(service); + if (providers != null && !providers.isEmpty()) { + for (Network.Provider provider : providers) { + VpcOfferingServiceMapVO offService = new VpcOfferingServiceMapVO(offering.getId(), service, provider); + _vpcOffSvcMapDao.persist(offService); + s_logger.trace("Added service for the vpc offering: " + offService + " with provider " + provider.getName()); + } + } else { + throw new InvalidParameterValueException("Provider is missing for the VPC offering service " + service.getName()); + } + } + } + + return offering; + } + }); } @Override @@ -635,14 +643,14 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis @DB - protected Vpc createVpc(long zoneId, long vpcOffId, Account vpcOwner, String vpcName, String displayText, String cidr, - String networkDomain) { - + protected Vpc createVpc(final long zoneId, final long vpcOffId, final Account vpcOwner, final String vpcName, final String displayText, final String cidr, + final String networkDomain) { + //Validate CIDR if (!NetUtils.isValidCIDR(cidr)) { throw new InvalidParameterValueException("Invalid CIDR specified " + cidr); } - + //cidr has to be RFC 1918 complient if (!NetUtils.validateGuestCidr(cidr)) { throw new InvalidParameterValueException("Guest Cidr " + cidr + " is not RFC1918 compliant"); @@ -657,17 +665,19 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis + "and the hyphen ('-'); can't start or end with \"-\""); } - Transaction txn = Transaction.currentTxn(); - txn.start(); - VpcVO vpc = new VpcVO (zoneId, vpcName, displayText, vpcOwner.getId(), vpcOwner.getDomainId(), vpcOffId, cidr, - networkDomain); - vpc = _vpcDao.persist(vpc, finalizeServicesAndProvidersForVpc(zoneId, vpcOffId)); - _resourceLimitMgr.incrementResourceCount(vpcOwner.getId(), ResourceType.vpc); - txn.commit(); + return Transaction.execute(new TransactionCallback() { + @Override + public VpcVO doInTransaction(TransactionStatus status) { + VpcVO vpc = new VpcVO (zoneId, vpcName, displayText, vpcOwner.getId(), vpcOwner.getDomainId(), vpcOffId, cidr, + networkDomain); + vpc = _vpcDao.persist(vpc, finalizeServicesAndProvidersForVpc(zoneId, vpcOffId)); + _resourceLimitMgr.incrementResourceCount(vpcOwner.getId(), ResourceType.vpc); - s_logger.debug("Created VPC " + vpc); + s_logger.debug("Created VPC " + vpc); - return vpc; + return vpc; + } + }); } private Map> finalizeServicesAndProvidersForVpc(long zoneId, long offeringId) { @@ -722,7 +732,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis @Override @DB - public boolean destroyVpc(Vpc vpc, Account caller, Long callerUserId) throws ConcurrentOperationException, ResourceUnavailableException { + public boolean destroyVpc(final Vpc vpc, Account caller, Long callerUserId) throws ConcurrentOperationException, ResourceUnavailableException { s_logger.debug("Destroying vpc " + vpc); //don't allow to delete vpc if it's in use by existing non system networks (system networks are networks of a private gateway of the VPC, @@ -735,16 +745,18 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis //mark VPC as inactive if (vpc.getState() != Vpc.State.Inactive) { s_logger.debug("Updating VPC " + vpc + " with state " + Vpc.State.Inactive + " as a part of vpc delete"); - VpcVO vpcVO = _vpcDao.findById(vpc.getId()); + final VpcVO vpcVO = _vpcDao.findById(vpc.getId()); vpcVO.setState(Vpc.State.Inactive); - Transaction txn = Transaction.currentTxn(); - txn.start(); - _vpcDao.update(vpc.getId(), vpcVO); - - //decrement resource count - _resourceLimitMgr.decrementResourceCount(vpc.getAccountId(), ResourceType.vpc); - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + _vpcDao.update(vpc.getId(), vpcVO); + + //decrement resource count + _resourceLimitMgr.decrementResourceCount(vpc.getAccountId(), ResourceType.vpc); + } + }); } //shutdown VPC @@ -863,7 +875,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis if (tags != null && !tags.isEmpty()) { int count = 0; - sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.Vpc.toString()); + sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.Vpc.toString()); for (String key : tags.keySet()) { sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); @@ -1140,71 +1152,72 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis } @DB - protected void validateNewVpcGuestNetwork(String cidr, String gateway, Account networkOwner, Vpc vpc, String networkDomain) { + protected void validateNewVpcGuestNetwork(final String cidr, final String gateway, final Account networkOwner, final Vpc vpc, final String networkDomain) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - Vpc locked = _vpcDao.acquireInLockTable(vpc.getId()); - if (locked == null) { - throw new CloudRuntimeException("Unable to acquire lock on " + vpc); - } - - try { - //check number of active networks in vpc - if (_ntwkDao.countVpcNetworks(vpc.getId()) >= _maxNetworks) { - throw new CloudRuntimeException("Number of networks per VPC can't extend " - + _maxNetworks + "; increase it using global config " + Config.VpcMaxNetworks); - } - - - //1) CIDR is required - if (cidr == null) { - throw new InvalidParameterValueException("Gateway/netmask are required when create network for VPC"); - } - - //2) Network cidr should be within vpcCidr - if (!NetUtils.isNetworkAWithinNetworkB(cidr, vpc.getCidr())) { - throw new InvalidParameterValueException("Network cidr " + cidr + " is not within vpc " + vpc + " cidr"); - } - - //3) Network cidr shouldn't cross the cidr of other vpc network cidrs - List ntwks = _ntwkDao.listByVpc(vpc.getId()); - for (Network ntwk : ntwks) { - assert (cidr != null) : "Why the network cidr is null when it belongs to vpc?"; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + Vpc locked = _vpcDao.acquireInLockTable(vpc.getId()); + if (locked == null) { + throw new CloudRuntimeException("Unable to acquire lock on " + vpc); + } - if (NetUtils.isNetworkAWithinNetworkB(ntwk.getCidr(), cidr) - || NetUtils.isNetworkAWithinNetworkB(cidr, ntwk.getCidr())) { - throw new InvalidParameterValueException("Network cidr " + cidr + " crosses other network cidr " + ntwk + - " belonging to the same vpc " + vpc); + try { + //check number of active networks in vpc + if (_ntwkDao.countVpcNetworks(vpc.getId()) >= _maxNetworks) { + throw new CloudRuntimeException("Number of networks per VPC can't extend " + + _maxNetworks + "; increase it using global config " + Config.VpcMaxNetworks); + } + + + //1) CIDR is required + if (cidr == null) { + throw new InvalidParameterValueException("Gateway/netmask are required when create network for VPC"); + } + + //2) Network cidr should be within vpcCidr + if (!NetUtils.isNetworkAWithinNetworkB(cidr, vpc.getCidr())) { + throw new InvalidParameterValueException("Network cidr " + cidr + " is not within vpc " + vpc + " cidr"); + } + + //3) Network cidr shouldn't cross the cidr of other vpc network cidrs + List ntwks = _ntwkDao.listByVpc(vpc.getId()); + for (Network ntwk : ntwks) { + assert (cidr != null) : "Why the network cidr is null when it belongs to vpc?"; + + if (NetUtils.isNetworkAWithinNetworkB(ntwk.getCidr(), cidr) + || NetUtils.isNetworkAWithinNetworkB(cidr, ntwk.getCidr())) { + throw new InvalidParameterValueException("Network cidr " + cidr + " crosses other network cidr " + ntwk + + " belonging to the same vpc " + vpc); + } + } + + //4) vpc and network should belong to the same owner + if (vpc.getAccountId() != networkOwner.getId()) { + throw new InvalidParameterValueException("Vpc " + vpc + " owner is different from the network owner " + + networkOwner); + } + + //5) network domain should be the same as VPC's + if (!networkDomain.equalsIgnoreCase(vpc.getNetworkDomain())) { + throw new InvalidParameterValueException("Network domain of the new network should match network" + + " domain of vpc " + vpc); + } + + //6) gateway should never be equal to the cidr subnet + if (NetUtils.getCidrSubNet(cidr).equalsIgnoreCase(gateway)) { + throw new InvalidParameterValueException("Invalid gateway specified. It should never be equal to the cidr subnet value"); + } + } finally { + s_logger.debug("Releasing lock for " + locked); + _vpcDao.releaseFromLockTable(locked.getId()); } } - - //4) vpc and network should belong to the same owner - if (vpc.getAccountId() != networkOwner.getId()) { - throw new InvalidParameterValueException("Vpc " + vpc + " owner is different from the network owner " - + networkOwner); - } - - //5) network domain should be the same as VPC's - if (!networkDomain.equalsIgnoreCase(vpc.getNetworkDomain())) { - throw new InvalidParameterValueException("Network domain of the new network should match network" + - " domain of vpc " + vpc); - } - - //6) gateway should never be equal to the cidr subnet - if (NetUtils.getCidrSubNet(cidr).equalsIgnoreCase(gateway)) { - throw new InvalidParameterValueException("Invalid gateway specified. It should never be equal to the cidr subnet value"); - } - - txn.commit(); - } finally { - s_logger.debug("Releasing lock for " + locked); - _vpcDao.releaseFromLockTable(locked.getId()); - } + }); } - protected List getVpcElements() { + public List getVpcElements() { if (vpcElements == null) { vpcElements = new ArrayList(); vpcElements.add((VpcProvider)_ntwkModel.getElementImplementingProvider(Provider.VPCVirtualRouter.getName())); @@ -1361,12 +1374,12 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis @Override @DB @ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_CREATE, eventDescription = "creating vpc private gateway", create=true) - public PrivateGateway createVpcPrivateGateway(long vpcId, Long physicalNetworkId, String broadcastUri, String ipAddress, - String gateway, String netmask, long gatewayOwnerId, Long networkOfferingId, Boolean isSourceNat, Long aclId) throws ResourceAllocationException, + public PrivateGateway createVpcPrivateGateway(final long vpcId, Long physicalNetworkId, final String broadcastUri, final String ipAddress, + final String gateway, final String netmask, final long gatewayOwnerId, final Long networkOfferingId, final Boolean isSourceNat, final Long aclId) throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException { //Validate parameters - Vpc vpc = getActiveVpc(vpcId); + final Vpc vpc = getActiveVpc(vpcId); if (vpc == null) { InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC by id specified"); ex.addProxyObject(String.valueOf(vpcId), "VPC"); @@ -1387,66 +1400,79 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis if (physNet == null) { physNet = _entityMgr.findById(PhysicalNetwork.class,physicalNetworkId); } - Long dcId = physNet.getDataCenterId(); + final Long dcId = physNet.getDataCenterId(); - Transaction txn = Transaction.currentTxn(); - txn.start(); - s_logger.debug("Creating Private gateway for VPC " + vpc); - //1) create private network unless it is existing and lswitch'd - Network privateNtwk = null; - if (BroadcastDomainType.getSchemeValue(BroadcastDomainType.fromString(broadcastUri)) == BroadcastDomainType.Lswitch) { - String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask); - - privateNtwk = _ntwkDao.getPrivateNetwork(broadcastUri, cidr, - gatewayOwnerId, dcId, networkOfferingId); - s_logger.info("found and using existing network for vpc " + vpc + ": " + broadcastUri); + final Long physicalNetworkIdFinal = physicalNetworkId; + final PhysicalNetwork physNetFinal = physNet; + VpcGatewayVO gatewayVO = null; + try { + gatewayVO = Transaction.execute(new TransactionCallbackWithException() { + @Override + public VpcGatewayVO doInTransaction(TransactionStatus status) throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException { + s_logger.debug("Creating Private gateway for VPC " + vpc); + //1) create private network unless it is existing and lswitch'd + Network privateNtwk = null; + if (BroadcastDomainType.getSchemeValue(BroadcastDomainType.fromString(broadcastUri)) == BroadcastDomainType.Lswitch) { + String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask); + + privateNtwk = _ntwkDao.getPrivateNetwork(broadcastUri, cidr, + gatewayOwnerId, dcId, networkOfferingId); + s_logger.info("found and using existing network for vpc " + vpc + ": " + broadcastUri); + } + if (privateNtwk == null) { + s_logger.info("creating new network for vpc " + vpc + " using broadcast uri: " + broadcastUri); + String networkName = "vpc-" + vpc.getName() + "-privateNetwork"; + privateNtwk = _ntwkSvc.createPrivateNetwork(networkName, networkName, physicalNetworkIdFinal, + broadcastUri, ipAddress, null, gateway, netmask, gatewayOwnerId, vpcId, isSourceNat, networkOfferingId); + } else { // create the nic/ip as createPrivateNetwork doesn''t do that work for us now + DataCenterVO dc = _dcDao.lockRow(physNetFinal.getDataCenterId(), true); + + //add entry to private_ip_address table + PrivateIpVO privateIp = _privateIpDao.findByIpAndSourceNetworkId(privateNtwk.getId(), ipAddress); + if (privateIp != null) { + throw new InvalidParameterValueException("Private ip address " + ipAddress + " already used for private gateway" + + " in zone " + _entityMgr.findById(DataCenter.class,dcId).getName()); + } + + Long mac = dc.getMacAddress(); + Long nextMac = mac + 1; + dc.setMacAddress(nextMac); + + privateIp = new PrivateIpVO(ipAddress, privateNtwk.getId(), nextMac, vpcId, true); + _privateIpDao.persist(privateIp); + + _dcDao.update(dc.getId(), dc); + } + + long networkAclId = NetworkACL.DEFAULT_DENY; + if (aclId != null) { + NetworkACLVO aclVO = _networkAclDao.findById(aclId); + if ( aclVO == null) { + throw new InvalidParameterValueException("Invalid network acl id passed "); + } + if ((aclVO.getVpcId() != vpcId) && !(aclId == NetworkACL.DEFAULT_DENY || aclId == NetworkACL.DEFAULT_ALLOW)) { + throw new InvalidParameterValueException("Private gateway and network acl are not in the same vpc"); + } + + networkAclId = aclId; + } + + //2) create gateway entry + VpcGatewayVO gatewayVO = new VpcGatewayVO(ipAddress, VpcGateway.Type.Private, vpcId, privateNtwk.getDataCenterId(), + privateNtwk.getId(), broadcastUri, gateway, netmask, vpc.getAccountId(), vpc.getDomainId(), isSourceNat, networkAclId); + _vpcGatewayDao.persist(gatewayVO); + + s_logger.debug("Created vpc gateway entry " + gatewayVO); + + return gatewayVO; + } + }); + } catch (Exception e) { + ExceptionUtil.rethrowRuntime(e); + ExceptionUtil.rethrow(e, InsufficientCapacityException.class); + ExceptionUtil.rethrow(e, ResourceAllocationException.class); + throw new IllegalStateException(e); } - if (privateNtwk == null) { - s_logger.info("creating new network for vpc " + vpc + " using broadcast uri: " + broadcastUri); - String networkName = "vpc-" + vpc.getName() + "-privateNetwork"; - privateNtwk = _ntwkSvc.createPrivateNetwork(networkName, networkName, physicalNetworkId, - broadcastUri, ipAddress, null, gateway, netmask, gatewayOwnerId, vpcId, isSourceNat, networkOfferingId); - } else { // create the nic/ip as createPrivateNetwork doesn''t do that work for us now - DataCenterVO dc = _dcDao.lockRow(physNet.getDataCenterId(), true); - - //add entry to private_ip_address table - PrivateIpVO privateIp = _privateIpDao.findByIpAndSourceNetworkId(privateNtwk.getId(), ipAddress); - if (privateIp != null) { - throw new InvalidParameterValueException("Private ip address " + ipAddress + " already used for private gateway" + - " in zone " + _entityMgr.findById(DataCenter.class,dcId).getName()); - } - - Long mac = dc.getMacAddress(); - Long nextMac = mac + 1; - dc.setMacAddress(nextMac); - - privateIp = new PrivateIpVO(ipAddress, privateNtwk.getId(), nextMac, vpcId, true); - _privateIpDao.persist(privateIp); - - _dcDao.update(dc.getId(), dc); - } - - long networkAclId = NetworkACL.DEFAULT_DENY; - if (aclId != null) { - NetworkACLVO aclVO = _networkAclDao.findById(aclId); - if ( aclVO == null) { - throw new InvalidParameterValueException("Invalid network acl id passed "); - } - if ((aclVO.getVpcId() != vpcId) && !(aclId == NetworkACL.DEFAULT_DENY || aclId == NetworkACL.DEFAULT_ALLOW)) { - throw new InvalidParameterValueException("Private gateway and network acl are not in the same vpc"); - } - - networkAclId = aclId; - } - - //2) create gateway entry - VpcGatewayVO gatewayVO = new VpcGatewayVO(ipAddress, VpcGateway.Type.Private, vpcId, privateNtwk.getDataCenterId(), - privateNtwk.getId(), broadcastUri, gateway, netmask, vpc.getAccountId(), vpc.getDomainId(), isSourceNat, networkAclId); - _vpcGatewayDao.persist(gatewayVO); - - s_logger.debug("Created vpc gateway entry " + gatewayVO); - - txn.commit(); return getVpcPrivateGateway(gatewayVO.getId()); } @@ -1496,26 +1522,28 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis @DB public boolean deleteVpcPrivateGateway(long gatewayId) throws ConcurrentOperationException, ResourceUnavailableException { - Transaction txn = Transaction.currentTxn(); - txn.start(); - VpcGatewayVO gatewayVO = _vpcGatewayDao.acquireInLockTable(gatewayId); + final VpcGatewayVO gatewayVO = _vpcGatewayDao.acquireInLockTable(gatewayId); if (gatewayVO == null || gatewayVO.getType() != VpcGateway.Type.Private) { throw new ConcurrentOperationException("Unable to lock gateway " + gatewayId); } try { - //don't allow to remove gateway when there are static routes associated with it - long routeCount = _staticRouteDao.countRoutesByGateway(gatewayVO.getId()); - if (routeCount > 0) { - throw new CloudRuntimeException("Can't delete private gateway " + gatewayVO + " as it has " + routeCount + - " static routes applied. Remove the routes first"); - } - - gatewayVO.setState(VpcGateway.State.Deleting); - _vpcGatewayDao.update(gatewayVO.getId(), gatewayVO); - s_logger.debug("Marked gateway " + gatewayVO + " with state " + VpcGateway.State.Deleting); - - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + //don't allow to remove gateway when there are static routes associated with it + long routeCount = _staticRouteDao.countRoutesByGateway(gatewayVO.getId()); + if (routeCount > 0) { + throw new CloudRuntimeException("Can't delete private gateway " + gatewayVO + " as it has " + routeCount + + " static routes applied. Remove the routes first"); + } + + gatewayVO.setState(VpcGateway.State.Deleting); + _vpcGatewayDao.update(gatewayVO.getId(), gatewayVO); + s_logger.debug("Marked gateway " + gatewayVO + " with state " + VpcGateway.State.Deleting); + } + }); + //1) delete the gateway on the backend PrivateGateway gateway = getVpcPrivateGateway(gatewayId); @@ -1539,9 +1567,9 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis } @DB - protected boolean deletePrivateGatewayFromTheDB(PrivateGateway gateway) { + protected boolean deletePrivateGatewayFromTheDB(final PrivateGateway gateway) { //check if there are ips allocted in the network - long networkId = gateway.getNetworkId(); + final long networkId = gateway.getNetworkId(); boolean deleteNetwork = true; List privateIps = _privateIpDao.listByNetworkId(networkId); @@ -1550,27 +1578,31 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis deleteNetwork = false; } - Transaction txn = Transaction.currentTxn(); - txn.start(); + //TODO: Clean this up, its bad. There is a DB transaction wrapping calls to NetworkElements (destroyNetwork will + // call network elements). + final boolean deleteNetworkFinal = deleteNetwork; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + PrivateIpVO ip = _privateIpDao.findByIpAndVpcId(gateway.getVpcId(), gateway.getIp4Address()); + if (ip != null) { + _privateIpDao.remove(ip.getId()); + s_logger.debug("Deleted private ip " + ip); + } + + if (deleteNetworkFinal) { + User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId()); + Account owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); + ReservationContext context = new ReservationContextImpl(null, null, callerUser, owner); + _ntwkMgr.destroyNetwork(networkId, context); + s_logger.debug("Deleted private network id=" + networkId); + } + + _vpcGatewayDao.remove(gateway.getId()); + s_logger.debug("Deleted private gateway " + gateway); + } + }); - PrivateIpVO ip = _privateIpDao.findByIpAndVpcId(gateway.getVpcId(), gateway.getIp4Address()); - if (ip != null) { - _privateIpDao.remove(ip.getId()); - s_logger.debug("Deleted private ip " + ip); - } - - if (deleteNetwork) { - User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId()); - Account owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); - ReservationContext context = new ReservationContextImpl(null, null, callerUser, owner); - _ntwkMgr.destroyNetwork(networkId, context); - s_logger.debug("Deleted private network id=" + networkId); - } - - _vpcGatewayDao.remove(gateway.getId()); - s_logger.debug("Deleted private gateway " + gateway); - - txn.commit(); return true; } @@ -1729,18 +1761,20 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis } @DB - protected boolean revokeStaticRoutesForVpc(long vpcId, Account caller) throws ResourceUnavailableException { + protected boolean revokeStaticRoutesForVpc(long vpcId, final Account caller) throws ResourceUnavailableException { //get all static routes for the vpc - List routes = _staticRouteDao.listByVpcId(vpcId); + final List routes = _staticRouteDao.listByVpcId(vpcId); s_logger.debug("Found " + routes.size() + " to revoke for the vpc " + vpcId); if (!routes.isEmpty()) { //mark all of them as revoke - Transaction txn = Transaction.currentTxn(); - txn.start(); - for (StaticRouteVO route : routes) { - markStaticRouteForRevoke(route, caller); - } - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + for (StaticRouteVO route : routes) { + markStaticRouteForRevoke(route, caller); + } + } + }); return applyStaticRoutes(vpcId); } @@ -1750,11 +1784,11 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis @Override @DB @ActionEvent(eventType = EventTypes.EVENT_STATIC_ROUTE_CREATE, eventDescription = "creating static route", create=true) - public StaticRoute createStaticRoute(long gatewayId, String cidr) throws NetworkRuleConflictException { + public StaticRoute createStaticRoute(long gatewayId, final String cidr) throws NetworkRuleConflictException { Account caller = CallContext.current().getCallingAccount(); //parameters validation - VpcGateway gateway = _vpcGatewayDao.findById(gatewayId); + final VpcGateway gateway = _vpcGatewayDao.findById(gatewayId); if (gateway == null) { throw new InvalidParameterValueException("Invalid gateway id is given"); } @@ -1763,7 +1797,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis throw new InvalidParameterValueException("Gateway is not in the " + VpcGateway.State.Ready + " state: " + gateway.getState()); } - Vpc vpc = getActiveVpc(gateway.getVpcId()); + final Vpc vpc = getActiveVpc(gateway.getVpcId()); if (vpc == null) { throw new InvalidParameterValueException("Can't add static route to VPC that is being deleted"); } @@ -1789,23 +1823,23 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis throw new InvalidParameterValueException("The static gateway cidr overlaps with one of the blacklisted routes of the zone the VPC belongs to"); } - Transaction txn = Transaction.currentTxn(); - txn.start(); + return Transaction.execute(new TransactionCallbackWithException() { + @Override + public StaticRouteVO doInTransaction(TransactionStatus status) throws NetworkRuleConflictException { + StaticRouteVO newRoute = new StaticRouteVO(gateway.getId(), cidr, vpc.getId(), vpc.getAccountId(), vpc.getDomainId()); + s_logger.debug("Adding static route " + newRoute); + newRoute = _staticRouteDao.persist(newRoute); + + detectRoutesConflict(newRoute); - StaticRouteVO newRoute = new StaticRouteVO(gateway.getId(), cidr, vpc.getId(), vpc.getAccountId(), vpc.getDomainId()); - s_logger.debug("Adding static route " + newRoute); - newRoute = _staticRouteDao.persist(newRoute); - - detectRoutesConflict(newRoute); - - if (!_staticRouteDao.setStateToAdd(newRoute)) { - throw new CloudRuntimeException("Unable to update the state to add for " + newRoute); - } - CallContext.current().setEventDetails("Static route Id: " + newRoute.getId()); - - txn.commit(); - - return newRoute; + if (!_staticRouteDao.setStateToAdd(newRoute)) { + throw new CloudRuntimeException("Unable to update the state to add for " + newRoute); + } + CallContext.current().setEventDetails("Static route Id: " + newRoute.getId()); + + return newRoute; + } + }); } protected boolean isCidrBlacklisted(String cidr, long zoneId) { @@ -1884,7 +1918,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis if (tags != null && !tags.isEmpty()) { int count = 0; - sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.StaticRoute.toString()); + sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.StaticRoute.toString()); for (String key : tags.keySet()) { sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); @@ -1947,23 +1981,22 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis return; } - Transaction txn = null; try { - txn = Transaction.open(Transaction.CLOUD_DB); - - // Cleanup inactive VPCs - List inactiveVpcs = _vpcDao.listInactiveVpcs(); - s_logger.info("Found " + inactiveVpcs.size() + " removed VPCs to cleanup"); - for (VpcVO vpc : inactiveVpcs) { - s_logger.debug("Cleaning up " + vpc); - destroyVpc(vpc, _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM); - } + Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) throws Exception { + // Cleanup inactive VPCs + List inactiveVpcs = _vpcDao.listInactiveVpcs(); + s_logger.info("Found " + inactiveVpcs.size() + " removed VPCs to cleanup"); + for (VpcVO vpc : inactiveVpcs) { + s_logger.debug("Cleaning up " + vpc); + destroyVpc(vpc, _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM); + } + } + }); } catch (Exception e) { s_logger.error("Exception ", e); } finally { - if (txn != null) { - txn.close(); - } lock.unlock(); } } catch (Exception e) { @@ -1976,7 +2009,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis @DB @Override @ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "associating Ip", async = true) - public IpAddress associateIPToVpc(long ipId, long vpcId) throws ResourceAllocationException, ResourceUnavailableException, + public IpAddress associateIPToVpc(final long ipId, final long vpcId) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException { Account caller = CallContext.current().getCallingAccount(); Account owner = null; @@ -2005,17 +2038,20 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis s_logger.debug("Associating ip " + ipToAssoc + " to vpc " + vpc); - Transaction txn = Transaction.currentTxn(); - txn.start(); - IPAddressVO ip = _ipAddressDao.findById(ipId); - //update ip address with networkId - ip.setVpcId(vpcId); - ip.setSourceNat(isSourceNat); - _ipAddressDao.update(ipId, ip); + final boolean isSourceNatFinal = isSourceNat; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + IPAddressVO ip = _ipAddressDao.findById(ipId); + //update ip address with networkId + ip.setVpcId(vpcId); + ip.setSourceNat(isSourceNatFinal); + _ipAddressDao.update(ipId, ip); - //mark ip as allocated - _ipAddrMgr.markPublicIpAsAllocated(ip); - txn.commit(); + //mark ip as allocated + _ipAddrMgr.markPublicIpAsAllocated(ip); + } + }); s_logger.debug("Successfully assigned ip " + ipToAssoc + " to vpc " + vpc); @@ -2178,4 +2214,9 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis return new ArrayList(providers.values()); } + + @Inject + public void setVpcElements(List vpcElements) { + this.vpcElements = vpcElements; + } } diff --git a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java index 6cd164dc3f1..831223bc261 100755 --- a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java @@ -26,7 +26,6 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; - import org.apache.cloudstack.api.command.user.vpn.ListRemoteAccessVpnsCmd; import org.apache.cloudstack.api.command.user.vpn.ListVpnUsersCmd; import org.apache.cloudstack.context.CallContext; @@ -80,8 +79,12 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackWithException; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.net.NetUtils; @Local(value = RemoteAccessVpnService.class) @@ -114,13 +117,13 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc @Override @DB - public RemoteAccessVpn createRemoteAccessVpn(long publicIpId, String ipRange, boolean openFirewall, long networkId) + public RemoteAccessVpn createRemoteAccessVpn(final long publicIpId, String ipRange, final boolean openFirewall, long networkId) throws NetworkRuleConflictException { CallContext ctx = CallContext.current(); - Account caller = ctx.getCallingAccount(); + final Account caller = ctx.getCallingAccount(); // make sure ip address exists - PublicIpAddress ipAddr = _networkMgr.getPublicIpAddress(publicIpId); + final PublicIpAddress ipAddr = _networkMgr.getPublicIpAddress(publicIpId); if (ipAddr == null) { throw new InvalidParameterValueException("Unable to create remote access vpn, invalid public IP address id" + publicIpId); } @@ -163,7 +166,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc if (ipRange == null) { ipRange = RemoteAccessVpnClientIpRange.valueIn(ipAddr.getAccountId()); } - String[] range = ipRange.split("-"); + final String[] range = ipRange.split("-"); if (range.length != 2) { throw new InvalidParameterValueException("Invalid ip range"); } @@ -187,19 +190,18 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc // TODO: check overlap with private and public ip ranges in datacenter long startIp = NetUtils.ip2Long(range[0]); - String newIpRange = NetUtils.long2Ip(++startIp) + "-" + range[1]; - String sharedSecret = PasswordGenerator.generatePresharedKey(_pskLength); + final String newIpRange = NetUtils.long2Ip(++startIp) + "-" + range[1]; + final String sharedSecret = PasswordGenerator.generatePresharedKey(_pskLength); - Transaction txn = Transaction.currentTxn(); - txn.start(); - - _rulesMgr.reservePorts(ipAddr, NetUtils.UDP_PROTO, Purpose.Vpn, openFirewall, caller, NetUtils.VPN_PORT, NetUtils.VPN_L2TP_PORT, NetUtils.VPN_NATT_PORT); - vpnVO = new RemoteAccessVpnVO(ipAddr.getAccountId(), ipAddr.getDomainId(), ipAddr.getAssociatedWithNetworkId(), - publicIpId, range[0], newIpRange, sharedSecret); - RemoteAccessVpn vpn = _remoteAccessVpnDao.persist(vpnVO); - - txn.commit(); - return vpn; + return Transaction.execute(new TransactionCallbackWithException() { + @Override + public RemoteAccessVpn doInTransaction(TransactionStatus status) throws NetworkRuleConflictException { + _rulesMgr.reservePorts(ipAddr, NetUtils.UDP_PROTO, Purpose.Vpn, openFirewall, caller, NetUtils.VPN_PORT, NetUtils.VPN_L2TP_PORT, NetUtils.VPN_NATT_PORT); + RemoteAccessVpnVO vpnVO = new RemoteAccessVpnVO(ipAddr.getAccountId(), ipAddr.getDomainId(), ipAddr.getAssociatedWithNetworkId(), + publicIpId, range[0], newIpRange, sharedSecret); + return _remoteAccessVpnDao.persist(vpnVO); + } + }); } private void validateRemoteAccessVpnConfiguration() throws ConfigurationException { @@ -230,7 +232,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc @Override @DB public void destroyRemoteAccessVpnForIp(long ipId, Account caller) throws ResourceUnavailableException { - RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findByPublicIpAddress(ipId); + final RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findByPublicIpAddress(ipId); if (vpn == null) { s_logger.debug("there are no Remote access vpns for public ip address id=" + ipId); return; @@ -247,7 +249,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc boolean success = false; try { for (RemoteAccessVPNServiceProvider element : _vpnServiceProviders) { - if (element.stopVpn(network, vpn)) { + if (element.stopVpn(vpn)) { success = true; break; } @@ -255,28 +257,28 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc } finally { if (success) { //Cleanup corresponding ports - List vpnFwRules = _rulesDao.listByIpAndPurpose(ipId, Purpose.Vpn); - Transaction txn = Transaction.currentTxn(); + final List vpnFwRules = _rulesDao.listByIpAndPurpose(ipId, Purpose.Vpn); boolean applyFirewall = false; - List fwRules = new ArrayList(); + final List fwRules = new ArrayList(); //if related firewall rule is created for the first vpn port, it would be created for the 2 other ports as well, so need to cleanup the backend if (_rulesDao.findByRelatedId(vpnFwRules.get(0).getId()) != null) { applyFirewall = true; } if (applyFirewall) { - txn.start(); - - for (FirewallRule vpnFwRule : vpnFwRules) { - //don't apply on the backend yet; send all 3 rules in a banch - _firewallMgr.revokeRelatedFirewallRule(vpnFwRule.getId(), false); - fwRules.add(_rulesDao.findByRelatedId(vpnFwRule.getId())); - } - - s_logger.debug("Marked " + fwRules.size() + " firewall rules as Revoked as a part of disable remote access vpn"); - - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + for (FirewallRule vpnFwRule : vpnFwRules) { + //don't apply on the backend yet; send all 3 rules in a banch + _firewallMgr.revokeRelatedFirewallRule(vpnFwRule.getId(), false); + fwRules.add(_rulesDao.findByRelatedId(vpnFwRule.getId())); + } + + s_logger.debug("Marked " + fwRules.size() + " firewall rules as Revoked as a part of disable remote access vpn"); + } + }); //now apply vpn rules on the backend s_logger.debug("Reapplying firewall rules for ip id=" + ipId + " as a part of disable remote access vpn"); @@ -285,26 +287,28 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc if (success) { try { - txn.start(); - _remoteAccessVpnDao.remove(vpn.getId()); - // Stop billing of VPN users when VPN is removed. VPN_User_ADD events will be generated when VPN is created again - List vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId()); - for(VpnUserVO user : vpnUsers){ - // VPN_USER_REMOVE event is already generated for users in Revoke state - if(user.getState() != VpnUser.State.Revoke){ - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(), - 0, user.getId(), user.getUsername(), user.getClass().getName(), user.getUuid()); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + _remoteAccessVpnDao.remove(vpn.getId()); + // Stop billing of VPN users when VPN is removed. VPN_User_ADD events will be generated when VPN is created again + List vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId()); + for(VpnUserVO user : vpnUsers){ + // VPN_USER_REMOVE event is already generated for users in Revoke state + if(user.getState() != VpnUser.State.Revoke){ + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(), + 0, user.getId(), user.getUsername(), user.getClass().getName(), user.getUuid()); + } + } + if (vpnFwRules != null) { + for (FirewallRule vpnFwRule : vpnFwRules) { + _rulesDao.remove(vpnFwRule.getId()); + s_logger.debug("Successfully removed firewall rule with ip id=" + vpnFwRule.getSourceIpAddressId() + " and port " + vpnFwRule.getSourcePortStart() + " as a part of vpn cleanup"); + } + } } - } - if (vpnFwRules != null) { - for (FirewallRule vpnFwRule : vpnFwRules) { - _rulesDao.remove(vpnFwRule.getId()); - s_logger.debug("Successfully removed firewall rule with ip id=" + vpnFwRule.getSourceIpAddressId() + " and port " + vpnFwRule.getSourcePortStart() + " as a part of vpn cleanup"); - } - } - txn.commit(); + }); } catch (Exception ex) { - txn.rollback(); s_logger.warn("Unable to release the three vpn ports from the firewall rules", ex); } } @@ -314,8 +318,8 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc @Override @DB - public VpnUser addVpnUser(long vpnOwnerId, String username, String password) { - Account caller = CallContext.current().getCallingAccount(); + public VpnUser addVpnUser(final long vpnOwnerId, final String username, final String password) { + final Account caller = CallContext.current().getCallingAccount(); if (!username.matches("^[a-zA-Z0-9][a-zA-Z0-9@._-]{2,63}$")) { throw new InvalidParameterValueException( @@ -324,46 +328,54 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc if (!password.matches("^[a-zA-Z0-9][a-zA-Z0-9@#+=._-]{2,31}$")) { throw new InvalidParameterValueException("Password has to be 3-32 characters including alphabets, numbers and the set '@#+=.-_'"); } - Transaction txn = Transaction.currentTxn(); - txn.start(); - Account owner = _accountDao.lockRow(vpnOwnerId, true); - if (owner == null) { - throw new InvalidParameterValueException("Unable to add vpn user: Another operation active"); - } - _accountMgr.checkAccess(caller, null, true, owner); - //don't allow duplicated user names for the same account - VpnUserVO vpnUser = _vpnUsersDao.findByAccountAndUsername(owner.getId(), username); - if (vpnUser != null) { - throw new InvalidParameterValueException("VPN User with name " + username + " is already added for account " + owner); - } - - long userCount = _vpnUsersDao.getVpnUserCount(owner.getId()); - if (userCount >= _userLimit) { - throw new AccountLimitException("Cannot add more than " + _userLimit + " remote access vpn users"); - } - - VpnUser user = _vpnUsersDao.persist(new VpnUserVO(vpnOwnerId, owner.getDomainId(), username, password)); - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_ADD, user.getAccountId(), 0, user.getId(), - user.getUsername(), user.getClass().getName(), user.getUuid()); - txn.commit(); - return user; + return Transaction.execute(new TransactionCallback() { + @Override + public VpnUser doInTransaction(TransactionStatus status) { + Account owner = _accountDao.lockRow(vpnOwnerId, true); + if (owner == null) { + throw new InvalidParameterValueException("Unable to add vpn user: Another operation active"); + } + _accountMgr.checkAccess(caller, null, true, owner); + + //don't allow duplicated user names for the same account + VpnUserVO vpnUser = _vpnUsersDao.findByAccountAndUsername(owner.getId(), username); + if (vpnUser != null) { + throw new InvalidParameterValueException("VPN User with name " + username + " is already added for account " + owner); + } + + long userCount = _vpnUsersDao.getVpnUserCount(owner.getId()); + if (userCount >= _userLimit) { + throw new AccountLimitException("Cannot add more than " + _userLimit + " remote access vpn users"); + } + + VpnUser user = _vpnUsersDao.persist(new VpnUserVO(vpnOwnerId, owner.getDomainId(), username, password)); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_ADD, user.getAccountId(), 0, user.getId(), + user.getUsername(), user.getClass().getName(), user.getUuid()); + + return user; + } + }); } @DB @Override public boolean removeVpnUser(long vpnOwnerId, String username, Account caller) { - VpnUserVO user = _vpnUsersDao.findByAccountAndUsername(vpnOwnerId, username); + final VpnUserVO user = _vpnUsersDao.findByAccountAndUsername(vpnOwnerId, username); if (user == null) { throw new InvalidParameterValueException("Could not find vpn user " + username); } _accountMgr.checkAccess(caller, null, true, user); - Transaction txn = Transaction.currentTxn(); - txn.start(); - user.setState(State.Revoke); - _vpnUsersDao.update(user.getId(), user); - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(), 0, user.getId(), - user.getUsername(), user.getClass().getName(), user.getUuid()); - txn.commit(); + + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + user.setState(State.Revoke); + _vpnUsersDao.update(user.getId(), user); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(), 0, user.getId(), + user.getUsername(), user.getClass().getName(), user.getUuid()); + } + }); + return true; } @@ -379,7 +391,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc public RemoteAccessVpnVO startRemoteAccessVpn(long ipAddressId, boolean openFirewall) throws ResourceUnavailableException { Account caller = CallContext.current().getCallingAccount(); - RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findByPublicIpAddress(ipAddressId); + final RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findByPublicIpAddress(ipAddressId); if (vpn == null) { throw new InvalidParameterValueException("Unable to find your vpn: " + ipAddressId); } @@ -397,7 +409,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc if (firewallOpened) { for (RemoteAccessVPNServiceProvider element : _vpnServiceProviders) { - if (element.startVpn(network, vpn)) { + if (element.startVpn(vpn)) { started = true; break; } @@ -407,20 +419,22 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc return vpn; } finally { if (started) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - vpn.setState(RemoteAccessVpn.State.Running); - _remoteAccessVpnDao.update(vpn.getId(), vpn); - - // Start billing of existing VPN users in ADD and Active state - List vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId()); - for(VpnUserVO user : vpnUsers){ - if(user.getState() != VpnUser.State.Revoke){ - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_ADD, user.getAccountId(), 0, - user.getId(), user.getUsername(), user.getClass().getName(), user.getUuid()); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + vpn.setState(RemoteAccessVpn.State.Running); + _remoteAccessVpnDao.update(vpn.getId(), vpn); + + // Start billing of existing VPN users in ADD and Active state + List vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId()); + for(VpnUserVO user : vpnUsers){ + if(user.getState() != VpnUser.State.Revoke){ + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_ADD, user.getAccountId(), 0, + user.getId(), user.getUsername(), user.getClass().getName(), user.getUuid()); + } + } } - } - txn.commit(); + }); } } } @@ -479,7 +493,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc } for (int i = 0; i < finals.length; i++) { - VpnUserVO user = users.get(i); + final VpnUserVO user = users.get(i); if (finals[i]) { if (user.getState() == State.Add) { user.setState(State.Active); @@ -489,12 +503,14 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc } } else { if (user.getState() == State.Add && (user.getUsername()).equals(userName)) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - _vpnUsersDao.remove(user.getId()); - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(), - 0, user.getId(), user.getUsername(), user.getClass().getName(), user.getUuid()); - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + _vpnUsersDao.remove(user.getId()); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(), + 0, user.getId(), user.getUsername(), user.getClass().getName(), user.getUuid()); + } + }); } s_logger.warn("Failed to apply vpn for user " + user.getUsername() + ", accountId=" + user.getAccountId()); } diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java index a385739f9aa..22e2020ad22 100755 --- a/server/src/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/com/cloud/projects/ProjectManagerImpl.java @@ -82,6 +82,10 @@ import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.sun.mail.smtp.SMTPMessage; import com.sun.mail.smtp.SMTPSSLTransport; @@ -175,7 +179,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { @Override @ActionEvent(eventType = EventTypes.EVENT_PROJECT_CREATE, eventDescription = "creating project", create=true) @DB - public Project createProject(String name, String displayText, String accountName, Long domainId) throws ResourceAllocationException{ + public Project createProject(final String name, final String displayText, String accountName, final Long domainId) throws ResourceAllocationException{ Account caller = CallContext.current().getCallingAccount(); Account owner = caller; @@ -201,30 +205,32 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { //do resource limit check _resourceLimitMgr.checkResourceLimit(owner, ResourceType.project); - Transaction txn = Transaction.currentTxn(); - txn.start(); + final Account ownerFinal = owner; + return Transaction.execute(new TransactionCallback() { + @Override + public Project doInTransaction(TransactionStatus status) { - //Create an account associated with the project - StringBuilder acctNm = new StringBuilder("PrjAcct-"); - acctNm.append(name).append("-").append(owner.getDomainId()); + //Create an account associated with the project + StringBuilder acctNm = new StringBuilder("PrjAcct-"); + acctNm.append(name).append("-").append(ownerFinal.getDomainId()); + + Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, UUID.randomUUID().toString()); + + Project project = _projectDao.persist(new ProjectVO(name, displayText, ownerFinal.getDomainId(), projectAccount.getId())); + + //assign owner to the project + assignAccountToProject(project, ownerFinal.getId(), ProjectAccount.Role.Admin); + + if (project != null) { + CallContext.current().setEventDetails("Project id=" + project.getId()); + } + + //Increment resource count + _resourceLimitMgr.incrementResourceCount(ownerFinal.getId(), ResourceType.project); - Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, UUID.randomUUID().toString()); - - Project project = _projectDao.persist(new ProjectVO(name, displayText, owner.getDomainId(), projectAccount.getId())); - - //assign owner to the project - assignAccountToProject(project, owner.getId(), ProjectAccount.Role.Admin); - - if (project != null) { - CallContext.current().setEventDetails("Project id=" + project.getId()); - } - - //Increment resource count - _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.project); - - txn.commit(); - - return project; + return project; + } + }); } @@ -268,20 +274,24 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { @DB @Override - public boolean deleteProject(Account caller, long callerUserId, ProjectVO project) { + public boolean deleteProject(Account caller, long callerUserId, final ProjectVO project) { //mark project as inactive first, so you can't add resources to it - Transaction txn = Transaction.currentTxn(); - txn.start(); - s_logger.debug("Marking project id=" + project.getId() + " with state " + State.Disabled + " as a part of project delete..."); - project.setState(State.Disabled); - boolean updateResult = _projectDao.update(project.getId(), project); - //owner can be already removed at this point, so adding the conditional check - Account projectOwner = getProjectOwner(project.getId()); - if (projectOwner != null) { - _resourceLimitMgr.decrementResourceCount(projectOwner.getId(), ResourceType.project); - } + boolean updateResult = Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + s_logger.debug("Marking project id=" + project.getId() + " with state " + State.Disabled + " as a part of project delete..."); + project.setState(State.Disabled); + boolean updateResult = _projectDao.update(project.getId(), project); + //owner can be already removed at this point, so adding the conditional check + Account projectOwner = getProjectOwner(project.getId()); + if (projectOwner != null) { + _resourceLimitMgr.decrementResourceCount(projectOwner.getId(), ResourceType.project); + } + + return updateResult; + } + }); - txn.commit(); if (updateResult) { //pass system caller when clenaup projects account @@ -298,7 +308,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { } @DB - private boolean cleanupProject(Project project, AccountVO caller, Long callerUserId) { + private boolean cleanupProject(final Project project, AccountVO caller, Long callerUserId) { boolean result=true; //Delete project's account AccountVO account = _accountDao.findById(project.getProjectAccountId()); @@ -308,20 +318,22 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { if (result) { //Unassign all users from the project - - Transaction txn = Transaction.currentTxn(); - txn.start(); - - s_logger.debug("Unassigning all accounts from project " + project + " as a part of project cleanup..."); - List projectAccounts = _projectAccountDao.listByProjectId(project.getId()); - for (ProjectAccount projectAccount : projectAccounts) { - result = result && unassignAccountFromProject(projectAccount.getProjectId(), projectAccount.getAccountId()); - } - - s_logger.debug("Removing all invitations for the project " + project + " as a part of project cleanup..."); - _projectInvitationDao.cleanupInvitations(project.getId()); - - txn.commit(); + result = Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + boolean result = true; + s_logger.debug("Unassigning all accounts from project " + project + " as a part of project cleanup..."); + List projectAccounts = _projectAccountDao.listByProjectId(project.getId()); + for (ProjectAccount projectAccount : projectAccounts) { + result = result && unassignAccountFromProject(projectAccount.getProjectId(), projectAccount.getAccountId()); + } + + s_logger.debug("Removing all invitations for the project " + project + " as a part of project cleanup..."); + _projectInvitationDao.cleanupInvitations(project.getId()); + + return result; + } + }); if (result) { s_logger.debug("Accounts are unassign successfully from project " + project + " as a part of project cleanup..."); } @@ -366,26 +378,28 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { } @Override @DB - public boolean deleteAccountFromProject(long projectId, long accountId) { - boolean success = true; - Transaction txn = Transaction.currentTxn(); - txn.start(); + public boolean deleteAccountFromProject(final long projectId, final long accountId) { + return Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + boolean success = true; - //remove account - ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId); - success = _projectAccountDao.remove(projectAccount.getId()); + //remove account + ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId); + success = _projectAccountDao.remove(projectAccount.getId()); - //remove all invitations for account - if (success) { - s_logger.debug("Removed account " + accountId + " from project " + projectId + " , cleaning up old invitations for account/project..."); - ProjectInvitation invite = _projectInvitationDao.findByAccountIdProjectId(accountId, projectId); - if (invite != null) { - success = success && _projectInvitationDao.remove(invite.getId()); + //remove all invitations for account + if (success) { + s_logger.debug("Removed account " + accountId + " from project " + projectId + " , cleaning up old invitations for account/project..."); + ProjectInvitation invite = _projectInvitationDao.findByAccountIdProjectId(accountId, projectId); + if (invite != null) { + success = success && _projectInvitationDao.remove(invite.getId()); + } + } + + return success; } - } - - txn.commit(); - return success; + }); } @Override @@ -442,11 +456,11 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { @Override @DB @ActionEvent(eventType = EventTypes.EVENT_PROJECT_UPDATE, eventDescription = "updating project", async=true) - public Project updateProject(long projectId, String displayText, String newOwnerName) throws ResourceAllocationException{ + public Project updateProject(final long projectId, final String displayText, final String newOwnerName) throws ResourceAllocationException{ Account caller = CallContext.current().getCallingAccount(); //check that the project exists - ProjectVO project = getProject(projectId); + final ProjectVO project = getProject(projectId); if (project == null) { throw new InvalidParameterValueException("Unable to find the project id=" + projectId); @@ -455,47 +469,49 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { //verify permissions _accountMgr.checkAccess(caller,AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId())); - Transaction txn = Transaction.currentTxn(); - txn.start(); - if (displayText != null) { - project.setDisplayText(displayText); - _projectDao.update(projectId, project); - } - - if (newOwnerName != null) { - //check that the new owner exists - Account futureOwnerAccount = _accountMgr.getActiveAccountByName(newOwnerName, project.getDomainId()); - if (futureOwnerAccount == null) { - throw new InvalidParameterValueException("Unable to find account name=" + newOwnerName + " in domain id=" + project.getDomainId()); - } - Account currentOwnerAccount = getProjectOwner(projectId); - if (currentOwnerAccount.getId() != futureOwnerAccount.getId()) { - ProjectAccountVO futureOwner = _projectAccountDao.findByProjectIdAccountId(projectId, futureOwnerAccount.getAccountId()); - if (futureOwner == null) { - throw new InvalidParameterValueException("Account " + newOwnerName + " doesn't belong to the project. Add it to the project first and then change the project's ownership"); + Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) throws ResourceAllocationException { + if (displayText != null) { + project.setDisplayText(displayText); + _projectDao.update(projectId, project); } - - //do resource limit check - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(futureOwnerAccount.getId()), ResourceType.project); - - //unset the role for the old owner - ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId()); - currentOwner.setAccountRole(Role.Regular); - _projectAccountDao.update(currentOwner.getId(), currentOwner); - _resourceLimitMgr.decrementResourceCount(currentOwnerAccount.getId(), ResourceType.project); - - //set new owner - futureOwner.setAccountRole(Role.Admin); - _projectAccountDao.update(futureOwner.getId(), futureOwner); - _resourceLimitMgr.incrementResourceCount(futureOwnerAccount.getId(), ResourceType.project); - - - } else { - s_logger.trace("Future owner " + newOwnerName + "is already the owner of the project id=" + projectId); + + if (newOwnerName != null) { + //check that the new owner exists + Account futureOwnerAccount = _accountMgr.getActiveAccountByName(newOwnerName, project.getDomainId()); + if (futureOwnerAccount == null) { + throw new InvalidParameterValueException("Unable to find account name=" + newOwnerName + " in domain id=" + project.getDomainId()); + } + Account currentOwnerAccount = getProjectOwner(projectId); + if (currentOwnerAccount.getId() != futureOwnerAccount.getId()) { + ProjectAccountVO futureOwner = _projectAccountDao.findByProjectIdAccountId(projectId, futureOwnerAccount.getAccountId()); + if (futureOwner == null) { + throw new InvalidParameterValueException("Account " + newOwnerName + " doesn't belong to the project. Add it to the project first and then change the project's ownership"); + } + + //do resource limit check + _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(futureOwnerAccount.getId()), ResourceType.project); + + //unset the role for the old owner + ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId()); + currentOwner.setAccountRole(Role.Regular); + _projectAccountDao.update(currentOwner.getId(), currentOwner); + _resourceLimitMgr.decrementResourceCount(currentOwnerAccount.getId(), ResourceType.project); + + //set new owner + futureOwner.setAccountRole(Role.Admin); + _projectAccountDao.update(futureOwner.getId(), futureOwner); + _resourceLimitMgr.incrementResourceCount(futureOwnerAccount.getId(), ResourceType.project); + + + } else { + s_logger.trace("Future owner " + newOwnerName + "is already the owner of the project id=" + projectId); + } + } } - } + }); - txn.commit(); return _projectDao.findById(projectId); @@ -649,37 +665,40 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { } @DB - public boolean activeInviteExists(Project project, Long accountId, String email) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - //verify if the invitation was already generated - ProjectInvitationVO invite = null; - if (accountId != null) { - invite = _projectInvitationDao.findByAccountIdProjectId(accountId, project.getId()); - } else if (email != null) { - invite = _projectInvitationDao.findByEmailAndProjectId(email, project.getId()); - } - - if (invite != null) { - if (invite.getState() == ProjectInvitation.State.Completed || - (invite.getState() == ProjectInvitation.State.Pending && _projectInvitationDao.isActive(invite.getId(), _invitationTimeOut))) { - return true; - } else { - if (invite.getState() == ProjectInvitation.State.Pending) { - expireInvitation(invite); - } - //remove the expired/declined invitation + public boolean activeInviteExists(final Project project, final Long accountId, final String email) { + return Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + //verify if the invitation was already generated + ProjectInvitationVO invite = null; if (accountId != null) { - s_logger.debug("Removing invitation in state " + invite.getState() + " for account id=" + accountId + " to project " + project); + invite = _projectInvitationDao.findByAccountIdProjectId(accountId, project.getId()); } else if (email != null) { - s_logger.debug("Removing invitation in state " + invite.getState() + " for email " + email + " to project " + project); + invite = _projectInvitationDao.findByEmailAndProjectId(email, project.getId()); } - _projectInvitationDao.expunge(invite.getId()); + if (invite != null) { + if (invite.getState() == ProjectInvitation.State.Completed || + (invite.getState() == ProjectInvitation.State.Pending && _projectInvitationDao.isActive(invite.getId(), _invitationTimeOut))) { + return true; + } else { + if (invite.getState() == ProjectInvitation.State.Pending) { + expireInvitation(invite); + } + //remove the expired/declined invitation + if (accountId != null) { + s_logger.debug("Removing invitation in state " + invite.getState() + " for account id=" + accountId + " to project " + project); + } else if (email != null) { + s_logger.debug("Removing invitation in state " + invite.getState() + " for email " + email + " to project " + project); + } + + _projectInvitationDao.expunge(invite.getId()); + } + } + + return false; } - } - txn.commit(); - return false; + }); } public ProjectInvitation generateTokenBasedInvitation(Project project, String email, String token) { @@ -710,7 +729,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { @Override @DB @ActionEvent(eventType = EventTypes.EVENT_PROJECT_INVITATION_UPDATE, eventDescription = "updating project invitation", async=true) - public boolean updateInvitation(long projectId, String accountName, String token, boolean accept) { + public boolean updateInvitation(final long projectId, String accountName, String token, final boolean accept) { Account caller = CallContext.current().getCallingAccount(); Long accountId = null; boolean result = true; @@ -721,7 +740,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { } //check that the project exists - Project project = getProject(projectId); + final Project project = getProject(projectId); if (project == null) { throw new InvalidParameterValueException("Unable to find the project id=" + projectId); @@ -755,29 +774,37 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { expireInvitation(invite); throw new InvalidParameterValueException("Invitation is expired for account id=" + accountName + " to the project id=" + projectId); } else { - Transaction txn = Transaction.currentTxn(); - txn.start(); - - ProjectInvitation.State newState = accept ? ProjectInvitation.State.Completed : ProjectInvitation.State.Declined; - - //update invitation - s_logger.debug("Marking invitation " + invite + " with state " + newState); - invite.setState(newState); - result = _projectInvitationDao.update(invite.getId(), invite); - - if (result && accept) { - //check if account already exists for the project (was added before invitation got accepted) - ProjectAccount projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId); - if (projectAccount != null) { - s_logger.debug("Account " + accountName + " already added to the project id=" + projectId); - } else { - assignAccountToProject(project, accountId, ProjectAccount.Role.Regular); + + final ProjectInvitationVO inviteFinal = invite; + final Long accountIdFinal = accountId; + final String accountNameFinal = accountName; + result = Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + boolean result = true; + + ProjectInvitation.State newState = accept ? ProjectInvitation.State.Completed : ProjectInvitation.State.Declined; + + //update invitation + s_logger.debug("Marking invitation " + inviteFinal + " with state " + newState); + inviteFinal.setState(newState); + result = _projectInvitationDao.update(inviteFinal.getId(), inviteFinal); + + if (result && accept) { + //check if account already exists for the project (was added before invitation got accepted) + ProjectAccount projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountIdFinal); + if (projectAccount != null) { + s_logger.debug("Account " + accountNameFinal + " already added to the project id=" + projectId); + } else { + assignAccountToProject(project, accountIdFinal, ProjectAccount.Role.Regular); + } + } else { + s_logger.warn("Failed to update project invitation " + inviteFinal + " with state " + newState); + } + + return result; } - } else { - s_logger.warn("Failed to update project invitation " + invite + " with state " + newState); - } - - txn.commit(); + }); } } else { throw new InvalidParameterValueException("Unable to find invitation for account name=" + accountName + " to the project id=" + projectId); @@ -794,11 +821,11 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { @Override @ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACTIVATE, eventDescription = "activating project") @DB - public Project activateProject(long projectId) { + public Project activateProject(final long projectId) { Account caller = CallContext.current().getCallingAccount(); //check that the project exists - ProjectVO project = getProject(projectId); + final ProjectVO project = getProject(projectId); if (project == null) { InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id"); @@ -821,15 +848,15 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { throw new InvalidParameterValueException("Can't activate the project in " + currentState + " state"); } - Transaction txn = Transaction.currentTxn(); - txn.start(); - - project.setState(Project.State.Active); - _projectDao.update(projectId, project); - - _accountMgr.enableAccount(project.getProjectAccountId()); - - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + project.setState(Project.State.Active); + _projectDao.update(projectId, project); + + _accountMgr.enableAccount(project.getProjectAccountId()); + } + }); return _projectDao.findById(projectId); } diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java index 7a9343cff41..e9d51936878 100755 --- a/server/src/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/com/cloud/resource/ResourceManagerImpl.java @@ -143,6 +143,9 @@ import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.QueryBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; @@ -783,10 +786,10 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } @DB - protected boolean doDeleteHost(long hostId, boolean isForced, boolean isForceDeleteStorage) { + protected boolean doDeleteHost(final long hostId, boolean isForced, final boolean isForceDeleteStorage) { User caller = _accountMgr.getActiveUser(CallContext.current().getCallingUserId()); // Verify that host exists - HostVO host = _hostDao.findById(hostId); + final HostVO host = _hostDao.findById(hostId); if (host == null) { throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist"); } @@ -799,7 +802,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, // Get storage pool host mappings here because they can be removed as a // part of handleDisconnect later // TODO: find out the bad boy, what's a buggy logic! - List pools = _storagePoolHostDao.listByHostIdIncludingRemoved(hostId); + final List pools = _storagePoolHostDao.listByHostIdIncludingRemoved(hostId); ResourceStateAdapter.DeleteHostAnswer answer = (ResourceStateAdapter.DeleteHostAnswer)dispatchToStateAdapters(ResourceStateAdapter.Event.DELETE_HOST, false, host, new Boolean(isForced), new Boolean(isForceDeleteStorage)); @@ -817,74 +820,77 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, return true; } - Transaction txn = Transaction.currentTxn(); - txn.start(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { - _dcDao.releasePrivateIpAddress(host.getPrivateIpAddress(), host.getDataCenterId(), null); - _agentMgr.disconnectWithoutInvestigation(hostId, Status.Event.Remove); - - // delete host details - _hostDetailsDao.deleteDetails(hostId); - - host.setGuid(null); - Long clusterId = host.getClusterId(); - host.setClusterId(null); - _hostDao.update(host.getId(), host); - - _hostDao.remove(hostId); - if (clusterId != null) { - List hosts = listAllHostsInCluster(clusterId); - if (hosts.size() == 0) { - ClusterVO cluster = _clusterDao.findById(clusterId); - cluster.setGuid(null); - _clusterDao.update(clusterId, cluster); + _dcDao.releasePrivateIpAddress(host.getPrivateIpAddress(), host.getDataCenterId(), null); + _agentMgr.disconnectWithoutInvestigation(hostId, Status.Event.Remove); + + // delete host details + _hostDetailsDao.deleteDetails(hostId); + + host.setGuid(null); + Long clusterId = host.getClusterId(); + host.setClusterId(null); + _hostDao.update(host.getId(), host); + + _hostDao.remove(hostId); + if (clusterId != null) { + List hosts = listAllHostsInCluster(clusterId); + if (hosts.size() == 0) { + ClusterVO cluster = _clusterDao.findById(clusterId); + cluster.setGuid(null); + _clusterDao.update(clusterId, cluster); + } + } + + try { + resourceStateTransitTo(host, ResourceState.Event.DeleteHost, _nodeId); + } catch (NoTransitionException e) { + s_logger.debug("Cannot transmit host " + host.getId() + "to Enabled state", e); + } + + // Delete the associated entries in host ref table + _storagePoolHostDao.deletePrimaryRecordsForHost(hostId); + + // Make sure any VMs that were marked as being on this host are cleaned up + List vms = _vmDao.listByHostId(hostId); + for (VMInstanceVO vm : vms) { + // this is how VirtualMachineManagerImpl does it when it syncs VM states + vm.setState(State.Stopped); + vm.setHostId(null); + _vmDao.persist(vm); + } + + // For pool ids you got, delete local storage host entries in pool table + // where + for (StoragePoolHostVO pool : pools) { + Long poolId = pool.getPoolId(); + StoragePoolVO storagePool = _storagePoolDao.findById(poolId); + if (storagePool.isLocal() && isForceDeleteStorage) { + storagePool.setUuid(null); + storagePool.setClusterId(null); + _storagePoolDao.update(poolId, storagePool); + _storagePoolDao.remove(poolId); + s_logger.debug("Local storage id=" + poolId + " is removed as a part of host removal id=" + hostId); + } + } + + // delete the op_host_capacity entry + Object[] capacityTypes = {Capacity.CAPACITY_TYPE_CPU, Capacity.CAPACITY_TYPE_MEMORY}; + SearchCriteria hostCapacitySC = _capacityDao.createSearchCriteria(); + hostCapacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId); + hostCapacitySC.addAnd("capacityType", SearchCriteria.Op.IN, capacityTypes); + _capacityDao.remove(hostCapacitySC); + // remove from dedicated resources + DedicatedResourceVO dr = _dedicatedDao.findByHostId(hostId); + if (dr != null) { + _dedicatedDao.remove(dr.getId()); + } } - } + }); - try { - resourceStateTransitTo(host, ResourceState.Event.DeleteHost, _nodeId); - } catch (NoTransitionException e) { - s_logger.debug("Cannot transmit host " + host.getId() + "to Enabled state", e); - } - - // Delete the associated entries in host ref table - _storagePoolHostDao.deletePrimaryRecordsForHost(hostId); - - // Make sure any VMs that were marked as being on this host are cleaned up - List vms = _vmDao.listByHostId(hostId); - for (VMInstanceVO vm : vms) { - // this is how VirtualMachineManagerImpl does it when it syncs VM states - vm.setState(State.Stopped); - vm.setHostId(null); - _vmDao.persist(vm); - } - - // For pool ids you got, delete local storage host entries in pool table - // where - for (StoragePoolHostVO pool : pools) { - Long poolId = pool.getPoolId(); - StoragePoolVO storagePool = _storagePoolDao.findById(poolId); - if (storagePool.isLocal() && isForceDeleteStorage) { - storagePool.setUuid(null); - storagePool.setClusterId(null); - _storagePoolDao.update(poolId, storagePool); - _storagePoolDao.remove(poolId); - s_logger.debug("Local storage id=" + poolId + " is removed as a part of host removal id=" + hostId); - } - } - - // delete the op_host_capacity entry - Object[] capacityTypes = {Capacity.CAPACITY_TYPE_CPU, Capacity.CAPACITY_TYPE_MEMORY}; - SearchCriteria hostCapacitySC = _capacityDao.createSearchCriteria(); - hostCapacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId); - hostCapacitySC.addAnd("capacityType", SearchCriteria.Op.IN, capacityTypes); - _capacityDao.remove(hostCapacitySC); - // remove from dedicated resources - DedicatedResourceVO dr = _dedicatedDao.findByHostId(hostId); - if (dr != null) { - _dedicatedDao.remove(dr.getId()); - } - txn.commit(); return true; } @@ -904,63 +910,61 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, @Override @DB - public boolean deleteCluster(DeleteClusterCmd cmd) { - Transaction txn = Transaction.currentTxn(); + public boolean deleteCluster(final DeleteClusterCmd cmd) { try { - txn.start(); - ClusterVO cluster = _clusterDao.lockRow(cmd.getId(), true); - if (cluster == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Cluster: " + cmd.getId() + " does not even exist. Delete call is ignored."); - } - txn.rollback(); - throw new CloudRuntimeException("Cluster: " + cmd.getId() + " does not exist"); - } + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + ClusterVO cluster = _clusterDao.lockRow(cmd.getId(), true); + if (cluster == null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Cluster: " + cmd.getId() + " does not even exist. Delete call is ignored."); + } + throw new CloudRuntimeException("Cluster: " + cmd.getId() + " does not exist"); + } + + Hypervisor.HypervisorType hypervisorType = cluster.getHypervisorType(); + + List hosts = listAllHostsInCluster(cmd.getId()); + if (hosts.size() > 0) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Cluster: " + cmd.getId() + " still has hosts, can't remove"); + } + throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has hosts"); + } + + // don't allow to remove the cluster if it has non-removed storage + // pools + List storagePools = _storagePoolDao.listPoolsByCluster(cmd.getId()); + if (storagePools.size() > 0) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Cluster: " + cmd.getId() + " still has storage pools, can't remove"); + } + throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has storage pools"); + } + + if (_clusterDao.remove(cmd.getId())) { + _capacityDao.removeBy(null, null, null, cluster.getId(), null); + // If this cluster is of type vmware, and if the nexus vswitch + // global parameter setting is turned + // on, remove the row in cluster_vsm_map for this cluster id. + if (hypervisorType == HypervisorType.VMware && Boolean.parseBoolean(_configDao.getValue(Config.VmwareUseNexusVSwitch.toString()))) { + _clusterVSMMapDao.removeByClusterId(cmd.getId()); + } + // remove from dedicated resources + DedicatedResourceVO dr = _dedicatedDao.findByClusterId(cluster.getId()); + if (dr != null) { + _dedicatedDao.remove(dr.getId()); + } + } - Hypervisor.HypervisorType hypervisorType = cluster.getHypervisorType(); - - List hosts = listAllHostsInCluster(cmd.getId()); - if (hosts.size() > 0) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Cluster: " + cmd.getId() + " still has hosts, can't remove"); } - txn.rollback(); - throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has hosts"); - } - - // don't allow to remove the cluster if it has non-removed storage - // pools - List storagePools = _storagePoolDao.listPoolsByCluster(cmd.getId()); - if (storagePools.size() > 0) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Cluster: " + cmd.getId() + " still has storage pools, can't remove"); - } - txn.rollback(); - throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has storage pools"); - } - - if (_clusterDao.remove(cmd.getId())) { - _capacityDao.removeBy(null, null, null, cluster.getId(), null); - // If this cluster is of type vmware, and if the nexus vswitch - // global parameter setting is turned - // on, remove the row in cluster_vsm_map for this cluster id. - if (hypervisorType == HypervisorType.VMware && Boolean.parseBoolean(_configDao.getValue(Config.VmwareUseNexusVSwitch.toString()))) { - _clusterVSMMapDao.removeByClusterId(cmd.getId()); - } - // remove from dedicated resources - DedicatedResourceVO dr = _dedicatedDao.findByClusterId(cluster.getId()); - if (dr != null) { - _dedicatedDao.remove(dr.getId()); - } - } - - txn.commit(); + }); return true; } catch (CloudRuntimeException e) { throw e; } catch (Throwable t) { s_logger.error("Unable to delete cluster: " + cmd.getId(), t); - txn.rollback(); return false; } } @@ -1034,26 +1038,15 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } if (doUpdate) { - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - _clusterDao.update(cluster.getId(), cluster); - txn.commit(); - } catch (Exception e) { - s_logger.error("Unable to update cluster due to " + e.getMessage(), e); - throw new CloudRuntimeException("Failed to update cluster. Please contact Cloud Support."); - } + _clusterDao.update(cluster.getId(), cluster); } if (newManagedState != null && !newManagedState.equals(oldManagedState)) { - Transaction txn = Transaction.currentTxn(); if (newManagedState.equals(Managed.ManagedState.Unmanaged)) { boolean success = false; try { - txn.start(); cluster.setManagedState(Managed.ManagedState.PrepareUnmanaged); _clusterDao.update(cluster.getId(), cluster); - txn.commit(); List hosts = listAllUpAndEnabledHosts(Host.Type.Routing, cluster.getId(), cluster.getPodId(), cluster.getDataCenterId()); for (HostVO host : hosts) { if (host.getType().equals(Host.Type.Routing) && !host.getStatus().equals(Status.Down) && !host.getStatus().equals(Status.Disconnected) && @@ -1092,16 +1085,12 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, throw new CloudRuntimeException("PrepareUnmanaged Failed due to some hosts are still in UP status after 5 Minutes, please try later "); } } finally { - txn.start(); cluster.setManagedState(success ? Managed.ManagedState.Unmanaged : Managed.ManagedState.PrepareUnmanagedError); _clusterDao.update(cluster.getId(), cluster); - txn.commit(); } } else if (newManagedState.equals(Managed.ManagedState.Managed)) { - txn.start(); cluster.setManagedState(Managed.ManagedState.Managed); _clusterDao.update(cluster.getId(), cluster); - txn.commit(); } } @@ -2459,36 +2448,46 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, @Override @DB @ActionEvent(eventType = EventTypes.EVENT_HOST_RESERVATION_RELEASE, eventDescription = "releasing host reservation", async = true) - public boolean releaseHostReservation(Long hostId) { - Transaction txn = Transaction.currentTxn(); + public boolean releaseHostReservation(final Long hostId) { try { - txn.start(); - PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId); - if (reservationEntry != null) { - long id = reservationEntry.getId(); - PlannerHostReservationVO hostReservation = _plannerHostReserveDao.lockRow(id, true); - if (hostReservation == null) { + return Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId); + if (reservationEntry != null) { + long id = reservationEntry.getId(); + PlannerHostReservationVO hostReservation = _plannerHostReserveDao.lockRow(id, true); + if (hostReservation == null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Host reservation for host: " + hostId + " does not even exist. Release reservartion call is ignored."); + } + return false; + } + hostReservation.setResourceUsage(null); + _plannerHostReserveDao.persist(hostReservation); + return true; + } + if (s_logger.isDebugEnabled()) { s_logger.debug("Host reservation for host: " + hostId + " does not even exist. Release reservartion call is ignored."); } - txn.rollback(); + return false; } - hostReservation.setResourceUsage(null); - _plannerHostReserveDao.persist(hostReservation); - txn.commit(); - return true; - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Host reservation for host: " + hostId + " does not even exist. Release reservartion call is ignored."); - } - return false; + }); } catch (CloudRuntimeException e) { throw e; } catch (Throwable t) { s_logger.error("Unable to release host reservation for host: " + hostId, t); - txn.rollback(); return false; } } + + @Override + public boolean start() { + // TODO Auto-generated method stub + return super.start(); + } + + } diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index 1f8713aae76..7417754da0c 100755 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -90,6 +90,9 @@ import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; @@ -361,8 +364,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim @Override @DB - public void checkResourceLimit(Account account, ResourceType type, long... count) throws ResourceAllocationException { - long numResources = ((count.length == 0) ? 1 : count[0]); + public void checkResourceLimit(final Account account, final ResourceType type, long... count) throws ResourceAllocationException { + final long numResources = ((count.length == 0) ? 1 : count[0]); Project project = null; // Don't place any limits on system or root admin accounts @@ -374,53 +377,53 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim project = _projectDao.findByProjectAccountId(account.getId()); } - Transaction txn = Transaction.currentTxn(); - txn.start(); - try { - // Lock all rows first so nobody else can read it - Set rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(account.getId(), ResourceOwnerType.Account, type); - SearchCriteria sc = ResourceCountSearch.create(); - sc.setParameters("id", rowIdsToLock.toArray()); - _resourceCountDao.lockRows(sc, null, true); - - // Check account limits - long accountLimit = findCorrectResourceLimitForAccount(account, type); - long potentialCount = _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type) + numResources; - if (accountLimit != Resource.RESOURCE_UNLIMITED && potentialCount > accountLimit) { - String message = "Maximum number of resources of type '" + type + "' for account name=" + account.getAccountName() - + " in domain id=" + account.getDomainId() + " has been exceeded."; - if (project != null) { - message = "Maximum number of resources of type '" + type + "' for project name=" + project.getName() + final Project projectFinal = project; + Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) throws ResourceAllocationException { + // Lock all rows first so nobody else can read it + Set rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(account.getId(), ResourceOwnerType.Account, type); + SearchCriteria sc = ResourceCountSearch.create(); + sc.setParameters("id", rowIdsToLock.toArray()); + _resourceCountDao.lockRows(sc, null, true); + + // Check account limits + long accountLimit = findCorrectResourceLimitForAccount(account, type); + long potentialCount = _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type) + numResources; + if (accountLimit != Resource.RESOURCE_UNLIMITED && potentialCount > accountLimit) { + String message = "Maximum number of resources of type '" + type + "' for account name=" + account.getAccountName() + " in domain id=" + account.getDomainId() + " has been exceeded."; + if (projectFinal != null) { + message = "Maximum number of resources of type '" + type + "' for project name=" + projectFinal.getName() + + " in domain id=" + account.getDomainId() + " has been exceeded."; + } + throw new ResourceAllocationException(message, type); } - throw new ResourceAllocationException(message, type); - } - - // check all domains in the account's domain hierarchy - Long domainId = null; - if (project != null) { - domainId = project.getDomainId(); - } else { - domainId = account.getDomainId(); - } - - while (domainId != null) { - DomainVO domain = _domainDao.findById(domainId); - // no limit check if it is ROOT domain - if (domainId != Domain.ROOT_DOMAIN) { - ResourceLimitVO domainLimit = _resourceLimitDao.findByOwnerIdAndType(domainId, ResourceOwnerType.Domain, type); - if (domainLimit != null && domainLimit.getMax().longValue() != Resource.RESOURCE_UNLIMITED) { - long domainCount = _resourceCountDao.getResourceCount(domainId, ResourceOwnerType.Domain, type); - if ((domainCount + numResources) > domainLimit.getMax().longValue()) { - throw new ResourceAllocationException("Maximum number of resources of type '" + type + "' for domain id=" + domainId + " has been exceeded.", type); + + // check all domains in the account's domain hierarchy + Long domainId = null; + if (projectFinal != null) { + domainId = projectFinal.getDomainId(); + } else { + domainId = account.getDomainId(); + } + + while (domainId != null) { + DomainVO domain = _domainDao.findById(domainId); + // no limit check if it is ROOT domain + if (domainId != Domain.ROOT_DOMAIN) { + ResourceLimitVO domainLimit = _resourceLimitDao.findByOwnerIdAndType(domainId, ResourceOwnerType.Domain, type); + if (domainLimit != null && domainLimit.getMax().longValue() != Resource.RESOURCE_UNLIMITED) { + long domainCount = _resourceCountDao.getResourceCount(domainId, ResourceOwnerType.Domain, type); + if ((domainCount + numResources) > domainLimit.getMax().longValue()) { + throw new ResourceAllocationException("Maximum number of resources of type '" + type + "' for domain id=" + domainId + " has been exceeded.", type); + } } } + domainId = domain.getParent(); } - domainId = domain.getParent(); } - } finally { - txn.commit(); - } + }); } @Override @@ -716,143 +719,143 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim } @DB - protected boolean updateResourceCountForAccount(long accountId, ResourceType type, boolean increment, long delta) { - boolean result = true; + protected boolean updateResourceCountForAccount(final long accountId, final ResourceType type, final boolean increment, final long delta) { try { - Transaction txn = Transaction.currentTxn(); - txn.start(); - - Set rowsToLock = _resourceCountDao.listAllRowsToUpdate(accountId, ResourceOwnerType.Account, type); - - // Lock rows first - SearchCriteria sc = ResourceCountSearch.create(); - sc.setParameters("id", rowsToLock.toArray()); - List rowsToUpdate = _resourceCountDao.lockRows(sc, null, true); - - for (ResourceCountVO rowToUpdate : rowsToUpdate) { - if (!_resourceCountDao.updateById(rowToUpdate.getId(), increment, delta)) { - s_logger.trace("Unable to update resource count for the row " + rowToUpdate); - result = false; + return Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + boolean result = true; + Set rowsToLock = _resourceCountDao.listAllRowsToUpdate(accountId, ResourceOwnerType.Account, type); + + // Lock rows first + SearchCriteria sc = ResourceCountSearch.create(); + sc.setParameters("id", rowsToLock.toArray()); + List rowsToUpdate = _resourceCountDao.lockRows(sc, null, true); + + for (ResourceCountVO rowToUpdate : rowsToUpdate) { + if (!_resourceCountDao.updateById(rowToUpdate.getId(), increment, delta)) { + s_logger.trace("Unable to update resource count for the row " + rowToUpdate); + result = false; + } + } + + return result; } - } - - txn.commit(); + }); } catch (Exception ex) { s_logger.error("Failed to update resource count for account id=" + accountId); - result = false; + return false; } - return result; } @DB - protected long recalculateDomainResourceCount(long domainId, ResourceType type) { - long newCount = 0; + protected long recalculateDomainResourceCount(final long domainId, final ResourceType type) { + return Transaction.execute(new TransactionCallback() { + @Override + public Long doInTransaction(TransactionStatus status) { + long newCount = 0; - Transaction txn = Transaction.currentTxn(); - txn.start(); - - try { - // Lock all rows first so nobody else can read it - Set rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(domainId, ResourceOwnerType.Domain, type); - SearchCriteria sc = ResourceCountSearch.create(); - sc.setParameters("id", rowIdsToLock.toArray()); - _resourceCountDao.lockRows(sc, null, true); - - ResourceCountVO domainRC = _resourceCountDao.findByOwnerAndType(domainId, ResourceOwnerType.Domain, type); - long oldCount = domainRC.getCount(); - - List domainChildren = _domainDao.findImmediateChildrenForParent(domainId); - // for each child domain update the resource count - if (type.supportsOwner(ResourceOwnerType.Domain)) { - - // calculate project count here - if (type == ResourceType.project) { - newCount = newCount + _projectDao.countProjectsForDomain(domainId); + // Lock all rows first so nobody else can read it + Set rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(domainId, ResourceOwnerType.Domain, type); + SearchCriteria sc = ResourceCountSearch.create(); + sc.setParameters("id", rowIdsToLock.toArray()); + _resourceCountDao.lockRows(sc, null, true); + + ResourceCountVO domainRC = _resourceCountDao.findByOwnerAndType(domainId, ResourceOwnerType.Domain, type); + long oldCount = domainRC.getCount(); + + List domainChildren = _domainDao.findImmediateChildrenForParent(domainId); + // for each child domain update the resource count + if (type.supportsOwner(ResourceOwnerType.Domain)) { + + // calculate project count here + if (type == ResourceType.project) { + newCount = newCount + _projectDao.countProjectsForDomain(domainId); + } + + for (DomainVO domainChild : domainChildren) { + long domainCount = recalculateDomainResourceCount(domainChild.getId(), type); + newCount = newCount + domainCount; // add the child domain count to parent domain count + } } - - for (DomainVO domainChild : domainChildren) { - long domainCount = recalculateDomainResourceCount(domainChild.getId(), type); - newCount = newCount + domainCount; // add the child domain count to parent domain count + + if (type.supportsOwner(ResourceOwnerType.Account)) { + List accounts = _accountDao.findActiveAccountsForDomain(domainId); + for (AccountVO account : accounts) { + long accountCount = recalculateAccountResourceCount(account.getId(), type); + newCount = newCount + accountCount; // add account's resource count to parent domain count + } } - } - - if (type.supportsOwner(ResourceOwnerType.Account)) { - List accounts = _accountDao.findActiveAccountsForDomain(domainId); - for (AccountVO account : accounts) { - long accountCount = recalculateAccountResourceCount(account.getId(), type); - newCount = newCount + accountCount; // add account's resource count to parent domain count + _resourceCountDao.setResourceCount(domainId, ResourceOwnerType.Domain, type, newCount); + + if (oldCount != newCount) { + s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " + + newCount + ") for type " + type + " for domain ID " + domainId + " is fixed during resource count recalculation."); } + + return newCount; } - _resourceCountDao.setResourceCount(domainId, ResourceOwnerType.Domain, type, newCount); - - if (oldCount != newCount) { - s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " + - newCount + ") for type " + type + " for domain ID " + domainId + " is fixed during resource count recalculation."); - } - } catch (Exception e) { - throw new CloudRuntimeException("Failed to update resource count for domain with Id " + domainId); - } finally { - txn.commit(); - } - - return newCount; + }); } @DB - protected long recalculateAccountResourceCount(long accountId, ResourceType type) { - Long newCount = null; + protected long recalculateAccountResourceCount(final long accountId, final ResourceType type) { + Long newCount = Transaction.execute(new TransactionCallback() { + @Override + public Long doInTransaction(TransactionStatus status) { + Long newCount = null; - Transaction txn = Transaction.currentTxn(); - txn.start(); - - // this lock guards against the updates to user_vm, volume, snapshot, public _ip and template table - // as any resource creation precedes with the resourceLimitExceeded check which needs this lock too - SearchCriteria sc = ResourceCountSearch.create(); - sc.setParameters("accountId", accountId); - _resourceCountDao.lockRows(sc, null, true); - - ResourceCountVO accountRC = _resourceCountDao.findByOwnerAndType(accountId, ResourceOwnerType.Account, type); - long oldCount = 0; - if (accountRC != null) - oldCount = accountRC.getCount(); - - if (type == Resource.ResourceType.user_vm) { - newCount = _userVmDao.countAllocatedVMsForAccount(accountId); - } else if (type == Resource.ResourceType.volume) { - newCount = _volumeDao.countAllocatedVolumesForAccount(accountId); - long virtualRouterCount = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId).size(); - newCount = newCount - virtualRouterCount; // don't count the volumes of virtual router - } else if (type == Resource.ResourceType.snapshot) { - newCount = _snapshotDao.countSnapshotsForAccount(accountId); - } else if (type == Resource.ResourceType.public_ip) { - newCount = calculatePublicIpForAccount(accountId); - } else if (type == Resource.ResourceType.template) { - newCount = _vmTemplateDao.countTemplatesForAccount(accountId); - } else if (type == Resource.ResourceType.project) { - newCount = _projectAccountDao.countByAccountIdAndRole(accountId, Role.Admin); - } else if (type == Resource.ResourceType.network) { - newCount = _networkDao.countNetworksUserCanCreate(accountId); - } else if (type == Resource.ResourceType.vpc) { - newCount = _vpcDao.countByAccountId(accountId); - } else if (type == Resource.ResourceType.cpu) { - newCount = countCpusForAccount(accountId); - } else if (type == Resource.ResourceType.memory) { - newCount = calculateMemoryForAccount(accountId); - } else if (type == Resource.ResourceType.primary_storage) { - List virtualRouters = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId); - newCount = _volumeDao.primaryStorageUsedForAccount(accountId, virtualRouters); - } else if (type == Resource.ResourceType.secondary_storage) { - newCount = calculateSecondaryStorageForAccount(accountId); - } else { - throw new InvalidParameterValueException("Unsupported resource type " + type); - } - _resourceCountDao.setResourceCount(accountId, ResourceOwnerType.Account, type, (newCount == null) ? 0 : newCount.longValue()); - - if (oldCount != newCount) { - s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " + - newCount + ") for type " + type + " for account ID " + accountId + " is fixed during resource count recalculation."); - } - txn.commit(); + // this lock guards against the updates to user_vm, volume, snapshot, public _ip and template table + // as any resource creation precedes with the resourceLimitExceeded check which needs this lock too + SearchCriteria sc = ResourceCountSearch.create(); + sc.setParameters("accountId", accountId); + _resourceCountDao.lockRows(sc, null, true); + + ResourceCountVO accountRC = _resourceCountDao.findByOwnerAndType(accountId, ResourceOwnerType.Account, type); + long oldCount = 0; + if (accountRC != null) + oldCount = accountRC.getCount(); + + if (type == Resource.ResourceType.user_vm) { + newCount = _userVmDao.countAllocatedVMsForAccount(accountId); + } else if (type == Resource.ResourceType.volume) { + newCount = _volumeDao.countAllocatedVolumesForAccount(accountId); + long virtualRouterCount = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId).size(); + newCount = newCount - virtualRouterCount; // don't count the volumes of virtual router + } else if (type == Resource.ResourceType.snapshot) { + newCount = _snapshotDao.countSnapshotsForAccount(accountId); + } else if (type == Resource.ResourceType.public_ip) { + newCount = calculatePublicIpForAccount(accountId); + } else if (type == Resource.ResourceType.template) { + newCount = _vmTemplateDao.countTemplatesForAccount(accountId); + } else if (type == Resource.ResourceType.project) { + newCount = _projectAccountDao.countByAccountIdAndRole(accountId, Role.Admin); + } else if (type == Resource.ResourceType.network) { + newCount = _networkDao.countNetworksUserCanCreate(accountId); + } else if (type == Resource.ResourceType.vpc) { + newCount = _vpcDao.countByAccountId(accountId); + } else if (type == Resource.ResourceType.cpu) { + newCount = countCpusForAccount(accountId); + } else if (type == Resource.ResourceType.memory) { + newCount = calculateMemoryForAccount(accountId); + } else if (type == Resource.ResourceType.primary_storage) { + List virtualRouters = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId); + newCount = _volumeDao.primaryStorageUsedForAccount(accountId, virtualRouters); + } else if (type == Resource.ResourceType.secondary_storage) { + newCount = calculateSecondaryStorageForAccount(accountId); + } else { + throw new InvalidParameterValueException("Unsupported resource type " + type); + } + _resourceCountDao.setResourceCount(accountId, ResourceOwnerType.Account, type, (newCount == null) ? 0 : newCount.longValue()); + + if (oldCount != newCount) { + s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " + + newCount + ") for type " + type + " for account ID " + accountId + " is fixed during resource count recalculation."); + } + + return newCount; + } + }); return (newCount == null) ? 0 : newCount.longValue(); } diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index 4c5c8a1c1cf..0676db8ca18 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -42,14 +42,13 @@ import javax.crypto.SecretKey; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.io.FileUtils; -import org.apache.log4j.Logger; - import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigDepotAdmin; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.config.impl.ConfigurationVO; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.FileUtils; +import org.apache.log4j.Logger; import com.cloud.cluster.ClusterManager; import com.cloud.configuration.Config; @@ -107,6 +106,10 @@ import com.cloud.utils.component.ManagerBase; import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn; +import com.cloud.utils.db.TransactionLegacy; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.utils.script.Script; @@ -249,11 +252,9 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio // Create userIpAddress ranges // Update existing vlans with networkId - Transaction txn = Transaction.currentTxn(); - List vlans = _vlanDao.listAll(); if (vlans != null && !vlans.isEmpty()) { - for (VlanVO vlan : vlans) { + for (final VlanVO vlan : vlans) { if (vlan.getNetworkId().longValue() == 0) { updateVlanWithNetworkId(vlan); } @@ -261,15 +262,19 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio // Create vlan user_ip_address range String ipPange = vlan.getIpRange(); String[] range = ipPange.split("-"); - String startIp = range[0]; - String endIp = range[1]; + final String startIp = range[0]; + final String endIp = range[1]; + + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + IPRangeConfig config = new IPRangeConfig(); + long startIPLong = NetUtils.ip2Long(startIp); + long endIPLong = NetUtils.ip2Long(endIp); + config.savePublicIPRange(TransactionLegacy.currentTxn(), startIPLong, endIPLong, vlan.getDataCenterId(), vlan.getId(), vlan.getNetworkId(), vlan.getPhysicalNetworkId()); + } + }); - txn.start(); - IPRangeConfig config = new IPRangeConfig(); - long startIPLong = NetUtils.ip2Long(startIp); - long endIPLong = NetUtils.ip2Long(endIp); - config.savePublicIPRange(txn, startIPLong, endIPLong, vlan.getDataCenterId(), vlan.getId(), vlan.getNetworkId(), vlan.getPhysicalNetworkId()); - txn.commit(); } } } @@ -292,6 +297,8 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio updateCloudIdentifier(); _configDepotAdmin.populateConfigurations(); + // setup XenServer default PV driver version + initiateXenServerPVDriverVersion(); // We should not update seed data UUID column here since this will be invoked in upgrade case as well. //updateUuids(); @@ -302,6 +309,84 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio _configDao.invalidateCache(); } + + private void templateDetailsInitIfNotExist(long id, String name, String value) { + TransactionLegacy txn = TransactionLegacy.currentTxn(); + PreparedStatement stmt = null; + PreparedStatement stmtInsert = null; + boolean insert = false; + try { + txn.start(); + stmt = txn.prepareAutoCloseStatement("SELECT id FROM vm_template_details WHERE template_id=? and name=?"); + stmt.setLong(1, id); + stmt.setString(2, name); + ResultSet rs = stmt.executeQuery(); + if(rs == null || !rs.next()) { + insert = true; + } + stmt.close(); + + if ( insert ) { + stmtInsert = txn.prepareAutoCloseStatement( + "INSERT INTO vm_template_details(template_id, name, value) VALUES(?, ?, ?)"); + stmtInsert.setLong(1, id); + stmtInsert.setString(2, name); + stmtInsert.setString(3, value); + if(stmtInsert.executeUpdate() < 1) { + throw new CloudRuntimeException("Unable to init template " + id + " datails: " + name); + } + } + txn.commit(); + } catch (Exception e) { + s_logger.warn("Unable to init template " + id + " datails: " + name, e); + throw new CloudRuntimeException("Unable to init template " + id + " datails: " + name); + } + } + + private void initiateXenServerPVDriverVersion() { + String pvdriverversion = Config.XenPVdriverVersion.getDefaultValue(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); + PreparedStatement pstmt = null; + ResultSet rs1 = null; + ResultSet rs2 = null; + try { + String oldValue = _configDao.getValue(Config.XenPVdriverVersion.key()); + if ( oldValue == null ) { + String sql = "select resource from host where hypervisor_type='XenServer' and removed is null and status not in ('Error', 'Removed') group by resource" ; + pstmt = txn.prepareAutoCloseStatement(sql); + rs1 = pstmt.executeQuery(); + while (rs1.next()) { + String resouce = rs1.getString(1); //resource column + if ( resouce == null ) continue; + if ( resouce.equalsIgnoreCase("com.cloud.hypervisor.xen.resource.XenServer56Resource") + || resouce.equalsIgnoreCase("com.cloud.hypervisor.xen.resource.XenServer56FP1Resource") + || resouce.equalsIgnoreCase("com.cloud.hypervisor.xen.resource.XenServer56SP2Resource") + || resouce.equalsIgnoreCase("com.cloud.hypervisor.xen.resource.XenServer600Resource") + || resouce.equalsIgnoreCase("com.cloud.hypervisor.xen.resource.XenServer602Resource") ) { + pvdriverversion = "xenserver56"; + break; + } + } + _configDao.getValueAndInitIfNotExist(Config.XenPVdriverVersion.key(), + Config.XenPVdriverVersion.getCategory(), pvdriverversion, Config.XenPVdriverVersion.getDescription()); + sql = "select id from vm_template where hypervisor_type='XenServer' and format!='ISO' and removed is null"; + pstmt = txn.prepareAutoCloseStatement(sql); + rs2 = pstmt.executeQuery(); + List tmpl_ids = new ArrayList(); + while (rs2.next()) { + tmpl_ids.add(rs2.getLong(1)); + } + for( Long tmpl_id : tmpl_ids) { + templateDetailsInitIfNotExist(tmpl_id, "hypervisortoolsversion", pvdriverversion); + } + } + } catch (Exception e) { + s_logger.debug("initiateXenServerPVDriverVersion failed due to " + e.toString()); + // ignore + } + } + + /* private void updateUuids() { _identityDao.initializeDefaultUuid("disk_offering"); @@ -352,7 +437,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio protected void saveUser() { // insert system account String insertSql = "INSERT INTO `cloud`.`account` (id, uuid, account_name, type, domain_id, account.default) VALUES (1, UUID(), 'system', '1', '1', 1)"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); stmt.executeUpdate(); @@ -361,7 +446,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio // insert system user insertSql = "INSERT INTO `cloud`.`user` (id, uuid, username, password, account_id, firstname, lastname, created, user.default)" + " VALUES (1, UUID(), 'system', RAND(), 1, 'system', 'cloud', now(), 1)"; - txn = Transaction.currentTxn(); + txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); stmt.executeUpdate(); @@ -377,7 +462,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio // create an account for the admin user first insertSql = "INSERT INTO `cloud`.`account` (id, uuid, account_name, type, domain_id, account.default) VALUES (" + id + ", UUID(), '" + username + "', '1', '1', 1)"; - txn = Transaction.currentTxn(); + txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); stmt.executeUpdate(); @@ -388,7 +473,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio insertSql = "INSERT INTO `cloud`.`user` (id, uuid, username, password, account_id, firstname, lastname, created, state, user.default) " + "VALUES (" + id + ", UUID(), '" + username + "', RAND(), 2, '" + firstname + "','" + lastname + "',now(), 'disabled', 1)"; - txn = Transaction.currentTxn(); + txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); stmt.executeUpdate(); @@ -419,7 +504,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio "VALUES ('default', 'Default Security Group', 2, 1, 'admin')"; } - txn = Transaction.currentTxn(); + txn = TransactionLegacy.currentTxn(); try { stmt = txn.prepareAutoCloseStatement(insertSql); stmt.executeUpdate(); @@ -559,7 +644,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio String already = _configDao.getValue("system.vm.password"); if (already == null) { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { String rpassword = PasswordGenerator.generatePresharedKey(8); String wSql = "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " @@ -643,7 +728,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio String insertSql2 = "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " + "VALUES ('Hidden','DEFAULT', 'management-server','ssh.publickey', '" + DBEncryptionUtil.encrypt(publicKey) + "','Public key for the entire CloudStack')"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt1 = txn.prepareAutoCloseStatement(insertSql1); stmt1.executeUpdate(); @@ -778,7 +863,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio String insertSql1 = "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " + "VALUES ('Hidden','DEFAULT', 'management-server','secstorage.copy.password', '" + DBEncryptionUtil.encrypt(password) + "','Password used to authenticate zone-to-zone template copy requests')"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt1 = txn.prepareAutoCloseStatement(insertSql1); stmt1.executeUpdate(); @@ -806,7 +891,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio } @DB - protected HostPodVO createPod(long userId, String podName, long zoneId, String gateway, String cidr, String startIp, String endIp) throws InternalErrorException { + protected HostPodVO createPod(long userId, String podName, final long zoneId, String gateway, String cidr, final String startIp, String endIp) throws InternalErrorException { String[] cidrPair = cidr.split("\\/"); String cidrAddress = cidrPair[0]; int cidrSize = Integer.parseInt(cidrPair[1]); @@ -828,37 +913,35 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio ipRange = ""; } - HostPodVO pod = new HostPodVO(podName, zoneId, gateway, cidrAddress, cidrSize, ipRange); - Transaction txn = Transaction.currentTxn(); + final HostPodVO pod = new HostPodVO(podName, zoneId, gateway, cidrAddress, cidrSize, ipRange); try { - txn.start(); - - if (_podDao.persist(pod) == null) { - txn.rollback(); - throw new InternalErrorException("Failed to create new pod. Please contact Cloud Support."); - } - - if (startIp != null) { - _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), startIp, endIp); - } - - String ipNums = _configDao.getValue("linkLocalIp.nums"); - int nums = Integer.parseInt(ipNums); - if (nums > 16 || nums <= 0) { - throw new InvalidParameterValueException("The linkLocalIp.nums: " + nums + "is wrong, should be 1~16"); - } - /* local link ip address starts from 169.254.0.2 - 169.254.(nums) */ - String[] linkLocalIpRanges = NetUtils.getLinkLocalIPRange(nums); - if (linkLocalIpRanges == null) { - throw new InvalidParameterValueException("The linkLocalIp.nums: " + nums + "may be wrong, should be 1~16"); - } else { - _zoneDao.addLinkLocalIpAddress(zoneId, pod.getId(), linkLocalIpRanges[0], linkLocalIpRanges[1]); - } - - txn.commit(); - + final String endIpFinal = endIp; + Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) throws InternalErrorException { + if (_podDao.persist(pod) == null) { + throw new InternalErrorException("Failed to create new pod. Please contact Cloud Support."); + } + + if (startIp != null) { + _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), startIp, endIpFinal); + } + + String ipNums = _configDao.getValue("linkLocalIp.nums"); + int nums = Integer.parseInt(ipNums); + if (nums > 16 || nums <= 0) { + throw new InvalidParameterValueException("The linkLocalIp.nums: " + nums + "is wrong, should be 1~16"); + } + /* local link ip address starts from 169.254.0.2 - 169.254.(nums) */ + String[] linkLocalIpRanges = NetUtils.getLinkLocalIPRange(nums); + if (linkLocalIpRanges == null) { + throw new InvalidParameterValueException("The linkLocalIp.nums: " + nums + "may be wrong, should be 1~16"); + } else { + _zoneDao.addLinkLocalIpAddress(zoneId, pod.getId(), linkLocalIpRanges[0], linkLocalIpRanges[1]); + } + } + }); } catch (Exception e) { - txn.rollback(); s_logger.error("Unable to create new pod due to " + e.getMessage(), e); throw new InternalErrorException("Failed to create new pod. Please contact Cloud Support."); } @@ -919,20 +1002,20 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio privateGatewayNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(privateGatewayNetworkOffering); //populate providers - Map defaultSharedNetworkOfferingProviders = new HashMap(); + final Map defaultSharedNetworkOfferingProviders = new HashMap(); defaultSharedNetworkOfferingProviders.put(Service.Dhcp, Provider.VirtualRouter); defaultSharedNetworkOfferingProviders.put(Service.Dns, Provider.VirtualRouter); defaultSharedNetworkOfferingProviders.put(Service.UserData, Provider.VirtualRouter); - Map defaultIsolatedNetworkOfferingProviders = defaultSharedNetworkOfferingProviders; + final Map defaultIsolatedNetworkOfferingProviders = defaultSharedNetworkOfferingProviders; - Map defaultSharedSGNetworkOfferingProviders = new HashMap(); + final Map defaultSharedSGNetworkOfferingProviders = new HashMap(); defaultSharedSGNetworkOfferingProviders.put(Service.Dhcp, Provider.VirtualRouter); defaultSharedSGNetworkOfferingProviders.put(Service.Dns, Provider.VirtualRouter); defaultSharedSGNetworkOfferingProviders.put(Service.UserData, Provider.VirtualRouter); defaultSharedSGNetworkOfferingProviders.put(Service.SecurityGroup, Provider.SecurityGroupProvider); - Map defaultIsolatedSourceNatEnabledNetworkOfferingProviders = new HashMap(); + final Map defaultIsolatedSourceNatEnabledNetworkOfferingProviders = new HashMap(); defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dhcp, Provider.VirtualRouter); defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dns, Provider.VirtualRouter); defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.UserData, Provider.VirtualRouter); @@ -944,7 +1027,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.PortForwarding, Provider.VirtualRouter); defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Vpn, Provider.VirtualRouter); - Map netscalerServiceProviders = new HashMap(); + final Map netscalerServiceProviders = new HashMap(); netscalerServiceProviders.put(Service.Dhcp, Provider.VirtualRouter); netscalerServiceProviders.put(Service.Dns, Provider.VirtualRouter); netscalerServiceProviders.put(Service.UserData, Provider.VirtualRouter); @@ -954,182 +1037,182 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio // The only one diff between 1 and 2 network offerings is that the first one has SG enabled. In Basic zone only // first network offering has to be enabled, in Advance zone - the second one - Transaction txn = Transaction.currentTxn(); - txn.start(); - - // Offering #1 - NetworkOfferingVO defaultSharedSGNetworkOffering = new NetworkOfferingVO( - NetworkOffering.DefaultSharedNetworkOfferingWithSGService, - "Offering for Shared Security group enabled networks", - TrafficType.Guest, - false, true, null, null, true, Availability.Optional, - null, Network.GuestType.Shared, true, true, false, false, false); - - defaultSharedSGNetworkOffering.setState(NetworkOffering.State.Enabled); - defaultSharedSGNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultSharedSGNetworkOffering); - - for (Service service : defaultSharedSGNetworkOfferingProviders.keySet()) { - NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(defaultSharedSGNetworkOffering.getId(), service, defaultSharedSGNetworkOfferingProviders.get(service)); - _ntwkOfferingServiceMapDao.persist(offService); - s_logger.trace("Added service for the network offering: " + offService); - } - - // Offering #2 - NetworkOfferingVO defaultSharedNetworkOffering = new NetworkOfferingVO( - NetworkOffering.DefaultSharedNetworkOffering, - "Offering for Shared networks", - TrafficType.Guest, - false, true, null, null, true, Availability.Optional, - null, Network.GuestType.Shared, true, true, false, false, false); - - defaultSharedNetworkOffering.setState(NetworkOffering.State.Enabled); - defaultSharedNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultSharedNetworkOffering); - - for (Service service : defaultSharedNetworkOfferingProviders.keySet()) { - NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(defaultSharedNetworkOffering.getId(), service, defaultSharedNetworkOfferingProviders.get(service)); - _ntwkOfferingServiceMapDao.persist(offService); - s_logger.trace("Added service for the network offering: " + offService); - } - - // Offering #3 - NetworkOfferingVO defaultIsolatedSourceNatEnabledNetworkOffering = new NetworkOfferingVO( - NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService, - "Offering for Isolated networks with Source Nat service enabled", - TrafficType.Guest, - false, false, null, null, true, Availability.Required, - null, Network.GuestType.Isolated, true, false, false, false, true); - - defaultIsolatedSourceNatEnabledNetworkOffering.setState(NetworkOffering.State.Enabled); - defaultIsolatedSourceNatEnabledNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultIsolatedSourceNatEnabledNetworkOffering); - - for (Service service : defaultIsolatedSourceNatEnabledNetworkOfferingProviders.keySet()) { - NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO - (defaultIsolatedSourceNatEnabledNetworkOffering.getId(), service, defaultIsolatedSourceNatEnabledNetworkOfferingProviders.get(service)); - _ntwkOfferingServiceMapDao.persist(offService); - s_logger.trace("Added service for the network offering: " + offService); - } - - // Offering #4 - NetworkOfferingVO defaultIsolatedEnabledNetworkOffering = new NetworkOfferingVO( - NetworkOffering.DefaultIsolatedNetworkOffering, - "Offering for Isolated networks with no Source Nat service", - TrafficType.Guest, - false, true, null, null, true, Availability.Optional, - null, Network.GuestType.Isolated, true, true, false, false, false); - - defaultIsolatedEnabledNetworkOffering.setState(NetworkOffering.State.Enabled); - defaultIsolatedEnabledNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultIsolatedEnabledNetworkOffering); - - for (Service service : defaultIsolatedNetworkOfferingProviders.keySet()) { - NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(defaultIsolatedEnabledNetworkOffering.getId(), service, defaultIsolatedNetworkOfferingProviders.get(service)); - _ntwkOfferingServiceMapDao.persist(offService); - s_logger.trace("Added service for the network offering: " + offService); - } - - // Offering #5 - NetworkOfferingVO defaultNetscalerNetworkOffering = new NetworkOfferingVO( - NetworkOffering.DefaultSharedEIPandELBNetworkOffering, - "Offering for Shared networks with Elastic IP and Elastic LB capabilities", - TrafficType.Guest, - false, true, null, null, true, Availability.Optional, - null, Network.GuestType.Shared, true, false, false, false, true, true, true, false, false, true, true, false, false); - - defaultNetscalerNetworkOffering.setState(NetworkOffering.State.Enabled); - defaultNetscalerNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetscalerNetworkOffering); - - for (Service service : netscalerServiceProviders.keySet()) { - NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(defaultNetscalerNetworkOffering.getId(), service, netscalerServiceProviders.get(service)); - _ntwkOfferingServiceMapDao.persist(offService); - s_logger.trace("Added service for the network offering: " + offService); - } - - // Offering #6 - NetworkOfferingVO defaultNetworkOfferingForVpcNetworks = new NetworkOfferingVO( - NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks, - "Offering for Isolated Vpc networks with Source Nat service enabled", - TrafficType.Guest, - false, false, null, null, true, Availability.Optional, - null, Network.GuestType.Isolated, false, false, false, false, true); - - defaultNetworkOfferingForVpcNetworks.setState(NetworkOffering.State.Enabled); - defaultNetworkOfferingForVpcNetworks = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetworkOfferingForVpcNetworks); - - Map defaultVpcNetworkOfferingProviders = new HashMap(); - defaultVpcNetworkOfferingProviders.put(Service.Dhcp, Provider.VPCVirtualRouter); - defaultVpcNetworkOfferingProviders.put(Service.Dns, Provider.VPCVirtualRouter); - defaultVpcNetworkOfferingProviders.put(Service.UserData, Provider.VPCVirtualRouter); - defaultVpcNetworkOfferingProviders.put(Service.NetworkACL, Provider.VPCVirtualRouter); - defaultVpcNetworkOfferingProviders.put(Service.Gateway, Provider.VPCVirtualRouter); - defaultVpcNetworkOfferingProviders.put(Service.Lb, Provider.VPCVirtualRouter); - defaultVpcNetworkOfferingProviders.put(Service.SourceNat, Provider.VPCVirtualRouter); - defaultVpcNetworkOfferingProviders.put(Service.StaticNat, Provider.VPCVirtualRouter); - defaultVpcNetworkOfferingProviders.put(Service.PortForwarding, Provider.VPCVirtualRouter); - defaultVpcNetworkOfferingProviders.put(Service.Vpn, Provider.VPCVirtualRouter); - - for (Service service : defaultVpcNetworkOfferingProviders.keySet()) { - NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO - (defaultNetworkOfferingForVpcNetworks.getId(), service, defaultVpcNetworkOfferingProviders.get(service)); - _ntwkOfferingServiceMapDao.persist(offService); - s_logger.trace("Added service for the network offering: " + offService); - } - - // Offering #7 - NetworkOfferingVO defaultNetworkOfferingForVpcNetworksNoLB = new NetworkOfferingVO( - NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB, - "Offering for Isolated Vpc networks with Source Nat service enabled and LB service Disabled", - TrafficType.Guest, - false, false, null, null, true, Availability.Optional, - null, Network.GuestType.Isolated, false, false, false, false, false); - - defaultNetworkOfferingForVpcNetworksNoLB.setState(NetworkOffering.State.Enabled); - defaultNetworkOfferingForVpcNetworksNoLB = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetworkOfferingForVpcNetworksNoLB); - - Map defaultVpcNetworkOfferingProvidersNoLB = new HashMap(); - defaultVpcNetworkOfferingProvidersNoLB.put(Service.Dhcp, Provider.VPCVirtualRouter); - defaultVpcNetworkOfferingProvidersNoLB.put(Service.Dns, Provider.VPCVirtualRouter); - defaultVpcNetworkOfferingProvidersNoLB.put(Service.UserData, Provider.VPCVirtualRouter); - defaultVpcNetworkOfferingProvidersNoLB.put(Service.NetworkACL, Provider.VPCVirtualRouter); - defaultVpcNetworkOfferingProvidersNoLB.put(Service.Gateway, Provider.VPCVirtualRouter); - defaultVpcNetworkOfferingProvidersNoLB.put(Service.SourceNat, Provider.VPCVirtualRouter); - defaultVpcNetworkOfferingProvidersNoLB.put(Service.StaticNat, Provider.VPCVirtualRouter); - defaultVpcNetworkOfferingProvidersNoLB.put(Service.PortForwarding, Provider.VPCVirtualRouter); - defaultVpcNetworkOfferingProvidersNoLB.put(Service.Vpn, Provider.VPCVirtualRouter); - - for (Service service : defaultVpcNetworkOfferingProvidersNoLB.keySet()) { - NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO - (defaultNetworkOfferingForVpcNetworksNoLB.getId(), service, defaultVpcNetworkOfferingProvidersNoLB.get(service)); - _ntwkOfferingServiceMapDao.persist(offService); - s_logger.trace("Added service for the network offering: " + offService); - } + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // Offering #1 + NetworkOfferingVO defaultSharedSGNetworkOffering = new NetworkOfferingVO( + NetworkOffering.DefaultSharedNetworkOfferingWithSGService, + "Offering for Shared Security group enabled networks", + TrafficType.Guest, + false, true, null, null, true, Availability.Optional, + null, Network.GuestType.Shared, true, true, false, false, false); - //offering #8 - network offering with internal lb service - NetworkOfferingVO internalLbOff = new NetworkOfferingVO( - NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB, - "Offering for Isolated Vpc networks with Internal LB support", - TrafficType.Guest, - false, false, null, null, true, Availability.Optional, - null, Network.GuestType.Isolated, false, false, false, true, false); - - internalLbOff.setState(NetworkOffering.State.Enabled); - internalLbOff = _networkOfferingDao.persistDefaultNetworkOffering(internalLbOff); - - Map internalLbOffProviders = new HashMap(); - internalLbOffProviders.put(Service.Dhcp, Provider.VPCVirtualRouter); - internalLbOffProviders.put(Service.Dns, Provider.VPCVirtualRouter); - internalLbOffProviders.put(Service.UserData, Provider.VPCVirtualRouter); - internalLbOffProviders.put(Service.NetworkACL, Provider.VPCVirtualRouter); - internalLbOffProviders.put(Service.Gateway, Provider.VPCVirtualRouter); - internalLbOffProviders.put(Service.Lb, Provider.InternalLbVm); - internalLbOffProviders.put(Service.SourceNat, Provider.VPCVirtualRouter); - - for (Service service : internalLbOffProviders.keySet()) { - NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO - (internalLbOff.getId(), service, internalLbOffProviders.get(service)); - _ntwkOfferingServiceMapDao.persist(offService); - s_logger.trace("Added service for the network offering: " + offService); - } - - txn.commit(); + defaultSharedSGNetworkOffering.setState(NetworkOffering.State.Enabled); + defaultSharedSGNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultSharedSGNetworkOffering); + + for (Service service : defaultSharedSGNetworkOfferingProviders.keySet()) { + NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(defaultSharedSGNetworkOffering.getId(), service, defaultSharedSGNetworkOfferingProviders.get(service)); + _ntwkOfferingServiceMapDao.persist(offService); + s_logger.trace("Added service for the network offering: " + offService); + } + + // Offering #2 + NetworkOfferingVO defaultSharedNetworkOffering = new NetworkOfferingVO( + NetworkOffering.DefaultSharedNetworkOffering, + "Offering for Shared networks", + TrafficType.Guest, + false, true, null, null, true, Availability.Optional, + null, Network.GuestType.Shared, true, true, false, false, false); + + defaultSharedNetworkOffering.setState(NetworkOffering.State.Enabled); + defaultSharedNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultSharedNetworkOffering); + + for (Service service : defaultSharedNetworkOfferingProviders.keySet()) { + NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(defaultSharedNetworkOffering.getId(), service, defaultSharedNetworkOfferingProviders.get(service)); + _ntwkOfferingServiceMapDao.persist(offService); + s_logger.trace("Added service for the network offering: " + offService); + } + + // Offering #3 + NetworkOfferingVO defaultIsolatedSourceNatEnabledNetworkOffering = new NetworkOfferingVO( + NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService, + "Offering for Isolated networks with Source Nat service enabled", + TrafficType.Guest, + false, false, null, null, true, Availability.Required, + null, Network.GuestType.Isolated, true, false, false, false, true); + + defaultIsolatedSourceNatEnabledNetworkOffering.setState(NetworkOffering.State.Enabled); + defaultIsolatedSourceNatEnabledNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultIsolatedSourceNatEnabledNetworkOffering); + + for (Service service : defaultIsolatedSourceNatEnabledNetworkOfferingProviders.keySet()) { + NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO + (defaultIsolatedSourceNatEnabledNetworkOffering.getId(), service, defaultIsolatedSourceNatEnabledNetworkOfferingProviders.get(service)); + _ntwkOfferingServiceMapDao.persist(offService); + s_logger.trace("Added service for the network offering: " + offService); + } + + // Offering #4 + NetworkOfferingVO defaultIsolatedEnabledNetworkOffering = new NetworkOfferingVO( + NetworkOffering.DefaultIsolatedNetworkOffering, + "Offering for Isolated networks with no Source Nat service", + TrafficType.Guest, + false, true, null, null, true, Availability.Optional, + null, Network.GuestType.Isolated, true, true, false, false, false); + + defaultIsolatedEnabledNetworkOffering.setState(NetworkOffering.State.Enabled); + defaultIsolatedEnabledNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultIsolatedEnabledNetworkOffering); + + for (Service service : defaultIsolatedNetworkOfferingProviders.keySet()) { + NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(defaultIsolatedEnabledNetworkOffering.getId(), service, defaultIsolatedNetworkOfferingProviders.get(service)); + _ntwkOfferingServiceMapDao.persist(offService); + s_logger.trace("Added service for the network offering: " + offService); + } + + // Offering #5 + NetworkOfferingVO defaultNetscalerNetworkOffering = new NetworkOfferingVO( + NetworkOffering.DefaultSharedEIPandELBNetworkOffering, + "Offering for Shared networks with Elastic IP and Elastic LB capabilities", + TrafficType.Guest, + false, true, null, null, true, Availability.Optional, + null, Network.GuestType.Shared, true, false, false, false, true, true, true, false, false, true, true, false, false); + + defaultNetscalerNetworkOffering.setState(NetworkOffering.State.Enabled); + defaultNetscalerNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetscalerNetworkOffering); + + for (Service service : netscalerServiceProviders.keySet()) { + NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(defaultNetscalerNetworkOffering.getId(), service, netscalerServiceProviders.get(service)); + _ntwkOfferingServiceMapDao.persist(offService); + s_logger.trace("Added service for the network offering: " + offService); + } + + // Offering #6 + NetworkOfferingVO defaultNetworkOfferingForVpcNetworks = new NetworkOfferingVO( + NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks, + "Offering for Isolated Vpc networks with Source Nat service enabled", + TrafficType.Guest, + false, false, null, null, true, Availability.Optional, + null, Network.GuestType.Isolated, false, false, false, false, true); + + defaultNetworkOfferingForVpcNetworks.setState(NetworkOffering.State.Enabled); + defaultNetworkOfferingForVpcNetworks = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetworkOfferingForVpcNetworks); + + Map defaultVpcNetworkOfferingProviders = new HashMap(); + defaultVpcNetworkOfferingProviders.put(Service.Dhcp, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.Dns, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.UserData, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.NetworkACL, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.Gateway, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.Lb, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.SourceNat, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.StaticNat, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.PortForwarding, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.Vpn, Provider.VPCVirtualRouter); + + for (Service service : defaultVpcNetworkOfferingProviders.keySet()) { + NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO + (defaultNetworkOfferingForVpcNetworks.getId(), service, defaultVpcNetworkOfferingProviders.get(service)); + _ntwkOfferingServiceMapDao.persist(offService); + s_logger.trace("Added service for the network offering: " + offService); + } + + // Offering #7 + NetworkOfferingVO defaultNetworkOfferingForVpcNetworksNoLB = new NetworkOfferingVO( + NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB, + "Offering for Isolated Vpc networks with Source Nat service enabled and LB service Disabled", + TrafficType.Guest, + false, false, null, null, true, Availability.Optional, + null, Network.GuestType.Isolated, false, false, false, false, false); + + defaultNetworkOfferingForVpcNetworksNoLB.setState(NetworkOffering.State.Enabled); + defaultNetworkOfferingForVpcNetworksNoLB = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetworkOfferingForVpcNetworksNoLB); + + Map defaultVpcNetworkOfferingProvidersNoLB = new HashMap(); + defaultVpcNetworkOfferingProvidersNoLB.put(Service.Dhcp, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProvidersNoLB.put(Service.Dns, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProvidersNoLB.put(Service.UserData, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProvidersNoLB.put(Service.NetworkACL, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProvidersNoLB.put(Service.Gateway, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProvidersNoLB.put(Service.SourceNat, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProvidersNoLB.put(Service.StaticNat, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProvidersNoLB.put(Service.PortForwarding, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProvidersNoLB.put(Service.Vpn, Provider.VPCVirtualRouter); + + for (Service service : defaultVpcNetworkOfferingProvidersNoLB.keySet()) { + NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO + (defaultNetworkOfferingForVpcNetworksNoLB.getId(), service, defaultVpcNetworkOfferingProvidersNoLB.get(service)); + _ntwkOfferingServiceMapDao.persist(offService); + s_logger.trace("Added service for the network offering: " + offService); + } + + //offering #8 - network offering with internal lb service + NetworkOfferingVO internalLbOff = new NetworkOfferingVO( + NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB, + "Offering for Isolated Vpc networks with Internal LB support", + TrafficType.Guest, + false, false, null, null, true, Availability.Optional, + null, Network.GuestType.Isolated, false, false, false, true, false); + + internalLbOff.setState(NetworkOffering.State.Enabled); + internalLbOff = _networkOfferingDao.persistDefaultNetworkOffering(internalLbOff); + + Map internalLbOffProviders = new HashMap(); + internalLbOffProviders.put(Service.Dhcp, Provider.VPCVirtualRouter); + internalLbOffProviders.put(Service.Dns, Provider.VPCVirtualRouter); + internalLbOffProviders.put(Service.UserData, Provider.VPCVirtualRouter); + internalLbOffProviders.put(Service.NetworkACL, Provider.VPCVirtualRouter); + internalLbOffProviders.put(Service.Gateway, Provider.VPCVirtualRouter); + internalLbOffProviders.put(Service.Lb, Provider.InternalLbVm); + internalLbOffProviders.put(Service.SourceNat, Provider.VPCVirtualRouter); + + for (Service service : internalLbOffProviders.keySet()) { + NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO + (internalLbOff.getId(), service, internalLbOffProviders.get(service)); + _ntwkOfferingServiceMapDao.persist(offService); + s_logger.trace("Added service for the network offering: " + offService); + } + } + }); } private void createDefaultNetworks() { @@ -1243,8 +1326,8 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio List domainResourceCount = _resourceCountDao.listResourceCountByOwnerType(ResourceOwnerType.Domain); List accountResourceCount = _resourceCountDao.listResourceCountByOwnerType(ResourceOwnerType.Account); - List accountSupportedResourceTypes = new ArrayList(); - List domainSupportedResourceTypes = new ArrayList(); + final List accountSupportedResourceTypes = new ArrayList(); + final List domainSupportedResourceTypes = new ArrayList(); for (ResourceType resourceType : resourceTypes) { if (resourceType.supportsOwner(ResourceOwnerType.Account)) { @@ -1255,59 +1338,63 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio } } - int accountExpectedCount = accountSupportedResourceTypes.size(); - int domainExpectedCount = domainSupportedResourceTypes.size(); + final int accountExpectedCount = accountSupportedResourceTypes.size(); + final int domainExpectedCount = domainSupportedResourceTypes.size(); if ((domainResourceCount.size() < domainExpectedCount * domains.size())) { s_logger.debug("resource_count table has records missing for some domains...going to insert them"); - for (DomainVO domain : domains) { + for (final DomainVO domain : domains) { // Lock domain - Transaction txn = Transaction.currentTxn(); - txn.start(); - _domainDao.lockRow(domain.getId(), true); - List domainCounts = _resourceCountDao.listByOwnerId(domain.getId(), ResourceOwnerType.Domain); - List domainCountStr = new ArrayList(); - for (ResourceCountVO domainCount : domainCounts) { - domainCountStr.add(domainCount.getType().toString()); - } - - if (domainCountStr.size() < domainExpectedCount) { - for (ResourceType resourceType : domainSupportedResourceTypes) { - if (!domainCountStr.contains(resourceType.toString())) { - ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, domain.getId(), ResourceOwnerType.Domain); - s_logger.debug("Inserting resource count of type " + resourceType + " for domain id=" + domain.getId()); - _resourceCountDao.persist(resourceCountVO); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + _domainDao.lockRow(domain.getId(), true); + List domainCounts = _resourceCountDao.listByOwnerId(domain.getId(), ResourceOwnerType.Domain); + List domainCountStr = new ArrayList(); + for (ResourceCountVO domainCount : domainCounts) { + domainCountStr.add(domainCount.getType().toString()); + } + + if (domainCountStr.size() < domainExpectedCount) { + for (ResourceType resourceType : domainSupportedResourceTypes) { + if (!domainCountStr.contains(resourceType.toString())) { + ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, domain.getId(), ResourceOwnerType.Domain); + s_logger.debug("Inserting resource count of type " + resourceType + " for domain id=" + domain.getId()); + _resourceCountDao.persist(resourceCountVO); + } + } } } - } - txn.commit(); + }); + } } if ((accountResourceCount.size() < accountExpectedCount * accounts.size())) { s_logger.debug("resource_count table has records missing for some accounts...going to insert them"); - for (AccountVO account : accounts) { + for (final AccountVO account : accounts) { // lock account - Transaction txn = Transaction.currentTxn(); - txn.start(); - _accountDao.lockRow(account.getId(), true); - List accountCounts = _resourceCountDao.listByOwnerId(account.getId(), ResourceOwnerType.Account); - List accountCountStr = new ArrayList(); - for (ResourceCountVO accountCount : accountCounts) { - accountCountStr.add(accountCount.getType().toString()); - } - - if (accountCountStr.size() < accountExpectedCount) { - for (ResourceType resourceType : accountSupportedResourceTypes) { - if (!accountCountStr.contains(resourceType.toString())) { - ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, account.getId(), ResourceOwnerType.Account); - s_logger.debug("Inserting resource count of type " + resourceType + " for account id=" + account.getId()); - _resourceCountDao.persist(resourceCountVO); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + _accountDao.lockRow(account.getId(), true); + List accountCounts = _resourceCountDao.listByOwnerId(account.getId(), ResourceOwnerType.Account); + List accountCountStr = new ArrayList(); + for (ResourceCountVO accountCount : accountCounts) { + accountCountStr.add(accountCount.getType().toString()); + } + + if (accountCountStr.size() < accountExpectedCount) { + for (ResourceType resourceType : accountSupportedResourceTypes) { + if (!accountCountStr.contains(resourceType.toString())) { + ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, account.getId(), ResourceOwnerType.Account); + s_logger.debug("Inserting resource count of type " + resourceType + " for account id=" + account.getId()); + _resourceCountDao.persist(resourceCountVO); + } + } } } - } - - txn.commit(); + }); } } } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 71730442589..1c6852379bc 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -194,6 +194,7 @@ import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd; import org.apache.cloudstack.api.command.admin.vlan.ListVlanIpRangesCmd; import org.apache.cloudstack.api.command.admin.vlan.ReleasePublicIpRangeCmd; import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd; +import org.apache.cloudstack.api.command.admin.vm.ExpungeVMCmd; import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd; import org.apache.cloudstack.api.command.admin.vm.MigrateVirtualMachineWithVolumeCmd; import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd; @@ -518,7 +519,7 @@ import com.cloud.projects.Project; import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.projects.ProjectManager; import com.cloud.resource.ResourceManager; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.server.auth.UserAuthenticator; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.GuestOS; @@ -565,6 +566,9 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.JoinBuilder; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.db.JoinBuilder.JoinType; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -1995,7 +1999,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe if (tags != null && !tags.isEmpty()) { int count = 0; - sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.PublicIpAddress.toString()); + sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.PublicIpAddress.toString()); for (String key : tags.keySet()) { sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); @@ -2166,12 +2170,12 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @Override @DB public DomainVO updateDomain(UpdateDomainCmd cmd) { - Long domainId = cmd.getId(); - String domainName = cmd.getDomainName(); - String networkDomain = cmd.getNetworkDomain(); + final Long domainId = cmd.getId(); + final String domainName = cmd.getDomainName(); + final String networkDomain = cmd.getNetworkDomain(); // check if domain exists in the system - DomainVO domain = _domainDao.findById(domainId); + final DomainVO domain = _domainDao.findById(domainId); if (domain == null) { InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find domain with specified domain id"); ex.addProxyObject(domainId.toString(), "domainId"); @@ -2212,27 +2216,26 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe } } - Transaction txn = Transaction.currentTxn(); - - txn.start(); - - if (domainName != null) { - String updatedDomainPath = getUpdatedDomainPath(domain.getPath(), domainName); - updateDomainChildren(domain, updatedDomainPath); - domain.setName(domainName); - domain.setPath(updatedDomainPath); - } - - if (networkDomain != null) { - if (networkDomain.isEmpty()) { - domain.setNetworkDomain(null); - } else { - domain.setNetworkDomain(networkDomain); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + if (domainName != null) { + String updatedDomainPath = getUpdatedDomainPath(domain.getPath(), domainName); + updateDomainChildren(domain, updatedDomainPath); + domain.setName(domainName); + domain.setPath(updatedDomainPath); + } + + if (networkDomain != null) { + if (networkDomain.isEmpty()) { + domain.setNetworkDomain(null); + } else { + domain.setNetworkDomain(networkDomain); + } + } + _domainDao.update(domainId, domain); } - } - _domainDao.update(domainId, domain); - - txn.commit(); + }); return _domainDao.findById(domainId); @@ -2370,7 +2373,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe for (SummedCapacity summedCapacity : summedCapacities) { CapacityVO capacity = new CapacityVO(summedCapacity.getDataCenterId(), summedCapacity.getPodId(), summedCapacity.getClusterId(), summedCapacity.getCapacityType(), summedCapacity.getPercentUsed()); - capacity.setUsedCapacity(summedCapacity.getUsedCapacity()); + capacity.setUsedCapacity(summedCapacity.getUsedCapacity() + summedCapacity.getReservedCapacity()); capacity.setTotalCapacity(summedCapacity.getTotalCapacity()); capacities.add(capacity); } @@ -2751,6 +2754,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe cmdList.add(AddNicToVMCmd.class); cmdList.add(DeployVMCmd.class); cmdList.add(DestroyVMCmd.class); + cmdList.add(ExpungeVMCmd.class); cmdList.add(GetVMPasswordCmd.class); cmdList.add(ListVMsCmd.class); cmdList.add(ScaleVMCmd.class); @@ -3440,7 +3444,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe // give us the same key if (_hashKey == null) { _hashKey = _configDao.getValueAndInitIfNotExist(Config.HashKey.key(), Config.HashKey.getCategory(), - getBase64EncodedRandomKey(128)); + getBase64EncodedRandomKey(128), Config.HashKey.getDescription()); } return _hashKey; } @@ -3450,7 +3454,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe if (_encryptionKey == null) { _encryptionKey = _configDao.getValueAndInitIfNotExist(Config.EncryptionKey.key(), Config.EncryptionKey.getCategory(), - getBase64EncodedRandomKey(128)); + getBase64EncodedRandomKey(128), Config.EncryptionKey.getDescription()); } return _encryptionKey; } @@ -3460,7 +3464,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe if (_encryptionIV == null) { _encryptionIV = _configDao.getValueAndInitIfNotExist(Config.EncryptionIV.key(), Config.EncryptionIV.getCategory(), - getBase64EncodedRandomKey(128)); + getBase64EncodedRandomKey(128), Config.EncryptionIV.getDescription()); } return _encryptionIV; } @@ -3651,7 +3655,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @Override @DB - public boolean updateHostPassword(UpdateHostPasswordCmd cmd) { + public boolean updateHostPassword(final UpdateHostPasswordCmd cmd) { if (cmd.getClusterId() == null && cmd.getHostId() == null) { throw new InvalidParameterValueException("You should provide one of cluster id or a host id."); } else if (cmd.getClusterId() == null) { @@ -3668,35 +3672,30 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe throw new InvalidParameterValueException("This operation is not supported for this hypervisor type"); } // get all the hosts in this cluster - List hosts = _resourceMgr.listAllHostsInCluster(cmd.getClusterId()); - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - for (HostVO h : hosts) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Changing password for host name = " + h.getName()); - } - // update password for this host - DetailVO nv = _detailsDao.findDetail(h.getId(), ApiConstants.USERNAME); - if (nv.getValue().equals(cmd.getUsername())) { - DetailVO nvp = _detailsDao.findDetail(h.getId(), ApiConstants.PASSWORD); - nvp.setValue(DBEncryptionUtil.encrypt(cmd.getPassword())); - _detailsDao.persist(nvp); - } else { - // if one host in the cluster has diff username then - // rollback to maintain consistency - txn.rollback(); - throw new InvalidParameterValueException( - "The username is not same for all hosts, please modify passwords for individual hosts."); + final List hosts = _resourceMgr.listAllHostsInCluster(cmd.getClusterId()); + + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + for (HostVO h : hosts) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Changing password for host name = " + h.getName()); + } + // update password for this host + DetailVO nv = _detailsDao.findDetail(h.getId(), ApiConstants.USERNAME); + if (nv.getValue().equals(cmd.getUsername())) { + DetailVO nvp = _detailsDao.findDetail(h.getId(), ApiConstants.PASSWORD); + nvp.setValue(DBEncryptionUtil.encrypt(cmd.getPassword())); + _detailsDao.persist(nvp); + } else { + // if one host in the cluster has diff username then + // rollback to maintain consistency + throw new InvalidParameterValueException( + "The username is not same for all hosts, please modify passwords for individual hosts."); + } } } - txn.commit(); - // if hypervisor is xenserver then we update it in - // CitrixResourceBase - } catch (Exception e) { - txn.rollback(); - throw new CloudRuntimeException("Failed to update password " + e.getMessage()); - } + }); } return true; diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java index b4ec9155faf..699c3c0f55c 100755 --- a/server/src/com/cloud/server/StatsCollector.java +++ b/server/src/com/cloud/server/StatsCollector.java @@ -85,6 +85,8 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.net.MacAddress; import com.cloud.vm.UserVmManager; import com.cloud.vm.UserVmVO; @@ -365,29 +367,29 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc scanLock.unlock(); return; } - Transaction txn = Transaction.open(Transaction.CLOUD_DB); try { - txn.start(); - //get all stats with delta > 0 - List updatedVmNetStats = _vmDiskStatsDao.listUpdatedStats(); - for(VmDiskStatisticsVO stat : updatedVmNetStats){ - if (_dailyOrHourly) { - //update agg bytes - stat.setAggBytesRead(stat.getCurrentBytesRead() + stat.getNetBytesRead()); - stat.setAggBytesWrite(stat.getCurrentBytesWrite() + stat.getNetBytesWrite()); - stat.setAggIORead(stat.getCurrentIORead() + stat.getNetIORead()); - stat.setAggIOWrite(stat.getCurrentIOWrite() + stat.getNetIOWrite()); - _vmDiskStatsDao.update(stat.getId(), stat); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + //get all stats with delta > 0 + List updatedVmNetStats = _vmDiskStatsDao.listUpdatedStats(); + for(VmDiskStatisticsVO stat : updatedVmNetStats){ + if (_dailyOrHourly) { + //update agg bytes + stat.setAggBytesRead(stat.getCurrentBytesRead() + stat.getNetBytesRead()); + stat.setAggBytesWrite(stat.getCurrentBytesWrite() + stat.getNetBytesWrite()); + stat.setAggIORead(stat.getCurrentIORead() + stat.getNetIORead()); + stat.setAggIOWrite(stat.getCurrentIOWrite() + stat.getNetIOWrite()); + _vmDiskStatsDao.update(stat.getId(), stat); + } + } + s_logger.debug("Successfully updated aggregate vm disk stats"); } - } - s_logger.debug("Successfully updated aggregate vm disk stats"); - txn.commit(); + }); } catch (Exception e){ - txn.rollback(); s_logger.debug("Failed to update aggregate disk stats", e); } finally { scanLock.unlock(); - txn.close(); } } } catch (Exception e){ @@ -402,122 +404,121 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc @Override protected void runInContext() { // collect the vm disk statistics(total) from hypervisor. added by weizhou, 2013.03. - Transaction txn = Transaction.open(Transaction.CLOUD_DB); try { - txn.start(); - SearchCriteria sc = _hostDao.createSearchCriteria(); - sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString()); - sc.addAnd("resourceState", SearchCriteria.Op.NIN, ResourceState.Maintenance, ResourceState.PrepareForMaintenance, ResourceState.ErrorInMaintenance); - sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.Routing.toString()); - sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, HypervisorType.KVM); // support KVM only util 2013.06.25 - List hosts = _hostDao.search(sc, null); - - for (HostVO host : hosts) { - List vms = _userVmDao.listRunningByHostId(host.getId()); - List vmIds = new ArrayList(); - - for (UserVmVO vm : vms) { - if (vm.getType() == VirtualMachine.Type.User) // user vm - vmIds.add(vm.getId()); - } - - HashMap> vmDiskStatsById = _userVmMgr.getVmDiskStatistics(host.getId(), host.getName(), vmIds); - if (vmDiskStatsById == null) - continue; - - Set vmIdSet = vmDiskStatsById.keySet(); - for(Long vmId : vmIdSet) - { - List vmDiskStats = vmDiskStatsById.get(vmId); - if (vmDiskStats == null) + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + SearchCriteria sc = _hostDao.createSearchCriteria(); + sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString()); + sc.addAnd("resourceState", SearchCriteria.Op.NIN, ResourceState.Maintenance, ResourceState.PrepareForMaintenance, ResourceState.ErrorInMaintenance); + sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.Routing.toString()); + sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, HypervisorType.KVM); // support KVM only util 2013.06.25 + List hosts = _hostDao.search(sc, null); + + for (HostVO host : hosts) { + List vms = _userVmDao.listRunningByHostId(host.getId()); + List vmIds = new ArrayList(); + + for (UserVmVO vm : vms) { + if (vm.getType() == VirtualMachine.Type.User) // user vm + vmIds.add(vm.getId()); + } + + HashMap> vmDiskStatsById = _userVmMgr.getVmDiskStatistics(host.getId(), host.getName(), vmIds); + if (vmDiskStatsById == null) continue; - UserVmVO userVm = _userVmDao.findById(vmId); - for (VmDiskStatsEntry vmDiskStat:vmDiskStats) { - SearchCriteria sc_volume = _volsDao.createSearchCriteria(); - sc_volume.addAnd("path", SearchCriteria.Op.EQ, vmDiskStat.getPath()); - VolumeVO volume = _volsDao.search(sc_volume, null).get(0); - VmDiskStatisticsVO previousVmDiskStats = _vmDiskStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), vmId, volume.getId()); - VmDiskStatisticsVO vmDiskStat_lock = _vmDiskStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), vmId, volume.getId()); - - if ((vmDiskStat.getBytesRead() == 0) && (vmDiskStat.getBytesWrite() == 0) - && (vmDiskStat.getIORead() == 0) && (vmDiskStat.getIOWrite() == 0)) { - s_logger.debug("IO/bytes read and write are all 0. Not updating vm_disk_statistics"); - continue; - } - - if (vmDiskStat_lock == null) { - s_logger.warn("unable to find vm disk stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId()+ " and volumeId:" + volume.getId()); - continue; - } - - if (previousVmDiskStats != null - && ((previousVmDiskStats.getCurrentBytesRead() != vmDiskStat_lock.getCurrentBytesRead()) - || (previousVmDiskStats.getCurrentBytesWrite() != vmDiskStat_lock.getCurrentBytesWrite()) - || (previousVmDiskStats.getCurrentIORead() != vmDiskStat_lock.getCurrentIORead()) - || (previousVmDiskStats.getCurrentIOWrite() != vmDiskStat_lock.getCurrentIOWrite()))) { - s_logger.debug("vm disk stats changed from the time GetVmDiskStatsCommand was sent. " + - "Ignoring current answer. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + - " Read(Bytes): " + vmDiskStat.getBytesRead() + " write(Bytes): " + vmDiskStat.getBytesWrite() + - " Read(IO): " + vmDiskStat.getIORead() + " write(IO): " + vmDiskStat.getIOWrite()); - continue; - } - - if (vmDiskStat_lock.getCurrentBytesRead() > vmDiskStat.getBytesRead()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Read # of bytes that's less than the last one. " + - "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + - " Reported: " + vmDiskStat.getBytesRead() + " Stored: " + vmDiskStat_lock.getCurrentBytesRead()); + + Set vmIdSet = vmDiskStatsById.keySet(); + for(Long vmId : vmIdSet) + { + List vmDiskStats = vmDiskStatsById.get(vmId); + if (vmDiskStats == null) + continue; + UserVmVO userVm = _userVmDao.findById(vmId); + for (VmDiskStatsEntry vmDiskStat:vmDiskStats) { + SearchCriteria sc_volume = _volsDao.createSearchCriteria(); + sc_volume.addAnd("path", SearchCriteria.Op.EQ, vmDiskStat.getPath()); + VolumeVO volume = _volsDao.search(sc_volume, null).get(0); + VmDiskStatisticsVO previousVmDiskStats = _vmDiskStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), vmId, volume.getId()); + VmDiskStatisticsVO vmDiskStat_lock = _vmDiskStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), vmId, volume.getId()); + + if ((vmDiskStat.getBytesRead() == 0) && (vmDiskStat.getBytesWrite() == 0) + && (vmDiskStat.getIORead() == 0) && (vmDiskStat.getIOWrite() == 0)) { + s_logger.debug("IO/bytes read and write are all 0. Not updating vm_disk_statistics"); + continue; + } + + if (vmDiskStat_lock == null) { + s_logger.warn("unable to find vm disk stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId()+ " and volumeId:" + volume.getId()); + continue; + } + + if (previousVmDiskStats != null + && ((previousVmDiskStats.getCurrentBytesRead() != vmDiskStat_lock.getCurrentBytesRead()) + || (previousVmDiskStats.getCurrentBytesWrite() != vmDiskStat_lock.getCurrentBytesWrite()) + || (previousVmDiskStats.getCurrentIORead() != vmDiskStat_lock.getCurrentIORead()) + || (previousVmDiskStats.getCurrentIOWrite() != vmDiskStat_lock.getCurrentIOWrite()))) { + s_logger.debug("vm disk stats changed from the time GetVmDiskStatsCommand was sent. " + + "Ignoring current answer. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + + " Read(Bytes): " + vmDiskStat.getBytesRead() + " write(Bytes): " + vmDiskStat.getBytesWrite() + + " Read(IO): " + vmDiskStat.getIORead() + " write(IO): " + vmDiskStat.getIOWrite()); + continue; + } + + if (vmDiskStat_lock.getCurrentBytesRead() > vmDiskStat.getBytesRead()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Read # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + + " Reported: " + vmDiskStat.getBytesRead() + " Stored: " + vmDiskStat_lock.getCurrentBytesRead()); + } + vmDiskStat_lock.setNetBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead()); + } + vmDiskStat_lock.setCurrentBytesRead(vmDiskStat.getBytesRead()); + if (vmDiskStat_lock.getCurrentBytesWrite() > vmDiskStat.getBytesWrite()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Write # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + + " Reported: " + vmDiskStat.getBytesWrite() + " Stored: " + vmDiskStat_lock.getCurrentBytesWrite()); + } + vmDiskStat_lock.setNetBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite()); + } + vmDiskStat_lock.setCurrentBytesWrite(vmDiskStat.getBytesWrite()); + if (vmDiskStat_lock.getCurrentIORead() > vmDiskStat.getIORead()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Read # of IO that's less than the last one. " + + "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + + " Reported: " + vmDiskStat.getIORead() + " Stored: " + vmDiskStat_lock.getCurrentIORead()); + } + vmDiskStat_lock.setNetIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead()); + } + vmDiskStat_lock.setCurrentIORead(vmDiskStat.getIORead()); + if (vmDiskStat_lock.getCurrentIOWrite() > vmDiskStat.getIOWrite()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Write # of IO that's less than the last one. " + + "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + + " Reported: " + vmDiskStat.getIOWrite() + " Stored: " + vmDiskStat_lock.getCurrentIOWrite()); + } + vmDiskStat_lock.setNetIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite()); + } + vmDiskStat_lock.setCurrentIOWrite(vmDiskStat.getIOWrite()); + + if (! _dailyOrHourly) { + //update agg bytes + vmDiskStat_lock.setAggBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite()); + vmDiskStat_lock.setAggBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead()); + vmDiskStat_lock.setAggIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite()); + vmDiskStat_lock.setAggIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead()); + } + + _vmDiskStatsDao.update(vmDiskStat_lock.getId(), vmDiskStat_lock); } - vmDiskStat_lock.setNetBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead()); } - vmDiskStat_lock.setCurrentBytesRead(vmDiskStat.getBytesRead()); - if (vmDiskStat_lock.getCurrentBytesWrite() > vmDiskStat.getBytesWrite()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Write # of bytes that's less than the last one. " + - "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + - " Reported: " + vmDiskStat.getBytesWrite() + " Stored: " + vmDiskStat_lock.getCurrentBytesWrite()); - } - vmDiskStat_lock.setNetBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite()); - } - vmDiskStat_lock.setCurrentBytesWrite(vmDiskStat.getBytesWrite()); - if (vmDiskStat_lock.getCurrentIORead() > vmDiskStat.getIORead()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Read # of IO that's less than the last one. " + - "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + - " Reported: " + vmDiskStat.getIORead() + " Stored: " + vmDiskStat_lock.getCurrentIORead()); - } - vmDiskStat_lock.setNetIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead()); - } - vmDiskStat_lock.setCurrentIORead(vmDiskStat.getIORead()); - if (vmDiskStat_lock.getCurrentIOWrite() > vmDiskStat.getIOWrite()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Write # of IO that's less than the last one. " + - "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + - " Reported: " + vmDiskStat.getIOWrite() + " Stored: " + vmDiskStat_lock.getCurrentIOWrite()); - } - vmDiskStat_lock.setNetIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite()); - } - vmDiskStat_lock.setCurrentIOWrite(vmDiskStat.getIOWrite()); - - if (! _dailyOrHourly) { - //update agg bytes - vmDiskStat_lock.setAggBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite()); - vmDiskStat_lock.setAggBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead()); - vmDiskStat_lock.setAggIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite()); - vmDiskStat_lock.setAggIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead()); - } - - _vmDiskStatsDao.update(vmDiskStat_lock.getId(), vmDiskStat_lock); } } - } - txn.commit(); + }); } catch (Exception e) { s_logger.warn("Error while collecting vm disk stats from hosts", e); - } finally { - txn.close(); } - } } diff --git a/server/src/com/cloud/servlet/CloudStartupServlet.java b/server/src/com/cloud/servlet/CloudStartupServlet.java index 8fbae924529..4fe96aa505e 100755 --- a/server/src/com/cloud/servlet/CloudStartupServlet.java +++ b/server/src/com/cloud/servlet/CloudStartupServlet.java @@ -30,6 +30,7 @@ import com.cloud.utils.LogUtils; import com.cloud.utils.SerialVersionUID; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; public class CloudStartupServlet extends HttpServlet { public static final Logger s_logger = Logger.getLogger(CloudStartupServlet.class.getName()); @@ -49,7 +50,7 @@ public class CloudStartupServlet extends HttpServlet { if(ComponentContext.getApplicationContext() != null) { _timer.cancel(); - Transaction txn = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); try { ComponentContext.initComponentsLifeCycle(); } finally { diff --git a/server/src/com/cloud/servlet/ConsoleProxyServlet.java b/server/src/com/cloud/servlet/ConsoleProxyServlet.java index e01d9595215..b3415db3779 100644 --- a/server/src/com/cloud/servlet/ConsoleProxyServlet.java +++ b/server/src/com/cloud/servlet/ConsoleProxyServlet.java @@ -57,6 +57,7 @@ import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.db.EntityManager; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineManager; @@ -573,7 +574,7 @@ public class ConsoleProxyServlet extends HttpServlet { return false; // no signature, bad request } - Transaction txn = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); txn.close(); User user = null; // verify there is a user with this api key diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index c046057db51..75cedd016b1 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -158,6 +158,10 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.JoinBuilder; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionLegacy; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.db.JoinBuilder.JoinType; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -1066,7 +1070,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C String sql = "SELECT volume_id from snapshots, snapshot_store_ref WHERE snapshots.id = snapshot_store_ref.snapshot_id and store_id=? GROUP BY volume_id"; List list = new ArrayList(); try { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); ResultSet rs = null; PreparedStatement pstmt = null; pstmt = txn.prepareAutoCloseStatement(sql); @@ -1086,7 +1090,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C List findAllSnapshotForVolume(Long volumeId) { String sql = "SELECT backup_snap_id FROM snapshots WHERE volume_id=? and backup_snap_id is not NULL"; try { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); ResultSet rs = null; PreparedStatement pstmt = null; pstmt = txn.prepareAutoCloseStatement(sql); @@ -1752,7 +1756,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Override public boolean deleteImageStore(DeleteImageStoreCmd cmd) { - long storeId = cmd.getId(); + final long storeId = cmd.getId(); // Verify that image store exists ImageStoreVO store = _imageStoreDao.findById(storeId); if (store == null) { @@ -1778,17 +1782,20 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } // ready to delete - Transaction txn = Transaction.currentTxn(); - txn.start(); - // first delete from image_store_details table, we need to do that since - // we are not actually deleting record from main - // image_data_store table, so delete cascade will not work - _imageStoreDetailsDao.deleteDetails(storeId); - _snapshotStoreDao.deletePrimaryRecordsForStore(storeId, DataStoreRole.Image); - _volumeStoreDao.deletePrimaryRecordsForStore(storeId); - _templateStoreDao.deletePrimaryRecordsForStore(storeId); - _imageStoreDao.remove(storeId); - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // first delete from image_store_details table, we need to do that since + // we are not actually deleting record from main + // image_data_store table, so delete cascade will not work + _imageStoreDetailsDao.deleteDetails(storeId); + _snapshotStoreDao.deletePrimaryRecordsForStore(storeId, DataStoreRole.Image); + _volumeStoreDao.deletePrimaryRecordsForStore(storeId); + _templateStoreDao.deletePrimaryRecordsForStore(storeId); + _imageStoreDao.remove(storeId); + } + }); + return true; } @@ -1862,7 +1869,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Override public boolean deleteSecondaryStagingStore(DeleteSecondaryStagingStoreCmd cmd) { - long storeId = cmd.getId(); + final long storeId = cmd.getId(); // Verify that cache store exists ImageStoreVO store = _imageStoreDao.findById(storeId); if (store == null) { @@ -1887,17 +1894,20 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } // ready to delete - Transaction txn = Transaction.currentTxn(); - txn.start(); - // first delete from image_store_details table, we need to do that since - // we are not actually deleting record from main - // image_data_store table, so delete cascade will not work - _imageStoreDetailsDao.deleteDetails(storeId); - _snapshotStoreDao.deletePrimaryRecordsForStore(storeId, DataStoreRole.ImageCache); - _volumeStoreDao.deletePrimaryRecordsForStore(storeId); - _templateStoreDao.deletePrimaryRecordsForStore(storeId); - _imageStoreDao.remove(storeId); - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // first delete from image_store_details table, we need to do that since + // we are not actually deleting record from main + // image_data_store table, so delete cascade will not work + _imageStoreDetailsDao.deleteDetails(storeId); + _snapshotStoreDao.deletePrimaryRecordsForStore(storeId, DataStoreRole.ImageCache); + _volumeStoreDao.deletePrimaryRecordsForStore(storeId); + _templateStoreDao.deletePrimaryRecordsForStore(storeId); + _imageStoreDao.remove(storeId); + } + }); + return true; } diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index 079f90c2bc9..071281c41fe 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -139,6 +139,8 @@ import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.EntityManager; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.utils.fsm.StateMachine2; @@ -403,34 +405,34 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic } @DB - protected VolumeVO persistVolume(Account owner, Long zoneId, String volumeName, String url, String format) { - - Transaction txn = Transaction.currentTxn(); - txn.start(); - - VolumeVO volume = new VolumeVO(volumeName, zoneId, -1, -1, -1, new Long(-1), null, null, 0, Volume.Type.DATADISK); - volume.setPoolId(null); - volume.setDataCenterId(zoneId); - volume.setPodId(null); - volume.setAccountId(owner.getAccountId()); - volume.setDomainId(owner.getDomainId()); - long diskOfferingId = _diskOfferingDao.findByUniqueName("Cloud.com-Custom").getId(); - volume.setDiskOfferingId(diskOfferingId); - // volume.setSize(size); - volume.setInstanceId(null); - volume.setUpdated(new Date()); - volume.setDomainId((owner == null) ? Domain.ROOT_DOMAIN : owner.getDomainId()); - volume.setFormat(ImageFormat.valueOf(format)); - volume = _volsDao.persist(volume); - CallContext.current().setEventDetails("Volume Id: " + volume.getId()); - - // Increment resource count during allocation; if actual creation fails, - // decrement it - _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume); - _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, UriUtils.getRemoteSize(url)); - - txn.commit(); - return volume; + protected VolumeVO persistVolume(final Account owner, final Long zoneId, final String volumeName, final String url, final String format) { + return Transaction.execute(new TransactionCallback() { + @Override + public VolumeVO doInTransaction(TransactionStatus status) { + VolumeVO volume = new VolumeVO(volumeName, zoneId, -1, -1, -1, new Long(-1), null, null, 0, Volume.Type.DATADISK); + volume.setPoolId(null); + volume.setDataCenterId(zoneId); + volume.setPodId(null); + volume.setAccountId(owner.getAccountId()); + volume.setDomainId(owner.getDomainId()); + long diskOfferingId = _diskOfferingDao.findByUniqueName("Cloud.com-Custom").getId(); + volume.setDiskOfferingId(diskOfferingId); + // volume.setSize(size); + volume.setInstanceId(null); + volume.setUpdated(new Date()); + volume.setDomainId((owner == null) ? Domain.ROOT_DOMAIN : owner.getDomainId()); + volume.setFormat(ImageFormat.valueOf(format)); + volume = _volsDao.persist(volume); + CallContext.current().setEventDetails("Volume Id: " + volume.getId()); + + // Increment resource count during allocation; if actual creation fails, + // decrement it + _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume); + _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, UriUtils.getRemoteSize(url)); + + return volume; + } + }); } /* @@ -599,49 +601,57 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic userSpecifiedName = getRandomVolumeName(); } - Transaction txn = Transaction.currentTxn(); - txn.start(); - - VolumeVO volume = new VolumeVO(userSpecifiedName, -1, -1, -1, -1, new Long(-1), null, null, 0, Volume.Type.DATADISK); - volume.setPoolId(null); - volume.setDataCenterId(zoneId); - volume.setPodId(null); - volume.setAccountId(ownerId); - volume.setDomainId(((caller == null) ? Domain.ROOT_DOMAIN : caller.getDomainId())); - volume.setDiskOfferingId(diskOfferingId); - volume.setSize(size); - volume.setMinIops(minIops); - volume.setMaxIops(maxIops); - volume.setInstanceId(null); - volume.setUpdated(new Date()); - volume.setDomainId((caller == null) ? Domain.ROOT_DOMAIN : caller.getDomainId()); - volume.setDisplayVolume(displayVolumeEnabled); - if (parentVolume != null) { - volume.setTemplateId(parentVolume.getTemplateId()); - volume.setFormat(parentVolume.getFormat()); - } else { - volume.setTemplateId(null); - } - - volume = _volsDao.persist(volume); - if (cmd.getSnapshotId() == null) { - // for volume created from snapshot, create usage event after volume creation - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), diskOfferingId, - null, size, Volume.class.getName(), volume.getUuid()); - } - - CallContext.current().setEventDetails("Volume Id: " + volume.getId()); - - // Increment resource count during allocation; if actual creation fails, - // decrement it - _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume); - _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize())); - - txn.commit(); + VolumeVO volume = commitVolume(cmd, caller, ownerId, displayVolumeEnabled, zoneId, diskOfferingId, size, + minIops, maxIops, parentVolume, userSpecifiedName); return volume; } + private VolumeVO commitVolume(final CreateVolumeCmd cmd, final Account caller, final long ownerId, final Boolean displayVolumeEnabled, + final Long zoneId, final Long diskOfferingId, final Long size, final Long minIops, final Long maxIops, final VolumeVO parentVolume, + final String userSpecifiedName) { + return Transaction.execute(new TransactionCallback() { + @Override + public VolumeVO doInTransaction(TransactionStatus status) { + VolumeVO volume = new VolumeVO(userSpecifiedName, -1, -1, -1, -1, new Long(-1), null, null, 0, Volume.Type.DATADISK); + volume.setPoolId(null); + volume.setDataCenterId(zoneId); + volume.setPodId(null); + volume.setAccountId(ownerId); + volume.setDomainId(((caller == null) ? Domain.ROOT_DOMAIN : caller.getDomainId())); + volume.setDiskOfferingId(diskOfferingId); + volume.setSize(size); + volume.setMinIops(minIops); + volume.setMaxIops(maxIops); + volume.setInstanceId(null); + volume.setUpdated(new Date()); + volume.setDomainId((caller == null) ? Domain.ROOT_DOMAIN : caller.getDomainId()); + volume.setDisplayVolume(displayVolumeEnabled); + if (parentVolume != null) { + volume.setTemplateId(parentVolume.getTemplateId()); + volume.setFormat(parentVolume.getFormat()); + } else { + volume.setTemplateId(null); + } + + volume = _volsDao.persist(volume); + if (cmd.getSnapshotId() == null) { + // for volume created from snapshot, create usage event after volume creation + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), diskOfferingId, + null, size, Volume.class.getName(), volume.getUuid()); + } + + CallContext.current().setEventDetails("Volume Id: " + volume.getId()); + + // Increment resource count during allocation; if actual creation fails, + // decrement it + _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume); + _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize())); + return volume; + } + }); + } + public boolean validateVolumeSizeRange(long size) { if (size < 0 || (size > 0 && size < (1024 * 1024 * 1024))) { throw new InvalidParameterValueException("Please specify a size of at least 1 Gb."); @@ -1309,7 +1319,11 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic throw new InvalidParameterValueException("Failed to find the destination storage pool: " + storagePoolId); } - if (!_volumeMgr.volumeOnSharedStoragePool(vol)) { + if (_volumeMgr.volumeOnSharedStoragePool(vol)) { + if (destPool.isLocal()) { + throw new InvalidParameterValueException("Migration of volume from shared to local storage pool is not supported"); + } + } else { throw new InvalidParameterValueException("Migration of volume from local storage pool is not supported"); } @@ -1320,7 +1334,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic try { newVol = _volumeMgr.migrateVolume(vol, destPool); } catch (StorageUnavailableException e) { - s_logger.debug("Failed to migrate volume", e); + s_logger.debug("Failed to migrate volume", e); } } return newVol; @@ -1545,15 +1559,25 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic } if (storeForRootStoreScope.getScopeType() != storeForDataStoreScope.getScopeType()) { - if (storeForDataStoreScope.getScopeType() == ScopeType.CLUSTER && storeForRootStoreScope.getScopeType() == ScopeType.HOST) { - HostScope hs = (HostScope)storeForRootStoreScope; - if (storeForDataStoreScope.getScopeId().equals(hs.getClusterId())) { + if (storeForDataStoreScope.getScopeType() == ScopeType.CLUSTER) { + Long vmClusterId = null; + if (storeForRootStoreScope.getScopeType() == ScopeType.HOST) { + HostScope hs = (HostScope)storeForRootStoreScope; + vmClusterId = hs.getClusterId(); + } else if (storeForRootStoreScope.getScopeType() == ScopeType.ZONE) { + Long hostId = _vmInstanceDao.findById(rootVolumeOfVm.getInstanceId()).getHostId(); + if (hostId != null) { + HostVO host = _hostDao.findById(hostId); + vmClusterId = host.getClusterId(); + } + } + if (storeForDataStoreScope.getScopeId().equals(vmClusterId)) { return false; } - } - if (storeForRootStoreScope.getScopeType() == ScopeType.CLUSTER && storeForDataStoreScope.getScopeType() == ScopeType.HOST) { - HostScope hs = (HostScope)storeForDataStoreScope; - if (storeForRootStoreScope.getScopeId().equals(hs.getClusterId())) { + } else if (storeForDataStoreScope.getScopeType() == ScopeType.HOST && + (storeForRootStoreScope.getScopeType() == ScopeType.CLUSTER || storeForRootStoreScope.getScopeType() == ScopeType.ZONE)) { + Long hostId = _vmInstanceDao.findById(rootVolumeOfVm.getInstanceId()).getHostId(); + if (storeForDataStoreScope.getScopeId().equals(hostId)) { return false; } } diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index dade9837d90..4bd1da84900 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -40,8 +40,11 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy.SnapshotOperation; +import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority; +import org.apache.cloudstack.engine.subsystem.api.storage.StorageStrategyFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy.SnapshotOperation; import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority; -import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority.Priority; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; @@ -78,7 +81,7 @@ import com.cloud.host.HostVO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.resource.ResourceManager; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.storage.CreateSnapshotPayload; import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; @@ -194,8 +197,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, @Inject EndPointSelector _epSelector; @Inject private ResourceManager _resourceMgr; - @Inject - protected List snapshotStrategies; + @Inject StorageStrategyFactory _storageStrategyFactory; private int _totalRetries; @@ -278,17 +280,10 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, } } - StrategyPriority.sortStrategies(snapshotStrategies, snapshot); - - SnapshotStrategy snapshotStrategy = null; - for (SnapshotStrategy strategy : snapshotStrategies) { - if (strategy.canHandle(snapshot) != Priority.CANT_HANDLE) { - snapshotStrategy = strategy; - break; - } - } + SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.REVERT); if (snapshotStrategy == null) { + s_logger.error("Unable to find snaphot strategy to handle snapshot with id '"+snapshotId+"'"); return false; } @@ -379,11 +374,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, String parent = null; try { for (String backupUuid : BackupUuids) { -<<<<<<< HEAD - downloadSnapshotFromSwiftCommand cmd = new downloadSnapshotFromSwiftCommand(swift, secStore.getUri(), dcId, accountId, volumeId, parent, backupUuid, _backupsnapshotwait); -======= DownloadSnapshotFromSwiftCommand cmd = new DownloadSnapshotFromSwiftCommand(swift, secondaryStoragePoolUrl, dcId, accountId, volumeId, parent, backupUuid, _backupsnapshotwait); ->>>>>>> master Answer answer = _agentMgr.sendToSSVM(dcId, cmd); if ((answer == null) || !answer.getResult()) { throw new CloudRuntimeException("downloadSnapshotsFromSwift failed "); @@ -517,16 +508,13 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, throw new InvalidParameterValueException("unable to find a snapshot with id " + snapshotId); } - StrategyPriority.sortStrategies(snapshotStrategies, snapshotCheck); - _accountMgr.checkAccess(caller, null, true, snapshotCheck); - SnapshotStrategy snapshotStrategy = null; - for (SnapshotStrategy strategy : snapshotStrategies) { - if (strategy.canHandle(snapshotCheck) != Priority.CANT_HANDLE) { - snapshotStrategy = strategy; - break; - } + SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshotCheck, SnapshotOperation.DELETE); + if (snapshotStrategy == null) { + s_logger.error("Unable to find snaphot strategy to handle snapshot with id '"+snapshotId+"'"); + return false; } + try { boolean result = snapshotStrategy.deleteSnapshot(snapshotId); if (result) { @@ -621,7 +609,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, if (tags != null && !tags.isEmpty()) { int count = 0; - sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.Snapshot.toString()); + sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.Snapshot.toString()); for (String key : tags.keySet()) { sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); @@ -711,17 +699,12 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, // Either way delete the snapshots for this volume. List snapshots = listSnapsforVolume(volumeId); for (SnapshotVO snapshot : snapshots) { - SnapshotVO snap = _snapshotDao.findById(snapshot.getId()); - SnapshotStrategy snapshotStrategy = null; - - StrategyPriority.sortStrategies(snapshotStrategies, snapshot); - - for (SnapshotStrategy strategy : snapshotStrategies) { - if (strategy.canHandle(snap) != Priority.CANT_HANDLE) { - snapshotStrategy = strategy; - break; - } + SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.DELETE); + if (snapshotStrategy == null) { + s_logger.error("Unable to find snaphot strategy to handle snapshot with id '"+snapshot.getId()+"'"); + continue; } + if (snapshotStrategy.deleteSnapshot(snapshot.getId())) { if (snapshot.getRecurringType() == Type.MANUAL) { _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.snapshot); @@ -1045,22 +1028,16 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, Long snapshotId = payload.getSnapshotId(); Account snapshotOwner = payload.getAccount(); SnapshotInfo snapshot = snapshotFactory.getSnapshot(snapshotId, volume.getDataStore()); - boolean processed = false; - - StrategyPriority.sortStrategies(snapshotStrategies, snapshot); try { - for (SnapshotStrategy strategy : snapshotStrategies) { - if (strategy.canHandle(snapshot) != Priority.CANT_HANDLE) { - processed = true; - snapshot = strategy.takeSnapshot(snapshot); - break; - } - } - if (!processed) { + SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE); + + if (snapshotStrategy == null) { throw new CloudRuntimeException("Can't find snapshot strategy to deal with snapshot:" + snapshotId); } + snapshotStrategy.takeSnapshot(snapshot); + try { postCreateSnapshot(volume.getId(), snapshotId, payload.getSnapshotPolicyId()); @@ -1235,4 +1212,5 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, } return snapshot; } + } diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index 79aba6340d9..7d7692f104c 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -48,7 +48,7 @@ import com.cloud.network.vpc.dao.StaticRouteDao; import com.cloud.network.vpc.dao.VpcDao; import com.cloud.projects.dao.ProjectDao; import com.cloud.server.ResourceTag; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.server.TaggedResourceService; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.dao.SnapshotDao; @@ -66,6 +66,8 @@ import com.cloud.utils.db.GenericDao; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.uuididentity.dao.IdentityDao; import com.cloud.vm.dao.NicDao; @@ -78,8 +80,8 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDao; public class TaggedResourceManagerImpl extends ManagerBase implements TaggedResourceService { public static final Logger s_logger = Logger.getLogger(TaggedResourceManagerImpl.class); - private static Map> _daoMap= - new HashMap>(); + private static Map> _daoMap= + new HashMap>(); @Inject AccountManager _accountMgr; @@ -133,26 +135,26 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso @Override public boolean configure(String name, Map params) throws ConfigurationException { - _daoMap.put(TaggedResourceType.UserVm, _userVmDao); - _daoMap.put(TaggedResourceType.Volume, _volumeDao); - _daoMap.put(TaggedResourceType.Template, _templateDao); - _daoMap.put(TaggedResourceType.ISO, _templateDao); - _daoMap.put(TaggedResourceType.Snapshot, _snapshotDao); - _daoMap.put(TaggedResourceType.Network, _networkDao); - _daoMap.put(TaggedResourceType.LoadBalancer, _lbDao); - _daoMap.put(TaggedResourceType.PortForwardingRule, _pfDao); - _daoMap.put(TaggedResourceType.FirewallRule, _firewallDao); - _daoMap.put(TaggedResourceType.SecurityGroup, _securityGroupDao); - _daoMap.put(TaggedResourceType.PublicIpAddress, _publicIpDao); - _daoMap.put(TaggedResourceType.Project, _projectDao); - _daoMap.put(TaggedResourceType.Vpc, _vpcDao); - _daoMap.put(TaggedResourceType.Nic, _nicDao); - _daoMap.put(TaggedResourceType.NetworkACL, _networkACLItemDao); - _daoMap.put(TaggedResourceType.StaticRoute, _staticRouteDao); - _daoMap.put(TaggedResourceType.VMSnapshot, _vmSnapshotDao); - _daoMap.put(TaggedResourceType.RemoteAccessVpn, _vpnDao); - _daoMap.put(TaggedResourceType.Zone, _dataCenterDao); - _daoMap.put(TaggedResourceType.ServiceOffering, _serviceOffDao); + _daoMap.put(ResourceObjectType.UserVm, _userVmDao); + _daoMap.put(ResourceObjectType.Volume, _volumeDao); + _daoMap.put(ResourceObjectType.Template, _templateDao); + _daoMap.put(ResourceObjectType.ISO, _templateDao); + _daoMap.put(ResourceObjectType.Snapshot, _snapshotDao); + _daoMap.put(ResourceObjectType.Network, _networkDao); + _daoMap.put(ResourceObjectType.LoadBalancer, _lbDao); + _daoMap.put(ResourceObjectType.PortForwardingRule, _pfDao); + _daoMap.put(ResourceObjectType.FirewallRule, _firewallDao); + _daoMap.put(ResourceObjectType.SecurityGroup, _securityGroupDao); + _daoMap.put(ResourceObjectType.PublicIpAddress, _publicIpDao); + _daoMap.put(ResourceObjectType.Project, _projectDao); + _daoMap.put(ResourceObjectType.Vpc, _vpcDao); + _daoMap.put(ResourceObjectType.Nic, _nicDao); + _daoMap.put(ResourceObjectType.NetworkACL, _networkACLItemDao); + _daoMap.put(ResourceObjectType.StaticRoute, _staticRouteDao); + _daoMap.put(ResourceObjectType.VMSnapshot, _vmSnapshotDao); + _daoMap.put(ResourceObjectType.RemoteAccessVpn, _vpnDao); + _daoMap.put(ResourceObjectType.Zone, _dataCenterDao); + _daoMap.put(ResourceObjectType.ServiceOffering, _serviceOffDao); return true; } @@ -168,7 +170,7 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso } @Override - public Long getResourceId(String resourceId, TaggedResourceType resourceType) { + public long getResourceId(String resourceId, ResourceObjectType resourceType) { GenericDao dao = _daoMap.get(resourceType); if (dao == null) { throw new CloudRuntimeException("Dao is not loaded for the resource type " + resourceType); @@ -198,14 +200,9 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso } return identityId; } - - protected String getTableName(TaggedResourceType resourceType) { - GenericDao dao = _daoMap.get(resourceType); - Class claz = DbUtil.getEntityBeanType(dao); - return DbUtil.getTableName(claz); - } - private Pair getAccountDomain(long resourceId, TaggedResourceType resourceType) { + + private Pair getAccountDomain(long resourceId, ResourceObjectType resourceType) { Pair pair = null; GenericDao dao = _daoMap.get(resourceType); @@ -241,9 +238,9 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso } @Override - public TaggedResourceType getResourceType(String resourceTypeStr) { + public ResourceObjectType getResourceType(String resourceTypeStr) { - for (TaggedResourceType type : ResourceTag.TaggedResourceType.values()) { + for (ResourceObjectType type : ResourceTag.ResourceObjectType.values()) { if (type.toString().equalsIgnoreCase(resourceTypeStr)) { return type; } @@ -254,60 +251,59 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso @Override @DB @ActionEvent(eventType = EventTypes.EVENT_TAGS_CREATE, eventDescription = "creating resource tags") - public List createTags(List resourceIds, TaggedResourceType resourceType, - Map tags, String customer) { - Account caller = CallContext.current().getCallingAccount(); + public List createTags(final List resourceIds, final ResourceObjectType resourceType, + final Map tags, final String customer) { + final Account caller = CallContext.current().getCallingAccount(); - List resourceTags = new ArrayList(tags.size()); + final List resourceTags = new ArrayList(tags.size()); - Transaction txn = Transaction.currentTxn(); - txn.start(); - - for (String key : tags.keySet()) { - for (String resourceId : resourceIds) { - Long id = getResourceId(resourceId, resourceType); - String resourceUuid = getUuid(resourceId, resourceType); - - //check if object exists - if (_daoMap.get(resourceType).findById(id) == null) { - throw new InvalidParameterValueException("Unable to find resource by id " + resourceId + - " and type " + resourceType); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + for (String key : tags.keySet()) { + for (String resourceId : resourceIds) { + if (!resourceType.resourceTagsSupport()) { + throw new InvalidParameterValueException("The resource type " + resourceType + " doesn't support resource tags"); + } + + long id = getResourceId(resourceId, resourceType); + String resourceUuid = getUuid(resourceId, resourceType); + + Pair accountDomainPair = getAccountDomain(id, resourceType); + Long domainId = accountDomainPair.second(); + Long accountId = accountDomainPair.first(); + if (accountId != null) { + _accountMgr.checkAccess(caller, null, false, _accountMgr.getAccount(accountId)); + } else if (domainId != null && caller.getType() != Account.ACCOUNT_TYPE_NORMAL) { + //check permissions; + _accountMgr.checkAccess(caller, _domainMgr.getDomain(domainId)); + } else { + throw new PermissionDeniedException("Account " + caller + " doesn't have permissions to create tags" + + " for resource " + key); + } + + String value = tags.get(key); + + if (value == null || value.isEmpty()) { + throw new InvalidParameterValueException("Value for the key " + key + " is either null or empty"); + } + + ResourceTagVO resourceTag = new ResourceTagVO(key, value, accountDomainPair.first(), + accountDomainPair.second(), + id, resourceType, customer, resourceUuid); + resourceTag = _resourceTagDao.persist(resourceTag); + resourceTags.add(resourceTag); + } } - - Pair accountDomainPair = getAccountDomain(id, resourceType); - Long domainId = accountDomainPair.second(); - Long accountId = accountDomainPair.first(); - if (accountId != null) { - _accountMgr.checkAccess(caller, null, false, _accountMgr.getAccount(accountId)); - } else if (domainId != null && caller.getType() != Account.ACCOUNT_TYPE_NORMAL) { - //check permissions; - _accountMgr.checkAccess(caller, _domainMgr.getDomain(domainId)); - } else { - throw new PermissionDeniedException("Account " + caller + " doesn't have permissions to create tags" + - " for resource " + key); - } - - String value = tags.get(key); - - if (value == null || value.isEmpty()) { - throw new InvalidParameterValueException("Value for the key " + key + " is either null or empty"); - } - - ResourceTagVO resourceTag = new ResourceTagVO(key, value, accountDomainPair.first(), - accountDomainPair.second(), - id, resourceType, customer, resourceUuid); - resourceTag = _resourceTagDao.persist(resourceTag); - resourceTags.add(resourceTag); } - } - - txn.commit(); - + }); + return resourceTags; } + @Override - public String getUuid(String resourceId, TaggedResourceType resourceType) { + public String getUuid(String resourceId, ResourceObjectType resourceType) { GenericDao dao = _daoMap.get(resourceType); Class claz = DbUtil.getEntityBeanType(dao); @@ -339,7 +335,7 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso @Override @DB @ActionEvent(eventType = EventTypes.EVENT_TAGS_DELETE, eventDescription = "deleting resource tags") - public boolean deleteTags(List resourceIds, TaggedResourceType resourceType, Map tags) { + public boolean deleteTags(List resourceIds, ResourceObjectType resourceType, Map tags) { Account caller = CallContext.current().getCallingAccount(); SearchBuilder sb = _resourceTagDao.createSearchBuilder(); @@ -354,7 +350,7 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso sc.setParameters("resourceType", resourceType); List resourceTags = _resourceTagDao.search(sc, null);; - List tagsToRemove = new ArrayList(); + final List tagsToRemove = new ArrayList(); // Finalize which tags should be removed for (ResourceTag resourceTag : resourceTags) { @@ -390,20 +386,22 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso } //Remove the tags - Transaction txn = Transaction.currentTxn(); - txn.start(); - for (ResourceTag tagToRemove : tagsToRemove) { - _resourceTagDao.remove(tagToRemove.getId()); - s_logger.debug("Removed the tag " + tagToRemove); - } - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + for (ResourceTag tagToRemove : tagsToRemove) { + _resourceTagDao.remove(tagToRemove.getId()); + s_logger.debug("Removed the tag " + tagToRemove); + } + } + }); return true; } @Override - public List listByResourceTypeAndId(TaggedResourceType type, long resourceId) { + public List listByResourceTypeAndId(ResourceObjectType type, long resourceId) { return _resourceTagDao.listBy(resourceId, type); } } diff --git a/server/src/com/cloud/template/TemplateAdapterBase.java b/server/src/com/cloud/template/TemplateAdapterBase.java index a0d4c772072..6194e6e1f4c 100755 --- a/server/src/com/cloud/template/TemplateAdapterBase.java +++ b/server/src/com/cloud/template/TemplateAdapterBase.java @@ -18,6 +18,7 @@ package com.cloud.template; import java.util.List; import java.util.Map; +import java.util.HashMap; import javax.inject.Inject; @@ -36,6 +37,7 @@ import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import com.cloud.api.ApiDBUtils; +import com.cloud.configuration.Config; import com.cloud.configuration.Resource.ResourceType; import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.DataCenterDao; @@ -45,6 +47,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.host.dao.HostDao; +import com.cloud.hypervisor.Hypervisor; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.org.Grouping; import com.cloud.projects.ProjectManager; @@ -214,6 +217,20 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat } } + if (hypervisorType.equals(Hypervisor.HypervisorType.XenServer) ) { + if( details == null || !details.containsKey("hypervisortoolsversion") + || details.get("hypervisortoolsversion") == null + || ((String)details.get("hypervisortoolsversion")).equalsIgnoreCase("none") ) { + String hpvs = _configDao.getValue(Config.XenPVdriverVersion.key()); + if ( hpvs != null) { + if ( details == null ) { + details = new HashMap(); + } + details.put("hypervisortoolsversion", hpvs); + } + } + } + Long id = _tmpltDao.getNextInSequence(Long.class, "id"); CallContext.current().setEventDetails("Id: " + id + " name: " + name); return new TemplateProfile(id, userId, name, displayText, bits, passwordEnabled, requiresHVM, url, isPublic, featured, isExtractable, imgfmt, guestOSId, zoneId, diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index c1ce89205ad..fb1bb272827 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -31,7 +31,6 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; - import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd; import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoCmd; @@ -177,6 +176,9 @@ import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.UserVmManager; import com.cloud.vm.UserVmVO; @@ -1163,11 +1165,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @DB @Override public boolean updateTemplateOrIsoPermissions(BaseUpdateTemplateOrIsoPermissionsCmd cmd) { - Transaction txn = Transaction.currentTxn(); - // Input validation - Long id = cmd.getId(); - Account caller = CallContext.current().getCallingAccount(); + final Long id = cmd.getId(); + final Account caller = CallContext.current().getCallingAccount(); List accountNames = cmd.getAccountNames(); List projectIds = cmd.getProjectIds(); Boolean isFeatured = cmd.isFeatured(); @@ -1284,28 +1284,31 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, //Derive the domain id from the template owner as updateTemplatePermissions is not cross domain operation Account owner = _accountMgr.getAccount(ownerId); - Domain domain = _domainDao.findById(owner.getDomainId()); + final Domain domain = _domainDao.findById(owner.getDomainId()); if ("add".equalsIgnoreCase(operation)) { - txn.start(); - for (String accountName : accountNames) { - Account permittedAccount = _accountDao.findActiveAccount(accountName, domain.getId()); - if (permittedAccount != null) { - if (permittedAccount.getId() == caller.getId()) { - continue; // don't grant permission to the template - // owner, they implicitly have permission + final List accountNamesFinal = accountNames; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + for (String accountName : accountNamesFinal) { + Account permittedAccount = _accountDao.findActiveAccount(accountName, domain.getId()); + if (permittedAccount != null) { + if (permittedAccount.getId() == caller.getId()) { + continue; // don't grant permission to the template + // owner, they implicitly have permission + } + LaunchPermissionVO existingPermission = _launchPermissionDao.findByTemplateAndAccount(id, permittedAccount.getId()); + if (existingPermission == null) { + LaunchPermissionVO launchPermission = new LaunchPermissionVO(id, permittedAccount.getId()); + _launchPermissionDao.persist(launchPermission); + } + } else { + throw new InvalidParameterValueException("Unable to grant a launch permission to account " + accountName + " in domain id=" + domain.getUuid() + + ", account not found. " + "No permissions updated, please verify the account names and retry."); + } } - LaunchPermissionVO existingPermission = _launchPermissionDao.findByTemplateAndAccount(id, permittedAccount.getId()); - if (existingPermission == null) { - LaunchPermissionVO launchPermission = new LaunchPermissionVO(id, permittedAccount.getId()); - _launchPermissionDao.persist(launchPermission); - } - } else { - txn.rollback(); - throw new InvalidParameterValueException("Unable to grant a launch permission to account " + accountName + " in domain id=" + domain.getUuid() - + ", account not found. " + "No permissions updated, please verify the account names and retry."); } - } - txn.commit(); + }); } else if ("remove".equalsIgnoreCase(operation)) { List accountIds = new ArrayList(); for (String accountName : accountNames) { @@ -1335,11 +1338,11 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (userId == null) { userId = User.UID_SYSTEM; } - long templateId = command.getEntityId(); + final long templateId = command.getEntityId(); Long volumeId = command.getVolumeId(); Long snapshotId = command.getSnapshotId(); VMTemplateVO privateTemplate = null; - Long accountId = null; + final Long accountId = null; SnapshotVO snapshot = null; VolumeVO volume = null; @@ -1428,26 +1431,31 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, zoneId, accountId, volumeId); }*/ if (privateTemplate == null) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - // template_store_ref entries should have been removed using our - // DataObject.processEvent command in case of failure, but clean - // it up here to avoid - // some leftovers which will cause removing template from - // vm_template table fail. - _tmplStoreDao.deletePrimaryRecordsForTemplate(templateId); - // Remove the template_zone_ref record - _tmpltZoneDao.deletePrimaryRecordsForTemplate(templateId); - // Remove the template record - _tmpltDao.expunge(templateId); + final VolumeVO volumeFinal = volume; + final SnapshotVO snapshotFinal = snapshot; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // template_store_ref entries should have been removed using our + // DataObject.processEvent command in case of failure, but clean + // it up here to avoid + // some leftovers which will cause removing template from + // vm_template table fail. + _tmplStoreDao.deletePrimaryRecordsForTemplate(templateId); + // Remove the template_zone_ref record + _tmpltZoneDao.deletePrimaryRecordsForTemplate(templateId); + // Remove the template record + _tmpltDao.expunge(templateId); + + // decrement resource count + if (accountId != null) { + _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template); + _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage, new Long(volumeFinal != null ? volumeFinal.getSize() + : snapshotFinal.getSize())); + } + } + }); - // decrement resource count - if (accountId != null) { - _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template); - _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage, new Long(volume != null ? volume.getSize() - : snapshot.getSize())); - } - txn.commit(); } } diff --git a/server/src/com/cloud/test/DatabaseConfig.java b/server/src/com/cloud/test/DatabaseConfig.java index 38a1abf7542..9370218be0c 100755 --- a/server/src/com/cloud/test/DatabaseConfig.java +++ b/server/src/com/cloud/test/DatabaseConfig.java @@ -57,6 +57,11 @@ import com.cloud.utils.PropertiesUtil; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionCallbackWithException; +import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn; +import com.cloud.utils.db.TransactionLegacy; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.net.NfsUtils; public class DatabaseConfig { @@ -407,34 +412,32 @@ public class DatabaseConfig { @DB protected void doConfig() { - Transaction txn = Transaction.currentTxn(); try { - - File configFile = new File(_configFileName); + final File configFile = new File(_configFileName); SAXParserFactory spfactory = SAXParserFactory.newInstance(); - SAXParser saxParser = spfactory.newSAXParser(); - DbConfigXMLHandler handler = new DbConfigXMLHandler(); + final SAXParser saxParser = spfactory.newSAXParser(); + final DbConfigXMLHandler handler = new DbConfigXMLHandler(); handler.setParent(this); - txn.start(); + Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) throws Exception { + // Save user configured values for all fields + saxParser.parse(configFile, handler); + + // Save default values for configuration fields + saveVMTemplate(); + saveRootDomain(); + saveDefaultConfiguations(); + } + }); - // Save user configured values for all fields - saxParser.parse(configFile, handler); - - // Save default values for configuration fields - saveVMTemplate(); - saveRootDomain(); - saveDefaultConfiguations(); - - txn.commit(); // Check pod CIDRs against each other, and against the guest ip network/netmask pzc.checkAllPodCidrSubnets(); - } catch (Exception ex) { System.out.print("ERROR IS"+ex); s_logger.error("error", ex); - txn.rollback(); } } @@ -486,7 +489,7 @@ public class DatabaseConfig { String insertSql1 = "INSERT INTO `host` (`id`, `name`, `status` , `type` , `private_ip_address`, `private_netmask` ,`private_mac_address` , `storage_ip_address` ,`storage_netmask`, `storage_mac_address`, `data_center_id`, `version`, `dom0_memory`, `last_ping`, `resource`, `guid`, `hypervisor_type`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; String insertSqlHostDetails = "INSERT INTO `host_details` (`id`, `host_id`, `name`, `value`) VALUES(?,?,?,?)"; String insertSql2 = "INSERT INTO `op_host` (`id`, `sequence`) VALUES(?, ?)"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql1); stmt.setLong(1, 0); @@ -563,7 +566,7 @@ public class DatabaseConfig { String hypervisor = _currentObjectParams.get("hypervisorType"); String insertSql1 = "INSERT INTO `cluster` (`id`, `name`, `data_center_id` , `pod_id`, `hypervisor_type` , `cluster_type`, `allocation_state`) VALUES (?,?,?,?,?,?,?)"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql1); stmt.setLong(1, id); @@ -599,7 +602,7 @@ public class DatabaseConfig { String insertSql1 = "INSERT INTO `storage_pool` (`id`, `name`, `uuid` , `pool_type` , `port`, `data_center_id` ,`available_bytes` , `capacity_bytes` ,`host_address`, `path`, `created`, `pod_id`,`status` , `cluster_id`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; // String insertSql2 = "INSERT INTO `netfs_storage_pool` VALUES (?,?,?)"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql1); stmt.setLong(1, id); @@ -704,7 +707,7 @@ public class DatabaseConfig { "`firewall_service_provided`, `source_nat_service_provided`, `load_balance_service_provided`, `static_nat_service_provided`," + "`port_forwarding_service_provided`, `user_data_service_provided`, `security_group_service_provided`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql1); stmt.setLong(1, id); @@ -742,7 +745,7 @@ public class DatabaseConfig { String insertSql1 = "INSERT INTO `virtual_router_providers` (`id`, `nsp_id`, `uuid` , `type` , `enabled`) " + "VALUES (?,?,?,?,?)"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql1); stmt.setLong(1, id); @@ -1030,7 +1033,7 @@ public class DatabaseConfig { String insertNWRateSql = "UPDATE `cloud`.`service_offering` SET `nw_rate` = ?"; String insertMCRateSql = "UPDATE `cloud`.`service_offering` SET `mc_rate` = ?"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt; @@ -1109,7 +1112,7 @@ public class DatabaseConfig { protected void saveUser() { // insert system account String insertSql = "INSERT INTO `cloud`.`account` (id, account_name, type, domain_id) VALUES (1, 'system', '1', '1')"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); stmt.executeUpdate(); @@ -1120,7 +1123,7 @@ public class DatabaseConfig { // insert system user insertSql = "INSERT INTO `cloud`.`user` (id, username, password, account_id, firstname, lastname, created)" + " VALUES (1, 'system', RAND(), 1, 'system', 'cloud', now())"; - txn = Transaction.currentTxn(); + txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); stmt.executeUpdate(); @@ -1159,7 +1162,7 @@ public class DatabaseConfig { // create an account for the admin user first insertSql = "INSERT INTO `cloud`.`account` (id, account_name, type, domain_id) VALUES (" + id + ", '" + username + "', '1', '1')"; - txn = Transaction.currentTxn(); + txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); stmt.executeUpdate(); @@ -1171,7 +1174,7 @@ public class DatabaseConfig { insertSql = "INSERT INTO `cloud`.`user` (id, username, password, account_id, firstname, lastname, email, created) " + "VALUES (" + id + ",'" + username + "','" + sb.toString() + "', 2, '" + firstname + "','" + lastname + "','" + email + "',now())"; - txn = Transaction.currentTxn(); + txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); stmt.executeUpdate(); @@ -1227,7 +1230,7 @@ public class DatabaseConfig { String selectSql = "SELECT name FROM cloud.configuration WHERE name = '" + name + "'"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql); ResultSet result = stmt.executeQuery(); @@ -1270,7 +1273,7 @@ public class DatabaseConfig { @DB protected void saveRootDomain() { String insertSql = "insert into `cloud`.`domain` (id, name, parent, owner, path, level) values (1, 'ROOT', NULL, 2, '/', 0)"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); stmt.executeUpdate(); @@ -1377,7 +1380,7 @@ public class DatabaseConfig { } public static String getDatabaseValueString(String selectSql, String name, String errorMsg) { - Transaction txn = Transaction.open("getDatabaseValueString"); + TransactionLegacy txn = TransactionLegacy.open("getDatabaseValueString"); PreparedStatement stmt = null; try { @@ -1399,7 +1402,7 @@ public class DatabaseConfig { } public static long getDatabaseValueLong(String selectSql, String name, String errorMsg) { - Transaction txn = Transaction.open("getDatabaseValueLong"); + TransactionLegacy txn = TransactionLegacy.open("getDatabaseValueLong"); PreparedStatement stmt = null; try { @@ -1420,7 +1423,7 @@ public class DatabaseConfig { } public static void saveSQL(String sql, String errorMsg) { - Transaction txn = Transaction.open("saveSQL"); + TransactionLegacy txn = TransactionLegacy.open("saveSQL"); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(sql); stmt.executeUpdate(); diff --git a/server/src/com/cloud/test/IPRangeConfig.java b/server/src/com/cloud/test/IPRangeConfig.java index 4b884f8c4b2..23ca1bba3ee 100755 --- a/server/src/com/cloud/test/IPRangeConfig.java +++ b/server/src/com/cloud/test/IPRangeConfig.java @@ -29,6 +29,7 @@ import java.util.Vector; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.net.NetUtils; @@ -303,7 +304,7 @@ public class IPRangeConfig { endIPLong = NetUtils.ip2Long(endIP); } - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); Vector problemIPs = null; if (type.equals("public")) { problemIPs = deletePublicIPRange(txn, startIPLong, endIPLong, vlanDbId); @@ -314,7 +315,7 @@ public class IPRangeConfig { return problemIPs; } - private Vector deletePublicIPRange(Transaction txn, long startIP, long endIP, long vlanDbId) { + private Vector deletePublicIPRange(TransactionLegacy txn, long startIP, long endIP, long vlanDbId) { String deleteSql = "DELETE FROM `cloud`.`user_ip_address` WHERE public_ip_address = ? AND vlan_id = ?"; String isPublicIPAllocatedSelectSql = "SELECT * FROM `cloud`.`user_ip_address` WHERE public_ip_address = ? AND vlan_id = ?"; @@ -349,7 +350,7 @@ public class IPRangeConfig { return problemIPs; } - private Vector deletePrivateIPRange(Transaction txn, long startIP, long endIP, long podId, long zoneId) { + private Vector deletePrivateIPRange(TransactionLegacy txn, long startIP, long endIP, long podId, long zoneId) { String deleteSql = "DELETE FROM `cloud`.`op_dc_ip_address_alloc` WHERE ip_address = ? AND pod_id = ? AND data_center_id = ?"; String isPrivateIPAllocatedSelectSql = "SELECT * FROM `cloud`.`op_dc_ip_address_alloc` WHERE ip_address = ? AND data_center_id = ? AND pod_id = ?"; @@ -429,7 +430,7 @@ public class IPRangeConfig { endIPLong = NetUtils.ip2Long(endIP); } - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); List problemIPs = null; if (type.equals("public")) { @@ -447,7 +448,7 @@ public class IPRangeConfig { return problemIPs; } - public Vector savePublicIPRange(Transaction txn, long startIP, long endIP, long zoneId, long vlanDbId, Long sourceNetworkId, long physicalNetworkId) { + public Vector savePublicIPRange(TransactionLegacy txn, long startIP, long endIP, long zoneId, long vlanDbId, Long sourceNetworkId, long physicalNetworkId) { String insertSql = "INSERT INTO `cloud`.`user_ip_address` (public_ip_address, data_center_id, vlan_db_id, mac_address, source_network_id, physical_network_id, uuid) VALUES (?, ?, ?, (select mac_address from `cloud`.`data_center` where id=?), ?, ?, ?)"; String updateSql = "UPDATE `cloud`.`data_center` set mac_address = mac_address+1 where id=?"; Vector problemIPs = new Vector(); @@ -485,7 +486,7 @@ public class IPRangeConfig { return problemIPs; } - public List savePrivateIPRange(Transaction txn, long startIP, long endIP, long podId, long zoneId) { + public List savePrivateIPRange(TransactionLegacy txn, long startIP, long endIP, long podId, long zoneId) { String insertSql = "INSERT INTO `cloud`.`op_dc_ip_address_alloc` (ip_address, data_center_id, pod_id, mac_address) VALUES (?, ?, ?, (select mac_address from `cloud`.`data_center` where id=?))"; String updateSql = "UPDATE `cloud`.`data_center` set mac_address = mac_address+1 where id=?"; Vector problemIPs = new Vector(); @@ -519,7 +520,7 @@ public class IPRangeConfig { return problemIPs; } - private Vector saveLinkLocalPrivateIPRange(Transaction txn, long startIP, long endIP, long podId, long zoneId) { + private Vector saveLinkLocalPrivateIPRange(TransactionLegacy txn, long startIP, long endIP, long podId, long zoneId) { String insertSql = "INSERT INTO `cloud`.`op_dc_link_local_ip_address_alloc` (ip_address, data_center_id, pod_id) VALUES (?, ?, ?)"; Vector problemIPs = new Vector(); diff --git a/server/src/com/cloud/test/PodZoneConfig.java b/server/src/com/cloud/test/PodZoneConfig.java index 59f8b6ce12d..628c74603cc 100644 --- a/server/src/com/cloud/test/PodZoneConfig.java +++ b/server/src/com/cloud/test/PodZoneConfig.java @@ -28,6 +28,7 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.net.NetUtils; public class PodZoneConfig { @@ -148,7 +149,7 @@ public class PodZoneConfig { HashMap> currentPodCidrSubnets = new HashMap>(); String selectSql = "SELECT id, cidr_address, cidr_size FROM host_pod_ref WHERE data_center_id=" + dcId; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql); ResultSet rs = stmt.executeQuery(); @@ -363,7 +364,7 @@ public class PodZoneConfig { String insertVnet = "INSERT INTO `cloud`.`op_dc_vnet_alloc` (vnet, data_center_id, physical_network_id) VALUES ( ?, ?, ?)"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertVnet); for (int i = begin; i <= end; i++) { @@ -483,7 +484,7 @@ public class PodZoneConfig { Vector allZoneIDs = new Vector(); String selectSql = "SELECT id FROM data_center"; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql); ResultSet rs = stmt.executeQuery(); diff --git a/server/src/com/cloud/usage/UsageServiceImpl.java b/server/src/com/cloud/usage/UsageServiceImpl.java index 2ffb01d3bce..d16d36d8a1f 100755 --- a/server/src/com/cloud/usage/UsageServiceImpl.java +++ b/server/src/com/cloud/usage/UsageServiceImpl.java @@ -34,11 +34,11 @@ import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.usage.UsageService; import org.apache.cloudstack.usage.UsageTypes; - import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.configuration.Config; +import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; @@ -54,6 +54,7 @@ import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.Filter; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value = { UsageService.class }) @@ -86,7 +87,7 @@ public class UsageServiceImpl extends ManagerBase implements UsageService, Manag @Override public boolean generateUsageRecords(GenerateUsageRecordsCmd cmd) { - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); try { UsageJobVO immediateJob = _usageJobDao.getNextImmediateJob(); if (immediateJob == null) { @@ -104,7 +105,7 @@ public class UsageServiceImpl extends ManagerBase implements UsageService, Manag txn.close(); // switch back to VMOPS_DB - Transaction swap = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy swap = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); swap.close(); } return true; @@ -150,7 +151,8 @@ public class UsageServiceImpl extends ManagerBase implements UsageService, Manag } boolean isAdmin = false; - + boolean isDomainAdmin = false; + //If accountId couldn't be found using accountName and domainId, get it from userContext if(accountId == null){ accountId = caller.getId(); @@ -158,6 +160,8 @@ public class UsageServiceImpl extends ManagerBase implements UsageService, Manag //If account_id or account_name is explicitly mentioned, list records for the specified account only even if the caller is of type admin if(caller.getType() == Account.ACCOUNT_TYPE_ADMIN){ isAdmin = true; + } else if(caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN){ + isDomainAdmin = true; } s_logger.debug("Account details not available. Using userContext accountId: " + accountId); } @@ -179,10 +183,20 @@ public class UsageServiceImpl extends ManagerBase implements UsageService, Manag SearchCriteria sc = _usageDao.createSearchCriteria(); - if (accountId != -1 && accountId != Account.ACCOUNT_ID_SYSTEM && !isAdmin) { + if (accountId != -1 && accountId != Account.ACCOUNT_ID_SYSTEM && !isAdmin && !isDomainAdmin) { sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId); } + if (isDomainAdmin) { + SearchCriteria sdc = _domainDao.createSearchCriteria(); + sdc.addOr("path", SearchCriteria.Op.LIKE, _domainDao.findById(caller.getDomainId()).getPath() + "%"); + List domains = _domainDao.search(sdc, null); + List domainIds = new ArrayList(); + for(DomainVO domain:domains) + domainIds.add(domain.getId()); + sc.addAnd("domainId", SearchCriteria.Op.IN, domainIds.toArray()); + } + if (domainId != null) { sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId); } @@ -199,14 +213,14 @@ public class UsageServiceImpl extends ManagerBase implements UsageService, Manag } List usageRecords = null; - Transaction txn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); try { usageRecords = _usageDao.searchAllRecords(sc, usageFilter); } finally { txn.close(); // switch back to VMOPS_DB - Transaction swap = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy swap = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); swap.close(); } diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index ae93548b7e2..27fd66a4b9b 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -136,6 +136,9 @@ import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.vm.InstanceGroupVO; @@ -480,22 +483,23 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } @DB - public void updateLoginAttempts(Long id, int attempts, boolean toDisable) { - Transaction txn = Transaction.currentTxn(); - txn.start(); + public void updateLoginAttempts(final Long id, final int attempts, final boolean toDisable) { try { - UserAccountVO user = null; - user = _userAccountDao.lockRow(id, true); - user.setLoginAttempts(attempts); - if(toDisable) { - user.setState(State.disabled.toString()); - } - _userAccountDao.update(id, user); - txn.commit(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + UserAccountVO user = null; + user = _userAccountDao.lockRow(id, true); + user.setLoginAttempts(attempts); + if(toDisable) { + user.setState(State.disabled.toString()); + } + _userAccountDao.update(id, user); + } + }); } catch (Exception e) { s_logger.error("Failed to update login attempts for user with id " + id ); } - txn.close(); } private boolean doSetUserStatus(long userId, State state) { @@ -697,7 +701,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } } - if (vpcsDeleted) { + if (networksDeleted && vpcsDeleted) { // release ip addresses belonging to the account List ipsToRelease = _ipAddressDao.listByAccount(accountId); for (IpAddress ip : ipsToRelease) { @@ -859,8 +863,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account"), @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User") }) - public UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, - Long domainId, String networkDomain, Map details, String accountUUID, String userUUID) { + public UserAccount createUserAccount(final String userName, final String password, final String firstName, final String lastName, final String email, final String timezone, String accountName, final short accountType, + Long domainId, final String networkDomain, final Map details, String accountUUID, final String userUUID) { if (accountName == null) { accountName = userName; @@ -902,31 +906,40 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } } - Transaction txn = Transaction.currentTxn(); - txn.start(); + final String accountNameFinal = accountName; + final Long domainIdFinal = domainId; + final String accountUUIDFinal = accountUUID; + Pair pair = Transaction.execute(new TransactionCallback>() { + @Override + public Pair doInTransaction(TransactionStatus status) { + // create account + String accountUUID = accountUUIDFinal; + if(accountUUID == null){ + accountUUID = UUID.randomUUID().toString(); + } + AccountVO account = createAccount(accountNameFinal, accountType, domainIdFinal, networkDomain, details, accountUUID); + long accountId = account.getId(); + + // create the first user for the account + UserVO user = createUser(accountId, userName, password, firstName, lastName, email, timezone, userUUID); + + if (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { + // set registration token + byte[] bytes = (domainIdFinal + accountNameFinal + userName + System.currentTimeMillis()).getBytes(); + String registrationToken = UUID.nameUUIDFromBytes(bytes).toString(); + user.setRegistrationToken(registrationToken); + } + return new Pair(user.getId(), account); + } + }); - // create account - if(accountUUID == null){ - accountUUID = UUID.randomUUID().toString(); - } - AccountVO account = createAccount(accountName, accountType, domainId, networkDomain, details, accountUUID); - long accountId = account.getId(); - - // create the first user for the account - UserVO user = createUser(accountId, userName, password, firstName, lastName, email, timezone, userUUID); - - if (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { - // set registration token - byte[] bytes = (domainId + accountName + userName + System.currentTimeMillis()).getBytes(); - String registrationToken = UUID.nameUUIDFromBytes(bytes).toString(); - user.setRegistrationToken(registrationToken); - } - txn.commit(); + long userId = pair.first(); + Account account = pair.second(); CallContext.current().putContextParameter(Account.class, account.getUuid()); //check success - return _userAccountDao.findById(user.getId()); + return _userAccountDao.findById(userId); } @Override @@ -1132,12 +1145,12 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @Override @DB @ActionEvent(eventType = EventTypes.EVENT_USER_ENABLE, eventDescription = "enabling User") - public UserAccount enableUser(long userId) { + public UserAccount enableUser(final long userId) { Account caller = CallContext.current().getCallingAccount(); // Check if user exists in the system - User user = _userDao.findById(userId); + final User user = _userDao.findById(userId); if (user == null || user.getRemoved() != null) { throw new InvalidParameterValueException("Unable to find active user by id " + userId); } @@ -1155,15 +1168,18 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M checkAccess(caller, null, true, account); - Transaction txn = Transaction.currentTxn(); - txn.start(); + boolean success = Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + boolean success = doSetUserStatus(userId, State.enabled); + + // make sure the account is enabled too + success = success && enableAccount(user.getAccountId()); + + return success; + } + }); - boolean success = doSetUserStatus(userId, State.enabled); - - // make sure the account is enabled too - success = success && enableAccount(user.getAccountId()); - - txn.commit(); if (success) { // whenever the user is successfully enabled, reset the login attempts to zero @@ -1390,7 +1406,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M String accountName = cmd.getAccountName(); String newAccountName = cmd.getNewName(); String networkDomain = cmd.getNetworkDomain(); - Map details = cmd.getDetails(); + final Map details = cmd.getDetails(); boolean success = false; Account account = null; @@ -1434,7 +1450,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } } - AccountVO acctForUpdate = _accountDao.findById(account.getId()); + final AccountVO acctForUpdate = _accountDao.findById(account.getId()); acctForUpdate.setAccountName(newAccountName); if (networkDomain != null) { @@ -1445,16 +1461,19 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } } - Transaction txn = Transaction.currentTxn(); - txn.start(); + final Account accountFinal = account; + success = Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + boolean success = _accountDao.update(accountFinal.getId(), acctForUpdate); - success = _accountDao.update(account.getId(), acctForUpdate); + if (details != null && success) { + _accountDetailsDao.update(accountFinal.getId(), details); + } - if (details != null && success) { - _accountDetailsDao.update(account.getId(), details); - } - - txn.commit(); + return success; + } + }); if (success) { CallContext.current().putContextParameter(Account.class, account.getUuid()); @@ -1706,7 +1725,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @Override @DB - public AccountVO createAccount(String accountName, short accountType, Long domainId, String networkDomain, Map details, String uuid) { + public AccountVO createAccount(final String accountName, final short accountType, final Long domainId, final String networkDomain, final Map details, final String uuid) { // Validate domain Domain domain = _domainMgr.getDomain(domainId); if (domain == null) { @@ -1747,29 +1766,30 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } // Create the account - Transaction txn = Transaction.currentTxn(); - txn.start(); + return Transaction.execute(new TransactionCallback() { + @Override + public AccountVO doInTransaction(TransactionStatus status) { + AccountVO account = _accountDao.persist(new AccountVO(accountName, domainId, networkDomain, accountType, uuid)); + + if (account == null) { + throw new CloudRuntimeException("Failed to create account name " + accountName + " in domain id=" + domainId); + } + + Long accountId = account.getId(); + + if (details != null) { + _accountDetailsDao.persist(accountId, details); + } + + // Create resource count records for the account + _resourceCountDao.createResourceCounts(accountId, ResourceLimit.ResourceOwnerType.Account); + + // Create default security group + _networkGroupMgr.createDefaultSecurityGroup(accountId); - AccountVO account = _accountDao.persist(new AccountVO(accountName, domainId, networkDomain, accountType, uuid)); - - if (account == null) { - throw new CloudRuntimeException("Failed to create account name " + accountName + " in domain id=" + domainId); - } - - Long accountId = account.getId(); - - if (details != null) { - _accountDetailsDao.persist(accountId, details); - } - - // Create resource count records for the account - _resourceCountDao.createResourceCounts(accountId, ResourceLimit.ResourceOwnerType.Account); - - // Create default security group - _networkGroupMgr.createDefaultSecurityGroup(accountId); - txn.commit(); - - return account; + return account; + } + }); } protected UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone, String userUUID) { @@ -2006,7 +2026,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M @Override @DB @ActionEvent(eventType = EventTypes.EVENT_REGISTER_FOR_SECRET_API_KEY, eventDescription = "register for the developer API keys") public String[] createApiKeyAndSecretKey(RegisterCmd cmd) { - Long userId = cmd.getId(); + final Long userId = cmd.getId(); User user = getUserIncludingRemoved(userId); if (user == null) { @@ -2019,12 +2039,14 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } // generate both an api key and a secret key, update the user table with the keys, return the keys to the user - String[] keys = new String[2]; - Transaction txn = Transaction.currentTxn(); - txn.start(); - keys[0] = createUserApiKey(userId); - keys[1] = createUserSecretKey(userId); - txn.commit(); + final String[] keys = new String[2]; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + keys[0] = createUserApiKey(userId); + keys[1] = createUserSecretKey(userId); + } + }); return keys; } diff --git a/server/src/com/cloud/user/DomainManagerImpl.java b/server/src/com/cloud/user/DomainManagerImpl.java index b885c48eda8..294214826e2 100644 --- a/server/src/com/cloud/user/DomainManagerImpl.java +++ b/server/src/com/cloud/user/DomainManagerImpl.java @@ -26,7 +26,6 @@ import javax.inject.Inject; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; - import org.apache.cloudstack.api.command.admin.domain.ListDomainChildrenCmd; import org.apache.cloudstack.api.command.admin.domain.ListDomainsCmd; import org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd; @@ -65,6 +64,9 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.vm.ReservationContext; @@ -158,7 +160,7 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom @Override @DB - public Domain createDomain(String name, Long parentId, Long ownerId, String networkDomain, String domainUUID) { + public Domain createDomain(final String name, final Long parentId, final Long ownerId, final String networkDomain, String domainUUID) { // Verify network domain if (networkDomain != null) { if (!NetUtils.verifyDomainName(networkDomain)) { @@ -181,11 +183,16 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom domainUUID = UUID.randomUUID().toString(); } - Transaction txn = Transaction.currentTxn(); - txn.start(); - DomainVO domain = _domainDao.create(new DomainVO(name, ownerId, parentId, networkDomain, domainUUID)); - _resourceCountDao.createResourceCounts(domain.getId(), ResourceLimit.ResourceOwnerType.Domain); - txn.commit(); + final String domainUUIDFinal = domainUUID; + DomainVO domain = Transaction.execute(new TransactionCallback() { + @Override + public DomainVO doInTransaction(TransactionStatus status) { + DomainVO domain = _domainDao.create(new DomainVO(name, ownerId, parentId, networkDomain, domainUUIDFinal)); + _resourceCountDao.createResourceCounts(domain.getId(), ResourceLimit.ResourceOwnerType.Domain); + return domain; + } + }); + CallContext.current().putContextParameter(Domain.class, domain.getUuid()); return domain; } @@ -544,12 +551,12 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom @ActionEvent(eventType = EventTypes.EVENT_DOMAIN_UPDATE, eventDescription = "updating Domain") @DB public DomainVO updateDomain(UpdateDomainCmd cmd) { - Long domainId = cmd.getId(); - String domainName = cmd.getDomainName(); - String networkDomain = cmd.getNetworkDomain(); + final Long domainId = cmd.getId(); + final String domainName = cmd.getDomainName(); + final String networkDomain = cmd.getNetworkDomain(); // check if domain exists in the system - DomainVO domain = _domainDao.findById(domainId); + final DomainVO domain = _domainDao.findById(domainId); if (domain == null) { InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find domain with specified domain id"); ex.addProxyObject(domainId.toString(), "domainId"); @@ -587,27 +594,28 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom } } - Transaction txn = Transaction.currentTxn(); - - txn.start(); - - if (domainName != null) { - String updatedDomainPath = getUpdatedDomainPath(domain.getPath(), domainName); - updateDomainChildren(domain, updatedDomainPath); - domain.setName(domainName); - domain.setPath(updatedDomainPath); - } - - if (networkDomain != null) { - if (networkDomain.isEmpty()) { - domain.setNetworkDomain(null); - } else { - domain.setNetworkDomain(networkDomain); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + if (domainName != null) { + String updatedDomainPath = getUpdatedDomainPath(domain.getPath(), domainName); + updateDomainChildren(domain, updatedDomainPath); + domain.setName(domainName); + domain.setPath(updatedDomainPath); + } + + if (networkDomain != null) { + if (networkDomain.isEmpty()) { + domain.setNetworkDomain(null); + } else { + domain.setNetworkDomain(networkDomain); + } + } + _domainDao.update(domainId, domain); + CallContext.current().putContextParameter(Domain.class, domain.getUuid()); } - } - _domainDao.update(domainId, domain); - CallContext.current().putContextParameter(Domain.class, domain.getUuid()); - txn.commit(); + }); + return _domainDao.findById(domainId); diff --git a/server/src/com/cloud/uuididentity/dao/IdentityDao.java b/server/src/com/cloud/uuididentity/dao/IdentityDao.java index e9149a0fe63..be412f3c8a9 100644 --- a/server/src/com/cloud/uuididentity/dao/IdentityDao.java +++ b/server/src/com/cloud/uuididentity/dao/IdentityDao.java @@ -17,7 +17,7 @@ package com.cloud.uuididentity.dao; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.utils.Pair; import com.cloud.utils.db.GenericDao; @@ -31,5 +31,5 @@ public interface IdentityDao extends GenericDao { * @param resourceType TODO * @return */ - Pair getAccountDomainInfo(String tableName, Long identityId, TaggedResourceType resourceType); + Pair getAccountDomainInfo(String tableName, Long identityId, ResourceObjectType resourceType); } diff --git a/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java b/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java index 18b7d8be186..9c54fb77048 100644 --- a/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java +++ b/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java @@ -28,11 +28,12 @@ import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.utils.Pair; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={IdentityDao.class}) @@ -48,7 +49,7 @@ public class IdentityDaoImpl extends GenericDaoBase implements assert(identityString != null); PreparedStatement pstmt = null; - Transaction txn = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); try { try { try { @@ -96,11 +97,11 @@ public class IdentityDaoImpl extends GenericDaoBase implements @DB @Override - public Pair getAccountDomainInfo(String tableName, Long identityId, TaggedResourceType resourceType) { + public Pair getAccountDomainInfo(String tableName, Long identityId, ResourceObjectType resourceType) { assert(tableName != null); PreparedStatement pstmt = null; - Transaction txn = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); try { Long domainId = null; Long accountId = null; @@ -120,7 +121,7 @@ public class IdentityDaoImpl extends GenericDaoBase implements //get accountId try { String account = "account_id"; - if (resourceType == TaggedResourceType.Project) { + if (resourceType == ResourceObjectType.Project) { account = "project_account_id"; } pstmt = txn.prepareAutoCloseStatement(String.format("SELECT " + account + " FROM `%s` WHERE id=?", tableName)); @@ -146,7 +147,7 @@ public class IdentityDaoImpl extends GenericDaoBase implements assert(identityString != null); PreparedStatement pstmt = null; - Transaction txn = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); try { try { pstmt = txn.prepareAutoCloseStatement( @@ -187,7 +188,7 @@ public class IdentityDaoImpl extends GenericDaoBase implements assert(tableName != null); List l = getNullUuidRecords(tableName); - Transaction txn = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); try { try { txn.start(); @@ -209,7 +210,7 @@ public class IdentityDaoImpl extends GenericDaoBase implements List l = new ArrayList(); PreparedStatement pstmt = null; - Transaction txn = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); try { try { pstmt = txn.prepareAutoCloseStatement( @@ -231,7 +232,7 @@ public class IdentityDaoImpl extends GenericDaoBase implements @DB void setInitialUuid(String tableName, long id) throws SQLException { - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmtUpdate = null; pstmtUpdate = txn.prepareAutoCloseStatement( diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 6e879161276..e97dfd798a1 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -35,15 +35,16 @@ import javax.naming.ConfigurationException; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; - import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.affinity.AffinityGroupService; import org.apache.cloudstack.affinity.AffinityGroupVO; import org.apache.cloudstack.affinity.dao.AffinityGroupDao; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; +import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseCmd.HTTPMethod; import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd; +import org.apache.cloudstack.api.command.admin.vm.ExpungeVMCmd; import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd; import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd; import org.apache.cloudstack.api.command.user.vm.DeployVMCmd; @@ -75,6 +76,8 @@ import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; @@ -239,8 +242,13 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackWithException; +import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.ExecutionException; import com.cloud.utils.fsm.NoTransitionException; @@ -1375,11 +1383,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir public UserVm recoverVirtualMachine(RecoverVMCmd cmd) throws ResourceAllocationException, CloudRuntimeException { - Long vmId = cmd.getId(); + final Long vmId = cmd.getId(); Account caller = CallContext.current().getCallingAccount(); // Verify input parameters - UserVmVO vm = _vmDao.findById(vmId.longValue()); + final UserVmVO vm = _vmDao.findById(vmId.longValue()); if (vm == null) { throw new InvalidParameterValueException( @@ -1409,68 +1417,70 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir s_logger.debug("Recovering vm " + vmId); } - Transaction txn = Transaction.currentTxn(); - AccountVO account = null; - txn.start(); - - account = _accountDao.lockRow(vm.getAccountId(), true); - - // if the account is deleted, throw error - if (account.getRemoved() != null) { - throw new CloudRuntimeException( - "Unable to recover VM as the account is deleted"); - } - - // Get serviceOffering for Virtual Machine - ServiceOfferingVO serviceOffering = _serviceOfferingDao.findById(vm.getServiceOfferingId()); - - // First check that the maximum number of UserVMs, CPU and Memory limit for the given - // accountId will not be exceeded - resourceLimitCheck(account, new Long(serviceOffering.getCpu()), new Long(serviceOffering.getRamSize())); - - _haMgr.cancelDestroy(vm, vm.getHostId()); - - try { - if (!_itMgr.stateTransitTo(vm, - VirtualMachine.Event.RecoveryRequested, null)) { - s_logger.debug("Unable to recover the vm because it is not in the correct state: " - + vmId); - throw new InvalidParameterValueException( - "Unable to recover the vm because it is not in the correct state: " + Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) throws ResourceAllocationException { + + Account account = _accountDao.lockRow(vm.getAccountId(), true); + + // if the account is deleted, throw error + if (account.getRemoved() != null) { + throw new CloudRuntimeException( + "Unable to recover VM as the account is deleted"); + } + + // Get serviceOffering for Virtual Machine + ServiceOfferingVO serviceOffering = _serviceOfferingDao.findById(vm.getServiceOfferingId()); + + // First check that the maximum number of UserVMs, CPU and Memory limit for the given + // accountId will not be exceeded + resourceLimitCheck(account, new Long(serviceOffering.getCpu()), new Long(serviceOffering.getRamSize())); + + _haMgr.cancelDestroy(vm, vm.getHostId()); + + try { + if (!_itMgr.stateTransitTo(vm, + VirtualMachine.Event.RecoveryRequested, null)) { + s_logger.debug("Unable to recover the vm because it is not in the correct state: " + vmId); - } - } catch (NoTransitionException e) { - throw new InvalidParameterValueException( - "Unable to recover the vm because it is not in the correct state: " - + vmId); - } - - // Recover the VM's disks - List volumes = _volsDao.findByInstance(vmId); - for (VolumeVO volume : volumes) { - if (volume.getVolumeType().equals(Volume.Type.ROOT)) { - // Create an event - Long templateId = volume.getTemplateId(); - Long diskOfferingId = volume.getDiskOfferingId(); - Long offeringId = null; - if (diskOfferingId != null) { - DiskOfferingVO offering = _diskOfferingDao - .findById(diskOfferingId); - if (offering != null - && (offering.getType() == DiskOfferingVO.Type.Disk)) { - offeringId = offering.getId(); + throw new InvalidParameterValueException( + "Unable to recover the vm because it is not in the correct state: " + + vmId); + } + } catch (NoTransitionException e) { + throw new InvalidParameterValueException( + "Unable to recover the vm because it is not in the correct state: " + + vmId); + } + + // Recover the VM's disks + List volumes = _volsDao.findByInstance(vmId); + for (VolumeVO volume : volumes) { + if (volume.getVolumeType().equals(Volume.Type.ROOT)) { + // Create an event + Long templateId = volume.getTemplateId(); + Long diskOfferingId = volume.getDiskOfferingId(); + Long offeringId = null; + if (diskOfferingId != null) { + DiskOfferingVO offering = _diskOfferingDao + .findById(diskOfferingId); + if (offering != null + && (offering.getType() == DiskOfferingVO.Type.Disk)) { + offeringId = offering.getId(); + } + } + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), + volume.getDataCenterId(), volume.getId(), volume.getName(), offeringId, templateId, + volume.getSize(), Volume.class.getName(), volume.getUuid()); } } - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), - volume.getDataCenterId(), volume.getId(), volume.getName(), offeringId, templateId, - volume.getSize(), Volume.class.getName(), volume.getUuid()); + + //Update Resource Count for the given account + resourceCountIncrement(account.getId(), new Long(serviceOffering.getCpu()), + new Long(serviceOffering.getRamSize())); } - } + }); - //Update Resource Count for the given account - resourceCountIncrement(account.getId(), new Long(serviceOffering.getCpu()), - new Long(serviceOffering.getRamSize())); - txn.commit(); return _vmDao.findById(vmId); } @@ -1934,7 +1944,30 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir @ActionEvent(eventType = EventTypes.EVENT_VM_DESTROY, eventDescription = "destroying Vm", async = true) public UserVm destroyVm(DestroyVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException { - return destroyVm(cmd.getId()); + CallContext ctx = CallContext.current(); + long vmId = cmd.getId(); + boolean expunge = cmd.getExpunge(); + + if (!_accountMgr.isAdmin(ctx.getCallingAccount().getType()) && expunge) { + throw new PermissionDeniedException("Parameter " + ApiConstants.EXPUNGE + " can be passed by Admin only"); + } + + UserVm destroyedVm = destroyVm(vmId); + if (expunge) { + UserVmVO vm = _vmDao.findById(vmId); + if (!expunge(vm, ctx.getCallingUserId(), ctx.getCallingAccount())) { + throw new CloudRuntimeException("Failed to expunge vm " + destroyedVm); + } + } + + return destroyedVm; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_VM_EXPUNGE, eventDescription = "expunging Vm", async = true) + public UserVm expungeVm(ExpungeVMCmd cmd) + throws ResourceUnavailableException, ConcurrentOperationException { + return expungeVm(cmd.getId()); } @Override @@ -1965,8 +1998,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir @DB protected InstanceGroupVO createVmGroup(String groupName, long accountId) { Account account = null; - final Transaction txn = Transaction.currentTxn(); - txn.start(); try { account = _accountDao.acquireInLockTable(accountId); // to ensure // duplicate @@ -1989,7 +2020,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir if (account != null) { _accountDao.releaseFromLockTable(accountId); } - txn.commit(); } } @@ -2032,7 +2062,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir @Override @DB - public boolean addInstanceToGroup(long userVmId, String groupName) { + public boolean addInstanceToGroup(final long userVmId, String groupName) { UserVmVO vm = _vmDao.findById(userVmId); InstanceGroupVO group = _vmGroupDao.findByAccountAndName( @@ -2043,43 +2073,47 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } if (group != null) { - final Transaction txn = Transaction.currentTxn(); - txn.start(); UserVm userVm = _vmDao.acquireInLockTable(userVmId); if (userVm == null) { s_logger.warn("Failed to acquire lock on user vm id=" + userVmId); } try { - // don't let the group be deleted when we are assigning vm to - // it. - InstanceGroupVO ngrpLock = _vmGroupDao.lockRow(group.getId(), - false); - if (ngrpLock == null) { - s_logger.warn("Failed to acquire lock on vm group id=" - + group.getId() + " name=" + group.getName()); - txn.rollback(); - return false; - } + final InstanceGroupVO groupFinal = group; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // don't let the group be deleted when we are assigning vm to + // it. + InstanceGroupVO ngrpLock = _vmGroupDao.lockRow(groupFinal.getId(), + false); + if (ngrpLock == null) { + s_logger.warn("Failed to acquire lock on vm group id=" + + groupFinal.getId() + " name=" + groupFinal.getName()); + throw new CloudRuntimeException("Failed to acquire lock on vm group id=" + + groupFinal.getId() + " name=" + groupFinal.getName()); + } + + // Currently don't allow to assign a vm to more than one group + if (_groupVMMapDao.listByInstanceId(userVmId) != null) { + // Delete all mappings from group_vm_map table + List groupVmMaps = _groupVMMapDao + .listByInstanceId(userVmId); + for (InstanceGroupVMMapVO groupMap : groupVmMaps) { + SearchCriteria sc = _groupVMMapDao + .createSearchCriteria(); + sc.addAnd("instanceId", SearchCriteria.Op.EQ, + groupMap.getInstanceId()); + _groupVMMapDao.expunge(sc); + } + } + InstanceGroupVMMapVO groupVmMapVO = new InstanceGroupVMMapVO( + groupFinal.getId(), userVmId); + _groupVMMapDao.persist(groupVmMapVO); - // Currently don't allow to assign a vm to more than one group - if (_groupVMMapDao.listByInstanceId(userVmId) != null) { - // Delete all mappings from group_vm_map table - List groupVmMaps = _groupVMMapDao - .listByInstanceId(userVmId); - for (InstanceGroupVMMapVO groupMap : groupVmMaps) { - SearchCriteria sc = _groupVMMapDao - .createSearchCriteria(); - sc.addAnd("instanceId", SearchCriteria.Op.EQ, - groupMap.getInstanceId()); - _groupVMMapDao.expunge(sc); } - } - InstanceGroupVMMapVO groupVmMapVO = new InstanceGroupVMMapVO( - group.getId(), userVmId); - _groupVMMapDao.persist(groupVmMapVO); + }); - txn.commit(); return true; } finally { if (userVm != null) { @@ -2442,7 +2476,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } @DB - protected UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, String hostName, String displayName, Account owner, Long diskOfferingId, + protected UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate tmplt, String hostName, String displayName, Account owner, Long diskOfferingId, Long diskSize, List networkList, List securityGroupIdList, String group, HTTPMethod httpmethod, String userData, String sshKeyPair, HypervisorType hypervisor, Account caller, Map requestedIps, IpAddresses defaultIps, Boolean isDisplayVmEnabled, String keyboard, List affinityGroupIdList) @@ -2454,7 +2488,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir throw new PermissionDeniedException( "The owner of vm to deploy is disabled: " + owner); } - + VMTemplateVO template = _templateDao.findById(tmplt.getId()); + if (template != null) { + _templateDao.loadDetails(template); + } + long accountId = owner.getId(); assert !(requestedIps != null && (defaultIps.getIp4Address() != null || defaultIps.getIp6Address() != null)) : "requestedIp list and defaultNetworkIp should never be specified together"; @@ -2744,98 +2782,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir hypervisorType = template.getHypervisorType(); } - Transaction txn = Transaction.currentTxn(); - txn.start(); - UserVmVO vm = new UserVmVO(id, instanceName, displayName, - template.getId(), hypervisorType, template.getGuestOSId(), - offering.getOfferHA(), offering.getLimitCpuUse(), - owner.getDomainId(), owner.getId(), offering.getId(), userData, - hostName, diskOfferingId); - vm.setUuid(uuidName); - vm.setDynamicallyScalable(template.isDynamicallyScalable()); - if (sshPublicKey != null) { - vm.setDetail("SSH.PublicKey", sshPublicKey); - } - - if (keyboard != null && !keyboard.isEmpty()) - vm.setDetail(VmDetailConstants.KEYBOARD, keyboard); - - if (isIso) { - vm.setIsoId(template.getId()); - } - - if(isDisplayVmEnabled != null){ - if(!_accountMgr.isRootAdmin(caller.getType())){ - throw new PermissionDeniedException( "Cannot update parameter displayvm, only admin permitted "); - } - vm.setDisplayVm(isDisplayVmEnabled); - }else { - vm.setDisplayVm(true); - } - - // If hypervisor is vSphere, check for clone type setting. - if (hypervisorType.equals(HypervisorType.VMware)) { - // retrieve clone flag. - UserVmCloneType cloneType = UserVmCloneType.linked; - String value = _configDao.getValue(Config.VmwareCreateFullClone.key()); - if (value != null) { - if (Boolean.parseBoolean(value) == true) - cloneType = UserVmCloneType.full; - } - UserVmCloneSettingVO vmCloneSettingVO = new UserVmCloneSettingVO(id, cloneType.toString()); - _vmCloneSettingDao.persist(vmCloneSettingVO); - } - - long guestOSId = template.getGuestOSId(); - GuestOSVO guestOS = _guestOSDao.findById(guestOSId); - long guestOSCategoryId = guestOS.getCategoryId(); - GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao.findById(guestOSCategoryId); - - - // If hypervisor is vSphere and OS is OS X, set special settings. - if (hypervisorType.equals(HypervisorType.VMware)) { - if (guestOS.getDisplayName().toLowerCase().contains("apple mac os")){ - vm.setDetail("smc.present", "TRUE"); - vm.setDetail(VmDetailConstants.ROOK_DISK_CONTROLLER, "scsi"); - vm.setDetail("firmware", "efi"); - s_logger.info("guestOS is OSX : overwrite root disk controller to scsi, use smc and efi"); - } - } - - _vmDao.persist(vm); - _vmDao.saveDetails(vm); - - s_logger.debug("Allocating in the DB for vm"); - DataCenterDeployment plan = new DataCenterDeployment(zone.getId()); - - List computeTags = new ArrayList(); - computeTags.add(offering.getHostTag()); - - List rootDiskTags = new ArrayList(); - rootDiskTags.add(offering.getTags()); - - if(isIso){ - VirtualMachineEntity vmEntity = _orchSrvc.createVirtualMachineFromScratch(vm.getUuid(), Long.toString(owner.getAccountId()), vm.getIsoId().toString(), hostName, displayName, hypervisor.name(), guestOSCategory.getName(), offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags, networkNicMap, plan); - }else { - VirtualMachineEntity vmEntity = _orchSrvc.createVirtualMachine(vm.getUuid(), Long.toString(owner.getAccountId()), Long.toString(template.getId()), hostName, displayName, hypervisor.name(), offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags, networkNicMap, plan); - } - - - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Successfully allocated DB entry for " + vm); - } - CallContext.current().setEventDetails("Vm Id: " + vm.getId()); - - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), - vm.getHostName(), offering.getId(), template.getId(), hypervisorType.toString(), - VirtualMachine.class.getName(), vm.getUuid()); - - //Update Resource Count for the given account - resourceCountIncrement(accountId, new Long(offering.getCpu()), - new Long(offering.getRamSize())); - - txn.commit(); + UserVmVO vm = commitUserVm(zone, template, hostName, displayName, owner, diskOfferingId, diskSize, userData, + hypervisor, caller, isDisplayVmEnabled, keyboard, accountId, offering, isIso, sshPublicKey, + networkNicMap, id, instanceName, uuidName, hypervisorType); // Assign instance to the group try { @@ -2860,6 +2809,113 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir return vm; } + private UserVmVO commitUserVm(final DataCenter zone, final VirtualMachineTemplate template, final String hostName, + final String displayName, final Account owner, final Long diskOfferingId, final Long diskSize, final String userData, + final HypervisorType hypervisor, final Account caller, final Boolean isDisplayVmEnabled, final String keyboard, final long accountId, + final ServiceOfferingVO offering, final boolean isIso, final String sshPublicKey, + final LinkedHashMap networkNicMap, final long id, final String instanceName, final String uuidName, + final HypervisorType hypervisorType) throws InsufficientCapacityException { + return Transaction.execute(new TransactionCallbackWithException() { + @Override + public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCapacityException { + UserVmVO vm = new UserVmVO(id, instanceName, displayName, + template.getId(), hypervisorType, template.getGuestOSId(), + offering.getOfferHA(), offering.getLimitCpuUse(), + owner.getDomainId(), owner.getId(), offering.getId(), userData, + hostName, diskOfferingId); + vm.setUuid(uuidName); + vm.setDynamicallyScalable(template.isDynamicallyScalable()); + if (sshPublicKey != null) { + vm.setDetail("SSH.PublicKey", sshPublicKey); + } + + if (keyboard != null && !keyboard.isEmpty()) + vm.setDetail(VmDetailConstants.KEYBOARD, keyboard); + + if (isIso) { + vm.setIsoId(template.getId()); + } + + if(isDisplayVmEnabled != null){ + if(!_accountMgr.isRootAdmin(caller.getType())){ + throw new PermissionDeniedException( "Cannot update parameter displayvm, only admin permitted "); + } + vm.setDisplayVm(isDisplayVmEnabled); + }else { + vm.setDisplayVm(true); + } + + // If hypervisor is vSphere, check for clone type setting. + if (hypervisorType.equals(HypervisorType.VMware)) { + // retrieve clone flag. + UserVmCloneType cloneType = UserVmCloneType.linked; + String value = _configDao.getValue(Config.VmwareCreateFullClone.key()); + if (value != null) { + if (Boolean.parseBoolean(value) == true) + cloneType = UserVmCloneType.full; + } + UserVmCloneSettingVO vmCloneSettingVO = new UserVmCloneSettingVO(id, cloneType.toString()); + _vmCloneSettingDao.persist(vmCloneSettingVO); + } + + long guestOSId = template.getGuestOSId(); + GuestOSVO guestOS = _guestOSDao.findById(guestOSId); + long guestOSCategoryId = guestOS.getCategoryId(); + GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao.findById(guestOSCategoryId); + + + // If hypervisor is vSphere and OS is OS X, set special settings. + if (hypervisorType.equals(HypervisorType.VMware)) { + if (guestOS.getDisplayName().toLowerCase().contains("apple mac os")){ + vm.setDetail("smc.present", "TRUE"); + vm.setDetail(VmDetailConstants.ROOK_DISK_CONTROLLER, "scsi"); + vm.setDetail("firmware", "efi"); + s_logger.info("guestOS is OSX : overwrite root disk controller to scsi, use smc and efi"); + } + } + + Map details = template.getDetails(); + if ( details != null && !details.isEmpty() ) { + vm.details.putAll(details); + } + + _vmDao.persist(vm); + _vmDao.saveDetails(vm); + + s_logger.debug("Allocating in the DB for vm"); + DataCenterDeployment plan = new DataCenterDeployment(zone.getId()); + + List computeTags = new ArrayList(); + computeTags.add(offering.getHostTag()); + + List rootDiskTags = new ArrayList(); + rootDiskTags.add(offering.getTags()); + + if(isIso){ + VirtualMachineEntity vmEntity = _orchSrvc.createVirtualMachineFromScratch(vm.getUuid(), Long.toString(owner.getAccountId()), vm.getIsoId().toString(), hostName, displayName, hypervisor.name(), guestOSCategory.getName(), offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags, networkNicMap, plan); + }else { + VirtualMachineEntity vmEntity = _orchSrvc.createVirtualMachine(vm.getUuid(), Long.toString(owner.getAccountId()), Long.toString(template.getId()), hostName, displayName, hypervisor.name(), offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags, networkNicMap, plan); + } + + + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Successfully allocated DB entry for " + vm); + } + CallContext.current().setEventDetails("Vm Id: " + vm.getId()); + + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), + vm.getHostName(), offering.getId(), template.getId(), hypervisorType.toString(), + VirtualMachine.class.getName(), vm.getUuid()); + + //Update Resource Count for the given account + resourceCountIncrement(accountId, new Long(offering.getCpu()), + new Long(offering.getRamSize())); + return vm; + } + }); + } + private void validateUserData(String userData, HTTPMethod httpmethod) { byte[] decodedUserData = null; if (userData != null) { @@ -3417,7 +3473,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } @Override - public void collectVmDiskStatistics (UserVmVO userVm) { + public void collectVmDiskStatistics (final UserVmVO userVm) { // support KVM only util 2013.06.25 if (!userVm.getHypervisorType().equals(HypervisorType.KVM)) return; @@ -3425,7 +3481,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir long hostId = userVm.getHostId(); List vmNames = new ArrayList(); vmNames.add(userVm.getInstanceName()); - HostVO host = _hostDao.findById(hostId); + final HostVO host = _hostDao.findById(hostId); GetVmDiskStatsAnswer diskStatsAnswer = null; try { @@ -3439,103 +3495,144 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir s_logger.warn("Error while collecting disk stats vm: " + userVm.getHostName() + " from host: " + host.getName() + "; details: " + diskStatsAnswer.getDetails()); return; } - Transaction txn = Transaction.open(Transaction.CLOUD_DB); try { - txn.start(); - HashMap> vmDiskStatsByName = diskStatsAnswer.getVmDiskStatsMap(); - if (vmDiskStatsByName == null) - return; - List vmDiskStats = vmDiskStatsByName.get(userVm.getInstanceName()); - if (vmDiskStats == null) - return; - - for (VmDiskStatsEntry vmDiskStat:vmDiskStats) { - SearchCriteria sc_volume = _volsDao.createSearchCriteria(); - sc_volume.addAnd("path", SearchCriteria.Op.EQ, vmDiskStat.getPath()); - VolumeVO volume = _volsDao.search(sc_volume, null).get(0); - VmDiskStatisticsVO previousVmDiskStats = _vmDiskStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), userVm.getId(), volume.getId()); - VmDiskStatisticsVO vmDiskStat_lock = _vmDiskStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), userVm.getId(), volume.getId()); - - if ((vmDiskStat.getIORead() == 0) && (vmDiskStat.getIOWrite() == 0) && (vmDiskStat.getBytesRead() == 0) && (vmDiskStat.getBytesWrite() == 0)) { - s_logger.debug("Read/Write of IO and Bytes are both 0. Not updating vm_disk_statistics"); - continue; - } - - if (vmDiskStat_lock == null) { - s_logger.warn("unable to find vm disk stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId()+ " and volumeId:" + volume.getId()); - continue; - } - - if (previousVmDiskStats != null - && ((previousVmDiskStats.getCurrentIORead() != vmDiskStat_lock.getCurrentIORead()) - || ((previousVmDiskStats.getCurrentIOWrite() != vmDiskStat_lock.getCurrentIOWrite()) - || (previousVmDiskStats.getCurrentBytesRead() != vmDiskStat_lock.getCurrentBytesRead()) - || (previousVmDiskStats.getCurrentBytesWrite() != vmDiskStat_lock.getCurrentBytesWrite())))) { - s_logger.debug("vm disk stats changed from the time GetVmDiskStatsCommand was sent. " + - "Ignoring current answer. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + - " IO Read: " + vmDiskStat.getIORead() + " IO Write: " + vmDiskStat.getIOWrite() + - " Bytes Read: " + vmDiskStat.getBytesRead() + " Bytes Write: " + vmDiskStat.getBytesWrite()); - continue; - } - - if (vmDiskStat_lock.getCurrentIORead() > vmDiskStat.getIORead()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Read # of IO that's less than the last one. " + - "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + - " Reported: " + vmDiskStat.getIORead() + " Stored: " + vmDiskStat_lock.getCurrentIORead()); - } - vmDiskStat_lock.setNetIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead()); - } - vmDiskStat_lock.setCurrentIORead(vmDiskStat.getIORead()); - if (vmDiskStat_lock.getCurrentIOWrite() > vmDiskStat.getIOWrite()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Write # of IO that's less than the last one. " + - "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + - " Reported: " + vmDiskStat.getIOWrite() + " Stored: " + vmDiskStat_lock.getCurrentIOWrite()); - } - vmDiskStat_lock.setNetIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite()); - } - vmDiskStat_lock.setCurrentIOWrite(vmDiskStat.getIOWrite()); - if (vmDiskStat_lock.getCurrentBytesRead() > vmDiskStat.getBytesRead()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Read # of Bytes that's less than the last one. " + - "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + - " Reported: " + vmDiskStat.getBytesRead() + " Stored: " + vmDiskStat_lock.getCurrentBytesRead()); - } - vmDiskStat_lock.setNetBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead()); - } - vmDiskStat_lock.setCurrentBytesRead(vmDiskStat.getBytesRead()); - if (vmDiskStat_lock.getCurrentBytesWrite() > vmDiskStat.getBytesWrite()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Write # of Bytes that's less than the last one. " + - "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + - " Reported: " + vmDiskStat.getBytesWrite() + " Stored: " + vmDiskStat_lock.getCurrentBytesWrite()); - } - vmDiskStat_lock.setNetBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite()); - } - vmDiskStat_lock.setCurrentBytesWrite(vmDiskStat.getBytesWrite()); - - if (! _dailyOrHourly) { - //update agg bytes - vmDiskStat_lock.setAggIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead()); - vmDiskStat_lock.setAggIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite()); - vmDiskStat_lock.setAggBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead()); - vmDiskStat_lock.setAggBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite()); - } - - _vmDiskStatsDao.update(vmDiskStat_lock.getId(), vmDiskStat_lock); - } - txn.commit(); + final GetVmDiskStatsAnswer diskStatsAnswerFinal = diskStatsAnswer; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + HashMap> vmDiskStatsByName = diskStatsAnswerFinal.getVmDiskStatsMap(); + if (vmDiskStatsByName == null) + return; + List vmDiskStats = vmDiskStatsByName.get(userVm.getInstanceName()); + if (vmDiskStats == null) + return; + + for (VmDiskStatsEntry vmDiskStat:vmDiskStats) { + SearchCriteria sc_volume = _volsDao.createSearchCriteria(); + sc_volume.addAnd("path", SearchCriteria.Op.EQ, vmDiskStat.getPath()); + VolumeVO volume = _volsDao.search(sc_volume, null).get(0); + VmDiskStatisticsVO previousVmDiskStats = _vmDiskStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), userVm.getId(), volume.getId()); + VmDiskStatisticsVO vmDiskStat_lock = _vmDiskStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), userVm.getId(), volume.getId()); + + if ((vmDiskStat.getIORead() == 0) && (vmDiskStat.getIOWrite() == 0) && (vmDiskStat.getBytesRead() == 0) && (vmDiskStat.getBytesWrite() == 0)) { + s_logger.debug("Read/Write of IO and Bytes are both 0. Not updating vm_disk_statistics"); + continue; + } + + if (vmDiskStat_lock == null) { + s_logger.warn("unable to find vm disk stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId()+ " and volumeId:" + volume.getId()); + continue; + } + + if (previousVmDiskStats != null + && ((previousVmDiskStats.getCurrentIORead() != vmDiskStat_lock.getCurrentIORead()) + || ((previousVmDiskStats.getCurrentIOWrite() != vmDiskStat_lock.getCurrentIOWrite()) + || (previousVmDiskStats.getCurrentBytesRead() != vmDiskStat_lock.getCurrentBytesRead()) + || (previousVmDiskStats.getCurrentBytesWrite() != vmDiskStat_lock.getCurrentBytesWrite())))) { + s_logger.debug("vm disk stats changed from the time GetVmDiskStatsCommand was sent. " + + "Ignoring current answer. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + + " IO Read: " + vmDiskStat.getIORead() + " IO Write: " + vmDiskStat.getIOWrite() + + " Bytes Read: " + vmDiskStat.getBytesRead() + " Bytes Write: " + vmDiskStat.getBytesWrite()); + continue; + } + + if (vmDiskStat_lock.getCurrentIORead() > vmDiskStat.getIORead()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Read # of IO that's less than the last one. " + + "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + + " Reported: " + vmDiskStat.getIORead() + " Stored: " + vmDiskStat_lock.getCurrentIORead()); + } + vmDiskStat_lock.setNetIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead()); + } + vmDiskStat_lock.setCurrentIORead(vmDiskStat.getIORead()); + if (vmDiskStat_lock.getCurrentIOWrite() > vmDiskStat.getIOWrite()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Write # of IO that's less than the last one. " + + "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + + " Reported: " + vmDiskStat.getIOWrite() + " Stored: " + vmDiskStat_lock.getCurrentIOWrite()); + } + vmDiskStat_lock.setNetIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite()); + } + vmDiskStat_lock.setCurrentIOWrite(vmDiskStat.getIOWrite()); + if (vmDiskStat_lock.getCurrentBytesRead() > vmDiskStat.getBytesRead()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Read # of Bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + + " Reported: " + vmDiskStat.getBytesRead() + " Stored: " + vmDiskStat_lock.getCurrentBytesRead()); + } + vmDiskStat_lock.setNetBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead()); + } + vmDiskStat_lock.setCurrentBytesRead(vmDiskStat.getBytesRead()); + if (vmDiskStat_lock.getCurrentBytesWrite() > vmDiskStat.getBytesWrite()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Write # of Bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() + + " Reported: " + vmDiskStat.getBytesWrite() + " Stored: " + vmDiskStat_lock.getCurrentBytesWrite()); + } + vmDiskStat_lock.setNetBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite()); + } + vmDiskStat_lock.setCurrentBytesWrite(vmDiskStat.getBytesWrite()); + + if (! _dailyOrHourly) { + //update agg bytes + vmDiskStat_lock.setAggIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead()); + vmDiskStat_lock.setAggIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite()); + vmDiskStat_lock.setAggBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead()); + vmDiskStat_lock.setAggBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite()); + } + + _vmDiskStatsDao.update(vmDiskStat_lock.getId(), vmDiskStat_lock); + } + } + }); } catch (Exception e) { - txn.rollback(); s_logger.warn("Unable to update vm disk statistics for vm: " + userVm.getId() + " from host: " + hostId, e); - } finally { - txn.close(); } } } + @Override + public UserVm expungeVm(long vmId) throws ResourceUnavailableException, + ConcurrentOperationException { + Account caller = CallContext.current().getCallingAccount(); + Long userId = caller.getId(); + // Verify input parameters + UserVmVO vm = _vmDao.findById(vmId); + if (vm == null) { + InvalidParameterValueException ex = new InvalidParameterValueException( + "Unable to find a virtual machine with specified vmId"); + ex.addProxyObject(String.valueOf(vmId), "vmId"); + throw ex; + } + + if (vm.getRemoved() != null) { + s_logger.trace("Vm id=" + vmId + " is already expunged"); + return vm; + } + + if ((vm.getState() != State.Destroyed) && (vm.getState() != State.Expunging)) { + CloudRuntimeException ex = new CloudRuntimeException( + "Please destroy vm with specified vmId before expunge"); + ex.addProxyObject(String.valueOf(vmId), "vmId"); + throw ex; + } + + _accountMgr.checkAccess(caller, null, true, vm); + + boolean status; + + status = expunge(vm, userId, caller); + if (status) { + return _vmDao.findByIdIncludingRemoved(vmId); + } else { + CloudRuntimeException ex = new CloudRuntimeException( + "Failed to expunge vm with specified vmId"); + ex.addProxyObject(String.valueOf(vmId), "vmId"); + throw ex; + } + + } @Override public Pair, Integer> searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, @@ -4271,7 +4368,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir @DB @Override @ActionEvent(eventType = EventTypes.EVENT_VM_MOVE, eventDescription = "move VM to another user", async = false) - public UserVm moveVMToUser(AssignVMCmd cmd) + public UserVm moveVMToUser(final AssignVMCmd cmd) throws ResourceAllocationException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { // VERIFICATIONS and VALIDATIONS @@ -4291,7 +4388,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } // get and check the valid VM - UserVmVO vm = _vmDao.findById(cmd.getVmId()); + final UserVmVO vm = _vmDao.findById(cmd.getVmId()); if (vm == null) { throw new InvalidParameterValueException( "There is no vm by that id " + cmd.getVmId()); @@ -4306,7 +4403,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir throw ex; } - Account oldAccount = _accountService.getActiveAccountById(vm + final Account oldAccount = _accountService.getActiveAccountById(vm .getAccountId()); if (oldAccount == null) { throw new InvalidParameterValueException("Invalid account for VM " @@ -4319,7 +4416,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir ex.addProxyObject(vm.getUuid(), "vmId"); throw ex; } - Account newAccount = _accountService.getActiveAccountByName( + final Account newAccount = _accountService.getActiveAccountByName( cmd.getAccountName(), cmd.getDomainId()); if (newAccount == null || newAccount.getType() == Account.ACCOUNT_TYPE_PROJECT) { @@ -4376,8 +4473,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir DataCenterVO zone = _dcDao.findById(vm.getDataCenterId()); // Get serviceOffering and Volumes for Virtual Machine - ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getServiceOfferingId()); - List volumes = _volsDao.findByInstance(cmd.getVmId()); + final ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getServiceOfferingId()); + final List volumes = _volsDao.findByInstance(cmd.getVmId()); //Remove vm from instance group removeInstanceFromInstanceGroup(cmd.getVmId()); @@ -4407,55 +4504,57 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir DomainVO domain = _domainDao.findById(cmd.getDomainId()); _accountMgr.checkAccess(newAccount, domain); - Transaction txn = Transaction.currentTxn(); - txn.start(); - //generate destroy vm event for usage - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), - vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(), - VirtualMachine.class.getName(), vm.getUuid()); - - // update resource counts for old account - resourceCountDecrement(oldAccount.getAccountId(), new Long(offering.getCpu()), - new Long(offering.getRamSize())); - - // OWNERSHIP STEP 1: update the vm owner - vm.setAccountId(newAccount.getAccountId()); - vm.setDomainId(cmd.getDomainId()); - _vmDao.persist(vm); - - // OS 2: update volume - for (VolumeVO volume : volumes) { - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), - volume.getDataCenterId(), volume.getId(), volume.getName(), Volume.class.getName(), volume.getUuid()); - _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.volume); - _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.primary_storage, - new Long(volume.getSize())); - volume.setAccountId(newAccount.getAccountId()); - volume.setDomainId(newAccount.getDomainId()); - _volsDao.persist(volume); - _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.volume); - _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.primary_storage, - new Long(volume.getSize())); - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), - volume.getDataCenterId(), volume.getId(), volume.getName(), - volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), - volume.getUuid()); - //snapshots: mark these removed in db - List snapshots = _snapshotDao.listByVolumeIdIncludingRemoved(volume.getId()); - for (SnapshotVO snapshot: snapshots){ - _snapshotDao.remove(snapshot.getId()); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + //generate destroy vm event for usage + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), + vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(), + VirtualMachine.class.getName(), vm.getUuid()); + + // update resource counts for old account + resourceCountDecrement(oldAccount.getAccountId(), new Long(offering.getCpu()), + new Long(offering.getRamSize())); + + // OWNERSHIP STEP 1: update the vm owner + vm.setAccountId(newAccount.getAccountId()); + vm.setDomainId(cmd.getDomainId()); + _vmDao.persist(vm); + + // OS 2: update volume + for (VolumeVO volume : volumes) { + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), + volume.getDataCenterId(), volume.getId(), volume.getName(), Volume.class.getName(), volume.getUuid()); + _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.volume); + _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.primary_storage, + new Long(volume.getSize())); + volume.setAccountId(newAccount.getAccountId()); + volume.setDomainId(newAccount.getDomainId()); + _volsDao.persist(volume); + _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.volume); + _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.primary_storage, + new Long(volume.getSize())); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), + volume.getDataCenterId(), volume.getId(), volume.getName(), + volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), + volume.getUuid()); + //snapshots: mark these removed in db + List snapshots = _snapshotDao.listByVolumeIdIncludingRemoved(volume.getId()); + for (SnapshotVO snapshot: snapshots){ + _snapshotDao.remove(snapshot.getId()); + } + } + + //update resource count of new account + resourceCountIncrement(newAccount.getAccountId(), new Long(offering.getCpu()), new Long(offering.getRamSize())); + + //generate usage events to account for this change + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), + vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(), + VirtualMachine.class.getName(), vm.getUuid()); } - } + }); - //update resource count of new account - resourceCountIncrement(newAccount.getAccountId(), new Long(offering.getCpu()), new Long(offering.getRamSize())); - - //generate usage events to account for this change - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), - vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(), - VirtualMachine.class.getName(), vm.getUuid()); - - txn.commit(); VirtualMachine vmoi = _itMgr.findById(vm.getId()); VirtualMachineProfileImpl vmOldProfile = new VirtualMachineProfileImpl(vmoi); diff --git a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java index aa772fefa9d..cd064f59667 100644 --- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java +++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java @@ -29,7 +29,6 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; - import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; @@ -90,6 +89,11 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionCallbackWithException; +import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.utils.fsm.StateMachine2; @@ -482,31 +486,30 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana } @DB - protected void processAnswer(VMSnapshotVO vmSnapshot, UserVmVO userVm, Answer as, Long hostId) { - final Transaction txn = Transaction.currentTxn(); + protected void processAnswer(final VMSnapshotVO vmSnapshot, UserVmVO userVm, final Answer as, Long hostId) { try { - txn.start(); - if (as instanceof CreateVMSnapshotAnswer) { - CreateVMSnapshotAnswer answer = (CreateVMSnapshotAnswer) as; - finalizeCreate(vmSnapshot, answer.getVolumeTOs()); - vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded); - } else if (as instanceof RevertToVMSnapshotAnswer) { - RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer) as; - finalizeRevert(vmSnapshot, answer.getVolumeTOs()); - vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded); - } else if (as instanceof DeleteVMSnapshotAnswer) { - DeleteVMSnapshotAnswer answer = (DeleteVMSnapshotAnswer) as; - finalizeDelete(vmSnapshot, answer.getVolumeTOs()); - _vmSnapshotDao.remove(vmSnapshot.getId()); - } - txn.commit(); + Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) throws NoTransitionException { + if (as instanceof CreateVMSnapshotAnswer) { + CreateVMSnapshotAnswer answer = (CreateVMSnapshotAnswer) as; + finalizeCreate(vmSnapshot, answer.getVolumeTOs()); + vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded); + } else if (as instanceof RevertToVMSnapshotAnswer) { + RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer) as; + finalizeRevert(vmSnapshot, answer.getVolumeTOs()); + vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded); + } else if (as instanceof DeleteVMSnapshotAnswer) { + DeleteVMSnapshotAnswer answer = (DeleteVMSnapshotAnswer) as; + finalizeDelete(vmSnapshot, answer.getVolumeTOs()); + _vmSnapshotDao.remove(vmSnapshot.getId()); + } + } + }); } catch (Exception e) { String errMsg = "Error while process answer: " + as.getClass() + " due to " + e.getMessage(); s_logger.error(errMsg, e); - txn.rollback(); throw new CloudRuntimeException(errMsg); - } finally { - txn.close(); } } diff --git a/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java b/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java index 8f2caad9780..b7b51c9c29f 100644 --- a/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java +++ b/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java @@ -34,12 +34,16 @@ import org.apache.cloudstack.affinity.dao.AffinityGroupDao; import org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDao; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; import org.apache.cloudstack.context.CallContext; - import org.apache.log4j.Logger; import org.springframework.context.annotation.Primary; + + + + + import com.cloud.deploy.DeploymentPlanner; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; @@ -65,6 +69,9 @@ import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.StateListener; import com.cloud.vm.UserVmVO; @@ -142,8 +149,8 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro @DB @Override - public AffinityGroup createAffinityGroupInternal(String account, Long domainId, String affinityGroupName, - String affinityGroupType, String description) { + public AffinityGroup createAffinityGroupInternal(String account, final Long domainId, final String affinityGroupName, + final String affinityGroupType, final String description) { Account caller = CallContext.current().getCallingAccount(); @@ -159,7 +166,7 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro "Unable to create affinity group, no Affinity Group Types configured"); } - AffinityGroupProcessor processor = typeProcessorMap.get(affinityGroupType); + final AffinityGroupProcessor processor = typeProcessorMap.get(affinityGroupType); if (processor.isAdminControlledGroup() && !_accountMgr.isRootAdmin(caller.getType())) { throw new PermissionDeniedException("Cannot create the affinity group"); @@ -210,21 +217,26 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro + affinityGroupName + " already exisits under the domain."); } - Transaction txn = Transaction.currentTxn(); - txn.start(); + final Account ownerFinal = owner; + final ControlledEntity.ACLType aclTypeFinal = aclType; + AffinityGroupVO group = Transaction.execute(new TransactionCallback() { + @Override + public AffinityGroupVO doInTransaction(TransactionStatus status) { + AffinityGroupVO group = new AffinityGroupVO(affinityGroupName, affinityGroupType, description, ownerFinal.getDomainId(), + ownerFinal.getId(), aclTypeFinal); + _affinityGroupDao.persist(group); + + if (domainId != null && aclTypeFinal == ACLType.Domain) { + boolean subDomainAccess = false; + subDomainAccess = processor.subDomainAccess(); + AffinityGroupDomainMapVO domainMap = new AffinityGroupDomainMapVO(group.getId(), domainId, subDomainAccess); + _affinityGroupDomainMapDao.persist(domainMap); + } + + return group; + } + }); - AffinityGroupVO group = new AffinityGroupVO(affinityGroupName, affinityGroupType, description, owner.getDomainId(), - owner.getId(), aclType); - _affinityGroupDao.persist(group); - - if (domainId != null && aclType == ACLType.Domain) { - boolean subDomainAccess = false; - subDomainAccess = processor.subDomainAccess(); - AffinityGroupDomainMapVO domainMap = new AffinityGroupDomainMapVO(group.getId(), domainId, subDomainAccess); - _affinityGroupDomainMapDao.persist(domainMap); - } - - txn.commit(); if (s_logger.isDebugEnabled()) { s_logger.debug("Created affinity group =" + affinityGroupName); @@ -265,35 +277,38 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro // check permissions _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, group); - final Transaction txn = Transaction.currentTxn(); - txn.start(); + final Long affinityGroupIdFinal = affinityGroupId; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { - group = _affinityGroupDao.lockRow(affinityGroupId, true); - if (group == null) { - throw new InvalidParameterValueException("Unable to find affinity group by id " + affinityGroupId); - } - - List affinityGroupVmMap = _affinityGroupVMMapDao.listByAffinityGroup(affinityGroupId); - if (!affinityGroupVmMap.isEmpty()) { - SearchBuilder listByAffinityGroup = _affinityGroupVMMapDao.createSearchBuilder(); - listByAffinityGroup.and("affinityGroupId", listByAffinityGroup.entity().getAffinityGroupId(), - SearchCriteria.Op.EQ); - listByAffinityGroup.done(); - SearchCriteria sc = listByAffinityGroup.create(); - sc.setParameters("affinityGroupId", affinityGroupId); - - _affinityGroupVMMapDao.lockRows(sc, null, true); - _affinityGroupVMMapDao.remove(sc); - } - - // call processor to handle the group delete - AffinityGroupProcessor processor = getAffinityGroupProcessorForType(group.getType()); - if (processor != null) { - processor.handleDeleteGroup(group); - } - - _affinityGroupDao.expunge(affinityGroupId); - txn.commit(); + AffinityGroupVO group = _affinityGroupDao.lockRow(affinityGroupIdFinal, true); + if (group == null) { + throw new InvalidParameterValueException("Unable to find affinity group by id " + affinityGroupIdFinal); + } + + List affinityGroupVmMap = _affinityGroupVMMapDao.listByAffinityGroup(affinityGroupIdFinal); + if (!affinityGroupVmMap.isEmpty()) { + SearchBuilder listByAffinityGroup = _affinityGroupVMMapDao.createSearchBuilder(); + listByAffinityGroup.and("affinityGroupId", listByAffinityGroup.entity().getAffinityGroupId(), + SearchCriteria.Op.EQ); + listByAffinityGroup.done(); + SearchCriteria sc = listByAffinityGroup.create(); + sc.setParameters("affinityGroupId", affinityGroupIdFinal); + + _affinityGroupVMMapDao.lockRows(sc, null, true); + _affinityGroupVMMapDao.remove(sc); + } + + // call processor to handle the group delete + AffinityGroupProcessor processor = getAffinityGroupProcessorForType(group.getType()); + if (processor != null) { + processor.handleDeleteGroup(group); + } + + _affinityGroupDao.expunge(affinityGroupIdFinal); + } + }); if (s_logger.isDebugEnabled()) { s_logger.debug("Deleted affinity group id=" + affinityGroupId); diff --git a/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java b/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java index 2385edcd1c5..b7cd231831c 100644 --- a/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java +++ b/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java @@ -26,7 +26,6 @@ import javax.inject.Inject; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; - import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.command.user.loadbalancer.ListApplicationLoadBalancersCmd; import org.apache.cloudstack.context.CallContext; @@ -58,7 +57,7 @@ import com.cloud.network.lb.LoadBalancingRulesService; import com.cloud.network.rules.FirewallRule.State; import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.projects.Project.ListProjectResourcesCriteria; -import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; @@ -72,6 +71,8 @@ import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackWithException; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; import com.cloud.utils.net.NetUtils; @@ -156,37 +157,40 @@ public class ApplicationLoadBalancerManagerImpl extends ManagerBase implements A @DB - protected ApplicationLoadBalancerRule persistLbRule(ApplicationLoadBalancerRuleVO newRule) throws NetworkRuleConflictException { - - Transaction txn = Transaction.currentTxn(); - txn.start(); - - //1) Persist the rule - newRule = _lbDao.persist(newRule); + protected ApplicationLoadBalancerRule persistLbRule(final ApplicationLoadBalancerRuleVO newRuleFinal) throws NetworkRuleConflictException { boolean success = true; - + ApplicationLoadBalancerRuleVO newRule = null; try { - //2) Detect conflicts - detectLbRulesConflicts(newRule); - if (!_firewallDao.setStateToAdd(newRule)) { - throw new CloudRuntimeException("Unable to update the state to add for " + newRule); - } - s_logger.debug("Load balancer " + newRule.getId() + " for Ip address " + newRule.getSourceIp().addr() + ", source port " - + newRule.getSourcePortStart() + ", instance port " + newRule.getDefaultPortStart() + " is added successfully."); - CallContext.current().setEventDetails("Load balancer Id: " + newRule.getId()); - Network ntwk = _networkModel.getNetwork(newRule.getNetworkId()); - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_CREATE, newRule.getAccountId(), - ntwk.getDataCenterId(), newRule.getId(), null, LoadBalancingRule.class.getName(), - newRule.getUuid()); - txn.commit(); + newRule = Transaction.execute(new TransactionCallbackWithException() { + @Override + public ApplicationLoadBalancerRuleVO doInTransaction(TransactionStatus status) throws NetworkRuleConflictException { + //1) Persist the rule + ApplicationLoadBalancerRuleVO newRule = _lbDao.persist(newRuleFinal); + //2) Detect conflicts + detectLbRulesConflicts(newRule); + if (!_firewallDao.setStateToAdd(newRule)) { + throw new CloudRuntimeException("Unable to update the state to add for " + newRule); + } + s_logger.debug("Load balancer " + newRule.getId() + " for Ip address " + newRule.getSourceIp().addr() + ", source port " + + newRule.getSourcePortStart() + ", instance port " + newRule.getDefaultPortStart() + " is added successfully."); + CallContext.current().setEventDetails("Load balancer Id: " + newRule.getId()); + Network ntwk = _networkModel.getNetwork(newRule.getNetworkId()); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_CREATE, newRule.getAccountId(), + ntwk.getDataCenterId(), newRule.getId(), null, LoadBalancingRule.class.getName(), + newRule.getUuid()); + + return newRule; + } + }); + return newRule; } catch (Exception e) { success = false; if (e instanceof NetworkRuleConflictException) { throw (NetworkRuleConflictException) e; } - throw new CloudRuntimeException("Unable to add lb rule for ip address " + newRule.getSourceIpAddressId(), e); + throw new CloudRuntimeException("Unable to add lb rule for ip address " + newRuleFinal.getSourceIpAddressId(), e); } finally { if (!success && newRule != null) { _lbMgr.removeLBRule(newRule); @@ -455,7 +459,7 @@ public class ApplicationLoadBalancerManagerImpl extends ManagerBase implements A if (tags != null && !tags.isEmpty()) { int count = 0; - sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.LoadBalancer.toString()); + sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.LoadBalancer.toString()); for (String key : tags.keySet()) { sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); diff --git a/server/src/org/apache/cloudstack/region/RegionManagerImpl.java b/server/src/org/apache/cloudstack/region/RegionManagerImpl.java index 046779f98fb..40ac46c176c 100755 --- a/server/src/org/apache/cloudstack/region/RegionManagerImpl.java +++ b/server/src/org/apache/cloudstack/region/RegionManagerImpl.java @@ -80,7 +80,7 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man dbProps = new Properties(); } try { - dbProps.load(new FileInputStream(dbPropsFile)); + PropertiesUtil.loadFromFile(dbProps, dbPropsFile); } catch (IOException e) { s_logger.fatal("Unable to load db properties file, pl. check the classpath and file path configuration", e); return false; diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java index 25a40ee9051..62b9748de3a 100644 --- a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java +++ b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java @@ -37,6 +37,9 @@ import com.cloud.user.AccountManager; import com.cloud.utils.Pair; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; @@ -46,7 +49,6 @@ import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.region.Region; import org.apache.cloudstack.region.dao.RegionDao; - import org.apache.log4j.Logger; import javax.ejb.Local; @@ -94,15 +96,15 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR "balancer rule", create = true) public GlobalLoadBalancerRule createGlobalLoadBalancerRule(CreateGlobalLoadBalancerRuleCmd newRule) { - Integer regionId = newRule.getRegionId(); - String algorithm = newRule.getAlgorithm(); - String stickyMethod = newRule.getStickyMethod(); - String name = newRule.getName(); - String description = newRule.getDescription(); - String domainName = newRule.getServiceDomainName(); - String serviceType = newRule.getServiceType(); + final Integer regionId = newRule.getRegionId(); + final String algorithm = newRule.getAlgorithm(); + final String stickyMethod = newRule.getStickyMethod(); + final String name = newRule.getName(); + final String description = newRule.getDescription(); + final String domainName = newRule.getServiceDomainName(); + final String serviceType = newRule.getServiceType(); - Account gslbOwner = _accountMgr.getAccount(newRule.getEntityOwnerId()); + final Account gslbOwner = _accountMgr.getAccount(newRule.getEntityOwnerId()); if (!GlobalLoadBalancerRule.Algorithm.isValidAlgorithm(algorithm)) { throw new InvalidParameterValueException("Invalid Algorithm: " + algorithm); @@ -135,18 +137,21 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR throw new CloudRuntimeException("GSLB service is not enabled in region : " + region.getName()); } - Transaction txn = Transaction.currentTxn(); - txn.start(); - GlobalLoadBalancerRuleVO newGslbRule = new GlobalLoadBalancerRuleVO(name, description, domainName, algorithm, - stickyMethod, serviceType, regionId, gslbOwner.getId(), gslbOwner.getDomainId(), - GlobalLoadBalancerRule.State.Staged); - _gslbRuleDao.persist(newGslbRule); + GlobalLoadBalancerRuleVO newGslbRule = Transaction.execute(new TransactionCallback() { + @Override + public GlobalLoadBalancerRuleVO doInTransaction(TransactionStatus status) { + GlobalLoadBalancerRuleVO newGslbRule = new GlobalLoadBalancerRuleVO(name, description, domainName, algorithm, + stickyMethod, serviceType, regionId, gslbOwner.getId(), gslbOwner.getDomainId(), + GlobalLoadBalancerRule.State.Staged); + _gslbRuleDao.persist(newGslbRule); - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_GLOBAL_LOAD_BALANCER_CREATE, newGslbRule.getAccountId(), - 0, newGslbRule.getId(), name, GlobalLoadBalancerRule.class.getName(), - newGslbRule.getUuid()); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_GLOBAL_LOAD_BALANCER_CREATE, newGslbRule.getAccountId(), + 0, newGslbRule.getId(), name, GlobalLoadBalancerRule.class.getName(), + newGslbRule.getUuid()); - txn.commit(); + return newGslbRule; + } + }); s_logger.debug("successfully created new global load balancer rule for the account " + gslbOwner.getId()); @@ -162,8 +167,8 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR CallContext ctx = CallContext.current(); Account caller = ctx.getCallingAccount(); - long gslbRuleId = assignToGslbCmd.getGlobalLoadBalancerRuleId(); - GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId); + final long gslbRuleId = assignToGslbCmd.getGlobalLoadBalancerRuleId(); + final GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId); if (gslbRule == null) { throw new InvalidParameterValueException("Invalid global load balancer rule id: " + gslbRuleId); } @@ -175,7 +180,7 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR + " is in revoked state"); } - List newLbRuleIds = assignToGslbCmd.getLoadBalancerRulesIds(); + final List newLbRuleIds = assignToGslbCmd.getLoadBalancerRulesIds(); if (newLbRuleIds == null || newLbRuleIds.isEmpty()) { throw new InvalidParameterValueException("empty list of load balancer rule Ids specified to be assigned" + " global load balancer rule"); @@ -244,30 +249,31 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR } } - Map lbRuleWeightMap = assignToGslbCmd.getLoadBalancerRuleWeightMap(); + final Map lbRuleWeightMap = assignToGslbCmd.getLoadBalancerRuleWeightMap(); - Transaction txn = Transaction.currentTxn(); - txn.start(); - - // persist the mapping for the new Lb rule that needs to assigned to a gslb rule - for (Long lbRuleId : newLbRuleIds) { - GlobalLoadBalancerLbRuleMapVO newGslbLbMap = new GlobalLoadBalancerLbRuleMapVO(); - newGslbLbMap.setGslbLoadBalancerId(gslbRuleId); - newGslbLbMap.setLoadBalancerId(lbRuleId); - if (lbRuleWeightMap != null && lbRuleWeightMap.get(lbRuleId) != null) { - newGslbLbMap.setWeight(lbRuleWeightMap.get(lbRuleId)); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // persist the mapping for the new Lb rule that needs to assigned to a gslb rule + for (Long lbRuleId : newLbRuleIds) { + GlobalLoadBalancerLbRuleMapVO newGslbLbMap = new GlobalLoadBalancerLbRuleMapVO(); + newGslbLbMap.setGslbLoadBalancerId(gslbRuleId); + newGslbLbMap.setLoadBalancerId(lbRuleId); + if (lbRuleWeightMap != null && lbRuleWeightMap.get(lbRuleId) != null) { + newGslbLbMap.setWeight(lbRuleWeightMap.get(lbRuleId)); + } + _gslbLbMapDao.persist(newGslbLbMap); + } + + // mark the gslb rule state as add + if (gslbRule.getState() == GlobalLoadBalancerRule.State.Staged || gslbRule.getState() == + GlobalLoadBalancerRule.State.Active ) { + gslbRule.setState(GlobalLoadBalancerRule.State.Add); + _gslbRuleDao.update(gslbRule.getId(), gslbRule); + } } - _gslbLbMapDao.persist(newGslbLbMap); - } + }); - // mark the gslb rule state as add - if (gslbRule.getState() == GlobalLoadBalancerRule.State.Staged || gslbRule.getState() == - GlobalLoadBalancerRule.State.Active ) { - gslbRule.setState(GlobalLoadBalancerRule.State.Add); - _gslbRuleDao.update(gslbRule.getId(), gslbRule); - } - - txn.commit(); boolean success = false; try { @@ -304,8 +310,8 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR CallContext ctx = CallContext.current(); Account caller = ctx.getCallingAccount(); - long gslbRuleId = removeFromGslbCmd.getGlobalLoadBalancerRuleId(); - GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId); + final long gslbRuleId = removeFromGslbCmd.getGlobalLoadBalancerRuleId(); + final GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId); if (gslbRule == null) { throw new InvalidParameterValueException("Invalid global load balancer rule id: " + gslbRuleId); } @@ -316,7 +322,7 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR throw new InvalidParameterValueException("global load balancer rule id: " + gslbRuleId + " is already in revoked state"); } - List lbRuleIdsToremove = removeFromGslbCmd.getLoadBalancerRulesIds(); + final List lbRuleIdsToremove = removeFromGslbCmd.getLoadBalancerRulesIds(); if (lbRuleIdsToremove == null || lbRuleIdsToremove.isEmpty()) { throw new InvalidParameterValueException("empty list of load balancer rule Ids specified to be un-assigned" + " to global load balancer rule"); @@ -356,23 +362,24 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR } } - Transaction txn = Transaction.currentTxn(); - txn.start(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // update the mapping of gslb rule to Lb rule, to revoke state + for (Long lbRuleId : lbRuleIdsToremove) { + GlobalLoadBalancerLbRuleMapVO removeGslbLbMap = _gslbLbMapDao.findByGslbRuleIdAndLbRuleId(gslbRuleId, lbRuleId); + removeGslbLbMap.setRevoke(true); + _gslbLbMapDao.update(removeGslbLbMap.getId(), removeGslbLbMap); + } - // update the mapping of gslb rule to Lb rule, to revoke state - for (Long lbRuleId : lbRuleIdsToremove) { - GlobalLoadBalancerLbRuleMapVO removeGslbLbMap = _gslbLbMapDao.findByGslbRuleIdAndLbRuleId(gslbRuleId, lbRuleId); - removeGslbLbMap.setRevoke(true); - _gslbLbMapDao.update(removeGslbLbMap.getId(), removeGslbLbMap); - } + // mark the gslb rule state as add + if (gslbRule.getState() == GlobalLoadBalancerRule.State.Staged) { + gslbRule.setState(GlobalLoadBalancerRule.State.Add); + _gslbRuleDao.update(gslbRule.getId(), gslbRule); + } - // mark the gslb rule state as add - if (gslbRule.getState() == GlobalLoadBalancerRule.State.Staged) { - gslbRule.setState(GlobalLoadBalancerRule.State.Add); - _gslbRuleDao.update(gslbRule.getId(), gslbRule); - } - - txn.commit(); + } + }); boolean success = false; try { @@ -387,19 +394,21 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR throw ex; } - txn.start(); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // remove the mappings of gslb rule to Lb rule that are in revoked state + for (Long lbRuleId : lbRuleIdsToremove) { + GlobalLoadBalancerLbRuleMapVO removeGslbLbMap = _gslbLbMapDao.findByGslbRuleIdAndLbRuleId(gslbRuleId, lbRuleId); + _gslbLbMapDao.remove(removeGslbLbMap.getId()); + } - // remove the mappings of gslb rule to Lb rule that are in revoked state - for (Long lbRuleId : lbRuleIdsToremove) { - GlobalLoadBalancerLbRuleMapVO removeGslbLbMap = _gslbLbMapDao.findByGslbRuleIdAndLbRuleId(gslbRuleId, lbRuleId); - _gslbLbMapDao.remove(removeGslbLbMap.getId()); - } + // on success set state back to Active + gslbRule.setState(GlobalLoadBalancerRule.State.Active); + _gslbRuleDao.update(gslbRule.getId(), gslbRule); - // on success set state back to Active - gslbRule.setState(GlobalLoadBalancerRule.State.Active); - _gslbRuleDao.update(gslbRule.getId(), gslbRule); - - txn.commit(); + } + }); success = true; } catch (ResourceUnavailableException e) { @@ -429,9 +438,9 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR } @DB - private void revokeGslbRule(long gslbRuleId, Account caller) { + private void revokeGslbRule(final long gslbRuleId, Account caller) { - GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId); + final GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId); if (gslbRule == null) { throw new InvalidParameterValueException("Invalid global load balancer rule id: " + gslbRuleId); @@ -454,19 +463,21 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR _gslbRuleDao.update(gslbRuleId, gslbRule); } - Transaction txn = Transaction.currentTxn(); - txn.start(); - - List gslbLbMapVos = _gslbLbMapDao.listByGslbRuleId(gslbRuleId); - if (gslbLbMapVos != null) { - //mark all the GSLB-LB mapping to be in revoke state - for (GlobalLoadBalancerLbRuleMapVO gslbLbMap : gslbLbMapVos) { - gslbLbMap.setRevoke(true); - _gslbLbMapDao.update(gslbLbMap.getId(), gslbLbMap); + final List gslbLbMapVos = Transaction.execute(new TransactionCallback>() { + @Override + public List doInTransaction(TransactionStatus status) { + List gslbLbMapVos = _gslbLbMapDao.listByGslbRuleId(gslbRuleId); + if (gslbLbMapVos != null) { + //mark all the GSLB-LB mapping to be in revoke state + for (GlobalLoadBalancerLbRuleMapVO gslbLbMap : gslbLbMapVos) { + gslbLbMap.setRevoke(true); + _gslbLbMapDao.update(gslbLbMap.getId(), gslbLbMap); + } + } + + return gslbLbMapVos; } - } - - txn.commit(); + }); boolean success = false; try { @@ -478,22 +489,25 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR throw new CloudRuntimeException("Failed to update the gloabal load balancer"); } - txn.start(); - //remove all mappings between GSLB rule and load balancer rules - if (gslbLbMapVos != null) { - for (GlobalLoadBalancerLbRuleMapVO gslbLbMap : gslbLbMapVos) { - _gslbLbMapDao.remove(gslbLbMap.getId()); + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + //remove all mappings between GSLB rule and load balancer rules + if (gslbLbMapVos != null) { + for (GlobalLoadBalancerLbRuleMapVO gslbLbMap : gslbLbMapVos) { + _gslbLbMapDao.remove(gslbLbMap.getId()); + } + } + + //remove the GSLB rule itself + _gslbRuleDao.remove(gslbRuleId); + + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_GLOBAL_LOAD_BALANCER_DELETE, gslbRule.getAccountId(), + 0, gslbRule.getId(), gslbRule.getName(), GlobalLoadBalancerRule.class.getName(), + gslbRule.getUuid()); } - } + }); - //remove the GSLB rule itself - _gslbRuleDao.remove(gslbRuleId); - - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_GLOBAL_LOAD_BALANCER_DELETE, gslbRule.getAccountId(), - 0, gslbRule.getId(), gslbRule.getName(), GlobalLoadBalancerRule.class.getName(), - gslbRule.getUuid()); - - txn.commit(); } @Override @@ -523,8 +537,6 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR throw new InvalidParameterValueException("Invalid persistence: " + stickyMethod); } - Transaction txn = Transaction.currentTxn(); - txn.start(); if (algorithm != null) { gslbRule.setAlgorithm(algorithm); } @@ -536,7 +548,6 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR } gslbRule.setState(GlobalLoadBalancerRule.State.Add); _gslbRuleDao.update(gslbRule.getId(), gslbRule); - txn.commit(); try { s_logger.debug("Updating global load balancer with id " + gslbRule.getUuid()); diff --git a/server/test/com/cloud/configuration/ConfigurationManagerTest.java b/server/test/com/cloud/configuration/ConfigurationManagerTest.java index 908f0d01056..2d2c03dcbaf 100755 --- a/server/test/com/cloud/configuration/ConfigurationManagerTest.java +++ b/server/test/com/cloud/configuration/ConfigurationManagerTest.java @@ -40,7 +40,6 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; - import org.apache.cloudstack.api.command.admin.vlan.DedicatePublicIpRangeCmd; import org.apache.cloudstack.api.command.admin.vlan.ReleasePublicIpRangeCmd; import org.apache.cloudstack.context.CallContext; @@ -69,6 +68,7 @@ import com.cloud.user.ResourceLimitService; import com.cloud.user.UserVO; import com.cloud.user.dao.AccountDao; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.net.Ip; public class ConfigurationManagerTest { @@ -213,7 +213,7 @@ public class ConfigurationManagerTest { } void runDedicatePublicIpRangePostiveTest() throws Exception { - Transaction txn = Transaction.open("runDedicatePublicIpRangePostiveTest"); + TransactionLegacy txn = TransactionLegacy.open("runDedicatePublicIpRangePostiveTest"); when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan); @@ -239,7 +239,7 @@ public class ConfigurationManagerTest { } void runDedicatePublicIpRangeInvalidRange() throws Exception { - Transaction txn = Transaction.open("runDedicatePublicIpRangeInvalidRange"); + TransactionLegacy txn = TransactionLegacy.open("runDedicatePublicIpRangeInvalidRange"); when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(null); try { @@ -252,7 +252,7 @@ public class ConfigurationManagerTest { } void runDedicatePublicIpRangeDedicatedRange() throws Exception { - Transaction txn = Transaction.open("runDedicatePublicIpRangeDedicatedRange"); + TransactionLegacy txn = TransactionLegacy.open("runDedicatePublicIpRangeDedicatedRange"); when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan); @@ -281,7 +281,7 @@ public class ConfigurationManagerTest { } void runDedicatePublicIpRangeInvalidZone() throws Exception { - Transaction txn = Transaction.open("runDedicatePublicIpRangeInvalidZone"); + TransactionLegacy txn = TransactionLegacy.open("runDedicatePublicIpRangeInvalidZone"); when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan); @@ -307,7 +307,7 @@ public class ConfigurationManagerTest { } void runDedicatePublicIpRangeIPAdressAllocated() throws Exception { - Transaction txn = Transaction.open("runDedicatePublicIpRangeIPAdressAllocated"); + TransactionLegacy txn = TransactionLegacy.open("runDedicatePublicIpRangeIPAdressAllocated"); when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan); @@ -334,7 +334,7 @@ public class ConfigurationManagerTest { } void runReleasePublicIpRangePostiveTest1() throws Exception { - Transaction txn = Transaction.open("runReleasePublicIpRangePostiveTest1"); + TransactionLegacy txn = TransactionLegacy.open("runReleasePublicIpRangePostiveTest1"); when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan); @@ -358,7 +358,7 @@ public class ConfigurationManagerTest { } void runReleasePublicIpRangePostiveTest2() throws Exception { - Transaction txn = Transaction.open("runReleasePublicIpRangePostiveTest2"); + TransactionLegacy txn = TransactionLegacy.open("runReleasePublicIpRangePostiveTest2"); when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan); @@ -392,7 +392,7 @@ public class ConfigurationManagerTest { } void runReleasePublicIpRangeInvalidIpRange() throws Exception { - Transaction txn = Transaction.open("runReleasePublicIpRangeInvalidIpRange"); + TransactionLegacy txn = TransactionLegacy.open("runReleasePublicIpRangeInvalidIpRange"); when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(null); try { @@ -405,7 +405,7 @@ public class ConfigurationManagerTest { } void runReleaseNonDedicatedPublicIpRange() throws Exception { - Transaction txn = Transaction.open("runReleaseNonDedicatedPublicIpRange"); + TransactionLegacy txn = TransactionLegacy.open("runReleaseNonDedicatedPublicIpRange"); when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan); diff --git a/server/test/com/cloud/metadata/ResourceMetaDataManagerTest.java b/server/test/com/cloud/metadata/ResourceMetaDataManagerTest.java index 68762ef0ca4..b0719553df1 100644 --- a/server/test/com/cloud/metadata/ResourceMetaDataManagerTest.java +++ b/server/test/com/cloud/metadata/ResourceMetaDataManagerTest.java @@ -17,42 +17,27 @@ package com.cloud.metadata; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.anyFloat; -import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.when; -import java.lang.reflect.Field; -import java.util.List; import java.util.Map; -import com.cloud.server.TaggedResourceService; -import com.cloud.utils.db.DB; -import com.cloud.vm.dao.NicDetailDao; -import org.apache.cloudstack.api.ServerApiException; -import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd; -import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd; +import javax.naming.ConfigurationException; + import org.apache.commons.collections.map.HashedMap; import org.junit.Before; -import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.Spy; import com.cloud.exception.ResourceAllocationException; -import com.cloud.metadata.ResourceMetaDataManager; -import com.cloud.metadata.ResourceMetaDataManagerImpl; import com.cloud.server.ResourceTag; -import com.cloud.storage.Volume; +import com.cloud.server.TaggedResourceService; import com.cloud.storage.dao.VolumeDetailsDao; -import com.cloud.user.dao.UserDao; - -import javax.naming.ConfigurationException; +import com.cloud.vm.dao.NicDetailDao; public class ResourceMetaDataManagerTest { @@ -88,12 +73,12 @@ public class ResourceMetaDataManagerTest { //when(_resourceMetaDataMgr.getResourceId(anyString(), eq(ResourceTag.TaggedResourceType.Volume))).thenReturn(1L); - doReturn(1L).when(_taggedResourceMgr).getResourceId(anyString(), eq(ResourceTag.TaggedResourceType.Volume)); + doReturn(1L).when(_taggedResourceMgr).getResourceId(anyString(), eq(ResourceTag.ResourceObjectType.Volume)); // _volumeDetailDao.removeDetails(id, key); doNothing().when(_volumeDetailDao).removeDetails(anyLong(), anyString()); doNothing().when(_nicDetailDao).removeDetails(anyLong(), anyString()); - _resourceMetaDataMgr.deleteResourceMetaData(anyString(), eq(ResourceTag.TaggedResourceType.Volume), anyString()); + _resourceMetaDataMgr.deleteResourceMetaData(anyString(), eq(ResourceTag.ResourceObjectType.Volume), anyString()); } @@ -103,14 +88,14 @@ public class ResourceMetaDataManagerTest { - doReturn(1L).when(_taggedResourceMgr).getResourceId("1", ResourceTag.TaggedResourceType.Volume); + doReturn(1L).when(_taggedResourceMgr).getResourceId("1", ResourceTag.ResourceObjectType.Volume); // _volumeDetailDao.removeDetails(id, key); doNothing().when(_volumeDetailDao).removeDetails(anyLong(), anyString()); doNothing().when(_nicDetailDao).removeDetails(anyLong(), anyString()); Map map = new HashedMap(); map.put("key","value"); - _resourceMetaDataMgr.addResourceMetaData("1", ResourceTag.TaggedResourceType.Volume, map); + _resourceMetaDataMgr.addResourceMetaData("1", ResourceTag.ResourceObjectType.Volume, map); } diff --git a/server/test/com/cloud/network/CreatePrivateNetworkTest.java b/server/test/com/cloud/network/CreatePrivateNetworkTest.java index 0e57b027217..9276309037c 100644 --- a/server/test/com/cloud/network/CreatePrivateNetworkTest.java +++ b/server/test/com/cloud/network/CreatePrivateNetworkTest.java @@ -36,7 +36,6 @@ import org.junit.Ignore; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; - import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -63,6 +62,7 @@ import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.exception.CloudRuntimeException; //@Ignore("Requires database to be set up") @@ -152,8 +152,8 @@ public class CreatePrivateNetworkTest { @Test @DB public void createInvalidlyHostedPrivateNetwork() { - Transaction __txn; - __txn = Transaction.open("createInvalidlyHostedPrivateNetworkTest"); + TransactionLegacy __txn; + __txn = TransactionLegacy.open("createInvalidlyHostedPrivateNetworkTest"); /* Network nw; */ try { /* nw = */ diff --git a/server/test/com/cloud/network/DedicateGuestVlanRangesTest.java b/server/test/com/cloud/network/DedicateGuestVlanRangesTest.java index d6ee630569e..ea7167b471f 100644 --- a/server/test/com/cloud/network/DedicateGuestVlanRangesTest.java +++ b/server/test/com/cloud/network/DedicateGuestVlanRangesTest.java @@ -37,7 +37,6 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; - import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd; import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd; import org.apache.cloudstack.api.command.admin.network.ReleaseDedicatedGuestVlanRangeCmd; @@ -56,6 +55,7 @@ import com.cloud.user.AccountVO; import com.cloud.user.UserVO; import com.cloud.user.dao.AccountDao; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; public class DedicateGuestVlanRangesTest { @@ -177,7 +177,7 @@ public class DedicateGuestVlanRangesTest { } void runDedicateGuestVlanRangePostiveTest() throws Exception { - Transaction txn = Transaction.open("runDedicateGuestVlanRangePostiveTest"); + TransactionLegacy txn = TransactionLegacy.open("runDedicateGuestVlanRangePostiveTest"); Field dedicateVlanField = _dedicateGuestVlanRangeClass.getDeclaredField("vlan"); dedicateVlanField.setAccessible(true); @@ -213,7 +213,7 @@ public class DedicateGuestVlanRangesTest { } void runDedicateGuestVlanRangeInvalidFormat() throws Exception { - Transaction txn = Transaction.open("runDedicateGuestVlanRangeInvalidFormat"); + TransactionLegacy txn = TransactionLegacy.open("runDedicateGuestVlanRangeInvalidFormat"); Field dedicateVlanField = _dedicateGuestVlanRangeClass.getDeclaredField("vlan"); dedicateVlanField.setAccessible(true); @@ -234,7 +234,7 @@ public class DedicateGuestVlanRangesTest { } void runDedicateGuestVlanRangeInvalidRangeValue() throws Exception { - Transaction txn = Transaction.open("runDedicateGuestVlanRangeInvalidRangeValue"); + TransactionLegacy txn = TransactionLegacy.open("runDedicateGuestVlanRangeInvalidRangeValue"); Field dedicateVlanField = _dedicateGuestVlanRangeClass.getDeclaredField("vlan"); dedicateVlanField.setAccessible(true); @@ -255,7 +255,7 @@ public class DedicateGuestVlanRangesTest { } void runDedicateGuestVlanRangeAllocatedVlans() throws Exception { - Transaction txn = Transaction.open("runDedicateGuestVlanRangeAllocatedVlans"); + TransactionLegacy txn = TransactionLegacy.open("runDedicateGuestVlanRangeAllocatedVlans"); Field dedicateVlanField = _dedicateGuestVlanRangeClass.getDeclaredField("vlan"); dedicateVlanField.setAccessible(true); @@ -281,7 +281,7 @@ public class DedicateGuestVlanRangesTest { } void runDedicateGuestVlanRangeDedicatedRange() throws Exception { - Transaction txn = Transaction.open("runDedicateGuestVlanRangeDedicatedRange"); + TransactionLegacy txn = TransactionLegacy.open("runDedicateGuestVlanRangeDedicatedRange"); Field dedicateVlanField = _dedicateGuestVlanRangeClass.getDeclaredField("vlan"); dedicateVlanField.setAccessible(true); @@ -310,7 +310,7 @@ public class DedicateGuestVlanRangesTest { } void runDedicateGuestVlanRangePartiallyDedicated() throws Exception { - Transaction txn = Transaction.open("runDedicateGuestVlanRangePartiallyDedicated"); + TransactionLegacy txn = TransactionLegacy.open("runDedicateGuestVlanRangePartiallyDedicated"); Field dedicateVlanField = _dedicateGuestVlanRangeClass.getDeclaredField("vlan"); dedicateVlanField.setAccessible(true); @@ -339,7 +339,7 @@ public class DedicateGuestVlanRangesTest { } void runReleaseDedicatedGuestVlanRangePostiveTest() throws Exception { - Transaction txn = Transaction.open("runReleaseDedicatedGuestVlanRangePostiveTest"); + TransactionLegacy txn = TransactionLegacy.open("runReleaseDedicatedGuestVlanRangePostiveTest"); AccountGuestVlanMapVO accountGuestVlanMap = new AccountGuestVlanMapVO(1L, 1L); when(networkService._accountGuestVlanMapDao.findById(anyLong())).thenReturn(accountGuestVlanMap); @@ -357,7 +357,7 @@ public class DedicateGuestVlanRangesTest { } void runReleaseDedicatedGuestVlanRangeInvalidRange() throws Exception { - Transaction txn = Transaction.open("runReleaseDedicatedGuestVlanRangeInvalidRange"); + TransactionLegacy txn = TransactionLegacy.open("runReleaseDedicatedGuestVlanRangeInvalidRange"); when(networkService._accountGuestVlanMapDao.findById(anyLong())).thenReturn(null); diff --git a/server/test/com/cloud/network/UpdatePhysicalNetworkTest.java b/server/test/com/cloud/network/UpdatePhysicalNetworkTest.java index 1c0eff6453a..264f91ccdff 100644 --- a/server/test/com/cloud/network/UpdatePhysicalNetworkTest.java +++ b/server/test/com/cloud/network/UpdatePhysicalNetworkTest.java @@ -24,7 +24,8 @@ import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.utils.Pair; import com.cloud.utils.db.Transaction; -import org.junit.Test; +import com.cloud.utils.db.TransactionLegacy; + import org.junit.*; import org.mockito.ArgumentCaptor; import org.mockito.MockitoAnnotations.*; @@ -58,7 +59,7 @@ public class UpdatePhysicalNetworkTest { @Test public void updatePhysicalNetworkTest(){ - Transaction txn = Transaction.open("updatePhysicalNetworkTest"); + TransactionLegacy txn = TransactionLegacy.open("updatePhysicalNetworkTest"); NetworkServiceImpl networkService = setUp(); existingRange.add("524"); when(_physicalNetworkDao.findById(anyLong())).thenReturn(physicalNetworkVO); diff --git a/server/test/com/cloud/network/vpn/MockRemoteAccessVPNServiceProvider.java b/server/test/com/cloud/network/vpn/MockRemoteAccessVPNServiceProvider.java index 1dde4a84ebb..6e8cd69a802 100644 --- a/server/test/com/cloud/network/vpn/MockRemoteAccessVPNServiceProvider.java +++ b/server/test/com/cloud/network/vpn/MockRemoteAccessVPNServiceProvider.java @@ -23,7 +23,6 @@ import javax.ejb.Local; import javax.naming.ConfigurationException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.network.Network; import com.cloud.network.RemoteAccessVpn; import com.cloud.network.VpnUser; import com.cloud.network.element.RemoteAccessVPNServiceProvider; @@ -63,14 +62,14 @@ public class MockRemoteAccessVPNServiceProvider extends ManagerBase implements } @Override - public boolean startVpn(Network network, RemoteAccessVpn vpn) + public boolean startVpn(RemoteAccessVpn vpn) throws ResourceUnavailableException { // TODO Auto-generated method stub return false; } @Override - public boolean stopVpn(Network network, RemoteAccessVpn vpn) + public boolean stopVpn(RemoteAccessVpn vpn) throws ResourceUnavailableException { // TODO Auto-generated method stub return false; diff --git a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java index c9a0480809b..3147f1f9752 100755 --- a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java +++ b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java @@ -432,7 +432,7 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu @Override public NetworkOfferingVO createNetworkOffering(String name, String displayText, TrafficType trafficType, String tags, boolean specifyVlan, Availability availability, Integer networkRate, Map> serviceProviderMap, boolean isDefault, GuestType type, boolean systemOnly, Long serviceOfferingId, boolean conserveMode, - Map> serviceCapabilityMap, boolean specifyIpRanges, boolean isPersistent, Map details, boolean egressDefaultPolicy, Integer maxconn) { + Map> serviceCapabilityMap, boolean specifyIpRanges, boolean isPersistent, Map details, boolean egressDefaultPolicy, Integer maxconn, boolean enableKeepAlive) { // TODO Auto-generated method stub return null; } diff --git a/server/test/com/cloud/vpc/dao/MockConfigurationDaoImpl.java b/server/test/com/cloud/vpc/dao/MockConfigurationDaoImpl.java index a0110b56dae..0802b7a324d 100644 --- a/server/test/com/cloud/vpc/dao/MockConfigurationDaoImpl.java +++ b/server/test/com/cloud/vpc/dao/MockConfigurationDaoImpl.java @@ -72,6 +72,15 @@ public class MockConfigurationDaoImpl extends GenericDaoBase vrProvider = new HashSet(); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, false, Availability.Optional, 200, serviceProviderMap, false, Network.GuestType.Isolated, false, - null, false, null, true, false, null, false, null); + null, false, null, true, false, null, false, null, true); assertNotNull("Isolated network offering with specifyIpRanges=true and with no sourceNatService, failed to create", off); } @@ -208,7 +208,7 @@ public class CreateNetworkOfferingTest extends TestCase{ serviceProviderMap.put(Network.Service.Lb , vrProvider); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, true, Availability.Optional, 200, serviceProviderMap, false, Network.GuestType.Isolated, false, - null, false, null, false, false, null, false, null); + null, false, null, false, false, null, false, null, true); // System.out.println("Creating Vpc Network Offering"); assertNotNull("Vpc Isolated network offering with Vpc provider ", off); } @@ -228,7 +228,7 @@ public class CreateNetworkOfferingTest extends TestCase{ serviceProviderMap.put(Network.Service.Lb, lbProvider); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, true, Availability.Optional, 200, serviceProviderMap, false, Network.GuestType.Isolated, false, null, false, - null, false, false, null, false, null); + null, false, false, null, false, null, true); // System.out.println("Creating Vpc Network Offering"); assertNotNull("Vpc Isolated network offering with Vpc and Netscaler provider ", off); } diff --git a/server/test/org/apache/cloudstack/region/RegionManagerTest.java b/server/test/org/apache/cloudstack/region/RegionManagerTest.java index db6bf20cfb7..d1d6de4ddb5 100644 --- a/server/test/org/apache/cloudstack/region/RegionManagerTest.java +++ b/server/test/org/apache/cloudstack/region/RegionManagerTest.java @@ -18,33 +18,20 @@ package org.apache.cloudstack.region; +import java.util.HashMap; + +import javax.naming.ConfigurationException; + import junit.framework.Assert; -import junit.framework.TestCase; -import org.apache.cloudstack.api.command.admin.domain.DeleteDomainCmd; -import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.region.dao.RegionDao; - -import org.apache.log4j.Logger; -import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.user.Account; -import com.cloud.user.dao.AccountDao; +public class RegionManagerTest { - -public class RegionManagerTest extends TestCase { - private static final Logger s_logger = Logger.getLogger(RegionManagerTest.class); - - @Before - @Override - protected void setUp() { - - } - @Test public void testUniqueName() { RegionManagerImpl regionMgr = new RegionManagerImpl(); @@ -59,4 +46,10 @@ public class RegionManagerTest extends TestCase { } } + @Test + public void configure() throws ConfigurationException { + RegionManagerImpl regionManager = new RegionManagerImpl(); + regionManager.configure("foo", new HashMap()); + Assert.assertTrue(regionManager.getId() != 0); + } } diff --git a/server/test/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java b/server/test/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java index d0f09513e29..504ab9cebb2 100644 --- a/server/test/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java +++ b/server/test/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java @@ -33,7 +33,6 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; - import org.apache.cloudstack.api.command.user.region.ha.gslb.AssignToGlobalLoadBalancerRuleCmd; import org.apache.cloudstack.api.command.user.region.ha.gslb.CreateGlobalLoadBalancerRuleCmd; import org.apache.cloudstack.api.command.user.region.ha.gslb.DeleteGlobalLoadBalancerRuleCmd; @@ -59,6 +58,7 @@ import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; import com.cloud.user.UserVO; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; import com.cloud.utils.net.Ip; public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { @@ -181,7 +181,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { void runCreateGlobalLoadBalancerRulePostiveTest() throws Exception { - Transaction txn = Transaction.open("runCreateGlobalLoadBalancerRulePostiveTest"); + TransactionLegacy txn = TransactionLegacy.open("runCreateGlobalLoadBalancerRulePostiveTest"); GlobalLoadBalancingRulesServiceImpl gslbServiceImpl = new GlobalLoadBalancingRulesServiceImpl(); @@ -246,7 +246,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { void runCreateGlobalLoadBalancerRuleInvalidAlgorithm() throws Exception { - Transaction txn = Transaction.open("runCreateGlobalLoadBalancerRulePostiveTest"); + TransactionLegacy txn = TransactionLegacy.open("runCreateGlobalLoadBalancerRulePostiveTest"); GlobalLoadBalancingRulesServiceImpl gslbServiceImpl = new GlobalLoadBalancingRulesServiceImpl(); @@ -311,7 +311,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { void runCreateGlobalLoadBalancerRuleInvalidStickyMethod() throws Exception { - Transaction txn = Transaction.open("runCreateGlobalLoadBalancerRulePostiveTest"); + TransactionLegacy txn = TransactionLegacy.open("runCreateGlobalLoadBalancerRulePostiveTest"); GlobalLoadBalancingRulesServiceImpl gslbServiceImpl = new GlobalLoadBalancingRulesServiceImpl(); @@ -376,7 +376,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { void runCreateGlobalLoadBalancerRuleInvalidServiceType() throws Exception { - Transaction txn = Transaction.open("runCreateGlobalLoadBalancerRulePostiveTest"); + TransactionLegacy txn = TransactionLegacy.open("runCreateGlobalLoadBalancerRulePostiveTest"); GlobalLoadBalancingRulesServiceImpl gslbServiceImpl = new GlobalLoadBalancingRulesServiceImpl(); @@ -441,7 +441,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { void runCreateGlobalLoadBalancerRuleInvalidDomainName() throws Exception { - Transaction txn = Transaction.open("runCreateGlobalLoadBalancerRulePostiveTest"); + TransactionLegacy txn = TransactionLegacy.open("runCreateGlobalLoadBalancerRulePostiveTest"); GlobalLoadBalancingRulesServiceImpl gslbServiceImpl = new GlobalLoadBalancingRulesServiceImpl(); @@ -507,7 +507,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { void runAssignToGlobalLoadBalancerRuleTest() throws Exception { - Transaction txn = Transaction.open("runAssignToGlobalLoadBalancerRuleTest"); + TransactionLegacy txn = TransactionLegacy.open("runAssignToGlobalLoadBalancerRuleTest"); GlobalLoadBalancingRulesServiceImpl gslbServiceImpl = new GlobalLoadBalancingRulesServiceImpl(); @@ -570,7 +570,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { void runAssignToGlobalLoadBalancerRuleTestSameZoneLb() throws Exception { - Transaction txn = Transaction.open("runAssignToGlobalLoadBalancerRuleTestSameZoneLb"); + TransactionLegacy txn = TransactionLegacy.open("runAssignToGlobalLoadBalancerRuleTestSameZoneLb"); GlobalLoadBalancingRulesServiceImpl gslbServiceImpl = new GlobalLoadBalancingRulesServiceImpl(); @@ -655,7 +655,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { void runAssignToGlobalLoadBalancerRuleTestRevokedState() throws Exception { - Transaction txn = Transaction.open("runAssignToGlobalLoadBalancerRuleTestRevokedState"); + TransactionLegacy txn = TransactionLegacy.open("runAssignToGlobalLoadBalancerRuleTestRevokedState"); GlobalLoadBalancingRulesServiceImpl gslbServiceImpl = new GlobalLoadBalancingRulesServiceImpl(); @@ -712,7 +712,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { void runRemoveFromGlobalLoadBalancerRuleTest() throws Exception { - Transaction txn = Transaction.open("runRemoveFromGlobalLoadBalancerRuleTest"); + TransactionLegacy txn = TransactionLegacy.open("runRemoveFromGlobalLoadBalancerRuleTest"); GlobalLoadBalancingRulesServiceImpl gslbServiceImpl = new GlobalLoadBalancingRulesServiceImpl(); @@ -785,7 +785,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { void runRemoveFromGlobalLoadBalancerRuleTestUnassignedLb() throws Exception { - Transaction txn = Transaction.open("runRemoveFromGlobalLoadBalancerRuleTestUnassignedLb"); + TransactionLegacy txn = TransactionLegacy.open("runRemoveFromGlobalLoadBalancerRuleTestUnassignedLb"); GlobalLoadBalancingRulesServiceImpl gslbServiceImpl = new GlobalLoadBalancingRulesServiceImpl(); @@ -846,7 +846,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { void runRemoveFromGlobalLoadBalancerRuleTestInvalidLb() throws Exception { - Transaction txn = Transaction.open("runRemoveFromGlobalLoadBalancerRuleTestInvalidLb"); + TransactionLegacy txn = TransactionLegacy.open("runRemoveFromGlobalLoadBalancerRuleTestInvalidLb"); GlobalLoadBalancingRulesServiceImpl gslbServiceImpl = new GlobalLoadBalancingRulesServiceImpl(); @@ -890,7 +890,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { void runDeleteGlobalLoadBalancerRuleTestWithNoLbRules() throws Exception { - Transaction txn = Transaction.open("runDeleteGlobalLoadBalancerRuleTestWithNoLbRules"); + TransactionLegacy txn = TransactionLegacy.open("runDeleteGlobalLoadBalancerRuleTestWithNoLbRules"); GlobalLoadBalancingRulesServiceImpl gslbServiceImpl = new GlobalLoadBalancingRulesServiceImpl(); @@ -936,7 +936,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { void runDeleteGlobalLoadBalancerRuleTestWithLbRules() throws Exception { - Transaction txn = Transaction.open("runDeleteGlobalLoadBalancerRuleTestWithLbRules"); + TransactionLegacy txn = TransactionLegacy.open("runDeleteGlobalLoadBalancerRuleTestWithLbRules"); GlobalLoadBalancingRulesServiceImpl gslbServiceImpl = new GlobalLoadBalancingRulesServiceImpl(); diff --git a/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties b/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties new file mode 100644 index 00000000000..7ff8a3ac13f --- /dev/null +++ b/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=secondary-storage-discoverer +parent=discoverer \ No newline at end of file diff --git a/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml b/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml new file mode 100644 index 00000000000..30521aa3261 --- /dev/null +++ b/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml @@ -0,0 +1,36 @@ + + + + + + + + + diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 85d25f9a860..75d959be3ba 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -857,10 +857,12 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } } + + long srcSize = srcFile.length(); ImageFormat format = getTemplateFormat(srcFile.getName()); String key = destData.getPath() + S3Utils.SEPARATOR + srcFile.getName(); - if (s3.isMultipartEnabled()){ - mputFile(s3, srcFile, bucket, key); + if (!s3.getSingleUpload(srcSize)){ + mputFile(s3, srcFile, bucket, key); } else{ putFile(s3, srcFile, bucket, key); } diff --git a/setup/db/db/schema-420to421.sql b/setup/db/db/schema-420to421.sql index 4dfe4e672cd..e72e1b219c6 100644 --- a/setup/db/db/schema-420to421.sql +++ b/setup/db/db/schema-420to421.sql @@ -20,10 +20,199 @@ --; -INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 's3.multipart.enabled', 'true', 'enable s3 multipart upload'); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 's3.singleupload.max.size', '5', + 'The maximum size limit for S3 single part upload API(in GB). If it is set to 0, then it means always use multi-part upload to upload object to S3. If it is set to -1, then it means always use single-part upload to upload object to S3.'); INSERT IGNORE INTO `cloud`.`configuration` VALUES ("Storage", 'DEFAULT', 'management-server', "enable.ha.storage.migration", "true", "Enable/disable storage migration across primary storage during HA"); -- Remove Windows Server 8 from guest_os_type dropdown to use Windows Server 2012 DELETE FROM `cloud`.`guest_os_hypervisor` where guest_os_id=168; -DELETE FROM `cloud`.`guest_os` where id=168; \ No newline at end of file +DELETE FROM `cloud`.`guest_os` where id=168; + + +--Add details to the user_vm_view (CLOUDSTACK-4649 - xen and UI code needs to retrieve the value of "hypervisortoolsversion" detail) + +DROP VIEW IF EXISTS `cloud`.`user_vm_view`; +CREATE VIEW `cloud`.`user_vm_view` AS + select + vm_instance.id id, + vm_instance.name name, + user_vm.display_name display_name, + user_vm.user_data user_data, + account.id account_id, + account.uuid account_uuid, + account.account_name account_name, + account.type account_type, + domain.id domain_id, + domain.uuid domain_uuid, + domain.name domain_name, + domain.path domain_path, + projects.id project_id, + projects.uuid project_uuid, + projects.name project_name, + instance_group.id instance_group_id, + instance_group.uuid instance_group_uuid, + instance_group.name instance_group_name, + vm_instance.uuid uuid, + vm_instance.last_host_id last_host_id, + vm_instance.vm_type type, + vm_instance.vnc_password vnc_password, + vm_instance.limit_cpu_use limit_cpu_use, + vm_instance.created created, + vm_instance.state state, + vm_instance.removed removed, + vm_instance.ha_enabled ha_enabled, + vm_instance.hypervisor_type hypervisor_type, + vm_instance.instance_name instance_name, + vm_instance.guest_os_id guest_os_id, + vm_instance.display_vm display_vm, + guest_os.uuid guest_os_uuid, + vm_instance.pod_id pod_id, + host_pod_ref.uuid pod_uuid, + vm_instance.private_ip_address private_ip_address, + vm_instance.private_mac_address private_mac_address, + vm_instance.vm_type vm_type, + data_center.id data_center_id, + data_center.uuid data_center_uuid, + data_center.name data_center_name, + data_center.is_security_group_enabled security_group_enabled, + data_center.networktype data_center_type, + host.id host_id, + host.uuid host_uuid, + host.name host_name, + vm_template.id template_id, + vm_template.uuid template_uuid, + vm_template.name template_name, + vm_template.display_text template_display_text, + vm_template.enable_password password_enabled, + iso.id iso_id, + iso.uuid iso_uuid, + iso.name iso_name, + iso.display_text iso_display_text, + service_offering.id service_offering_id, + disk_offering.uuid service_offering_uuid, + service_offering.cpu cpu, + service_offering.speed speed, + service_offering.ram_size ram_size, + disk_offering.name service_offering_name, + storage_pool.id pool_id, + storage_pool.uuid pool_uuid, + storage_pool.pool_type pool_type, + volumes.id volume_id, + volumes.uuid volume_uuid, + volumes.device_id volume_device_id, + volumes.volume_type volume_type, + security_group.id security_group_id, + security_group.uuid security_group_uuid, + security_group.name security_group_name, + security_group.description security_group_description, + nics.id nic_id, + nics.uuid nic_uuid, + nics.network_id network_id, + nics.ip4_address ip_address, + nics.ip6_address ip6_address, + nics.ip6_gateway ip6_gateway, + nics.ip6_cidr ip6_cidr, + nics.default_nic is_default_nic, + nics.gateway gateway, + nics.netmask netmask, + nics.mac_address mac_address, + nics.broadcast_uri broadcast_uri, + nics.isolation_uri isolation_uri, + vpc.id vpc_id, + vpc.uuid vpc_uuid, + networks.uuid network_uuid, + networks.name network_name, + networks.traffic_type traffic_type, + networks.guest_type guest_type, + user_ip_address.id public_ip_id, + user_ip_address.uuid public_ip_uuid, + user_ip_address.public_ip_address public_ip_address, + ssh_keypairs.keypair_name keypair_name, + resource_tags.id tag_id, + resource_tags.uuid tag_uuid, + resource_tags.key tag_key, + resource_tags.value tag_value, + resource_tags.domain_id tag_domain_id, + resource_tags.account_id tag_account_id, + resource_tags.resource_id tag_resource_id, + resource_tags.resource_uuid tag_resource_uuid, + resource_tags.resource_type tag_resource_type, + resource_tags.customer tag_customer, + async_job.id job_id, + async_job.uuid job_uuid, + async_job.job_status job_status, + async_job.account_id job_account_id, + affinity_group.id affinity_group_id, + affinity_group.uuid affinity_group_uuid, + affinity_group.name affinity_group_name, + affinity_group.description affinity_group_description, + vm_instance.dynamically_scalable dynamically_scalable, + all_details.name detail_name, + all_details.value detail_value + + from + `cloud`.`user_vm` + inner join + `cloud`.`vm_instance` ON vm_instance.id = user_vm.id + and vm_instance.removed is NULL + inner join + `cloud`.`account` ON vm_instance.account_id = account.id + inner join + `cloud`.`domain` ON vm_instance.domain_id = domain.id + left join + `cloud`.`guest_os` ON vm_instance.guest_os_id = guest_os.id + left join + `cloud`.`host_pod_ref` ON vm_instance.pod_id = host_pod_ref.id + left join + `cloud`.`projects` ON projects.project_account_id = account.id + left join + `cloud`.`instance_group_vm_map` ON vm_instance.id = instance_group_vm_map.instance_id + left join + `cloud`.`instance_group` ON instance_group_vm_map.group_id = instance_group.id + left join + `cloud`.`data_center` ON vm_instance.data_center_id = data_center.id + left join + `cloud`.`host` ON vm_instance.host_id = host.id + left join + `cloud`.`vm_template` ON vm_instance.vm_template_id = vm_template.id + left join + `cloud`.`vm_template` iso ON iso.id = user_vm.iso_id + left join + `cloud`.`service_offering` ON vm_instance.service_offering_id = service_offering.id + left join + `cloud`.`disk_offering` ON vm_instance.service_offering_id = disk_offering.id + left join + `cloud`.`volumes` ON vm_instance.id = volumes.instance_id + left join + `cloud`.`storage_pool` ON volumes.pool_id = storage_pool.id + left join + `cloud`.`security_group_vm_map` ON vm_instance.id = security_group_vm_map.instance_id + left join + `cloud`.`security_group` ON security_group_vm_map.security_group_id = security_group.id + left join + `cloud`.`nics` ON vm_instance.id = nics.instance_id and nics.removed is null + left join + `cloud`.`networks` ON nics.network_id = networks.id + left join + `cloud`.`vpc` ON networks.vpc_id = vpc.id and vpc.removed is null + left join + `cloud`.`user_ip_address` ON user_ip_address.vm_id = vm_instance.id + left join + `cloud`.`user_vm_details` as ssh_details ON ssh_details.vm_id = vm_instance.id + and ssh_details.name = 'SSH.PublicKey' + left join + `cloud`.`ssh_keypairs` ON ssh_keypairs.public_key = ssh_details.value + left join + `cloud`.`resource_tags` ON resource_tags.resource_id = vm_instance.id + and resource_tags.resource_type = 'UserVm' + left join + `cloud`.`async_job` ON async_job.instance_id = vm_instance.id + and async_job.instance_type = 'VirtualMachine' + and async_job.job_status = 0 + left join + `cloud`.`affinity_group_vm_map` ON vm_instance.id = affinity_group_vm_map.instance_id + left join + `cloud`.`affinity_group` ON affinity_group_vm_map.affinity_group_id = affinity_group.id + left join + `cloud`.`user_vm_details` as all_details ON all_details.vm_id = vm_instance.id; \ No newline at end of file diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql index 8e4aa939e03..aaebf960214 100644 --- a/setup/db/db/schema-421to430.sql +++ b/setup/db/db/schema-421to430.sql @@ -33,6 +33,8 @@ ALTER TABLE `cloud`.`async_job` ADD COLUMN `job_dispatcher` VARCHAR(64); ALTER TABLE `cloud`.`async_job` ADD COLUMN `job_executing_msid` bigint; ALTER TABLE `cloud`.`async_job` ADD COLUMN `job_pending_signals` int(10) NOT NULL DEFAULT 0; +ALTER TABLE `cloud`.`network_offerings` ADD COLUMN `keep_alive_enabled` int(1) unsigned NOT NULL DEFAULT 1 COMMENT 'true if connection should be reset after requests.'; + ALTER TABLE `cloud`.`vm_instance` ADD COLUMN `power_state` VARCHAR(74) DEFAULT 'PowerUnknown'; ALTER TABLE `cloud`.`vm_instance` ADD COLUMN `power_state_update_time` DATETIME; ALTER TABLE `cloud`.`vm_instance` ADD COLUMN `power_state_update_count` INT DEFAULT 0; diff --git a/setup/dev/advanced.cfg b/setup/dev/advanced.cfg index 4a483995f48..216314ff6bc 100644 --- a/setup/dev/advanced.cfg +++ b/setup/dev/advanced.cfg @@ -14,7 +14,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. - { "zones": [ { @@ -220,7 +219,10 @@ "passwd": "password", "user": "root", "port": 8096, - "hypervisor" : "simulator" + "hypervisor": "simulator", + "useHttps": "False", + "certCAPath": "NA", + "certPath": "NA" } ] } diff --git a/systemvm/patches/debian/config/etc/init.d/cloud-early-config b/systemvm/patches/debian/config/etc/init.d/cloud-early-config index 88ecc119b61..d44f94d7d17 100755 --- a/systemvm/patches/debian/config/etc/init.d/cloud-early-config +++ b/systemvm/patches/debian/config/etc/init.d/cloud-early-config @@ -1189,6 +1189,7 @@ change_password() { start() { # Clear /tmp for file lock rm -f /tmp/*.lock + rm -f /tmp/rrouter_bumped local hyp=$(hypervisor) [ $? -ne 0 ] && log_it "Failed to detect hypervisor type, bailing out of early init" && exit 10 log_it "Detected that we are running inside $hyp guest" diff --git a/systemvm/patches/debian/config/root/savepassword.sh b/systemvm/patches/debian/config/opt/cloud/bin/savepassword.sh similarity index 89% rename from systemvm/patches/debian/config/root/savepassword.sh rename to systemvm/patches/debian/config/opt/cloud/bin/savepassword.sh index fc736039c2e..1ea27e5b702 100755 --- a/systemvm/patches/debian/config/root/savepassword.sh +++ b/systemvm/patches/debian/config/opt/cloud/bin/savepassword.sh @@ -53,6 +53,13 @@ done [ -f $PASSWD_FILE ] || touch $PASSWD_FILE sed -i /$VM_IP/d $PASSWD_FILE -echo "$VM_IP=$PASSWORD" >> $PASSWD_FILE + +ps aux | grep serve_password.sh |grep -v grep 2>&1 > /dev/null +if [ $? -eq 0 ] +then + echo "$VM_IP=$PASSWORD" >> $PASSWD_FILE +else + echo "$VM_IP=saved_password" >> $PASSWD_FILE +fi unlock_exit $? $lock $locked diff --git a/systemvm/patches/debian/config/root/redundant_router/check_heartbeat.sh.templ b/systemvm/patches/debian/config/root/redundant_router/check_heartbeat.sh.templ index 1a390e69eea..95cabd6b067 100755 --- a/systemvm/patches/debian/config/root/redundant_router/check_heartbeat.sh.templ +++ b/systemvm/patches/debian/config/root/redundant_router/check_heartbeat.sh.templ @@ -25,10 +25,13 @@ then if [ $diff -lt 30 ] then echo Keepalived process is dead! >> [RROUTER_LOG] + [RROUTER_BIN_PATH]/services.sh stop >> [RROUTER_LOG] 2>&1 + [RROUTER_BIN_PATH]/disable_pubip.sh >> [RROUTER_LOG] 2>&1 + [RROUTER_BIN_PATH]/primary-backup.sh fault >> [RROUTER_LOG] 2>&1 service keepalived stop >> [RROUTER_LOG] 2>&1 service conntrackd stop >> [RROUTER_LOG] 2>&1 pkill -9 keepalived >> [RROUTER_LOG] 2>&1 - [RROUTER_BIN_PATH]/disable_pubip.sh >> [RROUTER_LOG] 2>&1 + pkill -9 conntrackd >> [RROUTER_LOG] 2>&1 echo Status: FAULT \(keepalived process is dead\) >> [RROUTER_LOG] exit fi diff --git a/systemvm/patches/debian/config/root/redundant_router/fault.sh.templ b/systemvm/patches/debian/config/root/redundant_router/fault.sh.templ index aecb08db247..c008a9cb449 100644 --- a/systemvm/patches/debian/config/root/redundant_router/fault.sh.templ +++ b/systemvm/patches/debian/config/root/redundant_router/fault.sh.templ @@ -27,7 +27,11 @@ fi echo To fault called >> [RROUTER_LOG] [RROUTER_BIN_PATH]/disable_pubip.sh >> [RROUTER_LOG] 2>&1 +echo Disable public ip >> [RROUTER_LOG] +[RROUTER_BIN_PATH]/services.sh stop >> [RROUTER_LOG] 2>&1 +echo Stop services $? >> [RROUTER_LOG] [RROUTER_BIN_PATH]/primary-backup.sh fault >> [RROUTER_LOG] 2>&1 +echo Switch conntrackd mode fault $? >> [RROUTER_LOG] echo Status: FAULT >> [RROUTER_LOG] releaseLockFile $lock $locked diff --git a/test/integration/component/maint/test_multiple_ip_ranges.py b/test/integration/component/maint/test_multiple_ip_ranges.py index 68b5979fc5d..3f0035e7769 100644 --- a/test/integration/component/maint/test_multiple_ip_ranges.py +++ b/test/integration/component/maint/test_multiple_ip_ranges.py @@ -384,3 +384,210 @@ class TestMultipleIpRanges(cloudstackTestCase): time.sleep(wait_time) return + @attr(tags=["sg"]) + def test_03_passwd_service_on_alias_IP(self): + """Deploy guest vm in new CIDR and verify passwd service on alias ip + 1.Deploy guest vm in new cidr + 2.Verify password service(socat) listens on alias ip in VR + """ + #Deploy guest vm + try : + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["server_without_disk"], + templateid = self.template.id, + accountid = self.account.name, + domainid = self.services["domainid"], + zoneid = self.services["zoneid"], + serviceofferingid = self.service_offering.id, + mode = self.services["mode"], + ) + except Exception as e : + raise Exception("Warning: Exception during vm deployment: {}".format(e)) + self.vm_response = VirtualMachine.list( + self.apiclient, + id = self.virtual_machine.id + ) + self.assertEqual( + isinstance(self.vm_response, list), + True, + "Check VM list response returned a valid list" + ) + self.ip_range = list(netaddr.iter_iprange(unicode(self.services["vlan_ip_range"]["startip"]), unicode(self.services["vlan_ip_range"]["endip"]))) + self.nic_ip = netaddr.IPAddress(unicode(self.vm_response[0].nic[0].ipaddress)) + self.debug("vm got {} as ip address".format(self.nic_ip)) + self.assertIn( + self.nic_ip, + self.ip_range, + "VM did not get the ip address from the new ip range" + ) + ip_alias = self.dbclient.execute( + "select ip4_address from nic_ip_alias;" + ) + alias_ip = str(ip_alias[0][0]) + self.debug("alias ip : %s" % alias_ip) + list_router_response = list_routers( + self.apiclient, + zoneid=self.zone.id, + listall=True + ) + self.assertEqual( + isinstance(list_router_response, list), + True, + "Check list response returns a valid list" + ) + router = list_router_response[0] + hosts = list_hosts( + self.apiclient, + zoneid=router.zoneid, + type='Routing', + state='Up', + id=router.hostid + ) + self.assertEqual( + isinstance(hosts, list), + True, + "Check list host returns a valid list" + ) + host = hosts[0] + self.debug("Router ID: %s, state: %s" % (router.id, router.state)) + self.assertEqual( + router.state, + 'Running', + "Check list router response for router state" + ) + proc = "socat" + result = get_process_status( + host.ipaddress, + self.services['host']["publicport"], + self.services['host']["username"], + self.services['host']["password"], + router.linklocalip, + "netstat -atnp | grep %s" % proc + ) + res = str(result) + self.debug("password process status on VR: %s" % res) + self.assertNotEqual( + res.find(alias_ip) + -1, + "password service is not running on alias ip" + ) + self.virtual_machine.delete(self.apiclient) + expunge_del = Configurations.list( + self.apiclient, + name = 'expunge.delay' + ) + expunge_int = Configurations.list( + self.apiclient, + name = 'expunge.interval' + ) + wait_time = int(expunge_del[0].value) + int(expunge_int[0].value) + int(30) + + self.debug("Waiting for {} seconds for the vm to expunge".format(wait_time)) + #wait for the vm to expunge + time.sleep(wait_time) + return + + @attr(tags=["sg"]) + def test_04_userdata_service_on_alias_IP(self): + """Deploy guest vm in new CIDR and verify userdata service on alias ip + 1.Deploy guest vm in new cidr + 2.Verify userdata service(apache2) listens on alias ip in VR + """ + #Deploy guest vm + try : + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["server_without_disk"], + templateid = self.template.id, + accountid = self.account.name, + domainid = self.services["domainid"], + zoneid = self.services["zoneid"], + serviceofferingid = self.service_offering.id, + mode = self.services["mode"], + ) + except Exception as e : + raise Exception("Warning: Exception during vm deployment: {}".format(e)) + self.vm_response = VirtualMachine.list( + self.apiclient, + id = self.virtual_machine.id + ) + self.assertEqual( + isinstance(self.vm_response, list), + True, + "Check VM list response returned a valid list" + ) + self.ip_range = list(netaddr.iter_iprange(unicode(self.services["vlan_ip_range"]["startip"]), unicode(self.services["vlan_ip_range"]["endip"]))) + self.nic_ip = netaddr.IPAddress(unicode(self.vm_response[0].nic[0].ipaddress)) + self.debug("vm got {} as ip address".format(self.nic_ip)) + self.assertIn( + self.nic_ip, + self.ip_range, + "VM did not get the ip address from the new ip range" + ) + ip_alias = self.dbclient.execute( + "select ip4_address from nic_ip_alias;" + ) + alias_ip = str(ip_alias[0][0]) + self.debug("alias ip : %s" % alias_ip) + list_router_response = list_routers( + self.apiclient, + zoneid=self.zone.id, + listall=True + ) + self.assertEqual( + isinstance(list_router_response, list), + True, + "Check list response returns a valid list" + ) + router = list_router_response[0] + hosts = list_hosts( + self.apiclient, + zoneid=router.zoneid, + type='Routing', + state='Up', + id=router.hostid + ) + self.assertEqual( + isinstance(hosts, list), + True, + "Check list host returns a valid list" + ) + host = hosts[0] + self.debug("Router ID: %s, state: %s" % (router.id, router.state)) + self.assertEqual( + router.state, + 'Running', + "Check list router response for router state" + ) + proc = "apache2" + result = get_process_status( + host.ipaddress, + self.services['host']["publicport"], + self.services['host']["username"], + self.services['host']["password"], + router.linklocalip, + "netstat -atnp | grep %s" % proc + ) + res = str(result) + self.debug("userdata process status on VR: %s" % res) + self.assertNotEqual( + res.find(alias_ip+":80 ") + -1, + "password service is not running on alias ip" + ) + self.virtual_machine.delete(self.apiclient) + expunge_del = Configurations.list( + self.apiclient, + name = 'expunge.delay' + ) + expunge_int = Configurations.list( + self.apiclient, + name = 'expunge.interval' + ) + wait_time = int(expunge_del[0].value) + int(expunge_int[0].value) + int(30) + + self.debug("Waiting for {} seconds for the vm to expunge".format(wait_time)) + #wait for the vm to expunge + time.sleep(wait_time) + return diff --git a/test/integration/component/memory_limits/test_domain_limits.py b/test/integration/component/memory_limits/test_domain_limits.py index 479ec0ba3e9..d87db84a470 100644 --- a/test/integration/component/memory_limits/test_domain_limits.py +++ b/test/integration/component/memory_limits/test_domain_limits.py @@ -32,7 +32,8 @@ from marvin.integration.lib.common import (get_domain, cleanup_resources, wait_for_cleanup, find_suitable_host, - get_resource_type + get_resource_type, + update_resource_count ) class Services: @@ -219,12 +220,16 @@ class TestDomainMemoryLimits(cloudstackTestCase): self.debug("Setting up account and domain hierarchy") self.setupAccounts() - users = { self.domain: self.admin, - self.child_domain: self.child_do_admin + users = { self.child_domain_1: self.child_do_admin_1, + self.child_domain_2: self.child_do_admin_2 } for domain, admin in users.items(): self.account = admin self.domain = domain + + #Resetting memory count in service offering + self.services["service_offering"]["memory"] = 5120 + self.debug("Creating an instance with service offering: %s" % self.service_offering.name) @@ -258,7 +263,7 @@ class TestDomainMemoryLimits(cloudstackTestCase): ) resource_count_after_stop = account_list[0].memorytotal - self.asserEqual(resource_count_after_stop, expected_resource_count, + self.assertEqual(resource_count_after_stop, expected_resource_count, "Resource count should be same after stopping the instance") self.debug("Creating service offering with 7 GB RAM") @@ -283,6 +288,8 @@ class TestDomainMemoryLimits(cloudstackTestCase): self.fail("Failed to change service offering of vm %s - %s" % (vm.name, e)) + update_resource_count(self.apiclient, domainid=self.domain.id, rtype=9) #RAM + account_list = Account.list(self.apiclient, id=self.account.id) self.assertIsInstance(account_list, list, @@ -308,13 +315,18 @@ class TestDomainMemoryLimits(cloudstackTestCase): self.fail("Failed to change service offering of vm %s - %s" % (vm.name, e)) + update_resource_count(self.apiclient, domainid=self.domain.id, rtype=9) #RAM + account_list = Account.list(self.apiclient, id=self.account.id) self.assertIsInstance(account_list, list, "List Accounts should return a valid response" ) + resource_count_after_downgrade = account_list[0].memorytotal + self.debug(resource_count_after_downgrade) + self.assertTrue(resource_count_after_downgrade < resource_count_after_upgrade, "Resource count should be less than before, after downgrading service offering") @@ -344,10 +356,13 @@ class TestDomainMemoryLimits(cloudstackTestCase): # 2. List Resource count for the root admin Memory usage # 3. Migrate vm to another host, resource count should list properly. + #Resetting memory count in service offering + self.services["service_offering"]["memory"] = 5120 + self.debug("Setting up account and domain hierarchy") self.setupAccounts() - users = { self.domain: self.admin, - self.child_domain: self.child_do_admin + users = { self.child_domain_1: self.child_do_admin_1, + self.child_domain_2: self.child_do_admin_2 } for domain, admin in users.items(): self.account = admin @@ -400,10 +415,13 @@ class TestDomainMemoryLimits(cloudstackTestCase): # 2. List Resource count for the root admin Memory usage # 3. Delete vm, resource count should list as 0 after delete operation. + # Resetting the memory count of service offering + self.services["service_offering"]["memory"] = 5120 + self.debug("Setting up account and domain hierarchy") self.setupAccounts() - users = { self.domain: self.admin, - self.child_domain: self.child_do_admin + users = { self.child_domain_1: self.child_do_admin_1, + self.child_domain_2: self.child_do_admin_2 } for domain, admin in users.items(): self.account = admin @@ -457,10 +475,13 @@ class TestDomainMemoryLimits(cloudstackTestCase): # 3. List Resource count for the root admin Memory usage # 4. Memory usage should list properly + # Resetting the memory count of service offering + self.services["service_offering"]["memory"] = 5120 + self.debug("Setting up account and domain hierarchy") self.setupAccounts() - users = { self.domain: self.admin, - self.child_domain: self.child_do_admin + users = { self.child_domain_1: self.child_do_admin_1, + self.child_domain_2: self.child_do_admin_2 } for domain, admin in users.items(): self.account = admin @@ -496,7 +517,6 @@ class TestDomainMemoryLimits(cloudstackTestCase): vm_3.delete(self.apiclient) return - class TestMultipleChildDomainsMemory(cloudstackTestCase): @classmethod @@ -507,7 +527,7 @@ class TestMultipleChildDomainsMemory(cloudstackTestCase): # Get Zone, Domain and templates cls.domain = get_domain(cls.api_client, cls.services) cls.zone = get_zone(cls.api_client, cls.services) - cls.services["mode"] = cls.zone.networktype + cls.services["mode"] = cls.zone.networktype cls.template = get_template( cls.api_client, @@ -548,8 +568,8 @@ class TestMultipleChildDomainsMemory(cloudstackTestCase): self.debug("Deploying an instance in account: %s" % account.name) - if api_client is None: - api_client = self.apiclient + if api_client is None: + api_client = self.apiclient try: vm = VirtualMachine.create( @@ -644,12 +664,12 @@ class TestMultipleChildDomainsMemory(cloudstackTestCase): account=self.cadmin_2.name, domainid=self.cadmin_2.domainid) - # Cleanup the resources created at end of test + # Cleanup the resources created at end of test self.cleanup.append(self.cadmin_1) self.cleanup.append(self.cadmin_2) self.cleanup.append(self.cdomain_1) - self.cleanup.append(self.cdomain_2) - self.cleanup.append(self.parentd_admin) + self.cleanup.append(self.cdomain_2) + self.cleanup.append(self.parentd_admin) self.cleanup.append(self.parent_domain) users = { @@ -687,11 +707,11 @@ class TestMultipleChildDomainsMemory(cloudstackTestCase): self.debug("Setting up account and domain hierarchy") self.setupAccounts() - api_client_cadmin_1 = self.testClient.createUserApiClient( + api_client_cadmin_1 = self.testClient.createUserApiClient( UserName=self.cadmin_1.name, DomainName=self.cadmin_1.domain) - api_client_cadmin_2 = self.testClient.createUserApiClient( + api_client_cadmin_2 = self.testClient.createUserApiClient( UserName=self.cadmin_2.name, DomainName=self.cadmin_2.domain) diff --git a/test/integration/component/test_egress_fw_rules.py b/test/integration/component/test_egress_fw_rules.py index 5c18f9c10a2..253cc46cab9 100644 --- a/test/integration/component/test_egress_fw_rules.py +++ b/test/integration/component/test_egress_fw_rules.py @@ -42,16 +42,6 @@ from marvin.cloudstackAPI.deleteEgressFirewallRule import deleteEgressFirewallRu from marvin.remoteSSHClient import remoteSSHClient import time -def log_test_exceptions(func): - def test_wrap_exception_log(self, *args, **kwargs): - try: - func(self, *args, **kwargs) - except Exception as e: - self.debug('Test %s Failed due to Exception=%s' % (func, e)) - raise e - test_wrap_exception_log.__doc__ = func.__doc__ - return test_wrap_exception_log - class Services: """Test service data: Egress Firewall rules Tests for Advance Zone. """ @@ -117,6 +107,7 @@ class Services: "serviceCapabilityList": { "SourceNat": { "SupportedSourceNatTypes": "peraccount", + "RedundantRouter": "true" } }, }, @@ -186,7 +177,7 @@ class TestEgressFWRules(cloudstackTestCase): if RR: self.debug("Redundant Router Enabled") - self.services["network_offering"]["serviceCapabilityList"]["RedundantRouter"] = "true" + self.services["network_offering"]["serviceCapabilityList"]["SourceNat"]["RedundantRouter"] = "true" self.network_offering = NetworkOffering.create(self.apiclient, self.services["network_offering"], @@ -288,16 +279,31 @@ class TestEgressFWRules(cloudstackTestCase): ssh.execute('chmod +x %s' % script_file) self.debug("%s %s" % (script_file, exec_cmd_params)) - self.debug('sleep %s seconds for egress rule to affect on Router.' % self.services['sleep']) - time.sleep(self.services['sleep']) - - result = ssh.execute("%s %s" % (script_file, exec_cmd_params)) - self.debug('Result is=%s' % result) - exec_success = False - if str(result).strip() == expected_result: - self.debug('script executed successfully exec_success=True') - exec_success = True + #Timeout set to 3 minutes + timeout = 180 + while timeout: + self.debug('sleep %s seconds for egress rule to affect on Router.' % self.services['sleep']) + time.sleep(self.services['sleep']) + result = ssh.execute("%s %s" % (script_file, exec_cmd_params)) + self.debug('Result is=%s' % result) + self.debug('Expected result is=%s' % expected_result) + + if str(result).strip() == expected_result: + exec_success = True + break + else: + if result == []: + self.fail("Router is not accessible") + # This means router network did not come up as yet loop back. + if "send" in result[0]: + timeout -= self.services['sleep'] + else: # Failed due to some other error + break + #end while + + if timeout == 0: + self.fail("Router network failed to come up after 3 minutes.") ssh.execute('rm -rf %s' % script_file) @@ -371,18 +377,17 @@ class TestEgressFWRules(cloudstackTestCase): self.virtual_machine.delete(self.apiclient) wait_for_cleanup(self.apiclient, ["expunge.interval", "expunge.delay"]) self.debug("Sleep for VM cleanup to complete.") - time.sleep(self.services['sleep']) + #time.sleep(self.services['sleep']) self.network.delete(self.apiclient) - wait_for_cleanup(self.apiclient, ["network.gc.wait", "network.gc.interval"]) self.debug("Sleep for Network cleanup to complete.") - time.sleep(self.services['sleep']) + wait_for_cleanup(self.apiclient, ["network.gc.wait", "network.gc.interval"]) + #time.sleep(self.services['sleep']) cleanup_resources(self.apiclient, reversed(self.cleanup)) self.debug("Cleanup complete!") except Exception as e: self.debug("Warning! Exception in tearDown: %s" % e) @attr(tags = ["advanced"]) - @log_test_exceptions def test_01_egress_fr1(self): """Test By-default the communication from guest n/w to public n/w is allowed. """ @@ -398,7 +403,6 @@ class TestEgressFWRules(cloudstackTestCase): negative_test=False) @attr(tags = ["advanced"]) - @log_test_exceptions def test_01_1_egress_fr1(self): """Test By-default the communication from guest n/w to public n/w is NOT allowed. """ @@ -415,7 +419,6 @@ class TestEgressFWRules(cloudstackTestCase): @attr(tags = ["advanced"]) - @log_test_exceptions def test_02_egress_fr2(self): """Test Allow Communication using Egress rule with CIDR + Port Range + Protocol. """ @@ -433,7 +436,6 @@ class TestEgressFWRules(cloudstackTestCase): negative_test=False) @attr(tags = ["advanced"]) - @log_test_exceptions def test_02_1_egress_fr2(self): """Test Allow Communication using Egress rule with CIDR + Port Range + Protocol. """ @@ -450,9 +452,7 @@ class TestEgressFWRules(cloudstackTestCase): "['0']", negative_test=False) - @attr(tags = ["advanced"]) - @log_test_exceptions def test_03_egress_fr3(self): """Test Communication blocked with network that is other than specified """ @@ -474,7 +474,6 @@ class TestEgressFWRules(cloudstackTestCase): negative_test=False) @attr(tags = ["advanced"]) - @log_test_exceptions def test_03_1_egress_fr3(self): """Test Communication blocked with network that is other than specified """ @@ -483,7 +482,7 @@ class TestEgressFWRules(cloudstackTestCase): # 3. create egress rule with specific CIDR + port range. # 4. login to VM. # 5. Try to reach to public network with other protocol/port range - self.create_vm() + self.create_vm(egress_policy=False) self.exec_script_on_user_vm('ping -c 1 www.google.com', "| grep -oP \'\d+(?=% packet loss)\'", "['100']", @@ -495,9 +494,7 @@ class TestEgressFWRules(cloudstackTestCase): "['failed:']", negative_test=False) - @attr(tags = ["advanced"]) - @log_test_exceptions def test_04_egress_fr4(self): """Test Create Egress rule and check the Firewall_Rules DB table """ @@ -517,10 +514,10 @@ class TestEgressFWRules(cloudstackTestCase): "Check DB Query result set") self.assertEqual(qresultset[0][0], "Firewall", - "DB results not matching") + "DB results not matching, expected: Firewall found: %s " % qresultset[0][0]) self.assertEqual(qresultset[0][1], "Egress", - "DB results not matching") + "DB results not matching, expected: Egress, found: %s" % qresultset[0][1]) qresultset = self.dbclient.execute("select egress_default_policy from network_offerings where name='%s';" % self.network_offering.name) self.assertEqual(isinstance(qresultset, list), True, @@ -530,12 +527,11 @@ class TestEgressFWRules(cloudstackTestCase): 0, "Check DB Query result set") self.assertEqual(qresultset[0][0], - "1", - "DB results not matching") + 1, + "DB results not matching, expected: 1, found: %s" % qresultset[0][0]) @attr(tags = ["advanced"]) - @log_test_exceptions def test_04_1_egress_fr4(self): """Test Create Egress rule and check the Firewall_Rules DB table """ @@ -555,10 +551,10 @@ class TestEgressFWRules(cloudstackTestCase): "Check DB Query result set") self.assertEqual(qresultset[0][0], "Firewall", - "DB results not matching") + "DB results not matching, expected: Firewall found: %s " % qresultset[0][0]) self.assertEqual(qresultset[0][1], "Egress", - "DB results not matching") + "DB results not matching, expected: Egress, found: %s" % qresultset[0][1]) qresultset = self.dbclient.execute("select egress_default_policy from network_offerings where name='%s';" % self.network_offering.name) self.assertEqual(isinstance(qresultset, list), True, @@ -568,13 +564,11 @@ class TestEgressFWRules(cloudstackTestCase): 0, "Check DB Query result set") self.assertEqual(qresultset[0][0], - "0", - "DB results not matching") - - + 0, + "DB results not matching, expected: 0, found: %s" % qresultset[0][0]) + @unittest.skip("Skip") @attr(tags = ["advanced"]) - @log_test_exceptions def test_05_egress_fr5(self): """Test Create Egress rule and check the IP tables """ @@ -592,8 +586,8 @@ class TestEgressFWRules(cloudstackTestCase): #TODO: Query VR for expected route rules. + @unittest.skip("Skip") @attr(tags = ["advanced"]) - @log_test_exceptions def test_05_1_egress_fr5(self): """Test Create Egress rule and check the IP tables """ @@ -612,7 +606,6 @@ class TestEgressFWRules(cloudstackTestCase): @attr(tags = ["advanced"]) - @log_test_exceptions def test_06_egress_fr6(self): """Test Create Egress rule without CIDR """ @@ -629,7 +622,6 @@ class TestEgressFWRules(cloudstackTestCase): negative_test=False) @attr(tags = ["advanced"]) - @log_test_exceptions def test_06_1_egress_fr6(self): """Test Create Egress rule without CIDR """ @@ -645,10 +637,7 @@ class TestEgressFWRules(cloudstackTestCase): "['0']", negative_test=False) - - @attr(tags = ["advanced"]) - @log_test_exceptions def test_07_egress_fr7(self): """Test Create Egress rule without End Port """ @@ -665,7 +654,6 @@ class TestEgressFWRules(cloudstackTestCase): negative_test=False) @attr(tags = ["advanced"]) - @log_test_exceptions def test_07_1_egress_fr7(self): """Test Create Egress rule without End Port """ @@ -681,9 +669,8 @@ class TestEgressFWRules(cloudstackTestCase): "['failed:']", negative_test=False) - + @unittest.skip("Skip") @attr(tags = ["advanced"]) - @log_test_exceptions def test_08_egress_fr8(self): """Test Port Forwarding and Egress Conflict """ @@ -694,8 +681,8 @@ class TestEgressFWRules(cloudstackTestCase): self.create_vm(pfrule=True) self.createEgressRule() + @unittest.skip("Skip") @attr(tags = ["advanced"]) - @log_test_exceptions def test_08_1_egress_fr8(self): """Test Port Forwarding and Egress Conflict """ @@ -708,7 +695,6 @@ class TestEgressFWRules(cloudstackTestCase): @attr(tags = ["advanced"]) - @log_test_exceptions def test_09_egress_fr9(self): """Test Delete Egress rule """ @@ -733,7 +719,6 @@ class TestEgressFWRules(cloudstackTestCase): negative_test=False) @attr(tags = ["advanced"]) - @log_test_exceptions def test_09_1_egress_fr9(self): """Test Delete Egress rule """ @@ -759,7 +744,6 @@ class TestEgressFWRules(cloudstackTestCase): @attr(tags = ["advanced"]) - @log_test_exceptions def test_10_egress_fr10(self): """Test Invalid CIDR and Invalid Port ranges """ @@ -771,7 +755,6 @@ class TestEgressFWRules(cloudstackTestCase): self.assertRaises(Exception, self.createEgressRule, '10.2.2.0/24') @attr(tags = ["advanced"]) - @log_test_exceptions def test_10_1_egress_fr10(self): """Test Invalid CIDR and Invalid Port ranges """ @@ -784,7 +767,6 @@ class TestEgressFWRules(cloudstackTestCase): @attr(tags = ["advanced"]) - @log_test_exceptions def test_11_egress_fr11(self): """Test Regression on Firewall + PF + LB + SNAT """ @@ -795,7 +777,6 @@ class TestEgressFWRules(cloudstackTestCase): self.create_vm(pfrule=True) @attr(tags = ["advanced"]) - @log_test_exceptions def test_11_1_egress_fr11(self): """Test Regression on Firewall + PF + LB + SNAT """ @@ -807,7 +788,6 @@ class TestEgressFWRules(cloudstackTestCase): @attr(tags = ["advanced"]) - @log_test_exceptions def test_12_egress_fr12(self): """Test Reboot Router """ @@ -825,7 +805,6 @@ class TestEgressFWRules(cloudstackTestCase): negative_test=False) @attr(tags = ["advanced"]) - @log_test_exceptions def test_12_1_egress_fr12(self): """Test Reboot Router """ @@ -842,9 +821,7 @@ class TestEgressFWRules(cloudstackTestCase): "['0']", negative_test=False) - @attr(tags = ["advanced"]) - @log_test_exceptions def test_13_egress_fr13(self): """Test Redundant Router : Master failover """ @@ -900,7 +877,6 @@ class TestEgressFWRules(cloudstackTestCase): negative_test=False) @attr(tags = ["advanced"]) - @log_test_exceptions def test_13_1_egress_fr13(self): """Test Redundant Router : Master failover """ diff --git a/test/integration/component/test_netscaler_nw_off.py b/test/integration/component/test_netscaler_nw_off.py index 3139257dd67..b94d47ea164 100644 --- a/test/integration/component/test_netscaler_nw_off.py +++ b/test/integration/component/test_netscaler_nw_off.py @@ -2359,11 +2359,10 @@ class TestNOWithNetscaler(cloudstackTestCase): cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = cls.template.id + cls._cleanup = [] try: cls.netscaler = add_netscaler(cls.api_client, cls.zone.id, cls.services["netscaler_1"]) - cls._cleanup = [ - cls.netscaler - ] + cls._cleanup.append(cls.netscaler) cls.service_offering = ServiceOffering.create( cls.api_client, cls.services["service_offering"] @@ -2403,7 +2402,7 @@ class TestNOWithNetscaler(cloudstackTestCase): return @attr(tags = ["advancedns"]) - def test_01_network_off_without_conserve_mode(self): + def test_01_netoff_without_conserve_mode(self): """Test Nw off with Conserve mode off, VR-All services, LB-netscaler """ @@ -2672,7 +2671,7 @@ class TestNOWithNetscaler(cloudstackTestCase): return @attr(tags = ["advancedns"]) - def test_02_network_off_with_conserve_mode_netscaler(self): + def test_02_net_off_conserve_mode_ns(self): """Test NW off with Conserve mode ON, LB-Netscaler and VR-All services """ diff --git a/test/integration/component/test_persistent_networks.py b/test/integration/component/test_persistent_networks.py new file mode 100644 index 00000000000..f61ccaae360 --- /dev/null +++ b/test/integration/component/test_persistent_networks.py @@ -0,0 +1,290 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +""" Tests for Persistent Networks without running VMs feature +""" +import marvin +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from marvin.cloudstackException import cloudstackAPIException +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * +import netaddr + +from nose.plugins.attrib import attr + +class Services(object): + """Test Persistent Networks without running VMs + """ + def __init__(self): + self.services = { + "account": { + "email": "test@test.com", + "firstname": "Test", + "lastname": "User", + "username": "test", + # Random characters are appended for unique + # username + "password": "password", + }, + "service_offering": { + "name": "Tiny Instance ", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 200, # in MHz + "memory": 256, # In MBs + }, + "shared_persistent_network_offering": { + "name": 'Network offering for Shared Persistent Network', + "displaytext": 'Network offering-DA services', + "guestiptype": 'Shared', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "ispersistent": 'True', + "serviceProviderList": { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Vpn": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'VirtualRouter', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, + }, + "isolated_persistent_network_offering": { + "name": 'Network offering for Isolated Persistent Network', + "displaytext": 'Network offering-DA services', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "ispersistent": 'True', + "serviceProviderList": { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Vpn": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'VirtualRouter', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, + }, + "isolated_network_offering": { + "name": 'Network offering for Isolated Persistent Network', + "displaytext": 'Network offering-DA services', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Vpn": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'VirtualRouter', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, + }, + "isolated_network": { + "name": "Isolated Network", + "displaytext": "Isolated Network", + }, + "virtual_machine": { + "displayname": "Test VM", + }, + "ostype": 'CentOS 5.3 (64-bit)', + # Cent OS 5.3 (64 bit) + "sleep": 90, + "timeout": 10, + "mode": 'advanced' + } + + + +class TestPersistentNetworks(cloudstackTestCase): + """Test Persistent Networks without running VMs + """ + + @classmethod + def setUpClass(cls): + cls.api_client = super(TestPersistentNetworks, cls).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["domainid"] = cls.domain.id + cls.services["zoneid"] = cls.zone.id + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + cls.services["account"] = cls.account.name + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.isolated_persistent_network_offering = cls.create_network_offering("isolated_persistent_network_offering") + cls.isolated_network = cls.create_isolated_network(cls.isolated_persistent_network_offering.id) + cls.isolated_network_offering = cls.create_network_offering("isolated_network_offering") + + + # network will be deleted as part of account cleanup + cls._cleanup = [ + cls.account, cls.service_offering, cls.isolated_persistent_network_offering, cls.isolated_network_offering + ] + return + + @classmethod + def tearDownClass(cls): + try: + # Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @classmethod + def create_network_offering(cls, network_offering_type): + network_offering = NetworkOffering.create( + cls.api_client, + cls.services[network_offering_type], + conservemode=False + ) + # Update network offering state from disabled to enabled. + network_offering_update_response = NetworkOffering.update( + network_offering, + cls.api_client, + id=network_offering.id, + state="enabled" + ) + return network_offering + + @classmethod + def create_isolated_network(cls, network_offering_id): + isolated_network = Network.create( + cls.api_client, + cls.services["isolated_network"], + networkofferingid=network_offering_id, + accountid=cls.account.name, + domainid=cls.domain.id, + zoneid=cls.zone.id + ) + cls.debug("persistent isolated network is created: " + isolated_network.id) + return isolated_network + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [ ] + return + + def tearDown(self): + try: + # Clean up, terminate the resources created + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def create_virtual_machine(self, network_id=None): + virtual_machine = VirtualMachine.create(self.apiclient, + self.services["virtual_machine"], + networkids=network_id, + serviceofferingid=self.service_offering.id, + accountid=self.account.name, + domainid=self.domain.id + ) + self.debug("Virtual Machine is created: " + virtual_machine.id) + return virtual_machine + + @attr(tags=["advanced"]) + def test_network_state_after_destroying_vms(self): + # steps + # 1. create virtual machine in network + # 2. destroy created virtual machine + # + # validation + # 1. Persistent network state should be implemented before VM creation and have some vlan assigned + # 2. virtual machine should be created successfully + # 3. Network state should be implemented even after destroying all vms in network + self.assertEquals(self.isolated_network.state, u"Implemented", "network state of persistent is not implemented") + self.assertIsNotNone(self.isolated_network.vlan, "vlan must not be null for persistent network") + + try: + virtual_machine = self.create_virtual_machine(network_id=self.isolated_network.id) + virtual_machine.delete(self.apiclient) + except Exception as e: + self.skipTest("vm creation/deletion fails") + + # wait for time such that, network is cleaned up + # assuming that it will change its state to allocated after this much period + wait_for_cleanup(self.api_client, ["network.gc.interval", "network.gc.wait"]) + + + networks = Network.list(self.apiclient, id=self.isolated_network.id) + self.assertEqual( + isinstance(networks, list), + True, + "list Networks should return valid response" + ) + + + self.assertEquals(networks[0].state, u"Implemented", "network state of persistent network after all vms are destroyed is not implemented") + + @attr(tags=["advanced"]) + def test_shared_network_offering_with_persistent(self): + # steps + # 1. create shared network offering with persistent field enabled + # + # validation + # 1. network offering should throw an exception + try: + shared_persistent_network_offering = self.create_network_offering("shared_persistent_network_offering") + shared_persistent_network_offering.delete(self.apiclient) + self.fail("For shared network ispersistent must be False") + except Exception as e: + pass + + @attr(tags=["advanced"]) + def test_upgrade_network_offering_to_persistent(self): + # steps + # 1. create isolated network with network offering which has ispersistent field disabled + # 2. upgrade isolated network offering to network offering which has ispersistent field enabled + # + # validation + # 1. update of network should happen successfully + # 2. network state should be implemented and have some vlan assigned + isolated_network = self.create_isolated_network(self.isolated_network_offering.id) + isolated_network_response = isolated_network.update(self.apiclient, networkofferingid=self.isolated_persistent_network_offering.id) + self.assertEquals(self.isolated_network.state, u"Implemented", "network state of isolated network upgraded to persistent is not implemented") + self.assertIsNotNone(self.isolated_network.vlan, "vlan must not be null isolated network upgraded to for persistent network") diff --git a/test/integration/component/test_reset_ssh_keypair.py b/test/integration/component/test_reset_ssh_keypair.py index ace449999f8..4d0c45e9e17 100644 --- a/test/integration/component/test_reset_ssh_keypair.py +++ b/test/integration/component/test_reset_ssh_keypair.py @@ -82,6 +82,23 @@ class Services: "mode": 'advanced', } +def wait_vm_start(apiclient, account, timeout, sleep): + while timeout: + vms = VirtualMachine.list( + apiclient, + account=account.name, + domainid=account.domainid, + listall=True + ) + if vms and vms[0].state == "Running": + return timeout + + time.sleep(sleep) + timeout = timeout - 1 + + return timeout + + class TestResetSSHKeypair(cloudstackTestCase): @classmethod @@ -339,7 +356,6 @@ class TestResetSSHKeypair(cloudstackTestCase): except Exception as e: self.fail("Failed to reset SSH key: %s, %s" % (virtual_machine.name, e)) - return self.debug("Starting the virtual machine after resetting the keypair") try: virtual_machine.start(self.apiclient) @@ -347,17 +363,13 @@ class TestResetSSHKeypair(cloudstackTestCase): self.fail("Failed to start virtual machine: %s, %s" % (virtual_machine.name, e)) - while True: - vms = VirtualMachine.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - listall=True - ) - if vms[0].state == "Running": - break - self.debug("Vm not in Running state sleep 60s") - time.sleep(60) + timeout = wait_vm_start(self.apiclient, self.account, self.services["timeout"], + self.services["sleep"]) + + if timeout == 0: + self.fail("The virtual machine %s failed to start even after %s minutes" + % (virtual_machine.name, self.services["timeout"])) + self.debug("SSH key path: %s" % str(keyPairFilePath)) try: virtual_machine.get_ssh_client(keyPairFileLocation=str(keyPairFilePath)) @@ -461,17 +473,12 @@ class TestResetSSHKeypair(cloudstackTestCase): self.fail("Failed to start virtual machine: %s, %s" % (virtual_machine.name, e)) - while True: - vms = VirtualMachine.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - listall=True - ) - if vms[0].state == "Running": - break - self.debug("Vm not in Running state sleep 60s") - time.sleep(60) + timeout = wait_vm_start(self.apiclient, self.account, self.services["timeout"], + self.services["sleep"]) + + if timeout == 0: + self.fail("The virtual machine %s failed to start even after %s minutes" + % (virtual_machine.name, self.services["timeout"])) self.debug("SSHing with new keypair") try: @@ -575,17 +582,13 @@ class TestResetSSHKeypair(cloudstackTestCase): except Exception as e: self.fail("Failed to start virtual machine: %s, %s" % (virtual_machine.name, e)) - while True: - vms = VirtualMachine.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - listall=True - ) - if vms[0].state == "Running": - break - self.debug("Vm not in Running state sleep 60s") - time.sleep(60) + + timeout = wait_vm_start(self.apiclient, self.account, self.services["timeout"], + self.services["sleep"]) + + if timeout == 0: + self.fail("The virtual machine %s failed to start even after %s minutes" + % (virtual_machine.name, self.services["timeout"])) self.debug("SSHing with new keypair") try: @@ -690,17 +693,13 @@ class TestResetSSHKeypair(cloudstackTestCase): except Exception as e: self.fail("Failed to start virtual machine: %s, %s" % (virtual_machine.name, e)) - while True: - vms = VirtualMachine.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - listall=True - ) - if vms[0].state == "Running": - break - self.debug("Vm not in Running state sleep 60s") - time.sleep(60) + + timeout = wait_vm_start(self.apiclient, self.account, self.services["timeout"], + self.services["sleep"]) + + if timeout == 0: + self.fail("The virtual machine %s failed to start even after %s minutes" + % (virtual_machine.name, self.services["timeout"])) self.debug("SSHing with new keypair") try: @@ -1206,18 +1205,14 @@ class TestResetSSHKeyUserRights(cloudstackTestCase): virtual_machine.start(self.apiclient) except Exception as e: self.fail("Failed to start virtual machine: %s, %s" % - (virtual_machine.name, e)) - while True: - vms = VirtualMachine.list( - self.apiclient, - account=self.user_account.name, - domainid=self.user_account.domainid, - listall=True - ) - if vms[0].state == "Running": - break - self.debug("Vm not in Running state sleep 60s") - time.sleep(60) + (virtual_machine.name, e)) + + timeout = wait_vm_start(self.apiclient, self.account, self.services["timeout"], + self.services["sleep"]) + + if timeout == 0: + self.fail("The virtual machine %s failed to start even after %s minutes" + % (vms[0].name, self.services["timeout"])) self.debug("SSHing with new keypair") try: @@ -1350,17 +1345,13 @@ class TestResetSSHKeyUserRights(cloudstackTestCase): except Exception as e: self.fail("Failed to start virtual machine: %s, %s" % (virtual_machine.name, e)) - while True: - vms = VirtualMachine.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - listall=True - ) - if vms[0].state == "Running": - break - self.debug("Vm not in Running state sleep 60s") - time.sleep(60) + + timeout = wait_vm_start(self.apiclient, self.account, self.services["timeout"], + self.services["sleep"]) + + if timeout == 0: + self.fail("The virtual machine %s failed to start even after %s minutes" + % (virtual_machine.name, self.services["timeout"])) self.debug("SSHing with new keypair") try: @@ -1494,17 +1485,13 @@ class TestResetSSHKeyUserRights(cloudstackTestCase): except Exception as e: self.fail("Failed to start virtual machine: %s, %s" % (virtual_machine.name, e)) - while True: - vms = VirtualMachine.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - listall=True - ) - if vms[0].state == "Running": - break - self.debug("Vm not in Running state sleep 60s") - time.sleep(60) + + timeout = wait_vm_start(self.apiclient, self.account, self.services["timeout"], + self.services["sleep"]) + + if timeout == 0: + self.fail("The virtual machine %s failed to start even after %s minutes" + % (virtual_machine.name, self.services["timeout"])) self.debug("SSHing with new keypair") try: diff --git a/tools/appliance/definitions/devcloud/base.sh b/tools/appliance/definitions/devcloud/base.sh index 122b3893c92..7fec0fc342d 100644 --- a/tools/appliance/definitions/devcloud/base.sh +++ b/tools/appliance/definitions/devcloud/base.sh @@ -6,7 +6,7 @@ apt-get -y update apt-get -y install curl unzip apt-get clean -echo 'cloud ALL=NOPASSWD:ALL' > /etc/sudoers.d/cloud +echo 'cloud ALL=NOPASSWD:/bin/chmod, /bin/cp, /bin/mkdir, /bin/mount, /bin/umount' > /etc/sudoers.d/cloud # Tweak sshd to prevent DNS resolution (speed up logins) echo 'UseDNS no' >> /etc/ssh/sshd_config diff --git a/tools/appliance/definitions/systemvmtemplate64/base.sh b/tools/appliance/definitions/systemvm64template/base.sh similarity index 85% rename from tools/appliance/definitions/systemvmtemplate64/base.sh rename to tools/appliance/definitions/systemvm64template/base.sh index d6faea04b41..46c5db6dcd1 100644 --- a/tools/appliance/definitions/systemvmtemplate64/base.sh +++ b/tools/appliance/definitions/systemvm64template/base.sh @@ -5,7 +5,7 @@ apt-get -y update apt-get -y install curl unzip # Set up sudo -echo 'vagrant ALL=NOPASSWD:ALL' > /etc/sudoers.d/vagrant +echo 'vagrant ALL=NOPASSWD:/bin/chmod, /bin/cp, /bin/mkdir, /bin/mount, /bin/umount' > /etc/sudoers.d/vagrant # Tweak sshd to prevent DNS resolution (speed up logins) echo 'UseDNS no' >> /etc/ssh/sshd_config diff --git a/tools/appliance/definitions/systemvmtemplate64/cleanup.sh b/tools/appliance/definitions/systemvm64template/cleanup.sh similarity index 100% rename from tools/appliance/definitions/systemvmtemplate64/cleanup.sh rename to tools/appliance/definitions/systemvm64template/cleanup.sh diff --git a/tools/appliance/definitions/systemvmtemplate64/definition.rb b/tools/appliance/definitions/systemvm64template/definition.rb similarity index 95% rename from tools/appliance/definitions/systemvmtemplate64/definition.rb rename to tools/appliance/definitions/systemvm64template/definition.rb index 30f2849978d..454145d3bd0 100644 --- a/tools/appliance/definitions/systemvmtemplate64/definition.rb +++ b/tools/appliance/definitions/systemvm64template/definition.rb @@ -1,7 +1,7 @@ Veewee::Definition.declare({ :cpu_count => '1', :memory_size=> '256', - :disk_size => '2000', :disk_format => 'VDI', :hostiocache => 'off', + :disk_size => '2500', :disk_format => 'VDI', :hostiocache => 'off', :os_type_id => 'Debian_64', :iso_file => "debian-7.0.0-amd64-netinst.iso", :iso_src => "http://cdimage.debian.org/mirror/cdimage/archive/7.0.0/amd64/iso-cd/debian-7.0.0-amd64-netinst.iso", diff --git a/tools/appliance/definitions/systemvmtemplate64/postinstall.sh b/tools/appliance/definitions/systemvm64template/postinstall.sh similarity index 95% rename from tools/appliance/definitions/systemvmtemplate64/postinstall.sh rename to tools/appliance/definitions/systemvm64template/postinstall.sh index 53ae2bb0e5a..3755b525aab 100644 --- a/tools/appliance/definitions/systemvmtemplate64/postinstall.sh +++ b/tools/appliance/definitions/systemvm64template/postinstall.sh @@ -105,7 +105,7 @@ setup_accounts() { echo "root:$ROOTPW" | chpasswd echo "cloud:`openssl rand -base64 32`" | chpasswd sed -i -e '/Defaults\s\+env_reset/a Defaults\texempt_group=admin' /etc/sudoers - sed -i -e 's/%admin ALL=(ALL) ALL/%admin ALL=NOPASSWD:ALL/g' /etc/sudoers + sed -i -e 's/%admin ALL=(ALL) ALL/%admin ALL=NOPASSWD:/bin/chmod, /bin/cp, /bin/mkdir, /bin/mount, /bin/umount/g' /etc/sudoers # Disable password based authentication via ssh, this will take effect on next reboot sed -i -e 's/^.*PasswordAuthentication .*$/PasswordAuthentication no/g' /etc/ssh/sshd_config # Secure ~/.ssh @@ -167,6 +167,7 @@ EOF fix_vhdutil() { wget --no-check-certificate http://download.cloud.com.s3.amazonaws.com/tools/vhd-util -O /bin/vhd-util + chmod a+x /bin/vhd-util } do_fixes() { @@ -203,12 +204,12 @@ configure_services() { cd /opt wget --no-check-certificate $snapshot_url -O cloudstack.tar.gz tar -zxvf cloudstack.tar.gz - cp -rv $snapshot_dir/patches/systemvm/debian/config/* / - cp -rv $snapshot_dir/patches/systemvm/debian/vpn/* / + cp -rv $snapshot_dir/systemvm/patches/debian/config/* / + cp -rv $snapshot_dir/systemvm/patches/debian/vpn/* / mkdir -p /usr/share/cloud/ - cd $snapshot_dir/patches/systemvm/debian/config + cd $snapshot_dir/systemvm/patches/debian/config tar -cvf /usr/share/cloud/cloud-scripts.tar * - cd $snapshot_dir/patches/systemvm/debian/vpn + cd $snapshot_dir/systemvm/patches/debian/vpn tar -rvf /usr/share/cloud/cloud-scripts.tar * cd /opt rm -fr $snapshot_dir cloudstack.tar.gz diff --git a/tools/appliance/definitions/systemvmtemplate64/preseed.cfg b/tools/appliance/definitions/systemvm64template/preseed.cfg similarity index 100% rename from tools/appliance/definitions/systemvmtemplate64/preseed.cfg rename to tools/appliance/definitions/systemvm64template/preseed.cfg diff --git a/tools/appliance/definitions/systemvmtemplate64/zerodisk.sh b/tools/appliance/definitions/systemvm64template/zerodisk.sh similarity index 89% rename from tools/appliance/definitions/systemvmtemplate64/zerodisk.sh rename to tools/appliance/definitions/systemvm64template/zerodisk.sh index 25bd8c4af2d..b00f7ae7ccc 100644 --- a/tools/appliance/definitions/systemvmtemplate64/zerodisk.sh +++ b/tools/appliance/definitions/systemvm64template/zerodisk.sh @@ -6,7 +6,7 @@ rm -fv .veewee_version .veewee_params .vbox_version echo "Cleaning up" # Zero out the free space to save space in the final image: -for path in / /boot /usr /var /opt /tmp +for path in / /boot /usr /var /opt /tmp /home do dd if=/dev/zero of=$path/zero bs=1M sync diff --git a/tools/appliance/definitions/systemvmtemplate/base.sh b/tools/appliance/definitions/systemvmtemplate/base.sh index 4d6092a5995..5aaa0eddbb6 100644 --- a/tools/appliance/definitions/systemvmtemplate/base.sh +++ b/tools/appliance/definitions/systemvmtemplate/base.sh @@ -7,7 +7,7 @@ apt-get -y install curl unzip apt-get clean # Set up sudo, TODO: Check security concerns -echo 'cloud ALL=NOPASSWD:ALL' > /etc/sudoers.d/cloud +echo 'cloud ALL=NOPASSWD:/bin/chmod, /bin/cp, /bin/mkdir, /bin/mount, /bin/umount' > /etc/sudoers.d/cloud # Tweak sshd to prevent DNS resolution (speed up logins) echo 'UseDNS no' >> /etc/ssh/sshd_config diff --git a/tools/appliance/definitions/systemvmtemplate/definition.rb b/tools/appliance/definitions/systemvmtemplate/definition.rb index 54c85aa60ef..33f25b2c31e 100644 --- a/tools/appliance/definitions/systemvmtemplate/definition.rb +++ b/tools/appliance/definitions/systemvmtemplate/definition.rb @@ -1,7 +1,7 @@ Veewee::Definition.declare({ :cpu_count => '1', :memory_size=> '256', - :disk_size => '2000', :disk_format => 'VDI', :hostiocache => 'off', + :disk_size => '2500', :disk_format => 'VDI', :hostiocache => 'off', :os_type_id => 'Debian', :iso_file => "debian-7.0.0-i386-netinst.iso", :iso_src => "http://cdimage.debian.org/mirror/cdimage/archive/7.0.0/i386/iso-cd/debian-7.0.0-i386-netinst.iso", diff --git a/tools/appliance/definitions/systemvmtemplate/postinstall.sh b/tools/appliance/definitions/systemvmtemplate/postinstall.sh index 997d8548501..1309d47a9f5 100644 --- a/tools/appliance/definitions/systemvmtemplate/postinstall.sh +++ b/tools/appliance/definitions/systemvmtemplate/postinstall.sh @@ -104,7 +104,7 @@ setup_accounts() { echo "root:$ROOTPW" | chpasswd echo "cloud:`openssl rand -base64 32`" | chpasswd sed -i -e '/Defaults\s\+env_reset/a Defaults\texempt_group=admin' /etc/sudoers - sed -i -e 's/%admin ALL=(ALL) ALL/%admin ALL=NOPASSWD:ALL/g' /etc/sudoers + sed -i -e 's/%admin ALL=(ALL) ALL/%admin ALL=NOPASSWD:/bin/chmod, /bin/cp, /bin/mkdir, /bin/mount, /bin/umount/g' /etc/sudoers # Disable password based authentication via ssh, this will take effect on next reboot sed -i -e 's/^.*PasswordAuthentication .*$/PasswordAuthentication no/g' /etc/ssh/sshd_config # Secure ~/.ssh @@ -203,12 +203,12 @@ configure_services() { cd /opt wget --no-check-certificate $snapshot_url -O cloudstack.tar.gz tar -zxvf cloudstack.tar.gz - cp -rv $snapshot_dir/patches/systemvm/debian/config/* / - cp -rv $snapshot_dir/patches/systemvm/debian/vpn/* / + cp -rv $snapshot_dir/systemvm/patches/debian/config/* / + cp -rv $snapshot_dir/systemvm/patches/debian/vpn/* / mkdir -p /usr/share/cloud/ - cd $snapshot_dir/patches/systemvm/debian/config + cd $snapshot_dir/systemvm/patches/debian/config tar -cvf /usr/share/cloud/cloud-scripts.tar * - cd $snapshot_dir/patches/systemvm/debian/vpn + cd $snapshot_dir/systemvm/patches/debian/vpn tar -rvf /usr/share/cloud/cloud-scripts.tar * cd /opt rm -fr $snapshot_dir cloudstack.tar.gz diff --git a/tools/devcloud/src/deps/boxes/basebox-build/postinstall.sh b/tools/devcloud/src/deps/boxes/basebox-build/postinstall.sh index 217d23024aa..f2b15602e8c 100644 --- a/tools/devcloud/src/deps/boxes/basebox-build/postinstall.sh +++ b/tools/devcloud/src/deps/boxes/basebox-build/postinstall.sh @@ -28,7 +28,7 @@ groupadd -r admin usermod -a -G admin devcloud echo "root:password" | chpasswd sed -i -e '/Defaults\s\+env_reset/a Defaults\texempt_group=admin' /etc/sudoers -sed -i -e 's/%admin ALL=(ALL) ALL/%admin ALL=NOPASSWD:ALL/g' /etc/sudoers +sed -i -e 's/%admin ALL=(ALL) ALL/%admin ALL=NOPASSWD:/bin/chmod, /bin/cp, /bin/mkdir, /bin/mount, /bin/umount/g' /etc/sudoers mkdir /home/devcloud/.ssh chmod 700 /home/devcloud/.ssh diff --git a/tools/marvin/marvin/cloudstackConnection.py b/tools/marvin/marvin/cloudstackConnection.py index 686c533b86a..2c027c36879 100644 --- a/tools/marvin/marvin/cloudstackConnection.py +++ b/tools/marvin/marvin/cloudstackConnection.py @@ -35,36 +35,37 @@ class cloudConnection(object): """ Connections to make API calls to the cloudstack management server """ - - def __init__(self, mgtSvr, port=8096, user=None, passwd=None, - apiKey=None, securityKey=None, - asyncTimeout=3600, logging=None, scheme='http', - path='client/api'): + def __init__(self, mgmtDet, asyncTimeout=3600, logging=None, + scheme='http', path='client/api'): self.loglevel() # Turn off requests logs - self.apiKey = apiKey - self.securityKey = securityKey - self.mgtSvr = mgtSvr - self.port = port - self.user = user - self.passwd = passwd + self.apiKey = mgmtDet.apiKey + self.securityKey = mgmtDet.securityKey + self.mgtSvr = mgmtDet.mgtSvrIp + self.port = mgmtDet.port + self.user = mgmtDet.user + self.passwd = mgmtDet.passwd + self.certCAPath = mgmtDet.certCAPath + self.certPath = mgmtDet.certPath self.logging = logging self.path = path self.retries = 5 + self.protocol = scheme self.asyncTimeout = asyncTimeout self.auth = True - if port == 8096 or \ + if self.port == 8096 or \ (self.apiKey is None and self.securityKey is None): self.auth = False - if scheme not in ['http', 'https']: - raise RequestException("Protocol must be HTTP") - self.protocol = scheme + if mgmtDet.useHttps == "True": + self.protocol = "https" self.baseurl = "%s://%s:%d/%s"\ % (self.protocol, self.mgtSvr, self.port, self.path) def __copy__(self): - return cloudConnection(self.mgtSvr, self.port, self.user, self.passwd, - self.apiKey, self.securityKey, - self.asyncTimeout, self.logging, self.protocol, + return cloudConnection(self.mgtSvr, self.port, self.user, + self.passwd, self.apiKey, + self.securityKey, + self.asyncTimeout, self.logging, + self.protocol, self.path) def loglevel(self, lvl=logging.WARNING): @@ -86,7 +87,7 @@ class cloudConnection(object): timeout = self.asyncTimeout while timeout > 0: - asyncResonse = self.marvin_request(cmd, response_type=response) + asyncResonse = self.marvinRequest(cmd, response_type=response) if asyncResonse.jobstatus == 2: raise cloudstackException.cloudstackAPIException( @@ -145,29 +146,78 @@ class cloudConnection(object): payload["signature"] = signature try: - if method == 'POST': - response = requests.post( - self.baseurl, params=payload, verify=False) + #https_flag : Signifies whether to verify connection over \ + #http or https, \ + #initialized to False, will be set to true if user provided https + #connection + https_flag = False + cert_path = () + if self.protocol == "https": + https_flag = True + if self.certCAPath != "NA" and self.certPath != "NA": + cert_path = (self.certCAPath, self.certPath) + + #Verify whether protocol is "http", then call the request over http + if self.protocol == "http": + if method == 'POST': + response = requests.post(self.baseurl, params=payload, + verify=https_flag) + else: + response = requests.get(self.baseurl, params=payload, + verify=https_flag) else: - response = requests.get( - self.baseurl, params=payload, verify=False) + ''' + If protocol is https, then create the connection url with \ + user provided certificates \ + provided as part of cert + ''' + try: + if method == 'POST': + response = requests.post(self.baseurl, + params=payload, + cert=cert_path, + verify=https_flag) + else: + response = requests.get(self.baseurl, params=payload, + cert=cert_path, + verify=https_flag) + except Exception, e: + ''' + If an exception occurs with user provided CA certs, \ + then try with default certs, \ + we dont need to mention here the cert path + ''' + self.logging.debug("Creating CS connection over https \ + didnt worked with user provided certs \ + , so trying with no certs %s" % e) + if method == 'POST': + response = requests.post(self.baseurl, + params=payload, + verify=https_flag) + else: + response = requests.get(self.baseurl, + params=payload, + verify=https_flag) except ConnectionError, c: - self.logging.debug("Connection refused. Reason: %s : %s" % - (self.baseurl, c)) + self.logging.debug("Connection refused. Reason: %s : %s" + % (self.baseurl, c)) raise c except HTTPError, h: - self.logging.debug("Server returned error code: %s" % h) + self.logging.debug("Http Error.Server returned error code: %s" % h) raise h except Timeout, t: self.logging.debug("Connection timed out with %s" % t) raise t except RequestException, r: - self.logging.debug("Error returned by server %s" % r) + self.logging.debug("RequestException from server %s" % r) raise r + except Exception, e: + self.logging.debug("Error returned by server %s" % r) + raise e else: return response - def sanitize_command(self, cmd): + def sanitizeCommand(self, cmd): """ Removes None values, Validates all required params are present @param cmd: Cmd object eg: createPhysicalNetwork @@ -205,9 +255,9 @@ class cloudConnection(object): for k, v in val.iteritems(): requests["%s[%d].%s" % (param, i, k)] = v i = i + 1 - return cmdname, isAsync, requests + return cmdname.strip(), isAsync, requests - def marvin_request(self, cmd, response_type=None, method='GET', data=''): + def marvinRequest(self, cmd, response_type=None, method='GET', data=''): """ Requester for marvin command objects @param cmd: marvin's command from cloudstackAPI @@ -215,11 +265,13 @@ class cloudConnection(object): @param method: HTTP GET/POST, defaults to GET @return: """ - cmdname, isAsync, payload = self.sanitize_command(cmd) + cmdname, isAsync, payload = self.sanitizeCommand(cmd) self.logging.debug("sending %s request: %s %s" % (method, cmdname, str(payload))) - response = self.request( - cmdname, self.auth, payload=payload, method=method) + response = self.request(cmdname, + self.auth, + payload=payload, + method=method) self.logging.debug("Request: %s Response: %s" % (response.url, response.text)) try: diff --git a/tools/marvin/marvin/cloudstackTestClient.py b/tools/marvin/marvin/cloudstackTestClient.py index 36f7f8d8369..fbd4abab992 100644 --- a/tools/marvin/marvin/cloudstackTestClient.py +++ b/tools/marvin/marvin/cloudstackTestClient.py @@ -23,20 +23,35 @@ import random import string import hashlib +''' +@Desc : CloudStackTestClient is encapsulated class for getting various \ + clients viz., apiclient,dbconnection etc +@Input : mgmtDetails : Management Server Details + dbSvrDetails: Database Server details of Management \ + Server. Retrieved from configuration file. + asyncTimeout : + defaultWorkerThreads : + logging : +''' + class cloudstackTestClient(object): - def __init__(self, mgtSvr=None, port=8096, user=None, passwd=None, - apiKey=None, securityKey=None, asyncTimeout=3600, - defaultWorkerThreads=10, logging=None): + def __init__(self, mgmtDetails, + dbSvrDetails, asyncTimeout=3600, + defaultWorkerThreads=10, + logging=None): self.connection = \ - cloudstackConnection.cloudConnection(mgtSvr, port, user, passwd, - apiKey, securityKey, - asyncTimeout, logging) + cloudstackConnection.cloudConnection(mgmtDetails, + asyncTimeout, + logging) self.apiClient =\ cloudstackAPIClient.CloudStackAPIClient(self.connection) self.dbConnection = None + if dbSvrDetails is not None: + self.createDbConnection(dbSvrDetails.dbSvr, dbSvrDetails.port, + dbSvrDetails.user, + dbSvrDetails.passwd, dbSvrDetails.db) self.asyncJobMgr = None - self.ssh = None self.id = None self.defaultWorkerThreads = defaultWorkerThreads @@ -48,10 +63,10 @@ class cloudstackTestClient(object): def identifier(self, id): self.id = id - def dbConfigure(self, host="localhost", port=3306, user='cloud', - passwd='cloud', db='cloud'): - self.dbConnection = dbConnection.dbConnection(host, port, user, passwd, - db) + def createDbConnection(self, host="localhost", port=3306, user='cloud', + passwd='cloud', db='cloud'): + self.dbConnection = dbConnection.dbConnection(host, port, user, + passwd, db) def isAdminContext(self): """ @@ -71,13 +86,6 @@ class cloudstackTestClient(object): except: return 0 # user - def random_gen(self, size=6, chars=string.ascii_uppercase + string.digits): - """Generate Random Strings of variable length""" - randomstr = ''.join(random.choice(chars) for x in range(size)) - if self.identifier: - return ''.join([self.identifier, '-', randomstr]) - return randomstr - def createUserApiClient(self, UserName, DomainName, acctType=0): if not self.isAdminContext(): return self.apiClient @@ -149,17 +157,6 @@ class cloudstackTestClient(object): def getDbConnection(self): return self.dbConnection - def executeSql(self, sql=None): - if sql is None or self.dbConnection is None: - return None - - return self.dbConnection.execute() - - def executeSqlFromFile(self, sqlFile=None): - if sqlFile is None or self.dbConnection is None: - return None - return self.dbConnection.executeSqlFromFile(sqlFile) - def getApiClient(self): self.apiClient.id = self.identifier return self.apiClient diff --git a/tools/marvin/marvin/codegenerator.py b/tools/marvin/marvin/codegenerator.py index 96729f6bbfe..e0f056f66a0 100644 --- a/tools/marvin/marvin/codegenerator.py +++ b/tools/marvin/marvin/codegenerator.py @@ -222,7 +222,7 @@ class codeGenerator(object): body += self.space + self.space body += 'response = %sResponse()\n' % cmdName body += self.space + self.space - body += 'response = self.connection.marvin_request(command,' + body += 'response = self.connection.marvinRequest(command,' body += ' response_type=response, method=method)\n' body += self.space + self.space + 'return response\n' body += self.newline diff --git a/tools/marvin/marvin/codes.py b/tools/marvin/marvin/codes.py new file mode 100644 index 00000000000..6099d88ba44 --- /dev/null +++ b/tools/marvin/marvin/codes.py @@ -0,0 +1,35 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +""" +@Desc : This module defines all codes, constants maintained globally \ + and used across marvin and its test features.The main purpose \ + is to maintain readability, maintain one common place for \ + all codes used or reused across test features. It enhances \ + maintainability and readability. Users just import statement \ + to receive all the codes mentioned here. EX: Here, we define \ + a code viz., ENABLED with value "Enabled",then using \ + this code in a sample feature say test_a.py as below. \ + + from marvinCodes import * + if obj.getvalue() == ENABLED + +@DateAdded: 20th October 2013 +""" + +ENABLED = "Enabled" +NETWORK_OFFERING = "network_offering" +ROOT = "ROOT" diff --git a/tools/marvin/marvin/configGenerator.py b/tools/marvin/marvin/configGenerator.py index a966ae089e4..50614c124c1 100644 --- a/tools/marvin/marvin/configGenerator.py +++ b/tools/marvin/marvin/configGenerator.py @@ -27,6 +27,9 @@ class managementServer(object): self.port = 8096 self.apiKey = None self.securityKey = None + self.useHttps = None + self.certCAPath = None + self.certPath = None class dbServer(object): @@ -830,7 +833,7 @@ def generate_setup_config(config, file=None): def get_setup_config(file): if not os.path.exists(file): raise IOError("config file %s not found. \ -please specify a valid config file" % file) + please specify a valid config file" % file) config = cloudstackConfiguration() configLines = [] with open(file, 'r') as fp: @@ -838,7 +841,9 @@ please specify a valid config file" % file) ws = line.strip() if not ws.startswith("#"): configLines.append(ws) - config = json.loads("\n".join(configLines)) + k = json.loads("\n".join(configLines)) + #config = json.loads("\n".join(configLines)) + config = k return jsonHelper.jsonLoader(config) if __name__ == "__main__": diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py index beed8c8eb19..f2dccdbc53c 100644 --- a/tools/marvin/marvin/deployDataCenter.py +++ b/tools/marvin/marvin/deployDataCenter.py @@ -32,8 +32,12 @@ class deployDataCenters(object): if not path.exists(cfgFile) \ and not path.exists(path.abspath(cfgFile)): raise IOError("config file %s not found. please \ -specify a valid config file" % cfgFile) + specify a valid config file" % cfgFile) self.configFile = cfgFile + ''' + parsed configuration information + ''' + self.config = None def addHosts(self, hosts, zoneId, podId, clusterId, hypervisor): if hosts is None: @@ -515,8 +519,10 @@ specify a valid config file" % cfgFile) raise cloudstackException.InvalidParameterException( "Failed to load config %s" % self.configFile) - mgt = self.config.mgtSvr[0] - + ''' Retrieving Management Server Connection Details ''' + mgtDetails = self.config.mgtSvr[0] + ''' Retrieving Database Connection Details''' + dbSvrDetails = self.config.dbSvr loggers = self.config.logger testClientLogFile = None self.testCaseLogFile = None @@ -534,36 +540,33 @@ specify a valid config file" % cfgFile) if testClientLogFile is not None: testClientLogger = logging.getLogger("testclient.testengine.run") fh = logging.FileHandler(testClientLogFile) - fh.setFormatter(logging. - Formatter("%(asctime)s - %(levelname)s - %(name)s\ - - %(message)s")) + fh.setFormatter(logging.Formatter( + "%(asctime)s - %(levelname)s - %(name)s\ - %(message)s") + ) testClientLogger.addHandler(fh) testClientLogger.setLevel(logging.INFO) self.testClientLogger = testClientLogger self.testClient = \ cloudstackTestClient.\ - cloudstackTestClient(mgt.mgtSvrIp, mgt.port, mgt.user, mgt.passwd, - mgt.apiKey, mgt.securityKey, + cloudstackTestClient(mgtDetails, + dbSvrDetails, logging=self.testClientLogger) - if mgt.apiKey is None: - apiKey, securityKey = self.registerApiKey() - self.testClient = cloudstackTestClient.cloudstackTestClient( - mgt.mgtSvrIp, 8080, - mgt.user, mgt.passwd, - apiKey, securityKey, - logging=self.testClientLogger) - """config database""" - dbSvr = self.config.dbSvr - if dbSvr is not None: - self.testClient.dbConfigure(dbSvr.dbSvr, dbSvr.port, dbSvr.user, - dbSvr.passwd, dbSvr.db) + if mgtDetails.apiKey is None: + mgtDetails.apiKey, mgtDetails.securityKey = self.registerApiKey() + mgtDetails.port = 8080 + self.testClient = \ + cloudstackTestClient.cloudstackTestClient( + mgtDetails, + dbSvrDetails, + logging= + self.testClientLogger) self.apiClient = self.testClient.getApiClient() """set hypervisor""" - if mgt.hypervisor: - self.apiClient.hypervisor = mgt.hypervisor + if mgtDetails.hypervisor: + self.apiClient.hypervisor = mgtDetails.hypervisor else: self.apiClient.hypervisor = "XenServer" # Defaults to Xenserver @@ -578,7 +581,6 @@ specify a valid config file" % cfgFile) self.apiClient.updateConfiguration(updateCfg) def copyAttributesToCommand(self, source, command): - map(lambda attr: setattr(command, attr, getattr(source, attr, None)), filter(lambda attr: not attr.startswith("__") and attr not in ["required", "isAsync"], dir(command))) @@ -586,7 +588,6 @@ specify a valid config file" % cfgFile) def configureS3(self, s3): if s3 is None: return - command = addS3.addS3Cmd() self.copyAttributesToCommand(s3, command) self.apiClient.addS3(command) @@ -598,16 +599,13 @@ specify a valid config file" % cfgFile) self.configureS3(self.config.s3) if __name__ == "__main__": - parser = OptionParser() - parser.add_option("-i", "--input", action="store", default="./datacenterCfg", dest="input", help="the path \ where the json config file generated, by default is \ ./datacenterCfg") (options, args) = parser.parse_args() - deploy = deployDataCenters(options.input) deploy.deploy() diff --git a/tools/marvin/marvin/marvinPlugin.py b/tools/marvin/marvin/marvinPlugin.py index aded17cca55..3b282e448db 100644 --- a/tools/marvin/marvin/marvinPlugin.py +++ b/tools/marvin/marvin/marvinPlugin.py @@ -22,6 +22,7 @@ import nose.core from marvin.cloudstackTestCase import cloudstackTestCase from marvin import deployDataCenter from nose.plugins.base import Plugin +import time class MarvinPlugin(Plugin): @@ -121,10 +122,28 @@ class MarvinPlugin(Plugin): self.config = config def beforeTest(self, test): - testname = test.__str__().split()[0] - self.testclient.identifier = '-'.join([self.identifier, testname]) + self.testName = test.__str__().split()[0] + self.testclient.identifier = '-'.join([self.identifier, self.testName]) self.logger.name = test.__str__() + def startTest(self, test): + """ + Currently used to record start time for tests + """ + self.startTime = time.time() + + def stopTest(self, test): + """ + Currently used to record end time for tests + """ + endTime = time.time() + if self.startTime is not None: + totTime = int(endTime - self.startTime) + self.logger.debug( + "****TestCaseName: %s; Time Taken: %s Seconds; \ + StartTime: %s; EndTime: %s****" + % (self.testName, str(totTime), self.startTime, endTime)) + def _injectClients(self, test): self.debug_stream. \ setFormatter(logging. diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index b5222cb8a5e..fd6e6f39eb4 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -5977,11 +5977,11 @@ label.error { margin-top: 9px !important; } -.multi-wizard.instance-wizard .data-disk-offering.required.custom-disk-size .select-container { +.multi-wizard.instance-wizard .custom-disk-size .select-container { height: 279px; } -.multi-wizard.instance-wizard .data-disk-offering.custom-disk-size .select-container { +.multi-wizard.instance-wizard .custom-disk-size .select-container { height: 213px; margin: -7px 6px 0 8px; /*+border-radius:6px;*/ @@ -5992,21 +5992,21 @@ label.error { border-radius: 6px 6px 6px 6px; } -.multi-wizard.instance-wizard .data-disk-offering .content .section input { +.multi-wizard.instance-wizard .content .section input { float: left; } -.multi-wizard.instance-wizard .data-disk-offering .content .section input[type=radio] { +.multi-wizard.instance-wizard .content .section input[type=radio] { margin: 8px 2px 0 17px; } -.multi-wizard.instance-wizard .data-disk-offering .content .section label { +.multi-wizard.instance-wizard .content .section label { display: block; float: left; margin: 10px 7px 7px; } -.multi-wizard.instance-wizard .data-disk-offering .content .section label.size { +.multi-wizard.instance-wizard .content .section label.size { color: #647A8E; font-weight: bold; /*+text-shadow:0px 1px 1px #FFFFFF;*/ @@ -6016,21 +6016,24 @@ label.error { text-shadow: 0px 1px 1px #FFFFFF; } -.multi-wizard.instance-wizard .data-disk-offering .content .section.custom-size { +.multi-wizard.instance-wizard .section.custom-size { position: relative; + background: white; + padding: 7px; + border-radius: 4px; } -.multi-wizard.instance-wizard .data-disk-offering .content .section.custom-size input[type=radio] { +.multi-wizard.instance-wizard .section.custom-size input[type=radio] { float: left; } -.multi-wizard.instance-wizard .data-disk-offering .content .section.custom-size input[type=text] { +.multi-wizard.instance-wizard .section.custom-size input[type=text] { float: left; width: 28px; margin: 6px -1px 0 8px; } -.multi-wizard.instance-wizard .data-disk-offering .content .section.custom-size label.error { +.multi-wizard.instance-wizard .section.custom-size label.error { position: absolute; top: 29px; left: 242px; @@ -11841,6 +11844,7 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it } .destroy .icon, +.expunge .icon, .remove .icon, .delete .icon, .decline .icon, @@ -11849,6 +11853,7 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it } .destroy:hover .icon, +.expunge:hover .icon, .remove:hover .icon, .delete:hover .icon, .deleteacllist:hover .icon { diff --git a/ui/dictionary.jsp b/ui/dictionary.jsp index 752a433b972..8db8308cbe3 100644 --- a/ui/dictionary.jsp +++ b/ui/dictionary.jsp @@ -29,6 +29,7 @@ dictionary = { 'message.select.disk.offering': '', 'label.home': '', 'label.use.default.language': '', +'label.root.disk.size': '', 'label.s3.nfs.path': '', 'label.s3.nfs.server': '', 'label.delete.events': '', @@ -216,6 +217,8 @@ dictionary = { 'label.action.enable.user.processing': '', 'label.action.enable.zone': '', 'label.action.enable.zone.processing': '', +'label.action.expunge.instance': '', +'label.action.expunge.instance.processing': '', 'label.action.force.reconnect': '', 'label.action.force.reconnect.processing': '', 'label.action.generate.keys': '', @@ -567,6 +570,7 @@ dictionary = { 'label.ESP.policy': '', 'label.esx.host': '', 'label.example': '', +'label.expunge': '', 'label.external.link': '', 'label.f5': '', 'label.failed': '', @@ -803,6 +807,7 @@ dictionary = { 'label.network.id': '', 'label.networking.and.security': '', 'label.network.label.display.for.blank.value': '', +'label.network.limits': '', 'label.network.name': '', 'label.network.offering.display.text': '', 'label.network.offering': '', @@ -1250,6 +1255,7 @@ dictionary = { 'message.action.enable.physical.network': '', 'message.action.enable.pod': '', 'message.action.enable.zone': '', +'message.action.expunge.instance': '', 'message.action.force.reconnect': '', 'message.action.host.enable.maintenance.mode': '', 'message.action.instance.reset.password': '', diff --git a/ui/index.jsp b/ui/index.jsp index 58d0ccab1a7..e223ab948b3 100644 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -1,1697 +1,1710 @@ <%-- -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. ---%><%@ page contentType="text/html; charset=UTF-8" %> + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + --%><%@ page contentType="text/html; charset=UTF-8" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> - + <% long now = System.currentTimeMillis(); %> + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - - - - - - - -
- -
- - - -
-
-
    -
  • 1
  • -
  • 2
  • -
  • 3
  • -
  • 4
  • -
  • 5
  • -
  • 6
  • -
  • 7
  • -
-
-
-
- -
-
- -
-

-

-
-
- -
-
- -
-

-

-
- - -
-
-
- - -
-
-
-
-
- -
- -
-
-

-
-
-
    -
  • -
  • -
  • -
- - - - - -
-
-
-
-
-
-
-
-
-
- - -
-
-

-
-
-
    -
  • -
  • -
  • -
- -
-
-
-
-
-
-
-
-
-
-
- - -
-
-

-
-
-
-
-
-
- - -
-
-

-
-
-
- - -
- - -
-
- - -
- - - - -
- - - - -
-
-
- - -
-
-

-
- -
- -
-
-
- - -
- -
-

-

-

-
- - -
-
-
- -
-
- - -
-
- - - - - - - - - - - -
-
-
-
-
-
- - - - - - - - - - - -
-
-
- - -
-
-
- - -
-
*
-
- -
-
- - -
-
-
- -
-
- -
- -
-
-
-
-
-
-
-
- -
-
- -
-
-
-
-
-
-
- -
-
- -
-
-
- -
-
- () -
-
- -
-
- -
-
- () -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - -
-
- -
-
- -
-
- -
-
- - -
-
- -
-
- -
-
- -
-
- - -
-
- -
-
- -
-
- -
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
- -
-
- - -
-
- -
-
-
- -
- -
-
-
-
- - -
-
- -
-
-
    -
  • 1
  • -
  • 2
  • -
  • 3
  • -
  • -
  • -
  • -
  • -
  • 4
  • -
  • -
  • -
  • -
  • 5
  • -
-
-
- -
-
-
- -
-

-

-
-
- -
- - -
-
-
- -
- - - -
-
- -
- - -
-
- + + + + + + + +
+ +
+ + -
+ +
+ +
+
+
    +
  • 1
  • +
  • 2
  • +
  • 3
  • +
  • 4
  • +
  • 5
  • +
  • 6
  • +
  • 7
  • +
-
- -
- -
-
- -
-
-
-
-
- -
- -
- -
-
- -
-
 
- -
-
-
    -
  • -
      -
    • " - class="traffic-type-draggable management"> - -
      - -   - Edit -
      -
    • -
    -
    -
    -
    -
    -
  • -
  • -
      -
    • " - class="traffic-type-draggable public"> - -
      - -   - Edit -
      -
    • -
    -
    -
    -
    -
    -
  • -
  • -
      -
    • " - class="traffic-type-draggable guest"> - -
      - -   - Edit -
      -
    • -
    -
    -
    -
    -
    -
  • -
  • -
      -
    • " - class="traffic-type-draggable storage"> - -
      - -   - Edit -
      -
    • -
    -
    -
    -
    -
    -
  • -
-
-
-
-
-
-
- -
- -
-
-
-
-
- -
- -
- - -
-
-
- -
- -
- -
-
-
-
-
- -
- -
- - -
-
-
-
-
- -
- -
- -
-
-
- -
- +
+
+ +
+
+ +
+

+

+
+
+ +
+
+ +
+

+

+
+ + +
+
+
+ + +
+
+
+
+
+ +
+ +
+
+

+
+
+
    +
  • +
  • +
  • +
-
- -
-
-
-
-
- -
- -
- -
-
-
-
-
- -
- -
- -
-
-
-
-
- -
- -
- -
-
-
-
-
- -
-
- - - - -
-
- -
- -
- -
-
- -
-
    -
  • -
    -
    -
  • -
  • -
    -
    -
  • -
  • -
    -
    -
  • -
-
- -
-
    -
  • -
    -
    -
  • -
  • -
    - -
    -
  • -
-
- -
-
- -
-
-
- -
-
    - -
  • - -
    -
    - -
    -
    5
    -
    + + + + +
    +
    +
    +
    +
    +
    +
    +
    + + +
    + + + + +
    + + + + +
    +
    +
    + + +
    +
    +

    +
    +
    +
      +
    • +
    • +
    • +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
+ + +
+
+

+
+
+
+
+
+
+ + +
+
+

+
+
+
+ + +
+ + +
+
+ + +
+ + + + +
+ + + + +
+
+
+ + +
+
+

+
+ +
+ +
+
+
+ + +
+ +
+

+

+

+
+ + +
+
+
+ +
+
+ + +
+
+ + + + + + + + + + + +
+
+
+
+
+
+ + + + + + + + + + + +
+
+
+ + +
+
+
+ + +
+
*
+
+ +
+
+ + +
+
+
+ +
+
+ +
+ +
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+ +
+
+ +
+
+
+ +
+
+ () +
+
+ +
+
+ +
+
+ () +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + +
+
+ +
+
+ +
+
+ +
+
+ + +
+
+ +
+
+ +
+
+ +
+
+ + +
+
+ +
+
+ +
+
+ +
+
+
+
+
- - -
-
10
-
+ + +
+
+
+
+
-
- - - -
  • - -
    -
    -
    10
    -
    -
    -
  • - - -
  • - -
    -
    -
    200
    -
    mb/s
    -
    -
  • - -
    -
    - - -
    -
    -
    - -
    -
      -
    • - -
      -
    • -
    -
    -
    -
    -
    - -
    -
    - -
    -
      - -
    • -
      -
      -
    • - - -
    • -
      -
      -
    • - - -
    • -
      -
      -
    • - - -
    • -
      -
      -
    • - - -
    • -
      -
      -
      - - -
      +
      +
      +
      +
      +
      + +
      +
      + +
      -
    • -
    -
    - -
    -
    - -
    - - -
    -
      -
    • -
      -
      -
    • -
    -
    -
    -
    - -
    -
    -
    - -
    -
    -   - -
    -
    + +
    +
    +
    + +
    + +
    +
    +
    +
    + + +
    +
    + +
    +
    +
      +
    • 1
    • +
    • 2
    • +
    • 3
    • +
    • +
    • +
    • +
    • +
    • 4
    • +
    • +
    • +
    • +
    • 5
    • +
    +
    +
    + +
    +
    +
    + +
    +

    +

    +
    +
    + +
    + + +
    +
    +
    + +
    + + + +
    +
    + +
    - -
    -
      -
    • - -   - - " - view-all-target="zones"> -
    • -
    • - -   - - " - view-all-target="pods"> -
    • -
    • - -   - - " - view-all-target="clusters"> -
    • -
    • - -   - - " - view-all-target="hosts"> -
    • -
    • - -   - - " - view-all-target="primaryStorage"> -
    • -
    • - -   - - " - view-all-target="secondaryStorage"> -
    • -
    • - -   - - " - view-all-target="systemVms"> -
    • -
    • - -   - - " - view-all-target="virtualRouters"> -
    • -
    -
    -
    + +
    +
    + +
    + + +
    +
    +
    +
    +
    + +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    + +
    + +
    +
    + +
    +
     
    + +
    +
    +
      +
    • +
        +
      • " + class="traffic-type-draggable management"> + +
        + +   + Edit +
        +
      • +
      +
      +
      +
      +
      +
    • +
    • +
        +
      • " + class="traffic-type-draggable public"> + +
        + +   + Edit +
        +
      • +
      +
      +
      +
      +
      +
    • +
    • +
        +
      • " + class="traffic-type-draggable guest"> + +
        + +   + Edit +
        +
      • +
      +
      +
      +
      +
      +
    • +
    • +
        +
      • " + class="traffic-type-draggable storage"> + +
        + +   + Edit +
        +
      • +
      +
      +
      +
      +
      +
    • +
    +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + +
    + +
    + + +
    +
    +
    + +
    + +
    + +
    +
    +
    +
    +
    + +
    + +
    + + +
    +
    +
    +
    +
    + +
    + +
    + +
    +
    +
    + +
    + - -
    - -
    -
      -
    • -
      1
      -
      Guest
      -

      Set up the network for traffic between end-user VMs.

      -
    • -
    • -
      2
      -
      Clusters
      -

      Define one or more clusters to group the compute hosts.

      -
    • -
    • -
      3
      -
      Hosts
      -

      Add hosts to clusters. Hosts run hypervisors and VMs.

      -
    • -
    • -
      4
      -
      Primary Storage
      -

      Add servers to store VM disk volumes in each cluster.

      -
    • -
    • -
      5
      -
      Secondary Storage
      -

      Add servers to store templates, ISOs, and snapshots for the whole zone.

      -
    • -
    -
    - - -
    -
      -
    • -
      1
      -
      Public
      -

      Set up the network for Internet traffic.

      -
    • -
    • -
      2
      -
      Guest
      -

      Set up the network for traffic between end-user VMs.

      -
    • -
    • -
      3
      -
      Clusters
      -

      Define one or more clusters to group the compute hosts.

      -
    • -
    • -
      4
      -
      Hosts
      -

      Add hosts to clusters. Hosts run hypervisors and VMs.

      -
    • -
    • -
      5
      -
      Primary Storage
      -

      Add servers to store VM disk volumes in each cluster.

      -
    • -
    • -
      6
      -
      Secondary Storage
      -

      Add servers to store templates, ISOs, and snapshots for the whole zone.

      -
    • -
    -
    - - -
    -
    - Zone Configuration -
    -
      -
    • -
      1
      -
      Public
      -
      Configure
      -
    • -
    • -
      Management
      -
      Configure
      -
    • -
    • -
      2
      -
      1
      -
      Guest
      -
      Configure
      -
    • -
    -
    - - -
    -
    -
    Add Resource
    -
    -
      -
    • -
      Pods
      -
      View All
      -
    • -
    • -
      3
      -
      2
      -
      Clusters
      -
      View All
      -
    • -
    • -
      4
      -
      3
      -
      Hosts
      -
      View All
      -
    • -
    • -
      5
      -
      4
      -
      Primary Storage
      -
      View All
      -
    • -
    • -
      6
      -
      5
      -
      Secondary Storage
      -
      View All
      -
    • -
    -
    -
    - - -
    - -
    -
    -
    - -
    - -
    - -
    - - -
    - - -
    -
      -
    • -
      - : -
      -
      -
      %
      -
      -
      -
      -
      -
      - - / - -
      -
      -
    • -
    -
    -
    - -
    -
    -
    -
    -
    -
      -
    • -
      - Alert 1 -

      Alert 1

      -

      Alert 1

      -
      -
    • -
    -
    - - -
    -
    -
    -
    -
      -
    • -
      - Alert 1 -

      Alert 1

      -
      -
    • -
    -
    -
    - - -
    -
    -
    - -
    -
      -
    • -
      -
      -
    • -
    • -
      -
      -
    • -
    • -
      -
      -
    • -
    -
    -
    - -
    -
      -
    • - - - - - - -
      -
      -
        -
      • -
        - -
      • +
        + +
        +
        +
        +
        +
      + +
      + +
      + +
      +
      +
      +
      +
      + +
      + +
      + +
      +
      +
      +
      +
      + +
      + +
      + +
      +
      +
      +
      +
      + +
      +
      + +
      +
      + +
      +
    + +
    + +
    + +
    +
    + +
    +
      +
    • +
      +
      +
    • +
    • +
      +
      +
    • +
    • +
      +
      +
    -
    - -
  • - - - - - - -
    - - - - - - - - - -
    -
    :
    -
    -
    -
    :
    -
    -
    -
  • - +
    + +
    +
      +
    • +
      +
      +
    • +
    • +
      + +
      +
    • +
    +
    + +
    +
    + +
    +
    +
    + +
    +
      + +
    • + +
      +
      + +
      +
      5
      +
      +
      + + +
      +
      10
      +
      +
      +
      +
    • + + +
    • + +
      +
      +
      10
      +
      +
      +
    • + + +
    • + +
      +
      +
      200
      +
      mb/s
      +
      +
    • +
    +
    +
    + + +
    +
    +
    + +
    +
      +
    • + +
      +
    • +
    +
    +
    +
    +
    + +
    +
    + +
    +
      + +
    • +
      +
      +
    • + + +
    • +
      +
      +
    • + + +
    • +
      +
      +
    • + + +
    • +
      +
      +
    • + + +
    • +
      +
      +
      + + +
      +
      +
    • +
    +
    + +
    +
    + +
    + + +
    +
    +
      +
    • +
      +
      +
    • +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +   + +
    +
    + + +
    +
      +
    • + +   + + " + view-all-target="zones"> +
    • +
    • + +   + + " + view-all-target="pods"> +
    • +
    • + +   + + " + view-all-target="clusters"> +
    • +
    • + +   + + " + view-all-target="hosts"> +
    • +
    • + +   + + " + view-all-target="primaryStorage"> +
    • +
    • + +   + + " + view-all-target="secondaryStorage"> +
    • +
    • + +   + + " + view-all-target="systemVms"> +
    • +
    • + +   + + " + view-all-target="virtualRouters"> +
    • +
    +
    +
    + + +
    + +
    +
      +
    • +
      1
      +
      Guest
      +

      Set up the network for traffic between end-user VMs.

      +
    • +
    • +
      2
      +
      Clusters
      +

      Define one or more clusters to group the compute hosts.

      +
    • +
    • +
      3
      +
      Hosts
      +

      Add hosts to clusters. Hosts run hypervisors and VMs.

      +
    • +
    • +
      4
      +
      Primary Storage
      +

      Add servers to store VM disk volumes in each cluster.

      +
    • +
    • +
      5
      +
      Secondary Storage
      +

      Add servers to store templates, ISOs, and snapshots for the whole zone.

      +
    • +
    +
    + + +
    +
      +
    • +
      1
      +
      Public
      +

      Set up the network for Internet traffic.

      +
    • +
    • +
      2
      +
      Guest
      +

      Set up the network for traffic between end-user VMs.

      +
    • +
    • +
      3
      +
      Clusters
      +

      Define one or more clusters to group the compute hosts.

      +
    • +
    • +
      4
      +
      Hosts
      +

      Add hosts to clusters. Hosts run hypervisors and VMs.

      +
    • +
    • +
      5
      +
      Primary Storage
      +

      Add servers to store VM disk volumes in each cluster.

      +
    • +
    • +
      6
      +
      Secondary Storage
      +

      Add servers to store templates, ISOs, and snapshots for the whole zone.

      +
    • +
    +
    + + +
    +
    + Zone Configuration +
    +
      +
    • +
      1
      +
      Public
      +
      Configure
      +
    • +
    • +
      Management
      +
      Configure
      +
    • +
    • +
      2
      +
      1
      +
      Guest
      +
      Configure
      +
    • +
    +
    + + +
    +
    +
    Add Resource
    +
    +
      +
    • +
      Pods
      +
      View All
      +
    • +
    • +
      3
      +
      2
      +
      Clusters
      +
      View All
      +
    • +
    • +
      4
      +
      3
      +
      Hosts
      +
      View All
      +
    • +
    • +
      5
      +
      4
      +
      Primary Storage
      +
      View All
      +
    • +
    • +
      6
      +
      5
      +
      Secondary Storage
      +
      View All
      +
    • +
    +
    +
    + + +
    + +
    +
    +
    + +
    + +
    + +
    + + +
    + + +
    +
      +
    • +
      + : +
      +
      +
      %
      +
      +
      +
      +
      +
      + + / + +
      +
      +
    • +
    +
    +
    + +
    +
    +
    +
    +
    +
      +
    • +
      + Alert 1 +

      Alert 1

      +

      Alert 1

      +
      +
    • +
    +
    + + +
    +
    +
    +
    +
      +
    • +
      + Alert 1 +

      Alert 1

      +
      +
    • +
    +
    +
    + + +
    +
    +
    + +
    +
      +
    • +
      +
      +
    • +
    • +
      +
      +
    • +
    • +
      +
      +
    • +
    +
    +
    + +
    +
      +
    • + + + + + + +
      +
      +
        +
      • +
        + +
      • +
      +
      +
    • +
    • + + + + + + +
      + + + + + + + + + +
      +
      :
      +
      +
      +
      :
      +
      +
      +
    • +
    +
    +
    + + +
    +

    Description

    + +
    +

    Schedule:

    + +
    +
      +
    • +
    • +
    • +
    • +
    + + +
    +
    + + + +
    +
    +
    + + +
    +
    + + +
    +
    +
    + +
    +
    + + +
    +
    Keep
    +
    + + +
    +
    +
    +
    + + +
    +
    + + + +
    +
    Time
    +
    + + + +
    +
    + + +
    +
    Timezone
    +
    + +
    +
    + + +
    +
    Keep
    +
    + + +
    +
    +
    +
    + + +
    +
    + + + +
    +
    Time
    +
    + + + +
    +
    + + +
    +
    Day of week
    +
    + +
    +
    + + +
    +
    Timezone
    +
    + +
    +
    + + +
    +
    Keep
    +
    + + +
    +
    +
    +
    + + +
    +
    + + + +
    +
    Time
    +
    + + + +
    +
    + + +
    +
    Day of month
    +
    + +
    +
    + + +
    +
    Timezone
    +
    + +
    +
    + + +
    +
    Keep
    +
    + + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +

    Scheduled Snapshots

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Time: min past the hrTimezone:
    Keep:
     
    Time: Timezone:
    Keep:
     
    Time: Every Timezone:
    Keep:
     
    Time: Day of monthTimezone:
    Keep:
     
    +
    +
    -
    - -
    -

    Description

    + + + + + + + + + -
    -

    Schedule:

    + + + + + + + + + + + + + + + + + + -
    -
      -
    • -
    • -
    • -
    • -
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - -
    -
    - - - -
    -
    -
    - - -
    -
    - - -
    -
    -
    - -
    -
    - - -
    -
    Keep
    -
    - - -
    -
    -
    -
    - - -
    -
    - - - -
    -
    Time
    -
    - - - -
    -
    - - -
    -
    Timezone
    -
    - -
    -
    - - -
    -
    Keep
    -
    - - -
    -
    -
    -
    - - -
    -
    - - - -
    -
    Time
    -
    - - - -
    -
    - - -
    -
    Day of week
    -
    - -
    -
    - - -
    -
    Timezone
    -
    - -
    -
    - - -
    -
    Keep
    -
    - - -
    -
    -
    -
    - - -
    -
    - - - -
    -
    Time
    -
    - - - -
    -
    - - -
    -
    Day of month
    -
    - -
    -
    - - -
    -
    Timezone
    -
    - -
    -
    - - -
    -
    Keep
    -
    - - -
    -
    -
    -
    -
    - -
    -
    -
    -
    - -
    -

    Scheduled Snapshots

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Time: min past the hrTimezone:
    Keep:
     
    Time: Timezone:
    Keep:
     
    Time: Every Timezone:
    Keep:
     
    Time: Day of monthTimezone:
    Keep:
     
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + diff --git a/ui/scripts/accounts.js b/ui/scripts/accounts.js index 14f7660f30f..a754d31b478 100644 --- a/ui/scripts/accounts.js +++ b/ui/scripts/accounts.js @@ -291,6 +291,24 @@ }); } + if (args.data.networkLimit != null) { + var data = { + resourceType: 6, + max: args.data.networkLimit, + domainid: accountObj.domainid, + account: accountObj.name + }; + + $.ajax({ + url: createURL('updateResourceLimit'), + data: data, + async: false, + success: function(json) { + accountObj["networkLimit"] = args.data.networkLimit; + } + }); + } + if (args.data.primaryStorageLimit != null) { var data = { resourceType: 10, @@ -651,6 +669,15 @@ return false; } }, + networkLimit: { + label: 'label.network.limits', + isEditable: function(context) { + if (context.accounts[0].accounttype == roleTypeUser || context.accounts[0].accounttype == roleTypeDomainAdmin) //updateResourceLimits is only allowed on account whose type is user or domain-admin + return true; + else + return false; + } + }, primaryStorageLimit: { label: 'label.primary.storage.limits', isEditable: function(context) { @@ -733,6 +760,9 @@ case "4": accountObj["templateLimit"] = limit.max; break; + case "6": + accountObj["networkLimit"] = limit.max; + break; case "7": accountObj["vpcLimit"] = limit.max; break; diff --git a/ui/scripts/instanceWizard.js b/ui/scripts/instanceWizard.js index 1179a87519e..40832aedf3c 100644 --- a/ui/scripts/instanceWizard.js +++ b/ui/scripts/instanceWizard.js @@ -237,6 +237,9 @@ data: { templates: templatesObj, hypervisors: hypervisorObjs + }, + customHidden: function(args) { + return true; } }); }, diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js index 41d1772dbe4..6e545fcc3e8 100644 --- a/ui/scripts/instances.js +++ b/ui/scripts/instances.js @@ -529,7 +529,7 @@ }, notification: { - pool: pollAsyncJobResult + poll: pollAsyncJobResult } }, destroy: { @@ -568,6 +568,39 @@ poll: pollAsyncJobResult } }, + expunge: { + label: 'label.action.expunge.instance', + compactLabel: 'label.expunge', + messages: { + confirm: function(args) { + return 'message.action.expunge.instance'; + }, + notification: function(args) { + return 'label.action.expunge.instance'; + } + }, + action: function(args) { + $.ajax({ + url: createURL("expungeVirtualMachine&id=" + args.context.instances[0].id), + dataType: "json", + async: true, + success: function(json) { + var jid = json.expungevirtualmachineresponse.jobid; + args.response.success({ + _custom: { + jobId: jid, + getActionFilter: function() { + return vmActionfilter; + } + } + }); + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + }, restore: { label: 'label.action.restore.instance', compactLabel: 'label.restore', @@ -796,13 +829,11 @@ isdynamicallyscalable: (args.data.isdynamicallyscalable == "on"), ostypeid: args.data.guestosid }; - if (args.data.displayname != args.context.instances[0].displayname) { $.extend(data, { displayName: args.data.displayname }); } - $.ajax({ url: createURL('updateVirtualMachine'), data: data, @@ -813,6 +844,26 @@ }); } }); + + + //***** addResourceDetail ***** + //XenServer only (starts here) + if(args.$detailView.find('form').find('div .detail-group').find('.xenserverToolsVersion61plus').length > 0) { + $.ajax({ + url: createURL('addResourceDetail'), + data: { + resourceType: 'uservm', + resourceId: 3, + 'details[0].key': 'hypervisortoolsversion', + 'details[0].value': (args.data.xenserverToolsVersion61plus == "on") ? 'xenserver61' : 'xenserver56' + }, + success: function(json) { + //do nothing + } + }); + } + //XenServer only (ends here) + } }, @@ -1463,9 +1514,13 @@ if (isAdmin()) { hiddenFields = []; } else { - hiddenFields = ["hypervisor"]; + hiddenFields = ["hypervisor", 'xenserverToolsVersion61plus']; } - + + if ('instances' in args.context && args.context.instances[0].hypervisor != 'XenServer') { + hiddenFields.push('xenserverToolsVersion61plus'); + } + if (!args.context.instances[0].publicip) { hiddenFields.push('publicip'); } @@ -1547,6 +1602,18 @@ label: 'label.hypervisor' }, + xenserverToolsVersion61plus: { + label: 'XenServer Tools Version 6.1+', + isBoolean: true, + isEditable: function () { + if (isAdmin()) + return true; + else + return false; + }, + converter: cloudStack.converters.toBooleanText + }, + /* isoid: { label: 'label.attached.iso', @@ -1617,11 +1684,22 @@ var jsonObj; if (json.listvirtualmachinesresponse.virtualmachine != null && json.listvirtualmachinesresponse.virtualmachine.length > 0) jsonObj = json.listvirtualmachinesresponse.virtualmachine[0]; + else if (isAdmin()) + jsonObj = $.extend(args.context.instances[0], { + state: "Expunged" + }); //after root admin expunge a VM, listVirtualMachines API will no longer returns this expunged VM to all users. else jsonObj = $.extend(args.context.instances[0], { state: "Destroyed" }); //after a regular user destroys a VM, listVirtualMachines API will no longer returns this destroyed VM to the regular user. + if ('details' in jsonObj && 'hypervisortoolsversion' in jsonObj.details) { + if (jsonObj.details.hypervisortoolsversion == 'xenserver61') + jsonObj.xenserverToolsVersion61plus = true; + else + jsonObj.xenserverToolsVersion61plus = false; + } + args.response.success({ actionFilter: vmActionfilter, data: jsonObj @@ -1944,6 +2022,8 @@ if (isAdmin() || isDomainAdmin()) { allowedActions.push("restore"); } + if (isAdmin()) + allowedActions.push("expunge"); } else if (jsonObj.state == 'Running') { allowedActions.push("stop"); allowedActions.push("restart"); @@ -2001,6 +2081,9 @@ // allowedActions.push("stop"); } else if (jsonObj.state == 'Error') { allowedActions.push("destroy"); + } else if (jsonObj.state == 'Expunging') { + if (isAdmin()) + allowedActions.push("expunge"); } return allowedActions; } diff --git a/ui/scripts/network.js b/ui/scripts/network.js index d0f6a927833..12e5389d9e6 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -139,6 +139,7 @@ var ipObj = args.context.item; var status = ipObj.state; + //***** apply to both Isolated Guest Network IP, VPC IP (begin) ***** if (status == 'Destroyed' || status == 'Releasing' || status == 'Released' || @@ -149,90 +150,105 @@ return []; } - if (args.context.networks[0].networkofferingconservemode == false) { - /* - (1) If IP is SourceNat, no StaticNat/VPN/PortForwarding/LoadBalancer can be enabled/added. - */ - if (ipObj.issourcenat == true) { - disallowedActions.push('enableStaticNAT'); - disallowedActions.push('enableVPN'); - } - - /* - (2) If IP is non-SourceNat, show StaticNat/VPN/PortForwarding/LoadBalancer at first. - 1. Once StaticNat is enabled, hide VPN/PortForwarding/LoadBalancer. - 2. Once VPN is enabled, hide StaticNat/PortForwarding/LoadBalancer. - 3. Once a PortForwarding rule is added, hide StaticNat/VPN/LoadBalancer. - 4. Once a LoadBalancer rule is added, hide StaticNat/VPN/PortForwarding. - */ - else { //ipObj.issourcenat == false - if (ipObj.isstaticnat) { //1. Once StaticNat is enabled, hide VPN/PortForwarding/LoadBalancer. - disallowedActions.push('enableVPN'); - } - if (ipObj.vpnenabled) { //2. Once VPN is enabled, hide StaticNat/PortForwarding/LoadBalancer. - disallowedActions.push('enableStaticNAT'); - } - - //3. Once a PortForwarding rule is added, hide StaticNat/VPN/LoadBalancer. - $.ajax({ - url: createURL('listPortForwardingRules'), - data: { - ipaddressid: ipObj.id, - listAll: true - }, - dataType: 'json', - async: false, - success: function(json) { - var rules = json.listportforwardingrulesresponse.portforwardingrule; - if (rules != null && rules.length > 0) { - disallowedActions.push('enableVPN'); - disallowedActions.push('enableStaticNAT'); - } - } - }); - - //4. Once a LoadBalancer rule is added, hide StaticNat/VPN/PortForwarding. - $.ajax({ - url: createURL('listLoadBalancerRules'), - data: { - publicipid: ipObj.id, - listAll: true - }, - dataType: 'json', - async: false, - success: function(json) { - var rules = json.listloadbalancerrulesresponse.loadbalancerrule; - if (rules != null && rules.length > 0) { - disallowedActions.push('enableVPN'); - disallowedActions.push('enableStaticNAT'); - } - } - }); - } - } - - if (ipObj.isstaticnat) { - disallowedActions.push('enableStaticNAT'); - } else { - disallowedActions.push('disableStaticNAT'); - } - - if (ipObj.networkOfferingHavingVpnService == true) { - if (ipObj.vpnenabled) { - disallowedActions.push('enableVPN'); - } else { - disallowedActions.push('disableVPN'); - } - } else { //ipObj.networkOfferingHavingVpnService == false - disallowedActions.push('disableVPN'); - disallowedActions.push('enableVPN'); - } - - if (ipObj.issourcenat) { + if (ipObj.issourcenat) { //sourceNAT IP doesn't support staticNAT disallowedActions.push('enableStaticNAT'); disallowedActions.push('disableStaticNAT'); disallowedActions.push('remove'); - } + } else { //non-sourceNAT IP supports staticNAT + if (ipObj.isstaticnat) { + disallowedActions.push('enableStaticNAT'); + } else { + disallowedActions.push('disableStaticNAT'); + } + } + //***** apply to both Isolated Guest Network IP, VPC IP (end) ***** + + + if (!('vpc' in args.context)) { //***** Guest Network section > Guest Network page > IP Address page ***** + if (args.context.networks[0].networkofferingconservemode == false) { + /* + (1) If IP is SourceNat, no StaticNat/VPN/PortForwarding/LoadBalancer can be enabled/added. + */ + if (ipObj.issourcenat == true) { + disallowedActions.push('enableStaticNAT'); + disallowedActions.push('enableVPN'); + } + + /* + (2) If IP is non-SourceNat, show StaticNat/VPN/PortForwarding/LoadBalancer at first. + 1. Once StaticNat is enabled, hide VPN/PortForwarding/LoadBalancer. + 2. Once VPN is enabled, hide StaticNat/PortForwarding/LoadBalancer. + 3. Once a PortForwarding rule is added, hide StaticNat/VPN/LoadBalancer. + 4. Once a LoadBalancer rule is added, hide StaticNat/VPN/PortForwarding. + */ + else { //ipObj.issourcenat == false + if (ipObj.isstaticnat) { //1. Once StaticNat is enabled, hide VPN/PortForwarding/LoadBalancer. + disallowedActions.push('enableVPN'); + } + if (ipObj.vpnenabled) { //2. Once VPN is enabled, hide StaticNat/PortForwarding/LoadBalancer. + disallowedActions.push('enableStaticNAT'); + } + + //3. Once a PortForwarding rule is added, hide StaticNat/VPN/LoadBalancer. + $.ajax({ + url: createURL('listPortForwardingRules'), + data: { + ipaddressid: ipObj.id, + listAll: true + }, + dataType: 'json', + async: false, + success: function(json) { + var rules = json.listportforwardingrulesresponse.portforwardingrule; + if (rules != null && rules.length > 0) { + disallowedActions.push('enableVPN'); + disallowedActions.push('enableStaticNAT'); + } + } + }); + + //4. Once a LoadBalancer rule is added, hide StaticNat/VPN/PortForwarding. + $.ajax({ + url: createURL('listLoadBalancerRules'), + data: { + publicipid: ipObj.id, + listAll: true + }, + dataType: 'json', + async: false, + success: function(json) { + var rules = json.listloadbalancerrulesresponse.loadbalancerrule; + if (rules != null && rules.length > 0) { + disallowedActions.push('enableVPN'); + disallowedActions.push('enableStaticNAT'); + } + } + }); + } + } + + if (ipObj.networkOfferingHavingVpnService == true) { + if (ipObj.vpnenabled) { + disallowedActions.push('enableVPN'); + } else { + disallowedActions.push('disableVPN'); + } + } else { //ipObj.networkOfferingHavingVpnService == false + disallowedActions.push('disableVPN'); + disallowedActions.push('enableVPN'); + } + } else { //***** VPC section > Configuration VPC > Router > Public IP Addresses ***** + if (ipObj.issourcenat) { //VPC sourceNAT IP: supports VPN + if (ipObj.vpnenabled) { + disallowedActions.push('enableVPN'); + } else { + disallowedActions.push('disableVPN'); + } + } else { //VPC non-sourceNAT IP: doesn't support VPN + disallowedActions.push('enableVPN'); + disallowedActions.push('disableVPN'); + } + } allowedActions = $.grep(allowedActions, function(item) { return $.inArray(item, disallowedActions) == -1; @@ -444,9 +460,7 @@ }) }); } - }); - //??? - + }); } }, @@ -1078,7 +1092,7 @@ label: 'label.restart.required', converter: function(booleanValue) { if (booleanValue == true) - return "Yes"; + return "Yes"; else if (booleanValue == false) return "No"; } @@ -1938,7 +1952,7 @@ } //*** from Guest Network section *** - if ('networks' in args.context) { + if (!('vpc' in args.context)) { if (args.context.networks[0].vpcid == null) { //Guest Network section > non-VPC network, show Acquire IP button return true; } else { //Guest Network section > VPC network, hide Acquire IP button @@ -1946,7 +1960,7 @@ } } //*** from VPC section *** - else { //'vpc' in args.context + else { //'vpc' in args.context //args.context.networks[0] has only one property => name: 'Router' return true; //VPC section, show Acquire IP button } }, @@ -2121,28 +2135,7 @@ detailView: { name: 'IP address detail', tabFilter: function(args) { - var item = args.context.ipAddresses[0]; - - // Get VPN data - $.ajax({ - url: createURL('listRemoteAccessVpns'), - data: { - listAll: true, - publicipid: item.id - }, - dataType: 'json', - async: false, - success: function(vpnResponse) { - var isVPNEnabled = vpnResponse.listremoteaccessvpnsresponse.count; - if (isVPNEnabled) { - item.vpnenabled = true; - item.remoteaccessvpn = vpnResponse.listremoteaccessvpnsresponse.remoteaccessvpn[0]; - }; - }, - error: function(data) { - args.response.error(parseXMLHttpResponse(data)); - } - }); + var item = args.context.ipAddresses[0]; var disabledTabs = []; var ipAddress = args.context.ipAddresses[0]; @@ -5935,7 +5928,7 @@ }; function getExtaPropertiesForIpObj(ipObj, args) { - if (!('vpc' in args.context)) { //from Guest Network section + if (!('vpc' in args.context)) { //***** Guest Network section > Guest Network page > IP Address page ***** var services = args.context.networks[0].service; if(services != null) { for(var i = 0; i < services.length; i++) { @@ -5959,12 +5952,32 @@ if (isVPNEnabled) { ipObj.vpnenabled = true; ipObj.remoteaccessvpn = vpnResponse.listremoteaccessvpnsresponse.remoteaccessvpn[0]; - }; + } else { + ipObj.vpnenabled = false; + } } }); } - } else { //from VPC section - ipObj.networkOfferingHavingVpnService = false; //VPN is not supported in IP in VPC, so hardcode it as false + } else { //***** VPC section > Configuration VPC > Router > Public IP Addresses ***** + if (ipObj.issourcenat) { //VPC sourceNAT IP: supports VPN + $.ajax({ + url: createURL('listRemoteAccessVpns'), + data: { + listAll: true, + publicipid: ipObj.id + }, + async: false, + success: function(vpnResponse) { + var isVPNEnabled = vpnResponse.listremoteaccessvpnsresponse.count; + if (isVPNEnabled) { + ipObj.vpnenabled = true; + ipObj.remoteaccessvpn = vpnResponse.listremoteaccessvpnsresponse.remoteaccessvpn[0]; + } else { + ipObj.vpnenabled = false; + } + } + }); + } } } diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js index 3d0794dfa27..4f3ba0c33ee 100644 --- a/ui/scripts/sharedFunctions.js +++ b/ui/scripts/sharedFunctions.js @@ -855,6 +855,7 @@ cloudStack.preFilter = { args.$form.find('.form-item[rel=isPublic]').hide(); } args.$form.find('.form-item[rel=isFeatured]').hide(); + args.$form.find('.form-item[rel=xenserverToolsVersion61plus]').hide(); } }, addLoadBalancerDevice: function(args) { //add netscaler device OR add F5 device diff --git a/ui/scripts/storage.js b/ui/scripts/storage.js index b16f4d4e77e..314621e3368 100644 --- a/ui/scripts/storage.js +++ b/ui/scripts/storage.js @@ -1960,7 +1960,7 @@ allowedActions.push("createTemplate"); allowedActions.push("createVolume"); - if (args.context.volumes[0].vmstate == "Stopped") { + if (jsonObj.revertable && args.context.volumes[0].vmstate == "Stopped") { allowedActions.push("revertSnapshot"); } } diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 0af39525175..7fb807d4c89 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -13779,6 +13779,7 @@ title: 'Blades', listView: { id: 'blades', + hideSearchBar: true, fields: { chassis: { label: 'Chassis' @@ -14676,7 +14677,38 @@ detailView: { name: 'Secondary storage details', isMaximized: true, - actions: { + actions: { + prepareObjectStoreMigration: { + label: 'Prepare Object Store Migration', + messages: { + confirm: function(args) { + return 'Please confirm you want to prepare migration of secondary storage to object store.'; + }, + notification: function(args) { + return 'Prepare Object Store Migration'; + } + }, + action: function(args) { + $.ajax({ + url: createURL('prepareSecondaryStorageForMigration'), + data: { + id: args.context.secondaryStorage[0].id + }, + success: function(json) { + var jid = json.preparesecondarystorageformigrationresponse.jobid; + args.response.success({ + _custom: { + jobId: jid + } + }); + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + }, + remove: { label: 'label.action.delete.secondary.storage', messages: { @@ -16146,6 +16178,11 @@ var jsonObj = args.context.item; var allowedActions = []; allowedActions.push("remove"); + + if (jsonObj.providername == 'NFS') { + allowedActions.push("prepareObjectStoreMigration"); + } + return allowedActions; } diff --git a/ui/scripts/templates.js b/ui/scripts/templates.js index ccb83c2c43a..922c87e32eb 100644 --- a/ui/scripts/templates.js +++ b/ui/scripts/templates.js @@ -214,10 +214,21 @@ $form.find('.form-item[rel=rootDiskControllerType]').css('display', 'inline-block'); $form.find('.form-item[rel=nicAdapterType]').css('display', 'inline-block'); $form.find('.form-item[rel=keyboardType]').css('display', 'inline-block'); + + $form.find('.form-item[rel=xenserverToolsVersion61plus]').hide(); + } else if ($(this).val() == "XenServer") { + $form.find('.form-item[rel=rootDiskControllerType]').hide(); + $form.find('.form-item[rel=nicAdapterType]').hide(); + $form.find('.form-item[rel=keyboardType]').hide(); + + if (isAdmin()) + $form.find('.form-item[rel=xenserverToolsVersion61plus]').css('display', 'inline-block'); } else { $form.find('.form-item[rel=rootDiskControllerType]').hide(); $form.find('.form-item[rel=nicAdapterType]').hide(); $form.find('.form-item[rel=keyboardType]').hide(); + + $form.find('.form-item[rel=xenserverToolsVersion61plus]').hide(); } }); @@ -225,6 +236,30 @@ } }, + xenserverToolsVersion61plus: { + label: 'XenServer Tools Version 6.1+', + isBoolean: true, + isChecked: function (args) { + var b = false; + if (isAdmin()) { + $.ajax({ + url: createURL('listConfigurations'), + data: { + name: 'xen.pvdriver.version' + }, + async: false, + success: function (json) { + if (json.listconfigurationsresponse.configuration != null && json.listconfigurationsresponse.configuration[0].value == 'xenserver61') { + b = true; + } + } + }); + } + return b; + }, + isHidden: true + }, + //fields for hypervisor == "VMware" (starts here) rootDiskControllerType: { label: 'label.root.disk.controller', @@ -344,6 +379,11 @@ id: 'TAR', description: 'TAR' }); + } else if (args.hypervisor == "Hyperv") { + items.push({ + id: 'VHD', + description: 'VHD' + }); } args.response.success({ data: items @@ -439,6 +479,16 @@ }); } + + //XenServer only (starts here) + if (args.$form.find('.form-item[rel=xenserverToolsVersion61plus]').css("display") != "none") { + $.extend(data, { + 'details[0].hypervisortoolsversion': (args.data.xenserverToolsVersion61plus == "on") ? "xenserver61" : "xenserver56" + }); + } + //XenServer only (ends here) + + //VMware only (starts here) if (args.$form.find('.form-item[rel=rootDiskControllerType]').css("display") != "none" && args.data.rootDiskControllerType != "") { $.extend(data, { @@ -612,6 +662,25 @@ } }); + + //***** addResourceDetail ***** + //XenServer only (starts here) + if(args.$detailView.find('form').find('div .detail-group').find('.xenserverToolsVersion61plus').length > 0) { + $.ajax({ + url: createURL('addResourceDetail'), + data: { + resourceType: 'template', + resourceId: 1, + 'details[0].key': 'hypervisortoolsversion', + 'details[0].value': (args.data.xenserverToolsVersion61plus == "on") ? 'xenserver61' : 'xenserver56' + }, + success: function(json) { + //do nothing + } + }); + } + //XenServer only (ends here) + //***** listTemplates ***** //So, we call listTemplates API to get a complete template object @@ -800,8 +869,13 @@ if (isAdmin()) { hiddenFields = []; } else { - hiddenFields = ["hypervisor"]; + hiddenFields = ["hypervisor", 'xenserverToolsVersion61plus']; } + + if ('templates' in args.context && args.context.templates[0].hypervisor != 'XenServer') { + hiddenFields.push('xenserverToolsVersion61plus'); + } + return hiddenFields; }, @@ -833,6 +907,17 @@ hypervisor: { label: 'label.hypervisor' }, + xenserverToolsVersion61plus: { + label: 'XenServer Tools Version 6.1+', + isBoolean: true, + isEditable: function () { + if (isAdmin()) + return true; + else + return false; + }, + converter: cloudStack.converters.toBooleanText + }, templatetype: { label: 'label.type' }, @@ -959,13 +1044,21 @@ url: createURL(apiCmd), dataType: "json", success: function(json) { - args.response.success({ - actionFilter: templateActionfilter, - data: json.listtemplatesresponse.template[0] - }); + var jsonObj = json.listtemplatesresponse.template[0]; + + if ('details' in jsonObj && 'hypervisortoolsversion' in jsonObj.details) { + if (jsonObj.details.hypervisortoolsversion == 'xenserver61') + jsonObj.xenserverToolsVersion61plus = true; + else + jsonObj.xenserverToolsVersion61plus = false; + } + + args.response.success({ + actionFilter: templateActionfilter, + data: jsonObj + }); } }); - } } } diff --git a/ui/scripts/ui-custom/instanceWizard.js b/ui/scripts/ui-custom/instanceWizard.js index c99155f3997..6aa93ffffff 100644 --- a/ui/scripts/ui-custom/instanceWizard.js +++ b/ui/scripts/ui-custom/instanceWizard.js @@ -263,6 +263,8 @@ }, 'select-iso': function($step, formData) { + $step.find('.section.custom-size').hide(); + var originalValues = function(formData) { var $inputs = $step.find('.wizard-step-conditional:visible') .find('input[type=radio]'); @@ -376,6 +378,21 @@ }); originalValues(formData); + + var custom = args.customHidden({ + context: context, + data: args.data + }); + + $step.find('.custom-size-label').remove(); + + if (!custom) { + $step.find('.section.custom-size').show(); + $step.addClass('custom-disk-size'); + } else { + $step.find('.section.custom-size').hide(); + $step.removeClass('custom-disk-size'); + } } } }; @@ -1014,21 +1031,25 @@ // Setup tabs and slider $wizard.find('.section.custom-size .size.max span').html(maxCustomDiskSize); $wizard.find('.tab-view').tabs(); - $wizard.find('.slider').slider({ + $wizard.find('.slider').each(function() { + var $slider = $(this); + + $slider.slider({ min: 1, max: maxCustomDiskSize, start: function(event) { - $wizard.find('div.data-disk-offering div.custom-size input[type=radio]').click(); + $slider.closest('.section.custom-size').find('input[type=radio]').click(); }, slide: function(event, ui) { - $wizard.find('div.data-disk-offering div.custom-size input[type=text]').val( + $slider.closest('.section.custom-size').find('input[type=text]').val( ui.value ); - $wizard.find('div.data-disk-offering span.custom-disk-size').html( + $slider.closest('.step').find('span.custom-disk-size').html( ui.value ); } }); + }); $wizard.find('div.data-disk-offering div.custom-size input[type=text]').bind('change', function() { var old = $wizard.find('div.data-disk-offering div.custom-size input[type=text]').val(); diff --git a/ui/scripts/ui/dialog.js b/ui/scripts/ui/dialog.js index 4de8423521a..fdcf9ff80fd 100644 --- a/ui/scripts/ui/dialog.js +++ b/ui/scripts/ui/dialog.js @@ -385,7 +385,13 @@ name: key, type: 'checkbox' }).appendTo($value); - if (field.isChecked) { + var isChecked; + if (typeof (field.isChecked) == 'function') { + isChecked = field.isChecked(); + } else { + isChecked = field.isChecked; + } + if (isChecked) { $input.attr('checked', strOrFunc(field.isChecked)); } else { // This is mainly for IE compatibility diff --git a/ui/scripts/ui/widgets/detailView.js b/ui/scripts/ui/widgets/detailView.js index b7235a45ffb..967eac550fd 100644 --- a/ui/scripts/ui/widgets/detailView.js +++ b/ui/scripts/ui/widgets/detailView.js @@ -369,6 +369,12 @@ }); }, + prepareObjectStoreMigration: function($detailView, args) { + var tab = args.tabs[args.activeTab]; + var isMultiple = tab.multiple; + uiActions.remove($detailView, args); + }, + /** * Convert editable fields to text boxes; clicking again saves data * @@ -490,6 +496,7 @@ action.action({ data: data, _custom: $detailView.data('_custom'), + $detailView: $detailView, context: $detailView.data('view-args').context, response: { success: function(args) { diff --git a/ui/scripts/ui/widgets/listView.js b/ui/scripts/ui/widgets/listView.js index 4b670646ce2..a213f5a9a14 100644 --- a/ui/scripts/ui/widgets/listView.js +++ b/ui/scripts/ui/widgets/listView.js @@ -1696,7 +1696,10 @@ noActionCol: listViewData.noActionCol }); createFilters($toolbar, listViewData.filters); + + if (listViewData.hideSearchBar != true) { createSearchBar($toolbar, listViewData); + } loadBody( $table, diff --git a/usage/src/com/cloud/usage/UsageManagerImpl.java b/usage/src/com/cloud/usage/UsageManagerImpl.java index 3ff53e0e6f6..1ee21c97e9a 100644 --- a/usage/src/com/cloud/usage/UsageManagerImpl.java +++ b/usage/src/com/cloud/usage/UsageManagerImpl.java @@ -84,7 +84,7 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; @Component @Local(value={UsageManager.class}) @@ -248,7 +248,7 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna m_sanity = m_sanityExecutor.scheduleAtFixedRate(new SanityCheck(), 1, m_sanityCheckInterval, TimeUnit.DAYS); } - Transaction usageTxn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy usageTxn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); try { if(m_heartbeatLock.lock(3)) { // 3 second timeout try { @@ -381,7 +381,7 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna s_logger.info("not parsing usage records since start time mills (" + startDateMillis + ") is on or after end time millis (" + endDateMillis + ")"); } - Transaction jobUpdateTxn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy jobUpdateTxn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); try { jobUpdateTxn.start(); // everything seemed to work...set endDate as the last success date @@ -411,7 +411,7 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna Map networkStats = null; List vmDiskStats = null; Map vmDiskUsages = null; - Transaction userTxn = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy userTxn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); try { Long limit = Long.valueOf(500); Long offset = Long.valueOf(0); @@ -552,7 +552,7 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna List events = _usageEventDao.getRecentEvents(new Date(endDateMillis)); - Transaction usageTxn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy usageTxn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); try { usageTxn.start(); @@ -779,7 +779,7 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna usageTxn.close(); // switch back to CLOUD_DB - Transaction swap = Transaction.open(Transaction.CLOUD_DB); + TransactionLegacy swap = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); if(!success){ _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USAGE_SERVER_RESULT, 0, new Long(0), "Usage job failed. Job id: "+job.getId(), "Usage job failed. Job id: "+job.getId()); } else { @@ -1664,7 +1664,7 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna private class Heartbeat extends ManagedContextRunnable { @Override protected void runInContext() { - Transaction usageTxn = Transaction.open(Transaction.USAGE_DB); + TransactionLegacy usageTxn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); try { if(!m_heartbeatLock.lock(3)) { // 3 second timeout if(s_logger.isTraceEnabled()) @@ -1723,7 +1723,7 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna @DB protected boolean updateJob(Long jobId, String hostname, Integer pid, Date heartbeat, int scheduled) { boolean changeOwner = false; - Transaction txn = Transaction.currentTxn(); + TransactionLegacy txn = TransactionLegacy.currentTxn(); try { txn.start(); diff --git a/usage/src/com/cloud/usage/UsageSanityChecker.java b/usage/src/com/cloud/usage/UsageSanityChecker.java index ed78a154047..35fbe8178fa 100644 --- a/usage/src/com/cloud/usage/UsageSanityChecker.java +++ b/usage/src/com/cloud/usage/UsageSanityChecker.java @@ -26,7 +26,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionLegacy; public class UsageSanityChecker { @@ -186,7 +186,7 @@ public class UsageSanityChecker { // Error while reading last check id } - Connection conn = Transaction.getStandaloneConnection(); + Connection conn = TransactionLegacy.getStandaloneConnection(); int maxId = 0; PreparedStatement pstmt = conn.prepareStatement("select max(id) from cloud_usage.cloud_usage"); ResultSet rs = pstmt.executeQuery(); diff --git a/utils/pom.xml b/utils/pom.xml old mode 100644 new mode 100755 index 35012b23343..451fcbfb4ef --- a/utils/pom.xml +++ b/utils/pom.xml @@ -36,6 +36,10 @@ org.springframework spring-context + + org.aspectj + aspectjweaver + log4j log4j @@ -107,10 +111,35 @@ org.reflections reflections + + + xml-apis + xml-apis + + org.owasp.esapi esapi + + + xml-apis + xml-apis + + + xml-apis + xml-apis-ext + + + xerces + xmlParserAPIs + + + + + commons-net + commons-net + 3.3 diff --git a/utils/src/com/cloud/utils/DateUtil.java b/utils/src/com/cloud/utils/DateUtil.java index 1854e155d64..1ddb65dbfc2 100644 --- a/utils/src/com/cloud/utils/DateUtil.java +++ b/utils/src/com/cloud/utils/DateUtil.java @@ -148,7 +148,13 @@ public class DateUtil { scheduleTime.set(Calendar.MINUTE, minutes); scheduleTime.set(Calendar.SECOND, 0); scheduleTime.set(Calendar.MILLISECOND, 0); - execDate = scheduleTime.getTime(); + try { + execDate = scheduleTime.getTime(); + } catch (IllegalArgumentException ex) { + scheduleTime.setLenient(true); + execDate = scheduleTime.getTime(); + scheduleTime.setLenient(false); + } // XXX: !execDate.after(startDate) is strictly for testing. // During testing we use a test clock which runs much faster than the real clock // So startDate and execDate will always be ahead in the future @@ -168,7 +174,13 @@ public class DateUtil { scheduleTime.set(Calendar.MINUTE, minutes); scheduleTime.set(Calendar.SECOND, 0); scheduleTime.set(Calendar.MILLISECOND, 0); - execDate = scheduleTime.getTime(); + try { + execDate = scheduleTime.getTime(); + } catch (IllegalArgumentException ex) { + scheduleTime.setLenient(true); + execDate = scheduleTime.getTime(); + scheduleTime.setLenient(false); + } // XXX: !execDate.after(startDate) is strictly for testing. // During testing we use a test clock which runs much faster than the real clock // So startDate and execDate will always be ahead in the future @@ -189,7 +201,13 @@ public class DateUtil { scheduleTime.set(Calendar.MINUTE, minutes); scheduleTime.set(Calendar.SECOND, 0); scheduleTime.set(Calendar.MILLISECOND, 0); - execDate = scheduleTime.getTime(); + try { + execDate = scheduleTime.getTime(); + } catch (IllegalArgumentException ex) { + scheduleTime.setLenient(true); + execDate = scheduleTime.getTime(); + scheduleTime.setLenient(false); + } // XXX: !execDate.after(startDate) is strictly for testing. // During testing we use a test clock which runs much faster than the real clock // So startDate and execDate will always be ahead in the future @@ -213,7 +231,13 @@ public class DateUtil { scheduleTime.set(Calendar.MINUTE, minutes); scheduleTime.set(Calendar.SECOND, 0); scheduleTime.set(Calendar.MILLISECOND, 0); - execDate = scheduleTime.getTime(); + try { + execDate = scheduleTime.getTime(); + } catch (IllegalArgumentException ex) { + scheduleTime.setLenient(true); + execDate = scheduleTime.getTime(); + scheduleTime.setLenient(false); + } // XXX: !execDate.after(startDate) is strictly for testing. // During testing we use a test clock which runs much faster than the real clock // So startDate and execDate will always be ahead in the future @@ -226,7 +250,14 @@ public class DateUtil { throw new CloudRuntimeException("Incorrect interval: "+type.toString()); } - return scheduleTime.getTime(); + try { + return scheduleTime.getTime(); + } catch (IllegalArgumentException ex) { + scheduleTime.setLenient(true); + Date nextScheduledDate = scheduleTime.getTime(); + scheduleTime.setLenient(false); + return nextScheduledDate; + } } // test only diff --git a/utils/src/com/cloud/utils/PropertiesUtil.java b/utils/src/com/cloud/utils/PropertiesUtil.java index e256fce9440..6db66ff484a 100755 --- a/utils/src/com/cloud/utils/PropertiesUtil.java +++ b/utils/src/com/cloud/utils/PropertiesUtil.java @@ -27,6 +27,7 @@ import java.util.Map; import java.util.Properties; import java.util.Set; +import org.apache.commons.io.IOUtils; import org.apache.log4j.Logger; public class PropertiesUtil { @@ -156,4 +157,19 @@ public class PropertiesUtil { } return configMap; } + + /** + * Load a Properties object with contents from a File. + * @param properties the properties object to be loaded + * @param file the file to load from + * @throws IOException + */ + public static void loadFromFile(Properties properties, File file) throws IOException { + InputStream stream = new FileInputStream(file); + try { + properties.load(stream); + } finally { + IOUtils.closeQuietly(stream); + } + } } diff --git a/utils/src/com/cloud/utils/S3Utils.java b/utils/src/com/cloud/utils/S3Utils.java index ce4d4b723e5..7918a202df5 100644 --- a/utils/src/com/cloud/utils/S3Utils.java +++ b/utils/src/com/cloud/utils/S3Utils.java @@ -171,6 +171,10 @@ public final class S3Utils { assert clientOptions != null; assert req != null; + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(format("Sending stream as S3 object using PutObjectRequest")); + } + acquireClient(clientOptions).putObject(req); } diff --git a/utils/src/com/cloud/utils/component/ComponentContext.java b/utils/src/com/cloud/utils/component/ComponentContext.java index 332e4eca1a0..ae2aefe057f 100644 --- a/utils/src/com/cloud/utils/component/ComponentContext.java +++ b/utils/src/com/cloud/utils/component/ComponentContext.java @@ -49,6 +49,7 @@ public class ComponentContext implements ApplicationContextAware { private static final Logger s_logger = Logger.getLogger(ComponentContext.class); private static ApplicationContext s_appContext; + private static Map, ApplicationContext> s_appContextDelegates; private static boolean s_initializeBeans = true; @Override @@ -234,11 +235,35 @@ public class ComponentContext implements ApplicationContextAware { public static T inject(Object instance) { // autowire dynamically loaded object - AutowireCapableBeanFactory beanFactory = s_appContext.getAutowireCapableBeanFactory(); + AutowireCapableBeanFactory beanFactory = getApplicationContext(instance).getAutowireCapableBeanFactory(); beanFactory.autowireBean(instance); return (T)instance; } + private static ApplicationContext getApplicationContext(Object instance) { + ApplicationContext result = null; + + if (instance != null && s_appContextDelegates != null) { + result = s_appContextDelegates.get(instance.getClass()); + } + + return result == null ? s_appContext : result; + } + + public static synchronized void addDelegateContext(Class clazz, ApplicationContext context) { + if (s_appContextDelegates == null) { + s_appContextDelegates = new HashMap, ApplicationContext>(); + } + + s_appContextDelegates.put(clazz, context); + } + + public static synchronized void removeDelegateContext(Class clazz) { + if (s_appContextDelegates != null) { + s_appContextDelegates.remove(clazz); + } + } + public boolean isInitializeBeans() { return s_initializeBeans; } diff --git a/utils/src/com/cloud/utils/exception/ExceptionUtil.java b/utils/src/com/cloud/utils/exception/ExceptionUtil.java index 977af928c14..322c23dc754 100644 --- a/utils/src/com/cloud/utils/exception/ExceptionUtil.java +++ b/utils/src/com/cloud/utils/exception/ExceptionUtil.java @@ -35,4 +35,16 @@ public class ExceptionUtil { } return writer.toString(); } + + @SuppressWarnings("unchecked") + public static void rethrow(Throwable t, Class clz) throws T { + if ( clz.isAssignableFrom(t.getClass()) ) + throw (T)t; + } + + public static void rethrowRuntime(Throwable t) { + rethrow(t, RuntimeException.class); + rethrow(t, Error.class); + } + } diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java index e64af4c7e3d..f5904250bb4 100755 --- a/utils/src/com/cloud/utils/net/NetUtils.java +++ b/utils/src/com/cloud/utils/net/NetUtils.java @@ -46,6 +46,7 @@ import com.googlecode.ipv6.IPv6Network; import com.cloud.utils.IteratorUtil; import com.cloud.utils.Pair; +import org.apache.commons.net.util.SubnetUtils; import com.cloud.utils.script.Script; public class NetUtils { @@ -1420,4 +1421,15 @@ public class NetUtils { mac = mac & 0x06FFFFFFFFFFl; return long2Mac(mac); } + + public static boolean isIpWithtInCidrRange(String ipAddress, String cidr) { + if (!isValidIp(ipAddress)) { + return false; + } + if (!isValidCIDR(cidr)) { + return false; + } + SubnetUtils subnetUtils = new SubnetUtils(cidr); + return subnetUtils.getInfo().isInRange(ipAddress); + } } diff --git a/utils/src/com/cloud/utils/ssh/SshHelper.java b/utils/src/com/cloud/utils/ssh/SshHelper.java index fb81e506ee5..84d8bc8056f 100755 --- a/utils/src/com/cloud/utils/ssh/SshHelper.java +++ b/utils/src/com/cloud/utils/ssh/SshHelper.java @@ -157,7 +157,7 @@ public class SshHelper { int currentReadBytes = 0; while (true) { if ((stdout.available() == 0) && (stderr.available() == 0)) { - int conditions = sess.waitForCondition(ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA | ChannelCondition.EOF, + int conditions = sess.waitForCondition(ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA | ChannelCondition.EOF | ChannelCondition.EXIT_STATUS, waitResultTimeoutInMs); if ((conditions & ChannelCondition.TIMEOUT) != 0) { @@ -166,7 +166,7 @@ public class SshHelper { throw new Exception(msg); } - if ((conditions & ChannelCondition.EOF) != 0) { + if ((conditions & ChannelCondition.EXIT_STATUS) != 0) { if ((conditions & (ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA)) == 0) { break; } @@ -185,6 +185,12 @@ public class SshHelper { } String result = sbResult.toString(); + + if (sess.getExitStatus() == null) { + //Exit status is NOT available. Returning failure result. + return new Pair(false, result); + } + if (sess.getExitStatus() != null && sess.getExitStatus().intValue() != 0) { s_logger.error("SSH execution of command " + command + " has an error status code in return. result output: " + result); return new Pair(false, result); diff --git a/utils/test/com/cloud/utils/PropertiesUtilsTest.java b/utils/test/com/cloud/utils/PropertiesUtilsTest.java new file mode 100644 index 00000000000..5ebe095d69d --- /dev/null +++ b/utils/test/com/cloud/utils/PropertiesUtilsTest.java @@ -0,0 +1,41 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.utils; + +import java.io.File; +import java.io.IOException; +import java.util.Properties; + +import org.apache.commons.io.FileUtils; +import org.junit.Assert; +import org.junit.Test; + +public class PropertiesUtilsTest { + @Test + public void findConfigFile() { + File configFile = PropertiesUtil.findConfigFile("notexistingresource"); + Assert.assertNull(configFile); + } + @Test + public void loadFromFile() throws IOException { + File file = File.createTempFile("test", ".properties"); + FileUtils.writeStringToFile(file, "a=b\nc=d\n"); + Properties properties = new Properties(); + PropertiesUtil.loadFromFile(properties, file); + Assert.assertEquals("b", properties.get("a")); + } +} diff --git a/utils/test/com/cloud/utils/exception/ExceptionUtilTest.java b/utils/test/com/cloud/utils/exception/ExceptionUtilTest.java new file mode 100644 index 00000000000..33fca37692b --- /dev/null +++ b/utils/test/com/cloud/utils/exception/ExceptionUtilTest.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.cloud.utils.exception; + +import static org.junit.Assert.*; + +import java.io.FileNotFoundException; +import java.io.IOException; + +import org.junit.Test; + +public class ExceptionUtilTest { + + @Test + public void test() throws Exception { + FileNotFoundException fnfe = new FileNotFoundException(); + try { + ExceptionUtil.rethrow(fnfe, IOException.class); + fail(); + } catch (IOException e) { + } + + ExceptionUtil.rethrow(fnfe, ClassNotFoundException.class); + + try { + ExceptionUtil.rethrow(fnfe, FileNotFoundException.class); + fail(); + } catch ( FileNotFoundException e ) { + } + } + +} diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContextPool.java b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContextPool.java index 69bde1997d9..c36b3a8ce24 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContextPool.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContextPool.java @@ -119,9 +119,9 @@ public class VmwareContextPool { } private TimerTask getTimerTask() { - return new TimerTask() { + return new ManagedContextTimerTask() { @Override - public void run() { + protected void runInContext() { try { // doIdleCheck();