You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ah...@apache.org on 2013/07/01 23:25:32 UTC

[48/50] [abbrv] Another merge from master. This is just getting laborious

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57bafc8f/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/api/commands/AddSspCmd.java
----------------------------------------------------------------------
diff --cc plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/api/commands/AddSspCmd.java
index 0000000,d42ee67..8aa0761
mode 000000,100644..100644
--- a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/api/commands/AddSspCmd.java
+++ b/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/api/commands/AddSspCmd.java
@@@ -1,0 -1,138 +1,139 @@@
+ // 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.commands;
+ import javax.inject.Inject;
+ 
++import org.apache.log4j.Logger;
++
+ 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.SspResponse;
+ import org.apache.cloudstack.api.response.ZoneResponse;
 -import org.apache.cloudstack.api.Parameter;
++import org.apache.cloudstack.context.CallContext;
+ import org.apache.cloudstack.network.element.SspService;
 -import org.apache.log4j.Logger;
+ 
+ import com.cloud.dc.dao.DataCenterDao;
+ import com.cloud.exception.ConcurrentOperationException;
+ import com.cloud.exception.InsufficientCapacityException;
+ import com.cloud.exception.NetworkRuleConflictException;
+ import com.cloud.exception.ResourceAllocationException;
+ import com.cloud.exception.ResourceUnavailableException;
+ import com.cloud.host.Host;
 -import com.cloud.user.UserContext;
+ 
+ 
+ @APICommand(name="addStratosphereSsp", responseObject=SspResponse.class, description="Adds stratosphere ssp server")
+ public class AddSspCmd extends BaseCmd {
+     private static final Logger s_logger = Logger.getLogger(AddSspCmd.class.getName());
+     @Inject
+     SspService _service;
+     @Inject
+     DataCenterDao _dcDao;
+ 
+     @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class,
+             required=true, description="the zone ID")
+     private Long zoneId;
+ 
+     @Parameter(name=ApiConstants.URL, type=CommandType.STRING, required=true, description="stratosphere ssp server url")
+     private String url;
+ 
+     @Parameter(name=ApiConstants.USERNAME, type=CommandType.STRING, required=false, description="stratosphere ssp api username")
+     private String username;
+ 
+     @Parameter(name=ApiConstants.PASSWORD, type=CommandType.STRING, required=false, description="stratosphere ssp api password")
+     private String password;
+ 
+     @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="stratosphere ssp api name")
+     private String name; // required because HostVO name field defined as NOT NULL.
+ 
+     @Parameter(name="tenantuuid", type=CommandType.STRING, required=false, description="stratosphere ssp tenant uuid")
+     private String tenantUuid; // required in creating ssp tenant_network
+ 
+     @Override
+     public String getCommandName() {
+         return getClass().getAnnotation(APICommand.class).name();
+     }
+ 
+     @Override
+     public long getEntityOwnerId() {
 -        return UserContext.current().getCaller().getId();
++        return CallContext.current().getCallingAccountId();
+     }
+ 
+     @Override
+     public void execute() throws ResourceUnavailableException,
+     InsufficientCapacityException, ConcurrentOperationException,
+     ResourceAllocationException, NetworkRuleConflictException {
+         s_logger.trace("execute");
+         Host host = _service.addSspHost(this);
+         SspResponse response = new SspResponse();
+         response.setResponseName(getCommandName());
+         response.setObjectName("ssphost");
 -        response.setUrl(this.getUrl());
++        response.setUrl(getUrl());
+         response.setZoneId(_dcDao.findById(getZoneId()).getUuid());
+         response.setHostId(host.getUuid());
 -        this.setResponseObject(response);
++        setResponseObject(response);
+     }
+ 
+     public Long getZoneId() {
+         return zoneId;
+     }
+ 
+     public void setZoneId(Long zoneId) {
+         this.zoneId = zoneId;
+     }
+ 
+     public String getUrl() {
+         return url;
+     }
+ 
+     public void setUrl(String url) {
+         this.url = url;
+     }
+ 
+     public String getUsername() {
+         return username;
+     }
+ 
+     public void setUsername(String username) {
+         this.username = username;
+     }
+ 
+     public String getPassword() {
+         return password;
+     }
+ 
+     public void setPassword(String password) {
+         this.password = password;
+     }
+ 
+     public String getName() {
+         return name;
+     }
+ 
+     public void setName(String name) {
+         this.name = name;
+     }
+ 
+     public String getTenantUuid() {
+         return tenantUuid;
+     }
+ 
+     public void setTenantUuid(String tenantUuid) {
+         this.tenantUuid = tenantUuid;
+     }
+ }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57bafc8f/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/api/commands/DeleteSspCmd.java
----------------------------------------------------------------------
diff --cc plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/api/commands/DeleteSspCmd.java
index 0000000,bfbd5d9..5177dfb
mode 000000,100644..100644
--- a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/api/commands/DeleteSspCmd.java
+++ b/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/api/commands/DeleteSspCmd.java
@@@ -1,0 -1,74 +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.api.commands;
+ 
+ import javax.inject.Inject;
+ 
 -import org.apache.cloudstack.api.response.SuccessResponse;
 -import org.apache.cloudstack.api.response.HostResponse;
++import org.apache.log4j.Logger;
++
+ 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.HostResponse;
++import org.apache.cloudstack.api.response.SuccessResponse;
++import org.apache.cloudstack.context.CallContext;
+ import org.apache.cloudstack.network.element.SspService;
 -import org.apache.log4j.Logger;
+ 
+ import com.cloud.exception.ConcurrentOperationException;
+ import com.cloud.exception.InsufficientCapacityException;
+ import com.cloud.exception.NetworkRuleConflictException;
+ import com.cloud.exception.ResourceAllocationException;
+ import com.cloud.exception.ResourceUnavailableException;
 -import com.cloud.user.UserContext;
+ 
+ @APICommand(name="deleteStratosphereSsp", responseObject=SuccessResponse.class, description="Removes stratosphere ssp server")
+ public class DeleteSspCmd extends BaseCmd {
+     private static final Logger s_logger = Logger.getLogger(AddSspCmd.class.getName());
+     @Inject
+     SspService _service;
+ 
+     @Parameter(name=ApiConstants.HOST_ID, type=CommandType.UUID, entityType=HostResponse.class,
+             required=true, description="the host ID of ssp server")
+     private Long hostId;
+ 
+     @Override
+     public String getCommandName() {
+         return getClass().getAnnotation(APICommand.class).name();
+     }
+ 
+     @Override
+     public long getEntityOwnerId() {
 -        return UserContext.current().getCaller().getId();
++        return CallContext.current().getCallingAccountId();
+     }
+ 
+     @Override
+     public void execute() throws ResourceUnavailableException,
+     InsufficientCapacityException, ConcurrentOperationException,
+     ResourceAllocationException, NetworkRuleConflictException {
+         s_logger.trace("execute");
+         SuccessResponse resp = new SuccessResponse();
+         resp.setSuccess(_service.deleteSspHost(this));
 -        this.setResponseObject(resp);
++        setResponseObject(resp);
+     }
+ 
+     public Long getHostId() {
+         return hostId;
+     }
+ 
+     public void setHostId(Long hostId) {
+         this.hostId = hostId;
+     }
+ }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57bafc8f/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspCredentialVO.java
----------------------------------------------------------------------
diff --cc plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspCredentialVO.java
index 0000000,9c6cf14..d05b270
mode 000000,100644..100644
--- a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspCredentialVO.java
+++ b/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspCredentialVO.java
@@@ -1,0 -1,67 +1,67 @@@
+ // 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.network.dao;
+ 
+ import javax.persistence.Column;
+ import javax.persistence.Entity;
+ import javax.persistence.GeneratedValue;
+ import javax.persistence.GenerationType;
+ import javax.persistence.Id;
+ import javax.persistence.Table;
+ 
+ @Entity
+ @Table(name="external_stratosphere_ssp_credentials")
+ public class SspCredentialVO {
+     @Id
+     @GeneratedValue(strategy = GenerationType.IDENTITY)
+     @Column(name="id")
+     private long id;
+ 
+     @Column(name="data_center_id")
 -    private long dataCenterId; // Actually, this is zoneId
++    private long zoneId; // Actually, this is zoneId, then name it as zone id.
+ 
+     // XXX: We might want to restrict access to this by cloudstack privileges.
+     @Column(name="username")
+     private String username;
+ 
+     @Column(name="password")
+     private String password;
+ 
+     public long getZoneId() {
 -        return dataCenterId;
++        return zoneId;
+     }
+ 
+     public void setZoneId(long zoneId) {
 -        this.dataCenterId = zoneId;
++        this.zoneId = zoneId;
+     }
+ 
+     public String getUsername() {
+         return username;
+     }
+ 
+     public void setUsername(String username) {
+         this.username = username;
+     }
+ 
+     public String getPassword() {
+         return password;
+     }
+ 
+     public void setPassword(String password) {
+         this.password = password;
+     }
+ }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57bafc8f/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspElement.java
----------------------------------------------------------------------
diff --cc plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspElement.java
index 0000000,823c16b..d145117
mode 000000,100644..100644
--- a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspElement.java
+++ b/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspElement.java
@@@ -1,0 -1,619 +1,622 @@@
+ // 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.network.element;
+ 
+ import java.net.MalformedURLException;
+ import java.net.URL;
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.HashMap;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Set;
+ import java.util.UUID;
+ 
+ import javax.ejb.Local;
+ import javax.inject.Inject;
+ import javax.naming.ConfigurationException;
+ 
+ import org.apache.cloudstack.api.commands.AddSspCmd;
+ import org.apache.cloudstack.api.commands.DeleteSspCmd;
+ import org.apache.cloudstack.network.dao.SspCredentialDao;
+ import org.apache.cloudstack.network.dao.SspCredentialVO;
+ import org.apache.cloudstack.network.dao.SspTenantDao;
+ import org.apache.cloudstack.network.dao.SspTenantVO;
+ import org.apache.cloudstack.network.dao.SspUuidDao;
+ import org.apache.cloudstack.network.dao.SspUuidVO;
+ import org.apache.log4j.Logger;
+ 
+ import com.cloud.configuration.dao.ConfigurationDao;
+ import com.cloud.dc.dao.DataCenterDao;
+ import com.cloud.deploy.DeployDestination;
+ import com.cloud.exception.ConcurrentOperationException;
+ import com.cloud.exception.InsufficientCapacityException;
+ import com.cloud.exception.InvalidParameterValueException;
+ import com.cloud.exception.ResourceUnavailableException;
+ import com.cloud.host.Host;
+ import com.cloud.host.HostVO;
+ import com.cloud.host.dao.HostDao;
+ import com.cloud.network.Network;
+ import com.cloud.network.Network.Capability;
+ import com.cloud.network.Network.Provider;
+ import com.cloud.network.Network.Service;
+ import com.cloud.network.NetworkManager;
+ import com.cloud.network.NetworkMigrationResponder;
+ import com.cloud.network.NetworkModel;
+ import com.cloud.network.Networks.BroadcastDomainType;
+ import com.cloud.network.PhysicalNetwork;
+ import com.cloud.network.PhysicalNetworkServiceProvider;
+ import com.cloud.network.PhysicalNetworkServiceProvider.State;
+ import com.cloud.network.dao.NetworkServiceMapDao;
+ import com.cloud.network.dao.PhysicalNetworkDao;
+ import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+ import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
+ import com.cloud.network.element.ConnectivityProvider;
+ import com.cloud.network.element.NetworkElement;
+ import com.cloud.offering.NetworkOffering;
++import com.cloud.resource.ResourceManager;
+ import com.cloud.utils.component.AdapterBase;
+ import com.cloud.utils.exception.CloudRuntimeException;
+ import com.cloud.vm.NicProfile;
+ import com.cloud.vm.NicVO;
+ import com.cloud.vm.ReservationContext;
 -import com.cloud.vm.VirtualMachine;
+ import com.cloud.vm.VirtualMachineProfile;
+ import com.cloud.vm.dao.NicDao;
 -import com.cloud.resource.ResourceManager;
+ 
+ /**
+  * Stratosphere sdn platform network element
+  *
+  * This class will be called per network setup operations.
+  * This class also have ssp specific methods.
+  *
+  * Current implementation use HostVO for storage of api endpoint information,
+  * but note this is not necessary. The other way is create our own database
+  * table for that information.
+  */
+ @Local(value={NetworkElement.class, SspManager.class})
+ public class SspElement extends AdapterBase implements ConnectivityProvider, SspManager, SspService, NetworkMigrationResponder {
+     private static final Logger s_logger = Logger.getLogger(SspElement.class);
+     public static final String s_SSP_NAME = "StratosphereSsp";
+ 
+     @Inject
+     NetworkServiceMapDao _ntwkSrvcDao;
+     @Inject
+     NetworkModel _networkModel;
+     @Inject
+     NetworkManager _networkMgr;
+     @Inject
+     ResourceManager _resourceMgr;
+     @Inject
+     PhysicalNetworkDao _physicalNetworkDao;
+     @Inject
+     PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
+     @Inject
+     SspCredentialDao _sspCredentialDao;
+     @Inject
+     SspTenantDao _sspTenantDao;
+     @Inject
+     SspUuidDao _sspUuidDao;
+     @Inject
+     DataCenterDao _dcDao;
+     @Inject
+     HostDao _hostDao;
+     @Inject
+     ConfigurationDao _configDao;
+     @Inject
+     NicDao _nicDao = null;
+ 
+     @Override
+     public boolean configure(String name, Map<String, Object> params)
+             throws ConfigurationException {
+         return super.configure(name, params);
+     }
+ 
+     @Override
+     public Map<Service, Map<Capability, String>> getCapabilities() {
+         Map<Service, Map<Capability, String>> capabilities = new HashMap<Service, Map<Capability, String>>();
+         capabilities.put(Service.Connectivity, new HashMap<Capability,String>()); // XXX: We might need some more category here.
+         return capabilities;
+     }
+ 
+     @Override
+     public Provider getProvider() {
+         Provider provider = null;
+         synchronized(s_SSP_NAME){
+             provider = Provider.getProvider(s_SSP_NAME);
+             if(provider==null){
+                 provider = new Provider(s_SSP_NAME, true);
+                 s_logger.debug("registering Network.Provider "+s_SSP_NAME);
+             }
+         }
+         return provider;
+     }
+ 
+     private List<SspClient> fetchSspClients(Long physicalNetworkId, Long dataCenterId, boolean enabled_only){
+         ArrayList<SspClient> clients = new ArrayList<SspClient>();
+ 
+         boolean provider_found = false;
+         PhysicalNetworkServiceProviderVO provider = _physicalNetworkServiceProviderDao.findByServiceProvider(physicalNetworkId, s_SSP_NAME);
+         if(enabled_only){
+             if(provider != null && provider.getState() == State.Enabled){
+                 provider_found = true;
+             }
+         }else{
+             provider_found = true;
+         }
+ 
+         if(physicalNetworkId != null && provider_found){
+             SspCredentialVO credential = _sspCredentialDao.findByZone(dataCenterId);
+             List<HostVO> hosts = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.L2Networking, dataCenterId);
+             for(HostVO host : hosts){
+                 assert(credential != null);
+                 _hostDao.loadDetails(host);
+                 if("v1Api".equals(host.getDetail("sspHost"))){
+                     clients.add(new SspClient(host.getDetail("url"), credential.getUsername(), credential.getPassword()));
+                 }
+             }
+         }
+         if(clients.size()==0){
+             String global_apiUrl = _configDao.getValueAndInitIfNotExist("ssp.url", "Network", null);
+             String global_username = _configDao.getValueAndInitIfNotExist("ssp.username", "Network", null);
+             String global_password = _configDao.getValueAndInitIfNotExist("ssp.password", "Network", null);
+             if(global_apiUrl != null && global_username != null && global_password != null){
+                 clients.add(new SspClient(global_apiUrl, global_username, global_password));
+             }
+         }
+         return clients;
+     }
+ 
+     /* (non-Javadoc)
+      * @see org.apache.cloudstack.network.element.NetworkElement#isReady(com.cloud.network.PhysicalNetworkServiceProvider)
+      */
+     @Override
+     public boolean isReady(PhysicalNetworkServiceProvider provider) {
+         PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(provider.getPhysicalNetworkId());
+         assert(physicalNetwork!=null);
+         if(physicalNetwork != null){
+             if(fetchSspClients(physicalNetwork.getId(), physicalNetwork.getDataCenterId(), false).size() > 0){
+                 return true;
+             }
+             s_logger.warn("Ssp api endpoint not found. "+physicalNetwork.toString());
+         }else{
+             s_logger.warn("PhysicalNetwork is NULL.");
+         }
+         return false;
+     }
+ 
+     /* (non-Javadoc)
+      * If this element is ready, then it can be enabled.
+      * @see org.apache.cloudstack.network.element.SspManager#isEnabled(com.cloud.network.PhysicalNetwork)
+      */
+     @Override
+     public boolean canHandle(PhysicalNetwork physicalNetwork){
+         if(physicalNetwork != null){
+             if(fetchSspClients(physicalNetwork.getId(), physicalNetwork.getDataCenterId(), true).size() > 0){
+                 return true;
+             }
+             s_logger.warn("enabled Ssp api endpoint not found. "+physicalNetwork.toString());
+         }else{
+             s_logger.warn("PhysicalNetwork is NULL.");
+         }
+         return false;
+     }
+ 
+     private boolean canHandle(Network network){
+         if(canHandle(_physicalNetworkDao.findById(network.getPhysicalNetworkId()))){
+             if(!_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), Service.Connectivity, getProvider())){
+                 s_logger.info("SSP is implicitly active for "+network);
+             }
+             return true;
+         }
+         return false;
+     }
+ 
+     @Override
+     public Host addSspHost(AddSspCmd cmd) {
+         SspClient client = new SspClient(cmd.getUrl(), cmd.getUsername(), cmd.getPassword());
+         if(!client.login()){
+             throw new CloudRuntimeException("Ssp login failed.");
+         }
+ 
+         long zoneId = cmd.getZoneId();
+         SspCredentialVO credential = _sspCredentialDao.findByZone(zoneId);
+         if(credential==null){
+             if(cmd.getUsername()==null || cmd.getPassword()==null){
+                 throw new InvalidParameterValueException("Initial credential required for zone: " + zoneId);
+             }
+             credential = new SspCredentialVO();
+             credential.setZoneId(zoneId);
+             credential.setUsername(cmd.getUsername());
+             credential.setPassword(cmd.getPassword());
+             _sspCredentialDao.persist(credential);
+         }else{
+             if(cmd.getUsername()!=null || cmd.getPassword()!=null){
+                 s_logger.warn("Tenant credential already configured for zone:"+zoneId);
+             }
+         }
+ 
+         String tenantUuid = _sspTenantDao.findUuidByZone(zoneId);
+         if(tenantUuid==null){
+             if(cmd.getTenantUuid()==null){
+                 throw new InvalidParameterValueException("Initial tenant uuid required for zone: " + zoneId);
+             }
+             SspTenantVO tenant = new SspTenantVO();
+             tenant.setZoneId(zoneId);
+             tenant.setUuid(cmd.getTenantUuid());
+             _sspTenantDao.persist(tenant);
+         }else{
+             if(cmd.getTenantUuid()!=null){
+                 s_logger.warn("Tenant uuid already configured for zone:"+zoneId);
+             }
+         }
+ 
+         String normalizedUrl = null;
+         String hostname = null;
+         try {
+             URL url = new URL(cmd.getUrl());
+             normalizedUrl = url.toString();
+             hostname = url.getHost();
+         } catch (MalformedURLException e1) {
+             throw new CloudRuntimeException("Invalid url "+cmd.getUrl());
+         }
+ 
+         List<HostVO> hosts = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.L2Networking, zoneId);
+         for(HostVO host : hosts){
+             assert(credential != null);
+             _hostDao.loadDetails(host);
+             if("v1Api".equals(host.getDetail("sspHost"))){
+                 if(normalizedUrl.equals(host.getDetail("url"))){
+                     s_logger.warn("Ssp host already registered "+normalizedUrl);
+                     return host;
+                 }
+             }
+         }
+         // SspHost HostVO will be created per zone and url.
+         HostVO host = new HostVO(UUID.randomUUID().toString());
+         host.setDataCenterId(zoneId);
+         host.setType(Host.Type.L2Networking);
+         host.setPrivateIpAddress(hostname); // db schema not null. It may be a name, not IP address.
+         //        host.setPrivateMacAddress(""); // db schema nullable
+         //        host.setPrivateNetmask(""); // db schema nullable
+         host.setVersion("1"); // strange db schema not null
+         host.setName(cmd.getName());
+ 
+         host.setDetails(new HashMap<String, String>());
+         host.setDetail("sspHost", "v1Api");
+         host.setDetail("url", normalizedUrl);
+         return _hostDao.persist(host);
+     }
+ 
+     @Override
+     public boolean deleteSspHost(DeleteSspCmd cmd) {
+         s_logger.info("deleteStratosphereSsp");
+         return _hostDao.remove(cmd.getHostId());
+     }
+ 
++    @Override
+     public boolean createNetwork(Network network, NetworkOffering offering,
+             DeployDestination dest, ReservationContext context){
+         if(_sspUuidDao.findUuidByNetwork(network) != null){
+             s_logger.info("Network already has ssp TenantNetwork uuid :"+network.toString());
+             return true;
+         }
+         if(!canHandle(network)){
+             return false;
+         }
+ 
+         String tenantUuid = _sspTenantDao.findUuidByZone(network.getDataCenterId());
+         if(tenantUuid==null){
+             tenantUuid = _configDao.getValueAndInitIfNotExist("ssp.tenant", "Network", null);
+         }
+ 
+         boolean processed = false;
+         for(SspClient client : fetchSspClients(network.getPhysicalNetworkId(), network.getDataCenterId(), true)){
+             SspClient.TenantNetwork sspNet = client.createTenantNetwork(tenantUuid, network.getName());
+             if(sspNet != null){
+                 SspUuidVO uuid = new SspUuidVO();
+                 uuid.setUuid(sspNet.uuid);
+                 uuid.setObjClass(SspUuidVO.objClassNetwork);
+                 uuid.setObjId(network.getId());
+                 _sspUuidDao.persist(uuid);
+                 return true;
+             }
+             processed = true;
+         }
+         if(processed){
+             s_logger.error("Could not allocate an uuid for network "+network.toString());
+             return false;
+         }else{
+             s_logger.error("Skipping #createNetwork() for "+network.toString());
+             return true;
+         }
+     }
+ 
++    @Override
+     public boolean deleteNetwork(Network network){
+         String tenantNetworkUuid = _sspUuidDao.findUuidByNetwork(network);
+         if(tenantNetworkUuid != null){
+             boolean processed = false;
+             for(SspClient client : fetchSspClients(network.getPhysicalNetworkId(), network.getDataCenterId(), true)){
+                 if(client.deleteTenantNetwork(tenantNetworkUuid)){
+                     _sspUuidDao.removeUuid(tenantNetworkUuid);
+                     processed = true;
+                     break;
+                 }
+             }
+             if(!processed){
+                 s_logger.error("Ssp api tenant network deletion failed "+network.toString());
+             }
+         }else{
+             s_logger.debug("Silently skipping #deleteNetwork() for "+network.toString());
+         }
+         return true;
+     }
+ 
+     // we use context.reservationId for dedup of guru & element operations.
++    @Override
+     public boolean createNicEnv(Network network, NicProfile nic, DeployDestination dest, ReservationContext context){
+         String tenantNetworkUuid = _sspUuidDao.findUuidByNetwork(network);
+         if(tenantNetworkUuid == null){
+             s_logger.debug("Skipping #createNicEnv() for nic on "+network.toString());
+             return true;
+         }
+ 
+         String reservationId = context.getReservationId();
+         List<SspUuidVO> tenantPortUuidVos = _sspUuidDao.listUUidVoByNicProfile(nic);
+         for(SspUuidVO tenantPortUuidVo : tenantPortUuidVos){
+             if(reservationId.equals(tenantPortUuidVo.getReservationId())){
+                 s_logger.info("Skipping because reservation found "+reservationId);
+                 return true;
+             }
+         }
+ 
+         String tenantPortUuid = null;
+         for(SspClient client : fetchSspClients(network.getPhysicalNetworkId(), network.getDataCenterId(), true)){
+             SspClient.TenantPort sspPort = client.createTenantPort(tenantNetworkUuid);
+             if(sspPort != null){
+                 tenantPortUuid = sspPort.uuid;
+                 nic.setReservationId(reservationId);
+ 
+                 SspUuidVO uuid = new SspUuidVO();
+                 uuid.setUuid(tenantPortUuid);
+                 uuid.setObjClass(SspUuidVO.objClassNicProfile);
+                 uuid.setObjId(nic.getId());
+                 uuid.setReservationId(reservationId);
+                 _sspUuidDao.persist(uuid);
+                 break;
+             }
+         }
+         if(tenantPortUuid == null){
+             s_logger.debug("#createNicEnv() failed for nic on "+network.toString());
+             return false;
+         }
+ 
+         for(SspClient client : fetchSspClients(network.getPhysicalNetworkId(), network.getDataCenterId(), true)){
+             SspClient.TenantPort sspPort = client.updateTenantVifBinding(tenantPortUuid, dest.getHost().getPrivateIpAddress());
+             if(sspPort != null){
+                 if(sspPort.vlanId != null){
+                     nic.setBroadcastType(BroadcastDomainType.Vlan);
+                     nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(String.valueOf(sspPort.vlanId)));
+                 }
+                 return true;
+             }
+         }
+         s_logger.error("Updating vif failed "+nic.toString());
+         return false;
+     }
+ 
++    @Override
+     public boolean deleteNicEnv(Network network, NicProfile nic, ReservationContext context){
+         if(context==null){
+             s_logger.error("ReservationContext was null for "+nic+" "+network);
+             return false;
+         }
+         String reservationId = context.getReservationId();
+ 
+         SspUuidVO deleteTarget = null;
+         SspUuidVO remainingTarget = null;
+         List<SspUuidVO> tenantPortUuidVos = _sspUuidDao.listUUidVoByNicProfile(nic);
+         for(SspUuidVO tenantPortUuidVo : tenantPortUuidVos){
+             if(reservationId.equals(tenantPortUuidVo.getReservationId())){
+                 deleteTarget = tenantPortUuidVo;
+             }else{
+                 remainingTarget = tenantPortUuidVo;
+             }
+         }
+ 
+         if(deleteTarget != null){ // delete the target ssp uuid (tenant-port)
+             String tenantPortUuid = deleteTarget.getUuid();
+             boolean processed = false;
+             for(SspClient client : fetchSspClients(network.getPhysicalNetworkId(), network.getDataCenterId(), true)){
+                 SspClient.TenantPort sspPort = client.updateTenantVifBinding(tenantPortUuid, null);
+                 if(sspPort != null){
+                     processed = true;
+                     break;
+                 }
+             }
+             if(!processed){
+                 s_logger.warn("Ssp api nic detach failed "+nic.toString());
+             }
+             processed = false;
+             for(SspClient client : fetchSspClients(network.getPhysicalNetworkId(), network.getDataCenterId(), true)){
+                 if(client.deleteTenantPort(tenantPortUuid)){
+                     _sspUuidDao.removeUuid(tenantPortUuid);
+                     processed = true;
+                     break;
+                 }
+             }
+             if(!processed){
+                 s_logger.warn("Ssp api tenant port deletion failed "+nic.toString());
+             }
+             _sspUuidDao.removeUuid(tenantPortUuid);
+         }
+         if(remainingTarget != null){
+             NicVO nicVo = _nicDao.findById(nic.getId());
+             nicVo.setReservationId(remainingTarget.getReservationId());
+             _nicDao.persist(nicVo); // persist the new reservationId
+         }
+         return true;
+     }
+ 
+     /* (non-Javadoc)
+      * Implements a network using ssp element.
+      *
+      * This method will be called right after NetworkGuru#implement().
+      * see also {@link #shutdown(Network, ReservationContext, boolean)}
+      * @see org.apache.cloudstack.network.element.NetworkElement#implement(com.cloud.network.Network, com.cloud.offering.NetworkOffering, com.cloud.deploy.DeployDestination, com.cloud.vm.ReservationContext)
+      */
+     @Override
+     public boolean implement(Network network, NetworkOffering offering,
+             DeployDestination dest, ReservationContext context)
+                     throws ConcurrentOperationException, ResourceUnavailableException,
+                     InsufficientCapacityException {
+         s_logger.info("implement");
+         return createNetwork(network, offering, dest, context);
+     }
+ 
+     /* (non-Javadoc)
+      * Shutdown the network implementation
+      *
+      * This method will be called right BEFORE NetworkGuru#shutdown().
+      * The entities was acquired by {@link #implement(Network, NetworkOffering, DeployDestination, ReservationContext)}
+      * @see org.apache.cloudstack.network.element.NetworkElement#shutdown(com.cloud.network.Network, com.cloud.vm.ReservationContext, boolean)
+      */
+     @Override
+     public boolean shutdown(Network network, ReservationContext context,
+             boolean cleanup) throws ConcurrentOperationException,
+             ResourceUnavailableException {
+         s_logger.trace("shutdown");
+         return deleteNetwork(network);
+     }
+ 
+     /* (non-Javadoc)
+      * Prepares a network environment for a VM nic.
+      *
+      * This method will be called right after NetworkGuru#reserve().
+      * The entities will be released by {@link #release(Network, NicProfile, VirtualMachineProfile, ReservationContext)}
+      * @see org.apache.cloudstack.network.element.NetworkElement#prepare(com.cloud.network.Network, com.cloud.vm.NicProfile, com.cloud.vm.VirtualMachineProfile, com.cloud.deploy.DeployDestination, com.cloud.vm.ReservationContext)
+      */
+     @Override
+     public boolean prepare(Network network, NicProfile nic,
 -            VirtualMachineProfile<? extends VirtualMachine> vm,
++            VirtualMachineProfile vm,
+             DeployDestination dest, ReservationContext context)
+                     throws ConcurrentOperationException, ResourceUnavailableException,
+                     InsufficientCapacityException {
+         s_logger.trace("prepare");
+         return createNicEnv(network, nic, dest, context);
+     }
+ 
+     /* (non-Javadoc)
+      * Release the network environment that was prepared for a VM nic.
+      *
+      * This method will be called right AFTER NetworkGuru#release().
+      * The entities was acquired in {@link #prepare(Network, NicProfile, VirtualMachineProfile, DeployDestination, ReservationContext)}
+      * @see org.apache.cloudstack.network.element.NetworkElement#release(com.cloud.network.Network, com.cloud.vm.NicProfile, com.cloud.vm.VirtualMachineProfile, com.cloud.vm.ReservationContext)
+      */
+     @Override
+     public boolean release(Network network, NicProfile nic,
 -            VirtualMachineProfile<? extends VirtualMachine> vm,
++            VirtualMachineProfile vm,
+             ReservationContext context) throws ConcurrentOperationException,
+             ResourceUnavailableException {
+         s_logger.trace("release");
+         return deleteNicEnv(network, nic, context);
+     }
+ 
+     /* (non-Javadoc)
+      * Destroy a network implementation.
+      *
+      * This method will be called right BEFORE NetworkGuru#trash() in "Expunge" phase.
+      * @see org.apache.cloudstack.network.element.NetworkElement#destroy(com.cloud.network.Network)
+      */
+     @Override
+     public boolean destroy(Network network, ReservationContext context)
+             throws ConcurrentOperationException, ResourceUnavailableException {
+         s_logger.trace("destroy");
+         // nothing to do here.
+         return true;
+     }
+ 
+     @Override
+     public boolean shutdownProviderInstances(
+             PhysicalNetworkServiceProvider provider, ReservationContext context)
+                     throws ConcurrentOperationException, ResourceUnavailableException {
+         s_logger.trace("shutdownProviderInstances");
+         return true;
+     }
+ 
+     @Override
+     public boolean canEnableIndividualServices() {
+         s_logger.trace("canEnableIndividualServices");
+         return true; // because there is only Connectivity
+     }
+ 
+     @Override
+     public boolean verifyServicesCombination(Set<Service> services) {
+         s_logger.trace("verifyServicesCombination "+services.toString());
+         return true;
+     }
+ 
+     @Override
+     public boolean prepareMigration(NicProfile nic, Network network,
 -            VirtualMachineProfile<? extends VirtualMachine> vm,
++            VirtualMachineProfile vm,
+             DeployDestination dest, ReservationContext context) {
+         try {
+             prepare(network, nic, vm, dest, context);
+         } catch (ConcurrentOperationException e) {
+             s_logger.error("prepareForMigration failed.", e);
+             return false;
+         } catch (ResourceUnavailableException e) {
+             s_logger.error("prepareForMigration failed.", e);
+             return false;
+         } catch (InsufficientCapacityException e) {
+             s_logger.error("prepareForMigration failed.", e);
+             return false;
+         }
+         return true;
+     }
+ 
+     @Override
+     public void rollbackMigration(NicProfile nic, Network network,
 -            VirtualMachineProfile<? extends VirtualMachine> vm,
++            VirtualMachineProfile vm,
+             ReservationContext src, ReservationContext dst) {
+         try {
+             release(network, nic, vm, dst);
+         } catch (ConcurrentOperationException e) {
+             s_logger.error("rollbackMigration failed.", e);
+         } catch (ResourceUnavailableException e) {
+             s_logger.error("rollbackMigration failed.", e);
+         }
+     }
+ 
+     @Override
+     public void commitMigration(NicProfile nic, Network network,
 -            VirtualMachineProfile<? extends VirtualMachine> vm,
++            VirtualMachineProfile vm,
+             ReservationContext src, ReservationContext dst) {
+         try {
+             release(network, nic, vm, src);
+         } catch (ConcurrentOperationException e) {
+             s_logger.error("commitMigration failed.", e);
+         } catch (ResourceUnavailableException e) {
+             s_logger.error("commitMigration failed.", e);
+         }
+     }
+ 
+     @Override
+     public List<Class<?>> getCommands() {
+         return Arrays.<Class<?>>asList(AddSspCmd.class, DeleteSspCmd.class);
+     }
+ }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57bafc8f/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/guru/SspGuestNetworkGuru.java
----------------------------------------------------------------------
diff --cc plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/guru/SspGuestNetworkGuru.java
index 0000000,6d5d871..1057bec
mode 000000,100644..100644
--- a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/guru/SspGuestNetworkGuru.java
+++ b/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/guru/SspGuestNetworkGuru.java
@@@ -1,0 -1,173 +1,172 @@@
+ // 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.network.guru;
+ 
+ import javax.ejb.Local;
+ import javax.inject.Inject;
+ 
+ import org.apache.cloudstack.network.element.SspElement;
+ import org.apache.cloudstack.network.element.SspManager;
+ import org.apache.log4j.Logger;
+ 
+ import com.cloud.dc.DataCenter.NetworkType;
+ import com.cloud.deploy.DeployDestination;
+ import com.cloud.exception.InsufficientAddressCapacityException;
+ import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
+ import com.cloud.network.Network;
+ import com.cloud.network.NetworkMigrationResponder;
+ import com.cloud.network.NetworkProfile;
+ import com.cloud.network.PhysicalNetwork;
+ import com.cloud.network.PhysicalNetwork.IsolationMethod;
+ import com.cloud.network.dao.NetworkDao;
+ import com.cloud.network.guru.GuestNetworkGuru;
+ import com.cloud.network.guru.NetworkGuru;
+ import com.cloud.offering.NetworkOffering;
+ import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+ import com.cloud.vm.NicProfile;
+ import com.cloud.vm.ReservationContext;
+ import com.cloud.vm.ReservationContextImpl;
 -import com.cloud.vm.VirtualMachine;
+ import com.cloud.vm.VirtualMachineProfile;
+ 
+ /**
+  * Stratosphere SDN Platform NetworkGuru
+  */
+ @Local(value=NetworkGuru.class)
+ public class SspGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigrationResponder {
+     private static final Logger s_logger = Logger.getLogger(SspGuestNetworkGuru.class);
+ 
+     @Inject
+     SspManager _sspMgr;
+     @Inject
+     NetworkDao _networkDao;
+     @Inject
+     NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
+ 
+     public SspGuestNetworkGuru() {
+         super();
+         _isolationMethods = new IsolationMethod[] { IsolationMethod.SSP };
+     }
+ 
+     @Override
+     protected boolean canHandle(NetworkOffering offering,
+             NetworkType networkType, PhysicalNetwork physicalNetwork) {
+         s_logger.trace("canHandle");
+ 
+         String setting = null;
+         if(physicalNetwork != null && physicalNetwork.getIsolationMethods().contains("SSP")){
+             // Be careful, PhysicalNetwork#getIsolationMethods() returns List<String>, not List<IsolationMethod>
+             setting = "physicalnetwork setting";
+         }else if(_ntwkOfferingSrvcDao.isProviderForNetworkOffering(offering.getId(), Network.Provider.getProvider(SspElement.s_SSP_NAME))){
+             setting = "network offering setting";
+         }
+         if(setting != null){
+             if (networkType != NetworkType.Advanced){
+                 s_logger.info("SSP enebled by "+setting+" but not active because networkType was "+networkType);
+             }else if(!isMyTrafficType(offering.getTrafficType())){
+                 s_logger.info("SSP enabled by "+setting+" but not active because traffic type not Guest");
+             }else if(offering.getGuestType() != Network.GuestType.Isolated){
+                 s_logger.info("SSP works for network isolatation.");
+             }else if(!_sspMgr.canHandle(physicalNetwork)){
+                 s_logger.info("SSP manager not ready");
+             }else{
+                 return true;
+             }
+         }else{
+             s_logger.debug("SSP not configured to be active");
+         }
+         return false;
+     }
+ 
+     /* (non-Javadoc)
+      * FYI: What is done in parent class is allocateVnet(vlan).
+      * Effective return object members are: cidr, broadcastUri, gateway, mode, physicalNetworkId
+      * The other members will be silently ignored.
+      * This method is called at DeployVMCmd#execute (running phase) - NetworkManagerImpl#prepare
+      * @see org.apache.cloudstack.network.guru.GuestNetworkGuru#implement(com.cloud.network.Network, com.cloud.offering.NetworkOffering, com.cloud.deploy.DeployDestination, com.cloud.vm.ReservationContext)
+      */
+     @Override
+     public Network implement(Network network, NetworkOffering offering,
+             DeployDestination dest, ReservationContext context)
+                     throws InsufficientVirtualNetworkCapcityException {
+         s_logger.trace("implement "+network.toString());
+         super.implement(network, offering, dest, context);
+         _sspMgr.createNetwork(network, offering, dest, context);
+         return network;
+     }
+ 
+ 
+     @Override
+     public void shutdown(NetworkProfile profile, NetworkOffering offering) {
+         s_logger.trace("shutdown "+profile.toString());
+         _sspMgr.deleteNetwork(profile);
+         super.shutdown(profile, offering);
+     }
+ 
+     @Override
+     public void reserve(NicProfile nic, Network network,
 -            VirtualMachineProfile<? extends VirtualMachine> vm,
++            VirtualMachineProfile vm,
+             DeployDestination dest, ReservationContext context)
+                     throws InsufficientVirtualNetworkCapcityException,
+                     InsufficientAddressCapacityException {
+         super.reserve(nic, network, vm, dest, context);
+         _sspMgr.createNicEnv(network, nic, dest, context);
+     }
+ 
+     @Override
+     public boolean release(NicProfile nic,
 -            VirtualMachineProfile<? extends VirtualMachine> vm,
++            VirtualMachineProfile vm,
+             String reservationId) {
+         Network network = _networkDao.findById(nic.getNetworkId());
+         _sspMgr.deleteNicEnv(network, nic, new ReservationContextImpl(reservationId, null, null));
+         return super.release(nic, vm, reservationId);
+     }
+ 
+     @Override
+     public void updateNicProfile(NicProfile profile, Network network) {
+         super.updateNicProfile(profile, network);
+     }
+ 
+     @Override
+     public boolean prepareMigration(NicProfile nic, Network network,
 -            VirtualMachineProfile<? extends VirtualMachine> vm,
++            VirtualMachineProfile vm,
+             DeployDestination dest, ReservationContext context) {
+         try {
+             reserve(nic, network, vm, dest, context);
+         } catch (InsufficientVirtualNetworkCapcityException e) {
+             s_logger.error("prepareForMigration failed", e);
+             return false;
+         } catch (InsufficientAddressCapacityException e) {
+             s_logger.error("prepareForMigration failed", e);
+             return false;
+         }
+         return true;
+     }
+ 
+     @Override
+     public void rollbackMigration(NicProfile nic, Network network,
 -            VirtualMachineProfile<? extends VirtualMachine> vm,
++            VirtualMachineProfile vm,
+             ReservationContext src, ReservationContext dst) {
+         release(nic, vm, dst.getReservationId());
+     }
+ 
+     @Override
+     public void commitMigration(NicProfile nic, Network network,
 -            VirtualMachineProfile<? extends VirtualMachine> vm,
++            VirtualMachineProfile vm,
+             ReservationContext src, ReservationContext dst) {
+         release(nic, vm, src.getReservationId());
+     }
+ }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57bafc8f/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
index f6d7b40,a31a036..ea42550
--- a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
+++ b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
@@@ -97,6 -96,36 +97,36 @@@ public class TemplateJoinDaoImpl extend
  
  
  
+     private String getTemplateStatus(TemplateJoinVO template){
+         boolean isAdmin = false;
 -        Account caller = UserContext.current().getCaller();
++        Account caller = CallContext.current().getCallingAccount();
+         if ((caller == null) || BaseCmd.isAdmin(caller.getType())) {
+             isAdmin = true;
+         }
+ 
+         // If the user is an Admin, add the template download status
+         String templateStatus = null;
+         if (isAdmin || caller.getId() == template.getAccountId()) {
+             // add download status
+             if (template.getDownloadState() != Status.DOWNLOADED) {
+                 templateStatus = "Processing";
+                 if (template.getDownloadState() == VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS) {
+                     if (template.getDownloadPercent() == 100) {
+                         templateStatus = "Installing Template";
+                     } else {
+                         templateStatus = template.getDownloadPercent() + "% Downloaded";
+                     }
+                 } else {
+                     templateStatus = template.getErrorString();
+                 }
+             } else if (template.getDownloadState() == VMTemplateHostVO.Status.DOWNLOADED) {
+                 templateStatus = "Download Complete";
+             } else {
+                 templateStatus = "Successfully Installed";
+             }
+         }
+         return templateStatus;
+     }
  
      @Override
      public TemplateResponse newTemplateResponse(TemplateJoinVO template) {
@@@ -137,33 -166,10 +167,10 @@@
          templateResponse.setDomainName(template.getDomainName());
  
  
- 
-         boolean isAdmin = false;
-         Account caller = CallContext.current().getCallingAccount();
-         if ((caller == null) || BaseCmd.isAdmin(caller.getType())) {
-             isAdmin = true;
-         }
- 
          // If the user is an Admin, add the template download status
-         if (isAdmin || caller.getId() == template.getAccountId()) {
-             // add download status
-             if (template.getDownloadState() != Status.DOWNLOADED) {
-                 String templateStatus = "Processing";
-                 if (template.getDownloadState() == VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS) {
-                     if (template.getDownloadPercent() == 100) {
-                         templateStatus = "Installing Template";
-                     } else {
-                         templateStatus = template.getDownloadPercent() + "% Downloaded";
-                     }
-                 } else {
-                     templateStatus = template.getErrorString();
-                 }
+         String templateStatus = getTemplateStatus(template);
+         if ( templateStatus != null ){
 -            templateResponse.setStatus(templateStatus);
 +                templateResponse.setStatus(templateStatus);
-             } else if (template.getDownloadState() == VMTemplateHostVO.Status.DOWNLOADED) {
-                 templateResponse.setStatus("Download Complete");
-             } else {
-                 templateResponse.setStatus("Successfully Installed");
-             }
          }
  
          Long templateSize = template.getSize();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57bafc8f/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57bafc8f/server/src/com/cloud/configuration/Config.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57bafc8f/server/src/com/cloud/configuration/ConfigurationManager.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/configuration/ConfigurationManager.java
index 831b2c8,1b99b63..9bbd537
--- a/server/src/com/cloud/configuration/ConfigurationManager.java
+++ b/server/src/com/cloud/configuration/ConfigurationManager.java
@@@ -107,8 -111,9 +110,9 @@@ public interface ConfigurationManager e
       * @param iopsWriteRate
       * @return newly created disk offering
       */
-     DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled,
+     DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized,
+     		boolean localStorageRequired, boolean isDisplayOfferingEnabled, Boolean isCustomizedIops, Long minIops, Long maxIops,
 -    		Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate);
 +            Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate);
  
      /**
       * Creates a new pod

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57bafc8f/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index a27c103,2089f82..e1a35ac
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@@ -2307,8 -2297,9 +2305,9 @@@ public class ConfigurationManagerImpl e
  
      @Override
      @ActionEvent(eventType = EventTypes.EVENT_DISK_OFFERING_CREATE, eventDescription = "creating disk offering")
-     public DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled,
+     public DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized,
+     		boolean localStorageRequired, boolean isDisplayOfferingEnabled, Boolean isCustomizedIops, Long minIops, Long maxIops,
 -    		Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate) {
 +            Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate) {
          long diskSize = 0;// special case for custom disk offerings
          if (numGibibytes != null && (numGibibytes <= 0)) {
              throw new InvalidParameterValueException("Please specify a disk size of at least 1 Gb.");
@@@ -2324,11 -2315,46 +2323,47 @@@
              isCustomized = true;
          }
  
+         if (isCustomizedIops != null) {
+             bytesReadRate = null;
+             bytesWriteRate = null;
+             iopsReadRate = null;
+             iopsWriteRate = null;
+ 
+             if (isCustomizedIops) {
+             	minIops = null;
+             	maxIops = null;
+             }
+             else {
+                 if (minIops == null && maxIops == null) {
+                     minIops = 0L;
+                     maxIops = 0L;
+                 }
+                 else {
+                 	if (minIops == null || minIops <= 0) {
+                 	    throw new InvalidParameterValueException("The min IOPS must be greater than 0.");
+         	        }
+ 
+                 	if (maxIops == null) {
+         	        	maxIops = 0L;
+         	        }
+ 
+                 	if (minIops > maxIops) {
+                 		throw new InvalidParameterValueException("The min IOPS must be less than or equal to the max IOPS.");
+                 	}
+                 }
+             }
+         }
+         else {
+             minIops = null;
+             maxIops = null;
+         }
+ 
          tags = cleanupTags(tags);
-         DiskOfferingVO newDiskOffering = new DiskOfferingVO(domainId, name, description, diskSize, tags, isCustomized);
+         DiskOfferingVO newDiskOffering = new DiskOfferingVO(domainId, name, description, diskSize, tags, isCustomized,
+         		isCustomizedIops, minIops, maxIops);
          newDiskOffering.setUseLocalStorage(localStorageRequired);
          newDiskOffering.setDisplayOffering(isDisplayOfferingEnabled);
 +        CallContext.current().setEventDetails("Disk offering id=" + newDiskOffering.getId());
  
          if (bytesReadRate != null && (bytesReadRate > 0))
              newDiskOffering.setBytesReadRate(bytesReadRate);
@@@ -3233,34 -3269,31 +3276,31 @@@
                              .getVlanType().toString(), ip.getSystem(), ip.getClass().getName(), ip.getUuid());
                  }
              }
+             try {
 -                if (_networkModel.areServicesSupportedInNetwork(vlanRange.getNetworkId(), Service.Dhcp)) {
 -                    Network network = _networkDao.findById(vlanRange.getNetworkId());
 -                    DhcpServiceProvider dhcpServiceProvider = _networkMgr.getDhcpServiceProvider(network);
 -                    if (!dhcpServiceProvider.getProvider().getName().equalsIgnoreCase(Provider.VirtualRouter.getName())) {
 +            if (_networkModel.areServicesSupportedInNetwork(vlanRange.getNetworkId(), Service.Dhcp)) {
 +                Network network = _networkDao.findById(vlanRange.getNetworkId());
 +                DhcpServiceProvider dhcpServiceProvider = _networkMgr.getDhcpServiceProvider(network);
 +                if (!dhcpServiceProvider.getProvider().getName().equalsIgnoreCase(Provider.VirtualRouter.getName())) {
-                     Transaction txn = Transaction.currentTxn();
-                     txn.start();
-                     if (!removeFromDb(vlanDbId)) {
-                         txn.rollback();
-                         txn.close();
-                         return false;
-                     }
- 
-                     else {
-                         txn.commit();
+                         deleteVLANFromDb(vlanDbId);
+                     } else {
+                         return  handleIpAliasDeletion(vlanRange, vlanDbId, dhcpServiceProvider, network);
                      }
                  }
  
                  else {
-                   return  handleIpAliasDeletion(vlanRange, vlanDbId, dhcpServiceProvider, network);
+                     deleteVLANFromDb(vlanDbId);
                  }
              }
+             catch ( SQLException e) {
+                throw  new CloudRuntimeException(e.getMessage());
+             }
+ 
          }
 -        return true;
 -    }
 +                    return  true;
 +                }
  
-     private boolean handleIpAliasDeletion(VlanVO vlanRange, long vlanDbId, DhcpServiceProvider dhcpServiceProvider, Network network) {
-         boolean result_final = false;
+     @DB
+     private boolean handleIpAliasDeletion(VlanVO vlanRange, long vlanDbId, DhcpServiceProvider dhcpServiceProvider, Network network) throws SQLException {
          Transaction txn = Transaction.currentTxn();
          txn.start();
          IPAddressVO ip = null;
@@@ -3268,89 -3301,54 +3308,54 @@@
          try{
              Integer allocIpCount=0;
              //search if the vlan has any allocated ips.
 -            allocIpCount = _publicIpAddressDao.countIPs(vlanRange.getDataCenterId(), vlanDbId, true);
 -            if (allocIpCount > 1) {
 +                allocIpCount = _publicIpAddressDao.countIPs(vlanRange.getDataCenterId(), vlanDbId, true);
 +                if (allocIpCount > 1) {
-                     throw  new InvalidParameterValueException ("cannot delete this range as some of the vlans are in use.");
+                 throw  new InvalidParameterValueException ("Cannot delete this range as some of the vlans are in use.");
 -            }
 +                }
-                 if (allocIpCount == 0){
-                 result_final=true;
+             else if (allocIpCount == 0){
+                 deleteVLANFromDb(vlanDbId);
 -            }
 +                }
              else {
                  ipAlias = _nicIpAliasDao.findByGatewayAndNetworkIdAndState(vlanRange.getVlanGateway(), vlanRange.getNetworkId(),  NicIpAlias.state.active);
-                 ipAlias.setState(NicIpAlias.state.revoked);
-                 _nicIpAliasDao.update(ipAlias.getId(), ipAlias);
+                 if (ipAlias == null) {
+                     throw  new InvalidParameterValueException ("Cannot delete this range as some of the Ips are in use.");
+                 }
+ 
                  //check if this ip belongs to this vlan and is allocated.
                  ip = _publicIpAddressDao.findByIpAndVlanId(ipAlias.getIp4Address(), vlanDbId);
                  if (ip != null && ip.getState() == IpAddress.State.Allocated) {
                      //check if there any other vlan ranges in the same subnet having free ips
                      List<VlanVO> vlanRanges = _vlanDao.listVlansByNetworkIdAndGateway(vlanRange.getNetworkId(), vlanRange.getVlanGateway());
                      //if there is no other vlanrage in this subnet. free the ip and delete the vlan.
-                     if (vlanRanges.size() == 1){
-                         boolean result = dhcpServiceProvider.removeDhcpSupportForSubnet(network);
-                         if (result == false) {
-                             result_final = false;
+                     if (vlanRanges.size() == 1) {
+                         ipAlias.setState(NicIpAlias.state.revoked);
+                         _nicIpAliasDao.update(ipAlias.getId(), ipAlias);
+                         if (!dhcpServiceProvider.removeDhcpSupportForSubnet(network)) {
                              s_logger.debug("Failed to delete the vlan range as we could not free the ip used to provide the dhcp service.");
-                         } else {
-                             _publicIpAddressDao.unassignIpAddress(ip.getId());
-                             result_final = true;
-                         }
-         } else {
-                         // if there are more vlans in the subnet check if there
-                         // are free ips.
-                         List<Long> vlanDbIdList = new ArrayList<Long>();
-                         for (VlanVO vlanrange : vlanRanges) {
-                             if (vlanrange.getId() != vlanDbId) {
-                                 vlanDbIdList.add(vlanrange.getId());
-                             }
-                         }
-                         s_logger.info("vlan Range"
-                                 + vlanRange.getId()
-                                 + " id being deleted, one of the Ips in this range is used to provide the dhcp service, trying to free this ip and allocate a new one.");
-                         for (VlanVO vlanrange : vlanRanges) {
-                             if (vlanrange.getId() != vlanDbId) {
- 
-                                 long freeIpsInsubnet =  _publicIpAddressDao.countFreeIpsInVlan(vlanrange.getId());
-                                 if (freeIpsInsubnet > 0){
-                                     //assign one free ip to the router for creating ip Alias. The ipalias is system managed ip so we are using the system account to allocate the ip not the caller.
-                                     boolean result = false;
-                                     PublicIp routerPublicIP = _networkMgr.assignPublicIpAddressFromVlans(network.getDataCenterId(), null, _accountDao.findById(Account.ACCOUNT_ID_SYSTEM), Vlan.VlanType.DirectAttached, vlanDbIdList, network.getId(), null, false);
-                                         s_logger.info("creating a db entry for the new ip alias.");
-                                         NicIpAliasVO newipAlias = new NicIpAliasVO(ipAlias.getNicId(), routerPublicIP.getAddress().addr(), ipAlias.getVmId(), ipAlias.getAccountId(), network.getDomainId(), network.getId(), ipAlias.getGateway(), ipAlias.getNetmask());
-                                         newipAlias.setAliasCount(routerPublicIP.getIpMacAddress());
-                                         _nicIpAliasDao.persist(newipAlias);
-                                         //we revoke all the rules and apply all the rules as a part of the removedhcp config. so the new ip will get configured when we delete the old ip.
-                                     s_logger.info("removing the old ip alias on router");
-                                     result = dhcpServiceProvider.removeDhcpSupportForSubnet(network);
-                                     if (result == false) {
-                                         s_logger.debug("could't delete the ip alias on the router");
-                                         result_final = false;
+                             //setting the state back to active
+                             ipAlias.setState(NicIpAlias.state.active);
+                             _nicIpAliasDao.update(ipAlias.getId(), ipAlias);
 -                        }
 -                        else {
 -                            _publicIpAddressDao.unassignIpAddress(ip.getId());
 +                                    }
 +                                    else {
 +                                    _publicIpAddressDao.unassignIpAddress(ip.getId());
-                                         result_final=true;
-                                     }
-         }
-                                 }
-                             }
+                             deleteVLANFromDb(vlanDbId);
                          }
+                     } else {
+                         // if there are more vlans in the subnet, free all the ips in the range except the ip alias.
+                         s_logger.info("vlan Range"+vlanRange.getId()+" id being deleted, one of the Ips in this range is used to provide the dhcp service, will free the rest of the IPs in range.");
+                         _publicIpAddressDao.deletePublicIPRangeExceptAliasIP(vlanDbId, ipAlias.getIp4Address());
+                         VlanVO vlan = _vlanDao.findById(vlanDbId);
+                         vlan.setIpRange(ipAlias.getIp4Address()+"-"+ipAlias.getIp4Address());
+                         _vlanDao.update(vlan.getId(), vlan);
 -                    }
 +    }
 +                }
- 
-         } catch (InsufficientAddressCapacityException e) {
-             throw new InvalidParameterValueException("cannot delete  vlan range"+ vlanRange.getId()+"one of the ips in this range is benig used to provide dhcp service. Cannot use some other ip as there are no free ips in this subnet");
                  }
-         finally {
-             if (result_final) {
-                 if (!removeFromDb(vlanDbId)) {
 -            }
+         } catch (CloudRuntimeException e) {
 -            txn.rollback();
 +                    txn.rollback();
+             throw e;
 -        }
 -        txn.commit();
 +                }
-                 else {
 +                    txn.commit();
-                 }
-                 txn.close();
-             }
-         }
-         return result_final;
+         return true;
      }
  
      @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57bafc8f/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57bafc8f/server/src/com/cloud/network/NetworkManagerImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57bafc8f/server/src/com/cloud/network/NetworkUsageManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/network/NetworkUsageManagerImpl.java
index 2bd55bb,972d3ff..7bd96a4
--- a/server/src/com/cloud/network/NetworkUsageManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkUsageManagerImpl.java
@@@ -32,6 -32,6 +32,10 @@@ import javax.naming.ConfigurationExcept
  import org.apache.log4j.Logger;
  import org.springframework.stereotype.Component;
  
++import org.apache.cloudstack.api.command.admin.usage.AddTrafficMonitorCmd;
++import org.apache.cloudstack.api.command.admin.usage.DeleteTrafficMonitorCmd;
++import org.apache.cloudstack.api.command.admin.usage.ListTrafficMonitorsCmd;
++
  import com.cloud.agent.AgentManager;
  import com.cloud.agent.Listener;
  import com.cloud.agent.api.AgentControlAnswer;
@@@ -68,17 -68,16 +72,9 @@@ import com.cloud.resource.ResourceManag
  import com.cloud.resource.ResourceStateAdapter;
  import com.cloud.resource.ServerResource;
  import com.cloud.resource.UnableDeleteHostException;
  import com.cloud.usage.UsageIPAddressVO;
  import com.cloud.user.AccountManager;
  import com.cloud.user.AccountVO;
--import com.cloud.user.User;
 -import com.cloud.user.UserContext;
  import com.cloud.user.UserStatisticsVO;
  import com.cloud.user.dao.UserStatisticsDao;
  import com.cloud.utils.NumbersUtil;
@@@ -195,16 -193,11 +190,11 @@@ public class NetworkUsageManagerImpl ex
              throw new InvalidParameterValueException("Could not find an traffic monitor with ID: " + hostId);
          }
  
- 		try {
- 			if (_resourceMgr.maintain(hostId) && _resourceMgr.deleteHost(hostId, false, false)) {
+         if (_resourceMgr.deleteHost(hostId, false, false)) {
 -            return true;
 -        } else {
 -            return false;
 -        }
 +				return true;
 +            } else {
 +                return false;
 +            }
-         } catch (AgentUnavailableException e) {
-             s_logger.debug(e);
-             return false;
-         }
      }
  
      @Override
@@@ -254,7 -247,7 +244,7 @@@
  
          private int _interval;
  
--        private long mgmtSrvrId = MacAddress.getMacAddress().toLong();
++        private final long mgmtSrvrId = MacAddress.getMacAddress().toLong();
  
          protected DirectNetworkStatsListener(int interval) {
              _interval = interval;
@@@ -529,13 -522,20 +519,20 @@@
          return host;
      }
  
 -    @Override
 +	@Override
      public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
 -        if(host.getType() != Host.Type.TrafficMonitor){
 -            return null;
 -        }
 +		if(host.getType() != Host.Type.TrafficMonitor){
 +	    return null;
 +    }
  
- 		return new DeleteHostAnswer(true);
+         long hostId = host.getId();
+         _agentMgr.disconnectWithoutInvestigation(hostId, Status.Event.Remove);
+         _detailsDao.deleteDetails(hostId);
+         host.setGuid(null);
+         _hostDao.update(hostId, host);
+         _hostDao.remove(hostId);
+         return new DeleteHostAnswer(false);
+ 
      }
  
  }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57bafc8f/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
index 113e5e2,470d9b8..bc50d95
--- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
+++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
@@@ -68,10 -69,6 +68,10 @@@ import com.cloud.exception.InvalidParam
  import com.cloud.exception.NetworkRuleConflictException;
  import com.cloud.exception.PermissionDeniedException;
  import com.cloud.exception.ResourceUnavailableException;
- import com.cloud.network.ExternalLoadBalancerUsageManager;
++import com.cloud.network.ExternalDeviceUsageManager;
 +import com.cloud.network.IpAddress;
 +import com.cloud.network.LBHealthCheckPolicyVO;
 +import com.cloud.network.Network;
  import com.cloud.network.Network.Capability;
  import com.cloud.network.Network.Provider;
  import com.cloud.network.Network.Service;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57bafc8f/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index 554e691,ddfa998..c5df621
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@@ -3687,13 -3690,16 +3686,16 @@@ public class VirtualNetworkApplianceMan
              rulesTO = new ArrayList<FirewallRuleTO>();
              for (FirewallRule rule : rules) {
                  FirewallRule.TrafficType traffictype = rule.getTrafficType();
 -                if(traffictype == FirewallRule.TrafficType.Ingress){
 +                if (traffictype == FirewallRule.TrafficType.Ingress) {
                      IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
 -                    FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr(),Purpose.Firewall,traffictype);
 +                    FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr(), Purpose.Firewall, traffictype);
                      rulesTO.add(ruleTO);
                  } else if (rule.getTrafficType() == FirewallRule.TrafficType.Egress){
+                     NetworkVO network = _networkDao.findById(guestNetworkId);
+                     NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+                     defaultEgressPolicy = offering.getEgressDefaultPolicy();
                      assert (rule.getSourceIpAddressId()==null) : "ipAddressId should be null for egress firewall rule. ";
-                     FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null,"",Purpose.Firewall, traffictype);
+                     FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null,"",Purpose.Firewall, traffictype, defaultEgressPolicy);
                      rulesTO.add(ruleTO);
                  }
              }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57bafc8f/server/src/com/cloud/resource/ResourceManagerImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/57bafc8f/server/src/com/cloud/storage/StorageManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/storage/StorageManagerImpl.java
index 55b214f,b64b202..ac04886
--- a/server/src/com/cloud/storage/StorageManagerImpl.java
+++ b/server/src/com/cloud/storage/StorageManagerImpl.java
@@@ -585,10 -578,9 +580,9 @@@ public class StorageManagerImpl extend
          if (_storageCleanupEnabled) {
              _executor.shutdown();
          }
- 
          return true;
      }
 -
 +    
      @DB
      @Override
      public DataStore createLocalStorage(Host host, StoragePoolInfo pInfo) throws ConnectionException {
@@@ -1097,95 -1095,51 +1097,51 @@@
      @Override
      @DB
      public void cleanupSecondaryStorage(boolean recurring) {
+         // NOTE that object_store refactor will immediately delete the object from secondary storage when deleteTemplate etc api is issued.
+         // so here we don't need to issue DeleteCommand to resource anymore, only need to remove db entry.
          try {
-             // Cleanup templates in secondary storage hosts
+             // Cleanup templates in template_store_ref
 -            List<DataStore> imageStores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(null));
 +            List<DataStore> imageStores = dataStoreMgr.getImageStoresByScope(new ZoneScope(null));
              for (DataStore store : imageStores) {
                  try {
                      long storeId = store.getId();
 -                    List<TemplateDataStoreVO> destroyedTemplateStoreVOs = this._templateStoreDao.listDestroyed(storeId);
 +                    List<TemplateDataStoreVO> destroyedTemplateStoreVOs = _templateStoreDao.listDestroyed(storeId);
                      s_logger.debug("Secondary storage garbage collector found " + destroyedTemplateStoreVOs.size()
-                             + " templates to cleanup on secondary storage host: " + store.getName());
+                             + " templates to cleanup on template_store_ref for store: " + store.getName());
                      for (TemplateDataStoreVO destroyedTemplateStoreVO : destroyedTemplateStoreVOs) {
-                         if (!_tmpltMgr.templateIsDeleteable(destroyedTemplateStoreVO.getTemplateId())) {
-                             if (s_logger.isDebugEnabled()) {
-                                 s_logger.debug("Not deleting template at: " + destroyedTemplateStoreVO);
-                             }
-                             continue;
-                         }
- 
                          if (s_logger.isDebugEnabled()) {
-                             s_logger.debug("Deleting template store: " + destroyedTemplateStoreVO);
-                         }
- 
-                         VMTemplateVO destroyedTemplate = _vmTemplateDao.findById(destroyedTemplateStoreVO.getTemplateId());
-                         if (destroyedTemplate == null) {
-                             s_logger.error("Cannot find template : " + destroyedTemplateStoreVO.getTemplateId() + " from template table");
-                             throw new CloudRuntimeException("Template " + destroyedTemplateStoreVO.getTemplateId()
-                                     + " is found in secondary storage, but not found in template table");
+                             s_logger.debug("Deleting template store DB entry: " + destroyedTemplateStoreVO);
                          }
-                         String installPath = destroyedTemplateStoreVO.getInstallPath();
- 
-                         TemplateInfo tmpl = tmplFactory.getTemplate(destroyedTemplateStoreVO.getTemplateId(), store);
-                         if (installPath != null) {
-                             EndPoint ep = _epSelector.select(store);
-                             Command cmd = new DeleteCommand(tmpl.getTO());
-                             Answer answer = ep.sendMessage(cmd);
- 
-                             if (answer == null || !answer.getResult()) {
-                                 s_logger.debug("Failed to delete " + destroyedTemplateStoreVO + " due to "
-                                         + ((answer == null) ? "answer is null" : answer.getDetails()));
-                             } else {
 -                        _templateStoreDao.remove(destroyedTemplateStoreVO.getId());
 +                                _templateStoreDao.remove(destroyedTemplateStoreVO.getId());
-                                 s_logger.debug("Deleted template at: " + destroyedTemplateStoreVO.getInstallPath());
-                             }
-                         } else {
-                             _templateStoreDao.remove(destroyedTemplateStoreVO.getId());
-                         }
                      }
                  } catch (Exception e) {
-                     s_logger.warn("problem cleaning up templates in secondary storage store " + store.getName(), e);
+                     s_logger.warn("problem cleaning up templates in template_store_ref for store: " + store.getName(), e);
                  }
              }
  
-             // CleanUp snapshots on Secondary Storage.
+             // CleanUp snapshots on snapshot_store_ref
              for (DataStore store : imageStores) {
 -                try {
 +                        try {
                      List<SnapshotDataStoreVO> destroyedSnapshotStoreVOs = _snapshotStoreDao.listDestroyed(store.getId());
                      s_logger.debug("Secondary storage garbage collector found " + destroyedSnapshotStoreVOs.size()
-                             + " snapshots to cleanup on secondary storage host: " + store.getName());
+                             + " snapshots to cleanup on snapshot_store_ref for store: " + store.getName());
                      for (SnapshotDataStoreVO destroyedSnapshotStoreVO : destroyedSnapshotStoreVOs) {
                          // check if this snapshot has child
                          SnapshotInfo snap = snapshotFactory.getSnapshot(destroyedSnapshotStoreVO.getSnapshotId(), store);
                          if ( snap.getChild() != null ){
                              s_logger.debug("Skip snapshot on store: " + destroyedSnapshotStoreVO + " , because it has child");
 -                            continue;
 -                        }
 +                                    continue;
 +                                }
  
                          if (s_logger.isDebugEnabled()) {
-                             s_logger.debug("Deleting snapshot on store: " + destroyedSnapshotStoreVO);
+                             s_logger.debug("Deleting snapshot store DB entry: " + destroyedSnapshotStoreVO);
 -                        }
 +                            }
  
-                         String installPath = destroyedSnapshotStoreVO.getInstallPath();
- 
-                         if (installPath != null) {
-                             EndPoint ep = _epSelector.select(store);
-                             DeleteCommand cmd = new DeleteCommand(snap.getTO());
-                             Answer answer = ep.sendMessage(cmd);
-                             if (answer == null || !answer.getResult()) {
-                                 s_logger.debug("Failed to delete " + destroyedSnapshotStoreVO + " due to "
-                                         + ((answer == null) ? "answer is null" : answer.getDetails()));
-                             } else {
-                                 _volumeStoreDao.remove(destroyedSnapshotStoreVO.getId());
-                                 s_logger.debug("Deleted snapshot at: " + destroyedSnapshotStoreVO.getInstallPath());
-                             }
-                         } else {
 -                        _snapshotStoreDao.remove(destroyedSnapshotStoreVO.getId());
 -                    }
 +                            _snapshotStoreDao.remove(destroyedSnapshotStoreVO.getId());
 +                        }
-                     }
  
                  } catch (Exception e2) {
-                     s_logger.warn("problem cleaning up snapshots in secondary storage store " + store.getName(), e2);
+                     s_logger.warn("problem cleaning up snapshots in snapshot_store_ref for store: " + store.getName(), e2);
                  }
  
              }
@@@ -1195,30 -1149,12 +1151,12 @@@
                  try {
                      List<VolumeDataStoreVO> destroyedStoreVOs = _volumeStoreDao.listDestroyed(store.getId());
                      s_logger.debug("Secondary storage garbage collector found " + destroyedStoreVOs.size()
-                             + " volumes to cleanup on secondary storage host: " + store.getName());
+                             + " volumes to cleanup on volume_store_ref for store: " + store.getName());
                      for (VolumeDataStoreVO destroyedStoreVO : destroyedStoreVOs) {
                          if (s_logger.isDebugEnabled()) {
-                             s_logger.debug("Deleting volume on store: " + destroyedStoreVO);
+                             s_logger.debug("Deleting volume store DB entry: " + destroyedStoreVO);
                          }
- 
-                         String installPath = destroyedStoreVO.getInstallPath();
- 
-                         VolumeInfo vol = volFactory.getVolume(destroyedStoreVO.getVolumeId(), store);
- 
-                         if (installPath != null) {
-                             EndPoint ep = _epSelector.select(store);
-                             DeleteCommand cmd = new DeleteCommand(vol.getTO());
-                             Answer answer = ep.sendMessage(cmd);
-                             if (answer == null || !answer.getResult()) {
-                                 s_logger.debug("Failed to delete " + destroyedStoreVO + " due to "
-                                         + ((answer == null) ? "answer is null" : answer.getDetails()));
-                             } else {
 -                        _volumeStoreDao.remove(destroyedStoreVO.getId());
 +                                _volumeStoreDao.remove(destroyedStoreVO.getId());
-                                 s_logger.debug("Deleted volume at: " + destroyedStoreVO.getInstallPath());
-                             }
-                         } else {
-                             _volumeStoreDao.remove(destroyedStoreVO.getId());
-                         }
                      }
  
                  } catch (Exception e2) {
@@@ -1338,10 -1274,10 +1276,10 @@@
      }
  
      @Override
 -    public void onManagementNodeLeft(List<ManagementServerHostVO> nodeList, long selfNodeId) {
 -        for (ManagementServerHostVO vo : nodeList) {
 +    public void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
 +        for (ManagementServerHost vo : nodeList) {
              if (vo.getMsid() == _serverId) {
-                 s_logger.info("Cleaning up storage maintenance jobs associated with Management server" + vo.getMsid());
+                 s_logger.info("Cleaning up storage maintenance jobs associated with Management server: " + vo.getMsid());
                  List<Long> poolIds = _storagePoolWorkDao.searchForPoolIdsForPendingWorkJobs(vo.getMsid());
                  if (poolIds.size() > 0) {
                      for (Long poolId : poolIds) {
@@@ -1577,9 -1550,10 +1552,10 @@@
                      allocatedSizeWithtemplate = _capacityMgr.getAllocatedPoolCapacity(poolVO, tmpl);
                  }
              }
-             if (volume.getState() != Volume.State.Ready)
+             if (volume.getState() != Volume.State.Ready) {
                  totalAskingSize = totalAskingSize + volume.getSize();
 -            }
 +        }
+         }
  
          long totalOverProvCapacity;
          if (pool.getPoolType() == StoragePoolType.NetworkFilesystem) {