You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mu...@apache.org on 2014/03/11 14:12:58 UTC

[01/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Repository: cloudstack
Updated Branches:
  refs/heads/distributedrouter b038c279a -> 6b5e234aa (forced update)


CLOUDSTACK-6047: Introduce Aggregated commands queue to VR


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/60dc2545
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/60dc2545
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/60dc2545

Branch: refs/heads/distributedrouter
Commit: 60dc25450a02f070c13a768d832a7a24d2b7b414
Parents: 7cb9132
Author: Sheng Yang <sh...@citrix.com>
Authored: Tue Mar 4 14:28:41 2014 -0800
Committer: Sheng Yang <sh...@citrix.com>
Committed: Thu Mar 6 16:22:01 2014 -0800

----------------------------------------------------------------------
 .../api/routing/FinishAggregationCommand.java   |  31 +++
 .../api/routing/StartAggregationCommand.java    |  31 +++
 .../virtualnetwork/VirtualRoutingResource.java  | 188 ++++++++++++++-----
 .../VirtualNetworkApplianceManagerImpl.java     |   8 +-
 .../debian/config/opt/cloud/bin/vr_cfg.sh       |  96 ++++++++++
 5 files changed, 302 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/60dc2545/core/src/com/cloud/agent/api/routing/FinishAggregationCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/routing/FinishAggregationCommand.java b/core/src/com/cloud/agent/api/routing/FinishAggregationCommand.java
new file mode 100644
index 0000000..bfafccd
--- /dev/null
+++ b/core/src/com/cloud/agent/api/routing/FinishAggregationCommand.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.agent.api.routing;
+
+public class FinishAggregationCommand extends NetworkElementCommand{
+    protected FinishAggregationCommand() {
+        super();
+    }
+
+    public FinishAggregationCommand(String name, String ip, String guestIp) {
+        super();
+        this.setAccessDetail(NetworkElementCommand.ROUTER_NAME, name);
+        this.setAccessDetail(NetworkElementCommand.ROUTER_IP, ip);
+        this.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, guestIp);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/60dc2545/core/src/com/cloud/agent/api/routing/StartAggregationCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/routing/StartAggregationCommand.java b/core/src/com/cloud/agent/api/routing/StartAggregationCommand.java
new file mode 100644
index 0000000..fbf97a8
--- /dev/null
+++ b/core/src/com/cloud/agent/api/routing/StartAggregationCommand.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.agent.api.routing;
+
+public class StartAggregationCommand extends NetworkElementCommand{
+    protected StartAggregationCommand() {
+        super();
+    }
+
+    public StartAggregationCommand(String name, String ip, String guestIp) {
+        super();
+        this.setAccessDetail(NetworkElementCommand.ROUTER_NAME, name);
+        this.setAccessDetail(NetworkElementCommand.ROUTER_IP, ip);
+        this.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, guestIp);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/60dc2545/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
index 9bebd4c..49e6812 100755
--- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
+++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
@@ -29,6 +29,7 @@ import com.cloud.agent.api.routing.CreateIpAliasCommand;
 import com.cloud.agent.api.routing.DeleteIpAliasCommand;
 import com.cloud.agent.api.routing.DhcpEntryCommand;
 import com.cloud.agent.api.routing.DnsMasqConfigCommand;
+import com.cloud.agent.api.routing.FinishAggregationCommand;
 import com.cloud.agent.api.routing.GroupAnswer;
 import com.cloud.agent.api.routing.IpAliasTO;
 import com.cloud.agent.api.routing.IpAssocCommand;
@@ -46,6 +47,7 @@ import com.cloud.agent.api.routing.SetSourceNatCommand;
 import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
 import com.cloud.agent.api.routing.SetStaticRouteCommand;
 import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
+import com.cloud.agent.api.routing.StartAggregationCommand;
 import com.cloud.agent.api.routing.VmDataCommand;
 import com.cloud.agent.api.routing.VpnUsersCfgCommand;
 import com.cloud.agent.api.to.DhcpTO;
@@ -72,6 +74,9 @@ import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Queue;
+import java.util.UUID;
+import java.util.concurrent.LinkedBlockingQueue;
 
 /**
  * VirtualNetworkResource controls and configures virtual networking
@@ -111,27 +116,34 @@ public class VirtualRoutingResource {
         protected static final String VPC_STATIC_NAT = "vpc_staticnat.sh";
         protected static final String VPC_STATIC_ROUTE = "vpc_staticroute.sh";
         protected static final String VPN_L2TP = "vpn_l2tp.sh";
+
+        protected static final String VR_CFG = "vr_cfg.sh";
     }
 
     private static final Logger s_logger = Logger.getLogger(VirtualRoutingResource.class);
     private VirtualRouterDeployer _vrDeployer;
+    private Map <String, Queue> _vrAggregateCommandsSet;
 
     private String _name;
     private int _sleep;
     private int _retry;
     private int _port;
 
+    private String _cfgVersion = "1.0";
+
     public VirtualRoutingResource(VirtualRouterDeployer deployer) {
         this._vrDeployer = deployer;
     }
 
     public Answer executeRequest(final NetworkElementCommand cmd) {
+        boolean aggregated = false;
         try {
             ExecutionResult rc = _vrDeployer.prepareCommand(cmd);
             if (!rc.isSuccess()) {
                 s_logger.error("Failed to prepare VR command due to " + rc.getDetails());
                 return new Answer(cmd, false, rc.getDetails());
             }
+            String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
 
             assert cmd.getRouterAccessIp() != null : "Why there is no access IP for VR?";
 
@@ -139,50 +151,22 @@ public class VirtualRoutingResource {
                 return executeQueryCommand(cmd);
             }
 
-            List<ConfigItem> cfg;
-            if (cmd instanceof SetPortForwardingRulesVpcCommand) {
-                cfg = generateConfig((SetPortForwardingRulesVpcCommand)cmd);
-            } else if (cmd instanceof SetPortForwardingRulesCommand) {
-                cfg = generateConfig((SetPortForwardingRulesCommand)cmd);
-            } else if (cmd instanceof SetStaticRouteCommand) {
-                cfg = generateConfig((SetStaticRouteCommand)cmd);
-            } else if (cmd instanceof SetStaticNatRulesCommand) {
-                cfg = generateConfig((SetStaticNatRulesCommand)cmd);
-            } else if (cmd instanceof LoadBalancerConfigCommand) {
-                cfg = generateConfig((LoadBalancerConfigCommand)cmd);
-            } else if (cmd instanceof SavePasswordCommand) {
-                cfg = generateConfig((SavePasswordCommand)cmd);
-            } else if (cmd instanceof DhcpEntryCommand) {
-                cfg = generateConfig((DhcpEntryCommand)cmd);
-            } else if (cmd instanceof CreateIpAliasCommand) {
-                cfg = generateConfig((CreateIpAliasCommand)cmd);
-            } else if (cmd instanceof DnsMasqConfigCommand) {
-                cfg = generateConfig((DnsMasqConfigCommand)cmd);
-            } else if (cmd instanceof DeleteIpAliasCommand) {
-                cfg = generateConfig((DeleteIpAliasCommand)cmd);
-            } else if (cmd instanceof VmDataCommand) {
-                cfg = generateConfig((VmDataCommand)cmd);
-            } else if (cmd instanceof SetFirewallRulesCommand) {
-                cfg = generateConfig((SetFirewallRulesCommand)cmd);
-            } else if (cmd instanceof BumpUpPriorityCommand) {
-                cfg = generateConfig((BumpUpPriorityCommand)cmd);
-            } else if (cmd instanceof RemoteAccessVpnCfgCommand) {
-                cfg = generateConfig((RemoteAccessVpnCfgCommand)cmd);
-            } else if (cmd instanceof VpnUsersCfgCommand) {
-                cfg = generateConfig((VpnUsersCfgCommand)cmd);
-            } else if (cmd instanceof Site2SiteVpnCfgCommand) {
-                cfg = generateConfig((Site2SiteVpnCfgCommand)cmd);
-            } else if (cmd instanceof SetMonitorServiceCommand) {
-                cfg = generateConfig((SetMonitorServiceCommand)cmd);
-            } else if (cmd instanceof SetupGuestNetworkCommand) {
-                cfg = generateConfig((SetupGuestNetworkCommand)cmd);
-            } else if (cmd instanceof SetNetworkACLCommand) {
-                cfg = generateConfig((SetNetworkACLCommand)cmd);
-            } else if (cmd instanceof SetSourceNatCommand) {
-                cfg = generateConfig((SetSourceNatCommand)cmd);
-            } else if (cmd instanceof IpAssocCommand) {
-                cfg = generateConfig((IpAssocCommand)cmd);
-            } else {
+            if (cmd instanceof StartAggregationCommand) {
+                return execute((StartAggregationCommand)cmd);
+            } else if (cmd instanceof FinishAggregationCommand) {
+                return execute((FinishAggregationCommand)cmd);
+            }
+
+            if (_vrAggregateCommandsSet.containsKey(routerName)) {
+                _vrAggregateCommandsSet.get(routerName).add(cmd);
+                aggregated = true;
+                // Clean up would be done after command has been executed
+                //TODO: Deal with group answer as well
+                return new Answer(cmd);
+            }
+
+            List<ConfigItem> cfg = generateCommandCfg(cmd);
+            if (cfg == null) {
                 return Answer.createUnsupportedCommandAnswer(cmd);
             }
 
@@ -190,9 +174,11 @@ public class VirtualRoutingResource {
         } catch (final IllegalArgumentException e) {
             return new Answer(cmd, false, e.getMessage());
         } finally {
-            ExecutionResult rc = _vrDeployer.cleanupCommand(cmd);
-            if (!rc.isSuccess()) {
-                s_logger.error("Failed to cleanup VR command due to " + rc.getDetails());
+            if (!aggregated) {
+                ExecutionResult rc = _vrDeployer.cleanupCommand(cmd);
+                if (!rc.isSuccess()) {
+                    s_logger.error("Failed to cleanup VR command due to " + rc.getDetails());
+                }
             }
         }
     }
@@ -952,6 +938,8 @@ public class VirtualRoutingResource {
         if (_vrDeployer == null) {
             throw new ConfigurationException("Unable to find the resource for VirtualRouterDeployer!");
         }
+
+        _vrAggregateCommandsSet = new HashMap<>();
         return true;
     }
 
@@ -1030,4 +1018,110 @@ public class VirtualRoutingResource {
 
         return false;
     }
+
+    private Answer execute(StartAggregationCommand cmd) {
+        // Access IP would be used as ID for router
+        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        assert routerName != null;
+        Queue<NetworkElementCommand> queue = new LinkedBlockingQueue<>();
+        _vrAggregateCommandsSet.put(routerName, queue);
+        return new Answer(cmd);
+    }
+
+    private List<ConfigItem> generateCommandCfg(NetworkElementCommand cmd) {
+        List<ConfigItem> cfg;
+        if (cmd instanceof SetPortForwardingRulesVpcCommand) {
+            cfg = generateConfig((SetPortForwardingRulesVpcCommand)cmd);
+        } else if (cmd instanceof SetPortForwardingRulesCommand) {
+            cfg = generateConfig((SetPortForwardingRulesCommand)cmd);
+        } else if (cmd instanceof SetStaticRouteCommand) {
+            cfg = generateConfig((SetStaticRouteCommand)cmd);
+        } else if (cmd instanceof SetStaticNatRulesCommand) {
+            cfg = generateConfig((SetStaticNatRulesCommand)cmd);
+        } else if (cmd instanceof LoadBalancerConfigCommand) {
+            cfg = generateConfig((LoadBalancerConfigCommand)cmd);
+        } else if (cmd instanceof SavePasswordCommand) {
+            cfg = generateConfig((SavePasswordCommand)cmd);
+        } else if (cmd instanceof DhcpEntryCommand) {
+            cfg = generateConfig((DhcpEntryCommand)cmd);
+        } else if (cmd instanceof CreateIpAliasCommand) {
+            cfg = generateConfig((CreateIpAliasCommand)cmd);
+        } else if (cmd instanceof DnsMasqConfigCommand) {
+            cfg = generateConfig((DnsMasqConfigCommand)cmd);
+        } else if (cmd instanceof DeleteIpAliasCommand) {
+            cfg = generateConfig((DeleteIpAliasCommand)cmd);
+        } else if (cmd instanceof VmDataCommand) {
+            cfg = generateConfig((VmDataCommand)cmd);
+        } else if (cmd instanceof SetFirewallRulesCommand) {
+            cfg = generateConfig((SetFirewallRulesCommand)cmd);
+        } else if (cmd instanceof BumpUpPriorityCommand) {
+            cfg = generateConfig((BumpUpPriorityCommand)cmd);
+        } else if (cmd instanceof RemoteAccessVpnCfgCommand) {
+            cfg = generateConfig((RemoteAccessVpnCfgCommand)cmd);
+        } else if (cmd instanceof VpnUsersCfgCommand) {
+            cfg = generateConfig((VpnUsersCfgCommand)cmd);
+        } else if (cmd instanceof Site2SiteVpnCfgCommand) {
+            cfg = generateConfig((Site2SiteVpnCfgCommand)cmd);
+        } else if (cmd instanceof SetMonitorServiceCommand) {
+            cfg = generateConfig((SetMonitorServiceCommand)cmd);
+        } else if (cmd instanceof SetupGuestNetworkCommand) {
+            cfg = generateConfig((SetupGuestNetworkCommand)cmd);
+        } else if (cmd instanceof SetNetworkACLCommand) {
+            cfg = generateConfig((SetNetworkACLCommand)cmd);
+        } else if (cmd instanceof SetSourceNatCommand) {
+            cfg = generateConfig((SetSourceNatCommand)cmd);
+        } else if (cmd instanceof IpAssocCommand) {
+            cfg = generateConfig((IpAssocCommand)cmd);
+        } else {
+            return null;
+        }
+        return cfg;
+    }
+
+    private Answer execute(FinishAggregationCommand cmd) {
+        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        assert routerName != null;
+        assert cmd.getRouterAccessIp() != null;
+        Queue<NetworkElementCommand> queue = _vrAggregateCommandsSet.get(routerName);
+        try {
+            StringBuilder sb = new StringBuilder();
+            sb.append("#Apache CloudStack Virtual Router Config File\n");
+            sb.append("<version>\n" + _cfgVersion + "\n</version>\n");
+            for (NetworkElementCommand command : queue) {
+                List<ConfigItem> cfg = generateCommandCfg(command);
+                if (cfg == null) {
+                    s_logger.warn("Unknown commands for VirtualRoutingResource, but continue: " + cmd.toString());
+                }
+
+                for (ConfigItem c : cfg) {
+                    if (c.isFile()) {
+                        sb.append("<file>\n");
+                        sb.append(c.getFilePath() + c.getFileName() + "\n");
+                        sb.append(c.getFileContents() + "\n");
+                        sb.append("</file>\n");
+                    } else {
+                        sb.append("<script>\n");
+                        sb.append("/opt/cloud/bin/" + c.getScript() + " " + c.getArgs() + "\n");
+                        sb.append("</script>\n");
+                    }
+                }
+            }
+            String cfgFilePath = "/var/cache/cloud/";
+            String cfgFileName = "VR-"+ UUID.randomUUID().toString() + ".cfg";
+            ExecutionResult result = _vrDeployer.createFileInVR(cmd.getRouterAccessIp(), cfgFilePath, cfgFileName, sb.toString());
+            if (!result.isSuccess()) {
+                return new Answer(cmd, false, result.getDetails());
+            }
+
+            result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), VRScripts.VR_CFG, "-c " + cfgFilePath + cfgFileName);
+            if (!result.isSuccess()) {
+                return new Answer(cmd, false, result.getDetails());
+            }
+            return new Answer(cmd);
+        } finally {
+            queue.clear();
+            _vrAggregateCommandsSet.remove(routerName);
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/60dc2545/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index 37171f5..8486f06 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -2736,12 +2736,10 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
             final Commands cmds = new Commands(Command.OnError.Stop);
             createApplyVpnCommands(true, vpn, router, cmds);
 
-            try {
-                _agentMgr.send(router.getHostId(), cmds);
-            } catch (final OperationTimedoutException e) {
-                s_logger.debug("Failed to start remote access VPN: ", e);
-                throw new AgentUnavailableException("Unable to send commands to virtual router ", router.getHostId(), e);
+            if (!sendCommandsToRouter(router, cmds)) {
+                throw new AgentUnavailableException("Unable to send commands to virtual router ", router.getHostId());
             }
+
             Answer answer = cmds.getAnswer("users");
             if (!answer.getResult()) {
                 s_logger.error("Unable to start vpn: unable add users to vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: " +

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/60dc2545/systemvm/patches/debian/config/opt/cloud/bin/vr_cfg.sh
----------------------------------------------------------------------
diff --git a/systemvm/patches/debian/config/opt/cloud/bin/vr_cfg.sh b/systemvm/patches/debian/config/opt/cloud/bin/vr_cfg.sh
new file mode 100755
index 0000000..8994a06
--- /dev/null
+++ b/systemvm/patches/debian/config/opt/cloud/bin/vr_cfg.sh
@@ -0,0 +1,96 @@
+#!/bin/bash
+# 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.
+
+#set -x
+
+cfg=
+version=
+log=/var/log/cloud.log
+
+log_it() {
+    logger -t cloud "$*"
+    echo "$(date) : $*" >> $log
+}
+
+while getopts 'c:' OPTION
+do
+  case $OPTION in
+      c) cfg="$OPTARG"
+          ;;
+  esac
+done
+
+while read line
+do
+    #comment
+    if [[ $line == \#* ]]
+    then
+	    continue
+    fi
+
+    if [ "$line" == "<version>" ]
+    then
+        read line
+        version=$line
+        log_it "VR config: configuation format version $version"
+        #skip </version>
+        read line
+        continue
+    fi
+
+    if [ "$line" == "<script>" ]
+    then
+        read line
+        log_it "VR config: executing: $line"
+        eval $line >> $log 2>&1
+        if [ $? -ne 0 ]
+        then
+            log_it "VR config: executing failed: $line"
+            # expose error info to mgmt server
+            echo "VR config: execution failed: \"$line\", check $log in VR for details "
+            exit 1
+        fi
+        #skip </script>
+        read line
+        log_it "VR config: execution success "
+        continue
+    fi
+
+    if [ "$line" == "<file>" ]
+    then
+        read line
+        file=$line
+        log_it "VR config: creating file: $file"
+        rm -f $file
+        while read line
+        do
+            if [ "$line" == "</file>" ]
+            then
+                break
+            fi
+            echo $line >> $file
+        done
+        log_it "VR config: create file success"
+        continue
+    fi
+done < $cfg
+
+#remove the configuration file, log file should have all the records as well
+rm -f $cfg
+
+exit 0


[29/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
Bug-Id: CS-19455 Add support for Hyper-v in regression test test_routers.py

Signed-off-by: sanjeevneelarapu <sa...@citrix.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/4eece72e
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/4eece72e
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/4eece72e

Branch: refs/heads/distributedrouter
Commit: 4eece72eb178d468e4b86c371e88d5f1ff4dde93
Parents: 3f7b628
Author: sanjeevneelarapu <sa...@citrix.com>
Authored: Mon Mar 10 17:56:22 2014 +0530
Committer: sanjeevneelarapu <sa...@citrix.com>
Committed: Mon Mar 10 18:12:21 2014 +0530

----------------------------------------------------------------------
 test/integration/component/test_routers.py   | 28 +++++++++++------------
 tools/marvin/marvin/integration/lib/utils.py |  3 ++-
 2 files changed, 16 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4eece72e/test/integration/component/test_routers.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_routers.py b/test/integration/component/test_routers.py
index f8359f0..ced3f52 100644
--- a/test/integration/component/test_routers.py
+++ b/test/integration/component/test_routers.py
@@ -1254,21 +1254,10 @@ class TestRouterStopCreateFW(cloudstackTestCase):
                     str(self.services["fw_rule"]["endport"]),
                     "Check end port of firewall rule"
                     )
-        hosts = list_hosts(
-                           self.apiclient,
-                           id=router.hostid,
-                           )
-        self.assertEqual(
-                        isinstance(hosts, list),
-                        True,
-                        "Check for list hosts response return valid data"
-                        )
-        host = hosts[0]
-        host.user, host.passwd = get_host_credentials(self.config, host.ipaddress)
-
         # For DNS and DHCP check 'dnsmasq' process status
-        if self.apiclient.hypervisor.lower() == 'vmware':
-               result = get_process_status(
+        if (self.apiclient.hypervisor.lower() == 'vmware'
+                         or self.apiclient.hypervisor.lower() == 'hyperv'):
+            result = get_process_status(
                                self.apiclient.connection.mgtSvr,
                                22,
                                self.apiclient.connection.user,
@@ -1278,6 +1267,17 @@ class TestRouterStopCreateFW(cloudstackTestCase):
                                 hypervisor=self.apiclient.hypervisor
                                )
         else:
+            hosts = list_hosts(
+                        self.apiclient,
+                        id=router.hostid,
+                        )
+            self.assertEqual(
+                        isinstance(hosts, list),
+                        True,
+                        "Check for list hosts response return valid data"
+                        )
+            host = hosts[0]
+            host.user, host.passwd = get_host_credentials(self.config, host.ipaddress)
             try:
                 result = get_process_status(
                     host.ipaddress,

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4eece72e/tools/marvin/marvin/integration/lib/utils.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/integration/lib/utils.py b/tools/marvin/marvin/integration/lib/utils.py
index e870158..709fdde 100644
--- a/tools/marvin/marvin/integration/lib/utils.py
+++ b/tools/marvin/marvin/integration/lib/utils.py
@@ -191,7 +191,8 @@ def get_process_status(hostip, port, username, password, linklocalip, process, h
 
     #SSH to the machine
     ssh = SshClient(hostip, port, username, password)
-    if str(hypervisor).lower() == 'vmware':
+    if (str(hypervisor).lower() == 'vmware'
+		or str(hypervisor).lower() == 'hyperv'):
         ssh_command = "ssh -i /var/cloudstack/management/.ssh/id_rsa -ostricthostkeychecking=no "
     else:
         ssh_command = "ssh -i ~/.ssh/id_rsa.cloud -ostricthostkeychecking=no "


[15/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
CLOUDSTACK-6170


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c427e8db
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c427e8db
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c427e8db

Branch: refs/heads/distributedrouter
Commit: c427e8db1c4294bec93aa9295052950888c0fecf
Parents: e37a6cd
Author: Mike Tutkowski <mi...@solidfire.com>
Authored: Thu Mar 6 14:00:56 2014 -0700
Committer: Mike Tutkowski <mi...@solidfire.com>
Committed: Fri Mar 7 15:38:50 2014 -0700

----------------------------------------------------------------------
 .../com/cloud/offering/DiskOfferingInfo.java    | 47 ++++++++++++++++++
 .../api/command/user/vm/DeployVMCmd.java        | 50 ++++++++++++++++++++
 .../src/com/cloud/vm/VirtualMachineManager.java |  4 +-
 .../service/VolumeOrchestrationService.java     |  2 +-
 .../com/cloud/vm/VirtualMachineManagerImpl.java | 11 +++--
 .../engine/orchestration/CloudOrchestrator.java | 40 ++++++++++++----
 .../orchestration/VolumeOrchestrator.java       | 10 ++--
 ui/css/cloudstack3.css                          | 40 ++++++++++++++++
 ui/index.jsp                                    | 11 +++++
 ui/scripts/instanceWizard.js                    | 16 ++++++-
 ui/scripts/ui-custom/instanceWizard.js          |  8 ++++
 11 files changed, 218 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c427e8db/api/src/com/cloud/offering/DiskOfferingInfo.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/offering/DiskOfferingInfo.java b/api/src/com/cloud/offering/DiskOfferingInfo.java
new file mode 100644
index 0000000..e9e7da1
--- /dev/null
+++ b/api/src/com/cloud/offering/DiskOfferingInfo.java
@@ -0,0 +1,47 @@
+package com.cloud.offering;
+
+public class DiskOfferingInfo {
+    private DiskOffering _diskOffering;
+    private Long _size;
+    private Long _minIops;
+    private Long _maxIops;
+
+    public DiskOfferingInfo() {
+    }
+
+    public DiskOfferingInfo(DiskOffering diskOffering) {
+        _diskOffering = diskOffering;
+    }
+
+    public void setDiskOffering(DiskOffering diskOffering) {
+        _diskOffering = diskOffering;
+    }
+
+    public DiskOffering getDiskOffering() {
+        return _diskOffering;
+    }
+
+    public void setSize(Long size) {
+        _size = size;
+    }
+
+    public Long getSize() {
+        return _size;
+    }
+
+    public void setMinIops(Long minIops) {
+        _minIops = minIops;
+    }
+
+    public Long getMinIops() {
+        return _minIops;
+    }
+
+    public void setMaxIops(Long maxIops) {
+        _maxIops = maxIops;
+    }
+
+    public Long getMaxIops() {
+        return _maxIops;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c427e8db/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
index d33e04e..bd363da 100755
--- a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
@@ -462,12 +462,62 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd {
         }
     }
 
+    // this is an opportunity to verify that parameters that came in via the Details Map are OK
+    // for example, minIops and maxIops should either both be specified or neither be specified and,
+    // if specified, minIops should be <= maxIops
+    private void verifyDetails() {
+        Map<String, String> map = getDetails();
+
+        if (map != null) {
+            String minIops = (String)map.get("minIops");
+            String maxIops = (String)map.get("maxIops");
+
+            if ((minIops != null && maxIops == null) || (minIops == null && maxIops != null)) {
+                throw new InvalidParameterValueException("Either 'Min IOPS' and 'Max IOPS' must both be specified or neither be specified.");
+            }
+
+            long lMinIops;
+
+            try {
+                if (minIops != null) {
+                    lMinIops = Long.valueOf(minIops);
+                }
+                else {
+                    lMinIops = 0;
+                }
+            }
+            catch (NumberFormatException ex) {
+                throw new InvalidParameterValueException("'Min IOPS' must be a whole number.");
+            }
+
+            long lMaxIops;
+
+            try {
+                if (maxIops != null) {
+                    lMaxIops = Long.valueOf(maxIops);
+                }
+                else {
+                    lMaxIops = 0;
+                }
+            }
+            catch (NumberFormatException ex) {
+                throw new InvalidParameterValueException("'Max IOPS' must be a whole number.");
+            }
+
+            if (lMinIops > lMaxIops) {
+                throw new InvalidParameterValueException("'Min IOPS' must be less than or equal to 'Max IOPS'.");
+            }
+        }
+    }
+
     @Override
     public void create() throws ResourceAllocationException {
         try {
             //Verify that all objects exist before passing them to the service
             Account owner = _accountService.getActiveAccountById(getEntityOwnerId());
 
+            verifyDetails();
+
             DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
             if (zone == null) {
                 throw new InvalidParameterValueException("Unable to find zone by id=" + zoneId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c427e8db/engine/api/src/com/cloud/vm/VirtualMachineManager.java
----------------------------------------------------------------------
diff --git a/engine/api/src/com/cloud/vm/VirtualMachineManager.java b/engine/api/src/com/cloud/vm/VirtualMachineManager.java
index 3535a32..350f396 100644
--- a/engine/api/src/com/cloud/vm/VirtualMachineManager.java
+++ b/engine/api/src/com/cloud/vm/VirtualMachineManager.java
@@ -37,11 +37,11 @@ import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.network.Network;
 import com.cloud.offering.DiskOffering;
+import com.cloud.offering.DiskOfferingInfo;
 import com.cloud.offering.ServiceOffering;
 import com.cloud.storage.StoragePool;
 import com.cloud.storage.Volume;
 import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.utils.Pair;
 import com.cloud.utils.component.Manager;
 import com.cloud.utils.fsm.NoTransitionException;
 
@@ -76,7 +76,7 @@ public interface VirtualMachineManager extends Manager {
      * @param hyperType Hypervisor type
      * @throws InsufficientCapacityException If there are insufficient capacity to deploy this vm.
      */
-    void allocate(String vmInstanceName, VirtualMachineTemplate template, ServiceOffering serviceOffering, Pair<? extends DiskOffering, Long> rootDiskOffering,
+    void allocate(String vmInstanceName, VirtualMachineTemplate template, ServiceOffering serviceOffering, DiskOfferingInfo rootDiskOfferingInfo,
         LinkedHashMap<? extends DiskOffering, Long> dataDiskOfferings, LinkedHashMap<? extends Network, List<? extends NicProfile>> auxiliaryNetworks, DeploymentPlan plan,
         HypervisorType hyperType) throws InsufficientCapacityException;
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c427e8db/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
index f79d336..2531074 100644
--- a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
+++ b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
@@ -106,7 +106,7 @@ public interface VolumeOrchestrationService {
 
     boolean canVmRestartOnAnotherServer(long vmId);
 
-    DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering offering, Long rootDisksize, VirtualMachineTemplate template, VirtualMachine vm,
+    DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering offering, Long rootDisksize, Long minIops, Long maxIops, VirtualMachineTemplate template, VirtualMachine vm,
         Account owner);
 
     String getVmNameFromVolumeId(long volumeId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c427e8db/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
index c13cde7..8edbb76 100755
--- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -154,6 +154,7 @@ import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.dao.NetworkVO;
 import com.cloud.network.rules.RulesManager;
 import com.cloud.offering.DiskOffering;
+import com.cloud.offering.DiskOfferingInfo;
 import com.cloud.offering.ServiceOffering;
 import com.cloud.org.Cluster;
 import com.cloud.resource.ResourceManager;
@@ -372,7 +373,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     @Override
     @DB
     public void allocate(String vmInstanceName, final VirtualMachineTemplate template, ServiceOffering serviceOffering,
-            final Pair<? extends DiskOffering, Long> rootDiskOffering, LinkedHashMap<? extends DiskOffering, Long> dataDiskOfferings,
+            final DiskOfferingInfo rootDiskOfferingInfo, LinkedHashMap<? extends DiskOffering, Long> dataDiskOfferings,
             final LinkedHashMap<? extends Network, List<? extends NicProfile>> auxiliaryNetworks, DeploymentPlan plan, HypervisorType hyperType)
                     throws InsufficientCapacityException {
 
@@ -412,11 +413,13 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
                         }
 
                         if (template.getFormat() == ImageFormat.ISO) {
-                            volumeMgr.allocateRawVolume(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOffering.first(), rootDiskOffering.second(), vmFinal, template, owner);
+                            volumeMgr.allocateRawVolume(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOfferingInfo.getDiskOffering(), rootDiskOfferingInfo.getSize(), vmFinal,
+                                    template, owner);
                         } else if (template.getFormat() == ImageFormat.BAREMETAL) {
                             // Do nothing
                         } else {
-                            volumeMgr.allocateTemplatedVolume(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOffering.first(), rootDiskOffering.second(), template, vmFinal, owner);
+                            volumeMgr.allocateTemplatedVolume(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOfferingInfo.getDiskOffering(), rootDiskOfferingInfo.getSize(),
+                                    rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), template, vmFinal, owner);
                         }
 
                         for (Map.Entry<? extends DiskOffering, Long> offering : dataDiskOfferingsFinal.entrySet()) {
@@ -433,7 +436,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     @Override
     public void allocate(String vmInstanceName, VirtualMachineTemplate template, ServiceOffering serviceOffering,
             LinkedHashMap<? extends Network, List<? extends NicProfile>> networks, DeploymentPlan plan, HypervisorType hyperType) throws InsufficientCapacityException {
-        allocate(vmInstanceName, template, serviceOffering, new Pair<DiskOffering, Long>(serviceOffering, null), null, networks, plan, hyperType);
+        allocate(vmInstanceName, template, serviceOffering, new DiskOfferingInfo(serviceOffering), null, networks, plan, hyperType);
     }
 
     private VirtualMachineGuru getVmGuru(VirtualMachine vm) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c427e8db/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java
index b00b5ad..7969e43 100755
--- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java
@@ -46,18 +46,19 @@ import com.cloud.network.Network;
 import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.dao.NetworkVO;
 import com.cloud.offering.DiskOffering;
+import com.cloud.offering.DiskOfferingInfo;
 import com.cloud.service.ServiceOfferingVO;
 import com.cloud.service.dao.ServiceOfferingDao;
 import com.cloud.storage.DiskOfferingVO;
 import com.cloud.storage.dao.DiskOfferingDao;
 import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.Pair;
 import com.cloud.utils.component.ComponentContext;
 import com.cloud.vm.NicProfile;
 import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachineManager;
 import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.UserVmDetailsDao;
 import com.cloud.vm.dao.VMInstanceDao;
 
 @Component
@@ -79,6 +80,9 @@ public class CloudOrchestrator implements OrchestrationService {
     protected UserVmDao _userVmDao = null;
 
     @Inject
+    protected UserVmDetailsDao _userVmDetailsDao = null;
+
+    @Inject
     protected ServiceOfferingDao _serviceOfferingDao;
 
     @Inject
@@ -176,12 +180,25 @@ public class CloudOrchestrator implements OrchestrationService {
         // If the template represents an ISO, a disk offering must be passed in, and will be used to create the root disk
         // Else, a disk offering is optional, and if present will be used to create the data disk
 
-        Pair<DiskOfferingVO, Long> rootDiskOffering = new Pair<DiskOfferingVO, Long>(null, null);
+        DiskOfferingInfo rootDiskOfferingInfo = new DiskOfferingInfo();
         LinkedHashMap<DiskOfferingVO, Long> dataDiskOfferings = new LinkedHashMap<DiskOfferingVO, Long>();
 
         ServiceOfferingVO offering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
-        rootDiskOffering.first(offering);
-        rootDiskOffering.second(rootDiskSize);
+
+        rootDiskOfferingInfo.setDiskOffering(offering);
+        rootDiskOfferingInfo.setSize(rootDiskSize);
+
+        if (offering.isCustomizedIops()) {
+            Map<String, String> userVmDetails = _userVmDetailsDao.listDetailsKeyPairs(vm.getId());
+
+            if (userVmDetails != null) {
+                String minIops = userVmDetails.get("minIops");
+                String maxIops = userVmDetails.get("maxIops");
+
+                rootDiskOfferingInfo.setMinIops(minIops != null && minIops.trim().length() > 0 ? Long.parseLong(minIops) : null);
+                rootDiskOfferingInfo.setMaxIops(maxIops != null && maxIops.trim().length() > 0 ? Long.parseLong(maxIops) : null);
+            }
+        }
 
         if (vm.getDiskOfferingId() != null) {
             DiskOfferingVO diskOffering = _diskOfferingDao.findById(vm.getDiskOfferingId());
@@ -199,7 +216,7 @@ public class CloudOrchestrator implements OrchestrationService {
             dataDiskOfferings.put(diskOffering, size);
         }
 
-        _itMgr.allocate(vm.getInstanceName(), _templateDao.findById(new Long(templateId)), offering, rootDiskOffering, dataDiskOfferings, networkIpMap, plan,
+        _itMgr.allocate(vm.getInstanceName(), _templateDao.findById(new Long(templateId)), offering, rootDiskOfferingInfo, dataDiskOfferings, networkIpMap, plan,
             hypervisorType);
 
         return vmEntity;
@@ -217,9 +234,11 @@ public class CloudOrchestrator implements OrchestrationService {
         //load vm instance and offerings and call virtualMachineManagerImpl
         VMInstanceVO vm = _vmDao.findByUuid(id);
 
-        Pair<DiskOffering, Long> rootDiskOffering = new Pair<DiskOffering, Long>(null, null);
         ServiceOfferingVO offering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
-        rootDiskOffering.first(offering);
+
+        DiskOfferingInfo rootDiskOfferingInfo = new DiskOfferingInfo();
+
+        rootDiskOfferingInfo.setDiskOffering(offering);
 
         LinkedHashMap<DiskOffering, Long> dataDiskOfferings = new LinkedHashMap<DiskOffering, Long>();
         Long diskOfferingId = vm.getDiskOfferingId();
@@ -238,8 +257,9 @@ public class CloudOrchestrator implements OrchestrationService {
             }
             _volumeMgr.validateVolumeSizeRange(size * 1024 * 1024 * 1024);
         }
-        rootDiskOffering.first(diskOffering);
-        rootDiskOffering.second(size);
+
+        rootDiskOfferingInfo.setDiskOffering(diskOffering);
+        rootDiskOfferingInfo.setSize(size);
 
         LinkedHashMap<Network, List<? extends NicProfile>> networkIpMap = new LinkedHashMap<Network, List<? extends NicProfile>>();
         for (String uuid : networkNicMap.keySet()) {
@@ -251,7 +271,7 @@ public class CloudOrchestrator implements OrchestrationService {
 
         HypervisorType hypervisorType = HypervisorType.valueOf(hypervisor);
 
-        _itMgr.allocate(vm.getInstanceName(), _templateDao.findById(new Long(isoId)), offering, rootDiskOffering, dataDiskOfferings, networkIpMap, plan, hypervisorType);
+        _itMgr.allocate(vm.getInstanceName(), _templateDao.findById(new Long(isoId)), offering, rootDiskOfferingInfo, dataDiskOfferings, networkIpMap, plan, hypervisorType);
 
         return vmEntity;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c427e8db/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
----------------------------------------------------------------------
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 4d0c787..f3753a7 100644
--- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
@@ -605,15 +605,19 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
     }
 
     @Override
-    public DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering offering, Long rootDisksize, VirtualMachineTemplate template, VirtualMachine vm, Account owner) {
+    public DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering offering, Long rootDisksize, Long minIops, Long maxIops, VirtualMachineTemplate template, VirtualMachine vm, Account owner) {
         assert (template.getFormat() != ImageFormat.ISO) : "ISO is not a template really....";
 
         Long size = _tmpltMgr.getTemplateSize(template.getId(), vm.getDataCenterId());
         if (rootDisksize != null) {
             size = (rootDisksize * 1024 * 1024 * 1024);
         }
-        VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterId(), owner.getDomainId(), owner.getId(), offering.getId(), size, offering.getMinIops(), offering.getMaxIops(),
-                null);
+
+        minIops = minIops != null ? minIops : offering.getMinIops();
+        maxIops = maxIops != null ? maxIops : offering.getMaxIops();
+
+        VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterId(), owner.getDomainId(), owner.getId(), offering.getId(), size, minIops, maxIops, null);
+
         vol.setFormat(getSupportedImageFormatForCluster(template.getHypervisorType()));
         if (vm != null) {
             vol.setInstanceId(vm.getId());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c427e8db/ui/css/cloudstack3.css
----------------------------------------------------------------------
diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css
index 162f77b..11c1c7e 100644
--- a/ui/css/cloudstack3.css
+++ b/ui/css/cloudstack3.css
@@ -6050,6 +6050,13 @@ label.error {
   border-radius: 4px;
 }
 
+.multi-wizard.instance-wizard .section.custom-iops {
+  position: relative;
+  background: #F4F4F4;
+  padding: 7px;
+  border-radius: 4px;
+}
+
 .multi-wizard.instance-wizard .section.custom-size input[type=radio] {
   float: left;
 }
@@ -6060,6 +6067,12 @@ label.error {
   margin: 6px -1px 0 8px;
 }
 
+.multi-wizard.instance-wizard .section.custom-iops input[type=text] {
+  float: left;
+  width: 28px;
+  margin: 6px -1px 0 8px;
+}
+
 .multi-wizard.instance-wizard .section.custom-size label.error {
   position: absolute;
   top: 29px;
@@ -6075,29 +6088,56 @@ label.error {
   height: 235px;
 }
 
+.instance-wizard .step.service-offering.custom-iops .select-container {
+  height: 235px;
+}
+
 .instance-wizard .step.service-offering .custom-size {
   display: none;
 }
 
+.instance-wizard .step.service-offering .custom-iops {
+  display: none;
+}
+
 .instance-wizard .step.service-offering.custom-size .custom-size {
   display: block;
 }
 
+.instance-wizard .step.service-offering.custom-iops .custom-iops {
+  display: block;
+}
+
 .instance-wizard .step.service-offering .custom-size .field {
   width: 30%;
   float: left;
   margin-bottom: 13px;
 }
 
+.instance-wizard .step.service-offering .custom-iops .field {
+  width: 30%;
+  float: left;
+  margin-bottom: 13px;
+}
+
 .instance-wizard .step.service-offering .custom-size .field label {
   text-indent: 20px;
 }
 
+.instance-wizard .step.service-offering .custom-iops .field label {
+  text-indent: 20px;
+}
+
 .instance-wizard .step.service-offering .custom-size .field input {
   width: 88%;
   margin-left: 26px;
 }
 
+.instance-wizard .step.service-offering .custom-iops .field input {
+  width: 88%;
+  margin-left: 26px;
+}
+
 /*** Network*/
 .multi-wizard.instance-wizard .no-network {
   background: #FFFFFF;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c427e8db/ui/index.jsp
----------------------------------------------------------------------
diff --git a/ui/index.jsp b/ui/index.jsp
index 4daa9eb..d46c395 100644
--- a/ui/index.jsp
+++ b/ui/index.jsp
@@ -221,6 +221,17 @@
                                         <input type="text" class="required disallowSpecialCharacters" name="compute-memory" />
                                     </div>
                                 </div>
+                                <!-- Custom iops slider -->
+                                <div class="section custom-iops">
+                                    <div class="field">
+                                        <label><fmt:message key="label.disk.iops.min"/></label>
+                                        <input type="text" class="disallowSpecialCharacters" name="disk-min-iops" />
+                                    </div>
+                                    <div class="field">
+                                        <label><fmt:message key="label.disk.iops.max"/></label>
+                                        <input type="text" class="disallowSpecialCharacters" name="disk-max-iops" />
+                                    </div>
+                                </div>
                             </div>
                         </div>
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c427e8db/ui/scripts/instanceWizard.js
----------------------------------------------------------------------
diff --git a/ui/scripts/instanceWizard.js b/ui/scripts/instanceWizard.js
index 3ee9af1..5c04d0e 100644
--- a/ui/scripts/instanceWizard.js
+++ b/ui/scripts/instanceWizard.js
@@ -301,6 +301,7 @@
                         args.response.success({
                             customFlag: 'iscustomized',
                         	//customFlag: 'offerha', //for testing only
+                        	customIopsFlag: 'iscustomizediops',
                             data: {
                                 serviceOfferings: serviceOfferingObjs
                             }
@@ -631,7 +632,20 @@
 	            	});
 	            }               
             }
-            
+
+            if (args.$wizard.find('input[name=disk-min-iops]').parent().parent().css('display') != 'none') {
+	            if (args.$wizard.find('input[name=disk-min-iops]').val().length > 0) {
+	            	$.extend(deployVmData, {
+	            	    'details[0].minIops' : args.$wizard.find('input[name=disk-min-iops]').val()
+	            	});
+	            }
+	            if (args.$wizard.find('input[name=disk-max-iops]').val().length > 0) {
+	            	$.extend(deployVmData, {
+	            	    'details[0].maxIops' : args.$wizard.find('input[name=disk-max-iops]').val()
+	            	});
+	            }
+            }
+
             //step 4: select disk offering
             if (args.data.diskofferingid != null && args.data.diskofferingid != "0") {                
             	$.extend(deployVmData, {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c427e8db/ui/scripts/ui-custom/instanceWizard.js
----------------------------------------------------------------------
diff --git a/ui/scripts/ui-custom/instanceWizard.js b/ui/scripts/ui-custom/instanceWizard.js
index 8884ebe..f5f7b10 100644
--- a/ui/scripts/ui-custom/instanceWizard.js
+++ b/ui/scripts/ui-custom/instanceWizard.js
@@ -458,6 +458,14 @@
                                             $step.removeClass('custom-size');
                                         }
 
+                                        var customIops = item[args.customIopsFlag];
+
+                                        if (customIops) {
+                                            $step.addClass('custom-iops');
+                                        } else {
+                                            $step.removeClass('custom-iops');
+                                        }
+
                                         return true;
                                     });
 


[17/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
CLOUDSTACK-5478: Enable publishing uuid for all the async apis in the CallContext.
The advantage would be that event publishing can pick up the uuid and publish them.


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/ded7e682
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/ded7e682
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/ded7e682

Branch: refs/heads/distributedrouter
Commit: ded7e682dc0a84f41c9953522016a86f4948ea35
Parents: 548c810
Author: Nitin Mehta <ni...@citrix.com>
Authored: Fri Mar 7 16:50:21 2014 -0800
Committer: Nitin Mehta <ni...@citrix.com>
Committed: Fri Mar 7 16:50:21 2014 -0800

----------------------------------------------------------------------
 api/src/com/cloud/event/EventTypes.java          |  5 +++++
 server/src/com/cloud/api/ApiDispatcher.java      |  7 +++++++
 server/src/com/cloud/api/ApiServer.java          | 11 ++++++++++-
 server/src/com/cloud/event/ActionEventUtils.java | 12 ++++++++----
 server/src/com/cloud/vm/UserVmManagerImpl.java   |  1 -
 5 files changed, 30 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ded7e682/api/src/com/cloud/event/EventTypes.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java
index ec54ea1..7994ada 100755
--- a/api/src/com/cloud/event/EventTypes.java
+++ b/api/src/com/cloud/event/EventTypes.java
@@ -493,10 +493,13 @@ public class EventTypes {
         entityEventDetails.put(EVENT_VM_REBOOT, VirtualMachine.class.getName());
         entityEventDetails.put(EVENT_VM_UPDATE, VirtualMachine.class.getName());
         entityEventDetails.put(EVENT_VM_UPGRADE, VirtualMachine.class.getName());
+        entityEventDetails.put(EVENT_VM_DYNAMIC_SCALE, VirtualMachine.class.getName());
         entityEventDetails.put(EVENT_VM_RESETPASSWORD, VirtualMachine.class.getName());
+        entityEventDetails.put(EVENT_VM_RESETSSHKEY, VirtualMachine.class.getName());
         entityEventDetails.put(EVENT_VM_MIGRATE, VirtualMachine.class.getName());
         entityEventDetails.put(EVENT_VM_MOVE, VirtualMachine.class.getName());
         entityEventDetails.put(EVENT_VM_RESTORE, VirtualMachine.class.getName());
+        entityEventDetails.put(EVENT_VM_EXPUNGE, VirtualMachine.class.getName());
 
         entityEventDetails.put(EVENT_ROUTER_CREATE, VirtualRouter.class.getName());
         entityEventDetails.put(EVENT_ROUTER_DESTROY, VirtualRouter.class.getName());
@@ -544,9 +547,11 @@ public class EventTypes {
         entityEventDetails.put(EVENT_LB_CERT_REMOVE, LoadBalancer.class.getName());
 
         // Account events
+        entityEventDetails.put(EVENT_ACCOUNT_ENABLE, Account.class.getName());
         entityEventDetails.put(EVENT_ACCOUNT_DISABLE, Account.class.getName());
         entityEventDetails.put(EVENT_ACCOUNT_CREATE, Account.class.getName());
         entityEventDetails.put(EVENT_ACCOUNT_DELETE, Account.class.getName());
+        entityEventDetails.put(EVENT_ACCOUNT_UPDATE, Account.class.getName());
         entityEventDetails.put(EVENT_ACCOUNT_MARK_DEFAULT_ZONE, Account.class.getName());
 
         // UserVO Events

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ded7e682/server/src/com/cloud/api/ApiDispatcher.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java
index 5d4b4d3..8f980d9 100755
--- a/server/src/com/cloud/api/ApiDispatcher.java
+++ b/server/src/com/cloud/api/ApiDispatcher.java
@@ -21,6 +21,7 @@ import java.util.Map;
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 
+import com.cloud.event.EventTypes;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.BaseAsyncCmd;
 import org.apache.cloudstack.api.BaseAsyncCreateCmd;
@@ -82,8 +83,14 @@ public class ApiDispatcher {
 
             final BaseAsyncCmd asyncCmd = (BaseAsyncCmd)cmd;
             final String startEventId = params.get(ApiConstants.CTX_START_EVENT_ID);
+            String uuid = params.get("uuid");
             ctx.setStartEventId(Long.valueOf(startEventId));
 
+            // Fow now use the key from EventTypes.java rather than getInstanceType bcz the later doesn't refer to the interfaces
+            if(EventTypes.getEntityForEvent(asyncCmd.getEventType()) != null){
+                ctx.putContextParameter(EventTypes.getEntityForEvent(asyncCmd.getEventType()), uuid);
+            }
+
             // Synchronise job on the object if needed
             if (asyncCmd.getJob() != null && asyncCmd.getSyncObjId() != null && asyncCmd.getSyncObjType() != null) {
                 Long queueSizeLimit = null;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ded7e682/server/src/com/cloud/api/ApiServer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java
index a9b1130..7ad7c10 100755
--- a/server/src/com/cloud/api/ApiServer.java
+++ b/server/src/com/cloud/api/ApiServer.java
@@ -53,6 +53,7 @@ import javax.naming.ConfigurationException;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 
+import com.cloud.event.EventTypes;
 import org.apache.cloudstack.acl.APIChecker;
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
@@ -517,6 +518,8 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
                 objectUuid = createCmd.getEntityUuid();
                 params.put("id", objectId.toString());
             } else {
+                // Extract the uuid before params are processed and id reflects internal db id
+                objectUuid = params.get("id");
                 dispatchChainFactory.getStandardDispatchChain().dispatch(new DispatchTask(cmdObj, params));
             }
 
@@ -528,10 +531,16 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
             if (caller != null) {
                 params.put("ctxAccountId", String.valueOf(caller.getId()));
             }
+            if(objectUuid != null){
+                params.put("uuid", objectUuid);
+            }
 
             long startEventId = ctx.getStartEventId();
             asyncCmd.setStartEventId(startEventId);
 
+            if(EventTypes.getEntityForEvent(asyncCmd.getEventType()) != null){
+                ctx.putContextParameter(EventTypes.getEntityForEvent(asyncCmd.getEventType()), objectUuid);
+            }
             // save the scheduled event
             final Long eventId =
                 ActionEventUtils.onScheduledActionEvent((callerUserId == null) ? User.UID_SYSTEM : callerUserId, asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(),
@@ -577,7 +586,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
                 !(cmdObj instanceof ListVolumesCmd) && !(cmdObj instanceof ListUsersCmd) && !(cmdObj instanceof ListAccountsCmd) &&
                 !(cmdObj instanceof ListStoragePoolsCmd) && !(cmdObj instanceof ListDiskOfferingsCmd) && !(cmdObj instanceof ListServiceOfferingsCmd) &&
                 !(cmdObj instanceof ListZonesByCmd)) {
-                buildAsyncListResponse((BaseListCmd)cmdObj, caller);
+                buildAsyncListResponse((BaseListCmd) cmdObj, caller);
             }
 
             SerializationContext.current().setUuidTranslation(true);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ded7e682/server/src/com/cloud/event/ActionEventUtils.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/event/ActionEventUtils.java b/server/src/com/cloud/event/ActionEventUtils.java
index 9724d99..5954670 100755
--- a/server/src/com/cloud/event/ActionEventUtils.java
+++ b/server/src/com/cloud/event/ActionEventUtils.java
@@ -25,7 +25,6 @@ import java.util.Map;
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 
-import com.cloud.vm.VirtualMachine;
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 
@@ -186,13 +185,19 @@ public class ActionEventUtils {
         // get the entity details for which ActionEvent is generated
         String entityType = null;
         String entityUuid = null;
+        CallContext context = CallContext.current();
         Class entityKey = getEntityKey(eventType);
         if (entityKey != null)
         {
-            CallContext context = CallContext.current();
+            //FIXME - Remove this
             entityUuid = (String)context.getContextParameter(entityKey);
             if (entityUuid != null)
                 entityType = entityKey.getName();
+        }else if (EventTypes.getEntityForEvent(eventType) != null){
+            entityType = EventTypes.getEntityForEvent(eventType);
+            if (entityType != null){
+                entityUuid = (String)context.getContextParameter(entityType);
+            }
         }
 
         org.apache.cloudstack.framework.events.Event event =
@@ -240,6 +245,7 @@ public class ActionEventUtils {
 
     private static Class getEntityKey(String eventType)
     {
+        // FIXME - Remove this
         if (eventType.startsWith("DOMAIN."))
         {
             return Domain.class;
@@ -251,8 +257,6 @@ public class ActionEventUtils {
         else if (eventType.startsWith("USER."))
         {
             return User.class;
-        }else if (eventType.startsWith("VM.")){
-            return VirtualMachine.class;
         }
 
         return null;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ded7e682/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 9c38430..d1df3c1 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -2982,7 +2982,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
         long vmId = cmd.getEntityId();
         Long hostId = cmd.getHostId();
         UserVmVO vm = _vmDao.findById(vmId);
-        CallContext.current().putContextParameter(VirtualMachine.class, vm.getUuid());
 
         Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> vmParamPair = null;
         try {


[13/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
Removed unused methods from BaseCmd class. Moved some helper methods to AccountManagerImpl class


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/7b0c5cfc
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/7b0c5cfc
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/7b0c5cfc

Branch: refs/heads/distributedrouter
Commit: 7b0c5cfcbe678fee006f7e00d116fb892b264f2f
Parents: c257fb0
Author: Alena Prokharchyk <al...@citrix.com>
Authored: Fri Mar 7 09:59:12 2014 -0800
Committer: Alena Prokharchyk <al...@citrix.com>
Committed: Fri Mar 7 11:33:10 2014 -0800

----------------------------------------------------------------------
 api/src/com/cloud/server/ManagementService.java |   4 -
 api/src/com/cloud/user/AccountService.java      |   2 +
 .../org/apache/cloudstack/api/BaseAsyncCmd.java |  36 -------
 api/src/org/apache/cloudstack/api/BaseCmd.java  | 100 ++-----------------
 .../BaseListTemplateOrIsoPermissionsCmd.java    |   5 +-
 .../api/command/admin/user/CreateUserCmd.java   |   5 +-
 .../affinitygroup/CreateAffinityGroupCmd.java   |   5 +-
 .../affinitygroup/DeleteAffinityGroupCmd.java   |   5 +-
 .../user/autoscale/CreateConditionCmd.java      |   5 +-
 .../api/command/user/iso/ListIsosCmd.java       |   5 +-
 .../api/command/user/iso/RegisterIsoCmd.java    |   5 +-
 .../command/user/network/CreateNetworkCmd.java  |   2 +-
 .../gslb/CreateGlobalLoadBalancerRuleCmd.java   |   5 +-
 .../user/resource/ListResourceLimitsCmd.java    |   5 +-
 .../user/resource/UpdateResourceCountCmd.java   |   7 +-
 .../user/resource/UpdateResourceLimitCmd.java   |   7 +-
 .../AuthorizeSecurityGroupEgressCmd.java        |   5 +-
 .../AuthorizeSecurityGroupIngressCmd.java       |   5 +-
 .../securitygroup/CreateSecurityGroupCmd.java   |   5 +-
 .../securitygroup/DeleteSecurityGroupCmd.java   |   5 +-
 .../command/user/ssh/CreateSSHKeyPairCmd.java   |   5 +-
 .../command/user/ssh/DeleteSSHKeyPairCmd.java   |   5 +-
 .../command/user/ssh/RegisterSSHKeyPairCmd.java |   5 +-
 .../command/user/template/ListTemplatesCmd.java |   5 +-
 .../user/template/RegisterTemplateCmd.java      |   5 +-
 .../api/command/user/vm/DeployVMCmd.java        |   2 +-
 .../command/user/vmgroup/CreateVMGroupCmd.java  |   5 +-
 .../command/user/volume/CreateVolumeCmd.java    |   2 +-
 .../command/user/volume/UploadVolumeCmd.java    |   5 +-
 .../api/command/user/vpc/CreateVPCCmd.java      |   2 +-
 .../api/command/user/vpn/AddVpnUserCmd.java     |   5 +-
 .../user/vpn/CreateVpnCustomerGatewayCmd.java   |   5 +-
 .../api/command/user/vpn/RemoveVpnUserCmd.java  |   5 +-
 .../command/user/vpn/ResetVpnConnectionCmd.java |   5 +-
 .../user/vpn/UpdateVpnCustomerGatewayCmd.java   |   5 +-
 .../api/command/CreateServiceInstanceCmd.java   |   2 +-
 .../contrail/management/MockAccountManager.java |   9 +-
 server/src/com/cloud/acl/DomainChecker.java     |   8 +-
 server/src/com/cloud/api/ApiServer.java         |  61 ++++++-----
 .../api/query/dao/TemplateJoinDaoImpl.java      |  13 +--
 .../com/cloud/server/ManagementServerImpl.java  |  10 --
 .../src/com/cloud/user/AccountManagerImpl.java  |  48 +++++++++
 .../ParamGenericValidationWorkerTest.java       |  58 +++++++----
 .../com/cloud/user/MockAccountManagerImpl.java  |   9 +-
 44 files changed, 214 insertions(+), 293 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/com/cloud/server/ManagementService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java
index 9b138fe..5fcf0b5 100755
--- a/api/src/com/cloud/server/ManagementService.java
+++ b/api/src/com/cloud/server/ManagementService.java
@@ -269,10 +269,6 @@ public interface ManagementService {
      */
     String generateRandomPassword();
 
-    public Long saveStartedEvent(Long userId, Long accountId, String type, String description, boolean startEventId, Long displayResourceEnabled);
-
-    public Long saveCompletedEvent(Long userId, Long accountId, String level, String type, String description, boolean displayResourceEnabled, long startEventId);
-
     /**
      * Search registered key pairs for the logged in user.
      *

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/com/cloud/user/AccountService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/user/AccountService.java b/api/src/com/cloud/user/AccountService.java
index a9be292..de0b470 100755
--- a/api/src/com/cloud/user/AccountService.java
+++ b/api/src/com/cloud/user/AccountService.java
@@ -103,4 +103,6 @@ public interface AccountService {
 
     void checkAccess(Account account, AccessType accessType, boolean sameOwner, ControlledEntity... entities) throws PermissionDeniedException;
 
+    Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly);
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/BaseAsyncCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/BaseAsyncCmd.java b/api/src/org/apache/cloudstack/api/BaseAsyncCmd.java
index bbc898f..0b1396f 100644
--- a/api/src/org/apache/cloudstack/api/BaseAsyncCmd.java
+++ b/api/src/org/apache/cloudstack/api/BaseAsyncCmd.java
@@ -16,9 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api;
 
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.user.User;
 
 /**
  * queryAsyncJobResult API command.
@@ -92,37 +89,4 @@ public abstract class BaseAsyncCmd extends BaseCmd {
     public Object getJob() {
         return job;
     }
-
-    protected long saveStartedEvent() {
-        return saveStartedEvent(getEventType(), "Executing job for " + getEventDescription(), getStartEventId());
-    }
-
-    protected long saveStartedEvent(String eventType, String description, Long startEventId) {
-        CallContext ctx = CallContext.current();
-        Long userId = ctx.getCallingUserId();
-        userId = (userId == null) ? User.UID_SYSTEM : userId;
-        Long startEvent = startEventId;
-        if (startEvent == null) {
-            startEvent = 0L;
-        }
-        return _mgr.saveStartedEvent((userId == null) ? User.UID_SYSTEM : userId, getEntityOwnerId(), eventType, description,
-                isDisplayResourceEnabled(), startEvent);
-    }
-
-    protected long saveCompletedEvent(String level, String description) {
-        return saveCompletedEvent(level, getEventType(), description, getStartEventId());
-    }
-
-    protected long saveCompletedEvent(String level, String eventType, String description, Long startEventId) {
-        CallContext ctx = CallContext.current();
-        Long userId = ctx.getCallingUserId();
-        userId = (userId == null) ? User.UID_SYSTEM : userId;
-        Long startEvent = startEventId;
-        if (startEvent == null) {
-            startEvent = 0L;
-        }
-        return _mgr.saveCompletedEvent((userId == null) ? User.UID_SYSTEM : userId, getEntityOwnerId(), level, eventType, description,
-                isDisplayResourceEnabled(), startEvent);
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/BaseCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java
index 02250d7..937ccc2 100644
--- a/api/src/org/apache/cloudstack/api/BaseCmd.java
+++ b/api/src/org/apache/cloudstack/api/BaseCmd.java
@@ -38,16 +38,12 @@ import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService;
 import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService;
 import org.apache.cloudstack.query.QueryService;
 import org.apache.cloudstack.usage.UsageService;
-
 import org.apache.log4j.Logger;
 
 import com.cloud.configuration.ConfigurationService;
-import com.cloud.domain.Domain;
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.NetworkRuleConflictException;
-import com.cloud.exception.PermissionDeniedException;
 import com.cloud.exception.ResourceAllocationException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.network.NetworkModel;
@@ -65,7 +61,6 @@ import com.cloud.network.vpc.VpcProvisioningService;
 import com.cloud.network.vpc.VpcService;
 import com.cloud.network.vpn.RemoteAccessVpnService;
 import com.cloud.network.vpn.Site2SiteVpnService;
-import com.cloud.projects.Project;
 import com.cloud.projects.ProjectService;
 import com.cloud.resource.ResourceService;
 import com.cloud.server.ManagementService;
@@ -88,36 +83,28 @@ import com.cloud.vm.snapshot.VMSnapshotService;
 
 public abstract class BaseCmd {
     private static final Logger s_logger = Logger.getLogger(BaseCmd.class.getName());
-
-    public static final String USER_ERROR_MESSAGE = "Internal error executing command, please contact your system administrator";
-    public static final int PROGRESS_INSTANCE_CREATED = 1;
-
     public static final String RESPONSE_TYPE_XML = "xml";
     public static final String RESPONSE_TYPE_JSON = "json";
-
-    public enum CommandType {
-        BOOLEAN, DATE, FLOAT, INTEGER, SHORT, LIST, LONG, OBJECT, MAP, STRING, TZDATE, UUID
-    }
-
     public static final DateFormat INPUT_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
     public static final DateFormat NEW_INPUT_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    public static final String USER_ERROR_MESSAGE = "Internal error executing command, please contact your system administrator";
     public static Pattern newInputDateFormat = Pattern.compile("[\\d]+-[\\d]+-[\\d]+ [\\d]+:[\\d]+:[\\d]+");
     private static final DateFormat s_outputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
-
     protected static final Map<Class<?>, List<Field>> fieldsForCmdClass = new HashMap<Class<?>, List<Field>>();
-
-    private Object _responseObject;
-    private Map<String, String> fullUrlParams;
-
-    public enum HTTPMethod {
+    public static enum HTTPMethod {
         GET, POST, PUT, DELETE
     }
+    public static enum CommandType {
+        BOOLEAN, DATE, FLOAT, INTEGER, SHORT, LIST, LONG, OBJECT, MAP, STRING, TZDATE, UUID
+    }
 
+    private Object _responseObject;
+    private Map<String, String> fullUrlParams;
     private HTTPMethod httpMethod;
-
     @Parameter(name = "response", type = CommandType.STRING)
     private String responseType;
 
+
     @Inject
     public ConfigurationService _configService;
     @Inject
@@ -174,7 +161,6 @@ public abstract class BaseCmd {
     public NetworkACLService _networkACLService;
     @Inject
     public Site2SiteVpnService _s2sVpnService;
-
     @Inject
     public QueryService _queryService;
     @Inject
@@ -282,10 +268,6 @@ public abstract class BaseCmd {
         _responseObject = responseObject;
     }
 
-    public ManagementService getMgmtServiceRef() {
-        return _mgr;
-    }
-
     public static String getDateString(final Date date) {
         if (date == null) {
             return "";
@@ -318,10 +300,6 @@ public abstract class BaseCmd {
         return filteredFields;
     }
 
-    protected Account getCurrentContextAccount() {
-        return CallContext.current().getCallingAccount();
-    }
-
     /**
      * This method doesn't return all the @{link Parameter}, but only the ones exposed
      * and allowed for current @{link RoleType}. This method will get the fields for a given
@@ -334,7 +312,7 @@ public abstract class BaseCmd {
     public List<Field> getParamFields() {
         final List<Field> allFields = getAllFieldsForClass(this.getClass());
         final List<Field> validFields = new ArrayList<Field>();
-        final Account caller = getCurrentContextAccount();
+        final Account caller = CallContext.current().getCallingAccount();
 
         for (final Field field : allFields) {
             final Parameter parameterAnnotation = field.getAnnotation(Parameter.class);
@@ -362,20 +340,6 @@ public abstract class BaseCmd {
         return validFields;
     }
 
-    protected long getInstanceIdFromJobSuccessResult(final String result) {
-        s_logger.debug("getInstanceIdFromJobSuccessResult not overridden in subclass " + this.getClass().getName());
-        return 0;
-    }
-
-    public static boolean isAdmin(final short accountType) {
-        return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) ||
-            (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN));
-    }
-
-    public static boolean isRootAdmin(final short accountType) {
-        return ((accountType == Account.ACCOUNT_TYPE_ADMIN));
-    }
-
     public void setFullUrlParams(final Map<String, String> map) {
         fullUrlParams = map;
     }
@@ -384,52 +348,6 @@ public abstract class BaseCmd {
         return fullUrlParams;
     }
 
-    public Long finalyzeAccountId(final String accountName, final Long domainId, final Long projectId, final boolean enabledOnly) {
-        if (accountName != null) {
-            if (domainId == null) {
-                throw new InvalidParameterValueException("Account must be specified with domainId parameter");
-            }
-
-            final Domain domain = _domainService.getDomain(domainId);
-            if (domain == null) {
-                throw new InvalidParameterValueException("Unable to find domain by id");
-            }
-
-            final Account account = _accountService.getActiveAccountByName(accountName, domainId);
-            if (account != null && account.getType() != Account.ACCOUNT_TYPE_PROJECT) {
-                if (!enabledOnly || account.getState() == Account.State.enabled) {
-                    return account.getId();
-                } else {
-                    throw new PermissionDeniedException("Can't add resources to the account id=" + account.getId() + " in state=" + account.getState() +
-                        " as it's no longer active");
-                }
-            } else {
-                // idList is not used anywhere, so removed it now
-                //List<IdentityProxy> idList = new ArrayList<IdentityProxy>();
-                //idList.add(new IdentityProxy("domain", domainId, "domainId"));
-                throw new InvalidParameterValueException("Unable to find account by name " + accountName + " in domain with specified id");
-            }
-        }
-
-        if (projectId != null) {
-            final Project project = _projectService.getProject(projectId);
-            if (project != null) {
-                if (!enabledOnly || project.getState() == Project.State.Active) {
-                    return project.getProjectAccountId();
-                } else {
-                    final PermissionDeniedException ex =
-                        new PermissionDeniedException("Can't add resources to the project with specified projectId in state=" + project.getState() +
-                            " as it's no longer active");
-                    ex.addProxyObject(project.getUuid(), "projectId");
-                    throw ex;
-                }
-            } else {
-                throw new InvalidParameterValueException("Unable to find project by id");
-            }
-        }
-        return null;
-    }
-
     /**
      * To be overwritten by any class who needs specific validation
      */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/BaseListTemplateOrIsoPermissionsCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/BaseListTemplateOrIsoPermissionsCmd.java b/api/src/org/apache/cloudstack/api/BaseListTemplateOrIsoPermissionsCmd.java
index 48c1e02..2eb6e5b 100644
--- a/api/src/org/apache/cloudstack/api/BaseListTemplateOrIsoPermissionsCmd.java
+++ b/api/src/org/apache/cloudstack/api/BaseListTemplateOrIsoPermissionsCmd.java
@@ -18,10 +18,9 @@ package org.apache.cloudstack.api;
 
 import java.util.List;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.response.TemplatePermissionsResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.template.VirtualMachineTemplate;
 import com.cloud.user.Account;
@@ -80,7 +79,7 @@ public class BaseListTemplateOrIsoPermissionsCmd extends BaseCmd {
         List<String> accountNames = _templateService.listTemplatePermissions(this);
 
         Account account = CallContext.current().getCallingAccount();
-        boolean isAdmin = (isAdmin(account.getType()));
+        boolean isAdmin = (_accountService.isAdmin(account.getType()));
 
         TemplatePermissionsResponse response = _responseGenerator.createTemplatePermissionsResponse(accountNames, id, isAdmin);
         response.setResponseName(getCommandName());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java
index 34feb49..51e218d 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.admin.user;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -27,6 +25,7 @@ import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.api.response.UserResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.user.Account;
 import com.cloud.user.User;
@@ -132,7 +131,7 @@ public class CreateUserCmd extends BaseCmd {
     @Override
     public long getEntityOwnerId() {
         Account account = CallContext.current().getCallingAccount();
-        if ((account == null) || isAdmin(account.getType())) {
+        if ((account == null) || _accountService.isAdmin(account.getType())) {
             if ((domainId != null) && (accountName != null)) {
                 Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId);
                 if (userAccount != null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/affinitygroup/CreateAffinityGroupCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/CreateAffinityGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/affinitygroup/CreateAffinityGroupCmd.java
index 41d5823..e23f890 100644
--- a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/CreateAffinityGroupCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/affinitygroup/CreateAffinityGroupCmd.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.affinitygroup;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.affinity.AffinityGroup;
 import org.apache.cloudstack.affinity.AffinityGroupResponse;
 import org.apache.cloudstack.api.APICommand;
@@ -29,6 +27,7 @@ import org.apache.cloudstack.api.Parameter;
 import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.event.EventTypes;
 import com.cloud.exception.ResourceAllocationException;
@@ -102,7 +101,7 @@ public class CreateAffinityGroupCmd extends BaseAsyncCreateCmd {
     @Override
     public long getEntityOwnerId() {
         Account account = CallContext.current().getCallingAccount();
-        if ((account == null) || isAdmin(account.getType())) {
+        if ((account == null) || _accountService.isAdmin(account.getType())) {
             if ((domainId != null) && (accountName != null)) {
                 Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId);
                 if (userAccount != null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java
index d4d1f2a..6a6dd25 100644
--- a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.affinitygroup;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.affinity.AffinityGroupResponse;
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiCommandJobType;
@@ -29,6 +27,7 @@ import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.api.response.SuccessResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.event.EventTypes;
 import com.cloud.exception.InvalidParameterValueException;
@@ -105,7 +104,7 @@ public class DeleteAffinityGroupCmd extends BaseAsyncCmd {
     @Override
     public long getEntityOwnerId() {
         Account account = CallContext.current().getCallingAccount();
-        if ((account == null) || isAdmin(account.getType())) {
+        if ((account == null) || _accountService.isAdmin(account.getType())) {
             if ((domainId != null) && (accountName != null)) {
                 Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId);
                 if (userAccount != null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateConditionCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateConditionCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateConditionCmd.java
index 356b836..7fbde9e 100644
--- a/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateConditionCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateConditionCmd.java
@@ -17,8 +17,6 @@
 
 package org.apache.cloudstack.api.command.user.autoscale;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiCommandJobType;
 import org.apache.cloudstack.api.ApiConstants;
@@ -30,6 +28,7 @@ import org.apache.cloudstack.api.response.ConditionResponse;
 import org.apache.cloudstack.api.response.CounterResponse;
 import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.event.EventTypes;
 import com.cloud.exception.ResourceAllocationException;
@@ -138,7 +137,7 @@ public class CreateConditionCmd extends BaseAsyncCreateCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, null, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, null, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java
index 8c3e218..28f98f0 100644
--- a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.iso;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiCommandJobType;
 import org.apache.cloudstack.api.ApiConstants;
@@ -27,6 +25,7 @@ import org.apache.cloudstack.api.response.ListResponse;
 import org.apache.cloudstack.api.response.TemplateResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.template.VirtualMachineTemplate.TemplateFilter;
 import com.cloud.user.Account;
@@ -120,7 +119,7 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd {
     public boolean listInReadyState() {
         Account account = CallContext.current().getCallingAccount();
         // It is account specific if account is admin type and domainId and accountName are not null
-        boolean isAccountSpecific = (account == null || isAdmin(account.getType())) && (getAccountName() != null) && (getDomainId() != null);
+        boolean isAccountSpecific = (account == null || _accountService.isAdmin(account.getType())) && (getAccountName() != null) && (getDomainId() != null);
         // Show only those that are downloaded.
         TemplateFilter templateFilter = TemplateFilter.valueOf(getIsoFilter());
         boolean onlyReady =

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/iso/RegisterIsoCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/RegisterIsoCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/RegisterIsoCmd.java
index af18057..ace662a 100644
--- a/api/src/org/apache/cloudstack/api/command/user/iso/RegisterIsoCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/iso/RegisterIsoCmd.java
@@ -18,8 +18,6 @@ package org.apache.cloudstack.api.command.user.iso;
 
 import java.util.List;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -33,6 +31,7 @@ import org.apache.cloudstack.api.response.ProjectResponse;
 import org.apache.cloudstack.api.response.TemplateResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.exception.ResourceAllocationException;
 import com.cloud.template.VirtualMachineTemplate;
@@ -182,7 +181,7 @@ public class RegisterIsoCmd extends BaseCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java
index 2f9220f..6a2c6b0 100644
--- a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java
@@ -286,7 +286,7 @@ public class CreateNetworkCmd extends BaseCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java
index 7015703..6782576 100644
--- a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java
@@ -19,8 +19,6 @@ package org.apache.cloudstack.api.command.user.region.ha.gslb;
 
 import javax.inject.Inject;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiCommandJobType;
 import org.apache.cloudstack.api.ApiConstants;
@@ -32,6 +30,7 @@ import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse;
 import org.apache.cloudstack.api.response.RegionResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.event.EventTypes;
 import com.cloud.exception.ResourceAllocationException;
@@ -192,7 +191,7 @@ public class CreateGlobalLoadBalancerRuleCmd extends BaseAsyncCreateCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, null, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, null, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/resource/ListResourceLimitsCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/resource/ListResourceLimitsCmd.java b/api/src/org/apache/cloudstack/api/command/user/resource/ListResourceLimitsCmd.java
index bd8942a..1576d93 100644
--- a/api/src/org/apache/cloudstack/api/command/user/resource/ListResourceLimitsCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/resource/ListResourceLimitsCmd.java
@@ -19,14 +19,13 @@ package org.apache.cloudstack.api.command.user.resource;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
 import org.apache.cloudstack.api.Parameter;
 import org.apache.cloudstack.api.response.ListResponse;
 import org.apache.cloudstack.api.response.ResourceLimitResponse;
+import org.apache.log4j.Logger;
 
 import com.cloud.configuration.ResourceLimit;
 
@@ -78,7 +77,7 @@ public class ListResourceLimitsCmd extends BaseListProjectAndAccountResourcesCmd
     @Override
     public void execute() {
         List<? extends ResourceLimit> result =
-            _resourceLimitService.searchForLimits(id, finalyzeAccountId(this.getAccountName(), this.getDomainId(), this.getProjectId(), false), this.getDomainId(),
+                _resourceLimitService.searchForLimits(id, _accountService.finalyzeAccountId(this.getAccountName(), this.getDomainId(), this.getProjectId(), false), this.getDomainId(),
                 resourceType, this.getStartIndex(), this.getPageSizeVal());
         ListResponse<ResourceLimitResponse> response = new ListResponse<ResourceLimitResponse>();
         List<ResourceLimitResponse> limitResponses = new ArrayList<ResourceLimitResponse>();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/resource/UpdateResourceCountCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/resource/UpdateResourceCountCmd.java b/api/src/org/apache/cloudstack/api/command/user/resource/UpdateResourceCountCmd.java
index 2616875..5a41749 100644
--- a/api/src/org/apache/cloudstack/api/command/user/resource/UpdateResourceCountCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/resource/UpdateResourceCountCmd.java
@@ -19,8 +19,6 @@ package org.apache.cloudstack.api.command.user.resource;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -32,6 +30,7 @@ import org.apache.cloudstack.api.response.ListResponse;
 import org.apache.cloudstack.api.response.ProjectResponse;
 import org.apache.cloudstack.api.response.ResourceCountResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.configuration.ResourceCount;
 import com.cloud.user.Account;
@@ -107,7 +106,7 @@ public class UpdateResourceCountCmd extends BaseCmd {
     @Override
     public long getEntityOwnerId() {
         Account account = CallContext.current().getCallingAccount();
-        if ((account == null) || isAdmin(account.getType())) {
+        if ((account == null) || _accountService.isAdmin(account.getType())) {
             if ((domainId != null) && (accountName != null)) {
                 Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId);
                 if (userAccount != null) {
@@ -126,7 +125,7 @@ public class UpdateResourceCountCmd extends BaseCmd {
     @Override
     public void execute() {
         List<? extends ResourceCount> result =
-            _resourceLimitService.recalculateResourceCount(finalyzeAccountId(accountName, domainId, projectId, true), getDomainId(), getResourceType());
+                _resourceLimitService.recalculateResourceCount(_accountService.finalyzeAccountId(accountName, domainId, projectId, true), getDomainId(), getResourceType());
 
         if ((result != null) && (result.size() > 0)) {
             ListResponse<ResourceCountResponse> response = new ListResponse<ResourceCountResponse>();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/resource/UpdateResourceLimitCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/resource/UpdateResourceLimitCmd.java b/api/src/org/apache/cloudstack/api/command/user/resource/UpdateResourceLimitCmd.java
index 015cafb..22d20d3 100644
--- a/api/src/org/apache/cloudstack/api/command/user/resource/UpdateResourceLimitCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/resource/UpdateResourceLimitCmd.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.resource;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -28,6 +26,7 @@ import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.api.response.ProjectResponse;
 import org.apache.cloudstack.api.response.ResourceLimitResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.configuration.ResourceLimit;
 
@@ -96,7 +95,7 @@ public class UpdateResourceLimitCmd extends BaseCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }
@@ -106,7 +105,7 @@ public class UpdateResourceLimitCmd extends BaseCmd {
 
     @Override
     public void execute() {
-        ResourceLimit result = _resourceLimitService.updateResourceLimit(finalyzeAccountId(accountName, domainId, projectId, true), getDomainId(), resourceType, max);
+        ResourceLimit result = _resourceLimitService.updateResourceLimit(_accountService.finalyzeAccountId(accountName, domainId, projectId, true), getDomainId(), resourceType, max);
         if (result != null || (result == null && max != null && max.longValue() == -1L)) {
             ResourceLimitResponse response = _responseGenerator.createResourceLimitResponse(result);
             response.setResponseName(getCommandName());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupEgressCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupEgressCmd.java b/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupEgressCmd.java
index 748f60c..7afce6a 100644
--- a/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupEgressCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupEgressCmd.java
@@ -22,8 +22,6 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiCommandJobType;
 import org.apache.cloudstack.api.ApiConstants;
@@ -36,6 +34,7 @@ import org.apache.cloudstack.api.response.ProjectResponse;
 import org.apache.cloudstack.api.response.SecurityGroupResponse;
 import org.apache.cloudstack.api.response.SecurityGroupRuleResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.event.EventTypes;
 import com.cloud.exception.InvalidParameterValueException;
@@ -176,7 +175,7 @@ public class AuthorizeSecurityGroupEgressCmd extends BaseAsyncCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupIngressCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupIngressCmd.java b/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupIngressCmd.java
index d93a57c..efb34b9 100644
--- a/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupIngressCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupIngressCmd.java
@@ -22,8 +22,6 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiCommandJobType;
 import org.apache.cloudstack.api.ApiConstants;
@@ -36,6 +34,7 @@ import org.apache.cloudstack.api.response.ProjectResponse;
 import org.apache.cloudstack.api.response.SecurityGroupResponse;
 import org.apache.cloudstack.api.response.SecurityGroupRuleResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.event.EventTypes;
 import com.cloud.exception.InvalidParameterValueException;
@@ -175,7 +174,7 @@ public class AuthorizeSecurityGroupIngressCmd extends BaseAsyncCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/securitygroup/CreateSecurityGroupCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/CreateSecurityGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/securitygroup/CreateSecurityGroupCmd.java
index 9e1bae3..3e94715 100644
--- a/api/src/org/apache/cloudstack/api/command/user/securitygroup/CreateSecurityGroupCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/securitygroup/CreateSecurityGroupCmd.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.securitygroup;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -28,6 +26,7 @@ import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.api.response.ProjectResponse;
 import org.apache.cloudstack.api.response.SecurityGroupResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.network.security.SecurityGroup;
 import com.cloud.user.Account;
@@ -97,7 +96,7 @@ public class CreateSecurityGroupCmd extends BaseCmd {
     @Override
     public long getEntityOwnerId() {
         Account account = CallContext.current().getCallingAccount();
-        if ((account == null) || isAdmin(account.getType())) {
+        if ((account == null) || _accountService.isAdmin(account.getType())) {
             if ((domainId != null) && (accountName != null)) {
                 Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId);
                 if (userAccount != null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/securitygroup/DeleteSecurityGroupCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/DeleteSecurityGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/securitygroup/DeleteSecurityGroupCmd.java
index 2b23ac0..c9bffe7 100644
--- a/api/src/org/apache/cloudstack/api/command/user/securitygroup/DeleteSecurityGroupCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/securitygroup/DeleteSecurityGroupCmd.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.securitygroup;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -29,6 +27,7 @@ import org.apache.cloudstack.api.response.ProjectResponse;
 import org.apache.cloudstack.api.response.SecurityGroupResponse;
 import org.apache.cloudstack.api.response.SuccessResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.ResourceInUseException;
@@ -110,7 +109,7 @@ public class DeleteSecurityGroupCmd extends BaseCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/ssh/CreateSSHKeyPairCmd.java
----------------------------------------------------------------------
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 3da6dc1..274c0cb 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
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.ssh;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.BaseCmd;
@@ -26,6 +24,7 @@ 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.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.user.SSHKeyPair;
 
@@ -80,7 +79,7 @@ public class CreateSSHKeyPairCmd extends BaseCmd {
     /////////////////////////////////////////////////////
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/ssh/DeleteSSHKeyPairCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/ssh/DeleteSSHKeyPairCmd.java b/api/src/org/apache/cloudstack/api/command/user/ssh/DeleteSSHKeyPairCmd.java
index cddf199..92105c1 100644
--- a/api/src/org/apache/cloudstack/api/command/user/ssh/DeleteSSHKeyPairCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/ssh/DeleteSSHKeyPairCmd.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.ssh;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.BaseCmd;
@@ -26,6 +24,7 @@ import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.api.response.ProjectResponse;
 import org.apache.cloudstack.api.response.SuccessResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.user.Account;
 
@@ -91,7 +90,7 @@ public class DeleteSSHKeyPairCmd extends BaseCmd {
     @Override
     public long getEntityOwnerId() {
         Account account = CallContext.current().getCallingAccount();
-        if ((account == null) || isAdmin(account.getType())) {
+        if ((account == null) || _accountService.isAdmin(account.getType())) {
             if ((domainId != null) && (accountName != null)) {
                 Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId);
                 if (userAccount != null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/ssh/RegisterSSHKeyPairCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/ssh/RegisterSSHKeyPairCmd.java b/api/src/org/apache/cloudstack/api/command/user/ssh/RegisterSSHKeyPairCmd.java
index 5b330f3..f6074e3 100644
--- a/api/src/org/apache/cloudstack/api/command/user/ssh/RegisterSSHKeyPairCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/ssh/RegisterSSHKeyPairCmd.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.ssh;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.BaseCmd;
@@ -26,6 +24,7 @@ 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;
 
@@ -88,7 +87,7 @@ public class RegisterSSHKeyPairCmd extends BaseCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java
index 9e95cf6..132d10c 100644
--- a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.template;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiCommandJobType;
 import org.apache.cloudstack.api.ApiConstants;
@@ -27,6 +25,7 @@ import org.apache.cloudstack.api.response.ListResponse;
 import org.apache.cloudstack.api.response.TemplateResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.template.VirtualMachineTemplate.TemplateFilter;
 import com.cloud.user.Account;
@@ -101,7 +100,7 @@ public class ListTemplatesCmd extends BaseListTaggedResourcesCmd {
 
         Account account = CallContext.current().getCallingAccount();
         // It is account specific if account is admin type and domainId and accountName are not null
-        boolean isAccountSpecific = (account == null || isAdmin(account.getType())) && (getAccountName() != null) && (getDomainId() != null);
+        boolean isAccountSpecific = (account == null || _accountService.isAdmin(account.getType())) && (getAccountName() != null) && (getDomainId() != null);
         // Show only those that are downloaded.
         TemplateFilter templateFilter = TemplateFilter.valueOf(getTemplateFilter());
         boolean onlyReady =

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
index 61e9428..e6abab2 100644
--- a/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
@@ -21,8 +21,6 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiCommandJobType;
 import org.apache.cloudstack.api.ApiConstants;
@@ -37,6 +35,7 @@ import org.apache.cloudstack.api.response.ProjectResponse;
 import org.apache.cloudstack.api.response.TemplateResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.exception.ResourceAllocationException;
 import com.cloud.template.VirtualMachineTemplate;
@@ -252,7 +251,7 @@ public class RegisterTemplateCmd extends BaseCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
index 1cc8380..d33e04e 100755
--- a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
@@ -381,7 +381,7 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/vmgroup/CreateVMGroupCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vmgroup/CreateVMGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmgroup/CreateVMGroupCmd.java
index 4676def..c364c2a 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vmgroup/CreateVMGroupCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vmgroup/CreateVMGroupCmd.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.vmgroup;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -28,6 +26,7 @@ import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.api.response.InstanceGroupResponse;
 import org.apache.cloudstack.api.response.ProjectResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.vm.InstanceGroup;
 
@@ -90,7 +89,7 @@ public class CreateVMGroupCmd extends BaseCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java
index 80b49fd..31d75d8 100644
--- a/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java
@@ -178,7 +178,7 @@ public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java
index 2d97ec9..737e8dc 100644
--- a/api/src/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.volume;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -29,6 +27,7 @@ import org.apache.cloudstack.api.response.ProjectResponse;
 import org.apache.cloudstack.api.response.VolumeResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.event.EventTypes;
 import com.cloud.exception.ConcurrentOperationException;
@@ -149,7 +148,7 @@ public class UploadVolumeCmd extends BaseAsyncCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java
index 62fa29f..a632b6d 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java
@@ -199,7 +199,7 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/vpn/AddVpnUserCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/AddVpnUserCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/AddVpnUserCmd.java
index 45d8703..68b5ea2 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vpn/AddVpnUserCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vpn/AddVpnUserCmd.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.vpn;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -28,6 +26,7 @@ import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.api.response.ProjectResponse;
 import org.apache.cloudstack.api.response.VpnUsersResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.domain.Domain;
 import com.cloud.event.EventTypes;
@@ -97,7 +96,7 @@ public class AddVpnUserCmd extends BaseAsyncCreateCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java
index 1894835..edc4680 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.vpn;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -27,6 +25,7 @@ import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.api.response.Site2SiteCustomerGatewayResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.event.EventTypes;
 import com.cloud.network.Site2SiteCustomerGateway;
@@ -143,7 +142,7 @@ public class CreateVpnCustomerGatewayCmd extends BaseAsyncCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, null, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, null, true);
         if (accountId == null) {
             accountId = CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/vpn/RemoveVpnUserCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/RemoveVpnUserCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/RemoveVpnUserCmd.java
index d49a208..f704db7 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vpn/RemoveVpnUserCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vpn/RemoveVpnUserCmd.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.vpn;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -28,6 +26,7 @@ import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.api.response.ProjectResponse;
 import org.apache.cloudstack.api.response.SuccessResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.event.EventTypes;
 import com.cloud.user.Account;
@@ -88,7 +87,7 @@ public class RemoveVpnUserCmd extends BaseAsyncCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/vpn/ResetVpnConnectionCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/ResetVpnConnectionCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/ResetVpnConnectionCmd.java
index 8c3f1d6..ee03000 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vpn/ResetVpnConnectionCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vpn/ResetVpnConnectionCmd.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.vpn;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -27,6 +25,7 @@ import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.api.response.Site2SiteVpnConnectionResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.event.EventTypes;
 import com.cloud.exception.ResourceUnavailableException;
@@ -82,7 +81,7 @@ public class ResetVpnConnectionCmd extends BaseAsyncCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, null, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, null, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java
index e0cafed..4583776 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.vpn;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -27,6 +25,7 @@ import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.api.response.Site2SiteCustomerGatewayResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.event.EventTypes;
 import com.cloud.network.Site2SiteCustomerGateway;
@@ -146,7 +145,7 @@ public class UpdateVpnCustomerGatewayCmd extends BaseAsyncCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, null, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, null, true);
         if (accountId == null) {
             accountId = CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/api/command/CreateServiceInstanceCmd.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/api/command/CreateServiceInstanceCmd.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/api/command/CreateServiceInstanceCmd.java
index 86e2949..d2cb4de 100644
--- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/api/command/CreateServiceInstanceCmd.java
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/api/command/CreateServiceInstanceCmd.java
@@ -186,7 +186,7 @@ public class CreateServiceInstanceCmd extends BaseAsyncCreateCmd {
 
     @Override
     public long getEntityOwnerId() {
-        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
         if (accountId == null) {
             return CallContext.current().getCallingAccount().getId();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java
index fa7be58..fb08dc6 100644
--- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java
+++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java
@@ -23,8 +23,6 @@ import java.util.Map;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.acl.ControlledEntity;
 import org.apache.cloudstack.acl.RoleType;
 import org.apache.cloudstack.acl.SecurityChecker.AccessType;
@@ -33,6 +31,7 @@ import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
 import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
 import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.api.query.vo.ControlledViewEntity;
 import com.cloud.configuration.ResourceLimit;
@@ -347,4 +346,10 @@ public class MockAccountManager extends ManagerBase implements AccountManager {
 
     }
 
+    @Override
+    public Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/server/src/com/cloud/acl/DomainChecker.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/acl/DomainChecker.java b/server/src/com/cloud/acl/DomainChecker.java
index f8acceb..7b1deaa 100755
--- a/server/src/com/cloud/acl/DomainChecker.java
+++ b/server/src/com/cloud/acl/DomainChecker.java
@@ -19,12 +19,10 @@ package com.cloud.acl;
 import javax.ejb.Local;
 import javax.inject.Inject;
 
-import org.springframework.stereotype.Component;
-
 import org.apache.cloudstack.acl.ControlledEntity;
 import org.apache.cloudstack.acl.SecurityChecker;
 import org.apache.cloudstack.affinity.AffinityGroup;
-import org.apache.cloudstack.api.BaseCmd;
+import org.springframework.stereotype.Component;
 
 import com.cloud.dc.DataCenter;
 import com.cloud.dc.DedicatedResourceVO;
@@ -104,7 +102,7 @@ public class DomainChecker extends AdapterBase implements SecurityChecker {
             Account owner = _accountDao.findById(template.getAccountId());
             // validate that the template is usable by the account
             if (!template.isPublicTemplate()) {
-                if (BaseCmd.isRootAdmin(caller.getType()) || (owner.getId() == caller.getId())) {
+                if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN || (owner.getId() == caller.getId())) {
                     return true;
                 }
                 //special handling for the project case
@@ -121,7 +119,7 @@ public class DomainChecker extends AdapterBase implements SecurityChecker {
             } else {
                 // Domain admin and regular user can delete/modify only templates created by them
                 if (accessType != null && accessType == AccessType.ModifyEntry) {
-                    if (!BaseCmd.isRootAdmin(caller.getType()) && owner.getId() != caller.getId()) {
+                    if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN && owner.getId() != caller.getId()) {
                         // For projects check if the caller account can access the project account
                         if (owner.getType() != Account.ACCOUNT_TYPE_PROJECT || !(_projectMgr.canAccessProjectAccount(caller, owner.getId()))) {
                             throw new PermissionDeniedException("Domain Admin and regular users can modify only their own Public templates");

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/server/src/com/cloud/api/ApiServer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java
index c94bc97..a9b1130 100755
--- a/server/src/com/cloud/api/ApiServer.java
+++ b/server/src/com/cloud/api/ApiServer.java
@@ -53,37 +53,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.ApiConstants;
@@ -122,6 +91,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.dispatch.DispatchChainFactory;
 import com.cloud.api.dispatch.DispatchTask;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
index fedc13d..07b4c91 100644
--- a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
+++ b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
@@ -24,15 +24,13 @@ import java.util.Map;
 import javax.ejb.Local;
 import javax.inject.Inject;
 
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.api.BaseCmd;
 import org.apache.cloudstack.api.response.TemplateResponse;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
 
 import com.cloud.api.ApiDBUtils;
 import com.cloud.api.ApiResponseHelper;
@@ -44,6 +42,7 @@ import com.cloud.storage.VMTemplateHostVO;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 import com.cloud.template.VirtualMachineTemplate;
 import com.cloud.user.Account;
+import com.cloud.user.AccountService;
 import com.cloud.utils.Pair;
 import com.cloud.utils.db.Filter;
 import com.cloud.utils.db.GenericDaoBase;
@@ -59,6 +58,8 @@ public class TemplateJoinDaoImpl extends GenericDaoBase<TemplateJoinVO, Long> im
 
     @Inject
     private ConfigurationDao _configDao;
+    @Inject
+    private AccountService _accountService;
 
     private final SearchBuilder<TemplateJoinVO> tmpltIdPairSearch;
 
@@ -98,7 +99,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase<TemplateJoinVO, Long> im
     private String getTemplateStatus(TemplateJoinVO template) {
         boolean isAdmin = false;
         Account caller = CallContext.current().getCallingAccount();
-        if ((caller == null) || BaseCmd.isAdmin(caller.getType())) {
+        if ((caller == null) || _accountService.isAdmin(caller.getType())) {
             isAdmin = true;
         }
 
@@ -307,7 +308,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase<TemplateJoinVO, Long> im
 
         Account caller = CallContext.current().getCallingAccount();
         boolean isAdmin = false;
-        if ((caller == null) || BaseCmd.isAdmin(caller.getType())) {
+        if ((caller == null) || _accountService.isAdmin(caller.getType())) {
             isAdmin = true;
         }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 4fa9467..49a9eb5 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -3301,16 +3301,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
     }
 
     @Override
-    public Long saveStartedEvent(Long userId, Long accountId, String type, String description, boolean displayResourceEnabled, Long startEventId) {
-        return ActionEventUtils.onStartedActionEvent(userId, accountId, type, description, displayResourceEnabled, startEventId);
-    }
-
-    @Override
-    public Long saveCompletedEvent(Long userId, Long accountId, String level, String type, String description, boolean displayResourceEnabled, long startEventId) {
-        return ActionEventUtils.onCompletedActionEvent(userId, accountId, level, type, displayResourceEnabled, description, startEventId);
-    }
-
-    @Override
     @DB
     public String uploadCertificate(UploadCustomCertificateCmd cmd) {
         if (cmd.getPrivateKey() != null && cmd.getAlias() != null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/server/src/com/cloud/user/AccountManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java
index 186cfb2..c48e9b5 100755
--- a/server/src/com/cloud/user/AccountManagerImpl.java
+++ b/server/src/com/cloud/user/AccountManagerImpl.java
@@ -2326,4 +2326,52 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
     public UserAccount getUserByApiKey(String apiKey) {
         return _userAccountDao.getUserByApiKey(apiKey);
     }
+
+    @Override
+    public Long finalyzeAccountId(final String accountName, final Long domainId, final Long projectId, final boolean enabledOnly) {
+        if (accountName != null) {
+            if (domainId == null) {
+                throw new InvalidParameterValueException("Account must be specified with domainId parameter");
+            }
+
+            final Domain domain = _domainMgr.getDomain(domainId);
+            if (domain == null) {
+                throw new InvalidParameterValueException("Unable to find domain by id");
+            }
+
+            final Account account = getActiveAccountByName(accountName, domainId);
+            if (account != null && account.getType() != Account.ACCOUNT_TYPE_PROJECT) {
+                if (!enabledOnly || account.getState() == Account.State.enabled) {
+                    return account.getId();
+                } else {
+                    throw new PermissionDeniedException("Can't add resources to the account id=" + account.getId() + " in state=" + account.getState() +
+                            " as it's no longer active");
+                }
+            } else {
+                // idList is not used anywhere, so removed it now
+                // List<IdentityProxy> idList = new ArrayList<IdentityProxy>();
+                // idList.add(new IdentityProxy("domain", domainId, "domainId"));
+                throw new InvalidParameterValueException("Unable to find account by name " + accountName + " in domain with specified id");
+            }
+        }
+
+        if (projectId != null) {
+            final Project project = _projectMgr.getProject(projectId);
+            if (project != null) {
+                if (!enabledOnly || project.getState() == Project.State.Active) {
+                    return project.getProjectAccountId();
+                } else {
+                    final PermissionDeniedException ex =
+                            new PermissionDeniedException("Can't add resources to the project with specified projectId in state=" + project.getState() +
+                                    " as it's no longer active");
+                    ex.addProxyObject(project.getUuid(), "projectId");
+                    throw ex;
+                }
+            } else {
+                throw new InvalidParameterValueException("Unable to find project by id");
+            }
+        }
+        return null;
+    }
+
 }


[10/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
Dispatcher corrections, refactoring and tests

Corrects problems from previous attempt. Fixes based on help comments from
the community and conflict resolution

Signed-off-by: Daan Hoogland <da...@onecht.net>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c211f0bb
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c211f0bb
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c211f0bb

Branch: refs/heads/distributedrouter
Commit: c211f0bbbe940ed3b9a6e9ef4b5a29be16062e85
Parents: 4552ec6
Author: Antonio Fornie <af...@schubergphilis.com>
Authored: Fri Mar 7 09:57:31 2014 -0600
Committer: Daan Hoogland <da...@onecht.net>
Committed: Fri Mar 7 19:12:07 2014 +0100

----------------------------------------------------------------------
 .../org/apache/cloudstack/api/ApiConstants.java |  15 +-
 api/src/org/apache/cloudstack/api/BaseCmd.java  | 185 ++++---
 .../org/apache/cloudstack/api/BaseListCmd.java  |  30 +-
 .../org/apache/cloudstack/api/BaseCmdTest.java  |  69 +++
 .../core/spring-server-core-misc-context.xml    |  12 +
 server/src/com/cloud/api/ApiDispatcher.java     | 490 +------------------
 server/src/com/cloud/api/ApiServer.java         | 374 +++++++-------
 server/src/com/cloud/api/ApiServlet.java        | 133 ++---
 .../api/dispatch/CommandCreationWorker.java     |  56 +++
 .../com/cloud/api/dispatch/DispatchChain.java   |  40 ++
 .../api/dispatch/DispatchChainFactory.java      |  72 +++
 .../com/cloud/api/dispatch/DispatchTask.java    |  41 ++
 .../com/cloud/api/dispatch/DispatchWorker.java  |  30 ++
 .../dispatch/ParamGenericValidationWorker.java  | 103 ++++
 .../cloud/api/dispatch/ParamProcessWorker.java  | 428 ++++++++++++++++
 .../cloud/api/dispatch/ParamUnpackWorker.java   | 114 +++++
 .../dispatch/SpecificCmdValidationWorker.java   |  34 ++
 .../cloud/network/as/AutoScaleManagerImpl.java  | 466 +++++++++---------
 .../VirtualNetworkApplianceManagerImpl.java     |   2 -
 .../storage/snapshot/SnapshotSchedulerImpl.java | 105 ++--
 .../test/com/cloud/api/ApiDispatcherTest.java   | 106 ----
 .../api/dispatch/CommandCreationWorkerTest.java |  48 ++
 .../api/dispatch/DispatchChainFactoryTest.java  |  55 +++
 .../ParamGenericValidationWorkerTest.java       | 173 +++++++
 .../api/dispatch/ParamProcessWorkerTest.java    | 107 ++++
 .../SpecificCmdValidationWorkerTest.java        |  48 ++
 26 files changed, 2157 insertions(+), 1179 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index 14df653..f0de48e 100755
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -23,7 +23,8 @@ public class ApiConstants {
     public static final String ACCOUNT_ID = "accountid";
     public static final String ALGORITHM = "algorithm";
     public static final String ALLOCATED_ONLY = "allocatedonly";
-    public static final String API_KEY = "userapikey";
+    public static final String API_KEY = "apikey";
+    public static final String USER_API_KEY = "userapikey";
     public static final String APPLIED = "applied";
     public static final String AVAILABLE = "available";
     public static final String BITS = "bits";
@@ -49,10 +50,16 @@ public class ApiConstants {
     public static final String CLUSTER_ID = "clusterid";
     public static final String CLUSTER_NAME = "clustername";
     public static final String CLUSTER_TYPE = "clustertype";
+    public static final String COMMAND = "command";
+    public static final String CMD_EVENT_TYPE = "cmdeventtype";
     public static final String COMPONENT = "component";
     public static final String CPU_NUMBER = "cpunumber";
     public static final String CPU_SPEED = "cpuspeed";
     public static final String CREATED = "created";
+    public static final String CTX_ACCOUNT_ID = "ctxaccountid";
+    public static final String CTX_USER_ID = "ctxuserid";
+    public static final String CTXSTARTEVENTID = "ctxstarteventid";
+    public static final String CTX_START_EVENT_ID = "ctxStartEventId";
     public static final String CUSTOMIZED = "customized";
     public static final String CUSTOMIZED_IOPS = "customizediops";
     public static final String CUSTOM_ID = "customid";
@@ -79,6 +86,7 @@ public class ApiConstants {
     public static final String IP6_DNS2 = "ip6dns2";
     public static final String DOMAIN = "domain";
     public static final String DOMAIN_ID = "domainid";
+    public static final String DOMAIN__ID = "domainId";
     public static final String DURATION = "duration";
     public static final String EMAIL = "email";
     public static final String END_DATE = "enddate";
@@ -86,6 +94,7 @@ public class ApiConstants {
     public static final String END_IPV6 = "endipv6";
     public static final String END_PORT = "endport";
     public static final String ENTRY_TIME = "entrytime";
+    public static final String EXPIRES = "expires";
     public static final String FETCH_LATEST = "fetchlatest";
     public static final String FIRSTNAME = "firstname";
     public static final String FORCED = "forced";
@@ -209,8 +218,11 @@ public class ApiConstants {
     public static final String SENT = "sent";
     public static final String SENT_BYTES = "sentbytes";
     public static final String SERVICE_OFFERING_ID = "serviceofferingid";
+    public static final String SESSIONKEY = "sessionkey";
     public static final String SHOW_CAPACITIES = "showcapacities";
     public static final String SHOW_REMOVED = "showremoved";
+    public static final String SIGNATURE = "signature";
+    public static final String SIGNATURE_VERSION = "signatureversion";
     public static final String SIZE = "size";
     public static final String SNAPSHOT_ID = "snapshotid";
     public static final String SNAPSHOT_POLICY_ID = "snapshotpolicyid";
@@ -277,6 +289,7 @@ public class ApiConstants {
     public static final String NETWORKRATE = "networkrate";
     public static final String HOST_TAGS = "hosttags";
     public static final String SSH_KEYPAIR = "keypair";
+    public static final String HTTPMETHOD = "httpmethod";
     public static final String HOST_CPU_CAPACITY = "hostcpucapacity";
     public static final String HOST_CPU_NUM = "hostcpunum";
     public static final String HOST_MEM_CAPACITY = "hostmemcapacity";

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/api/src/org/apache/cloudstack/api/BaseCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java
index e869ddf..02250d7 100644
--- a/api/src/org/apache/cloudstack/api/BaseCmd.java
+++ b/api/src/org/apache/cloudstack/api/BaseCmd.java
@@ -17,22 +17,28 @@
 
 package org.apache.cloudstack.api;
 
+import java.lang.reflect.Field;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.regex.Pattern;
 
 import javax.inject.Inject;
 
+import org.apache.cloudstack.acl.RoleType;
 import org.apache.cloudstack.affinity.AffinityGroupService;
 import org.apache.cloudstack.alert.AlertService;
+import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
 import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService;
 import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService;
 import org.apache.cloudstack.query.QueryService;
 import org.apache.cloudstack.usage.UsageService;
+
 import org.apache.log4j.Logger;
 
 import com.cloud.configuration.ConfigurationService;
@@ -74,6 +80,7 @@ import com.cloud.user.Account;
 import com.cloud.user.AccountService;
 import com.cloud.user.DomainService;
 import com.cloud.user.ResourceLimitService;
+import com.cloud.utils.ReflectUtil;
 import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.db.UUIDManager;
 import com.cloud.vm.UserVmService;
@@ -97,7 +104,9 @@ public abstract class BaseCmd {
     public static Pattern newInputDateFormat = Pattern.compile("[\\d]+-[\\d]+-[\\d]+ [\\d]+:[\\d]+:[\\d]+");
     private static final DateFormat s_outputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
 
-    private Object _responseObject = null;
+    protected static final Map<Class<?>, List<Field>> fieldsForCmdClass = new HashMap<Class<?>, List<Field>>();
+
+    private Object _responseObject;
     private Map<String, String> fullUrlParams;
 
     public enum HTTPMethod {
@@ -205,7 +214,7 @@ public abstract class BaseCmd {
         return httpMethod;
     }
 
-    public void setHttpMethod(String method) {
+    public void setHttpMethod(final String method) {
         if (method != null) {
             if (method.equalsIgnoreCase("GET"))
                 httpMethod = HTTPMethod.GET;
@@ -227,12 +236,36 @@ public abstract class BaseCmd {
         return responseType;
     }
 
-    public void setResponseType(String responseType) {
+    public void setResponseType(final String responseType) {
         this.responseType = responseType;
     }
 
+    /**
+     * For some reason this method does not return the actual command name, but more a name that
+     * is used to create the response. So you can expect for a XCmd a value like xcmdresponse. Anyways
+     * this methods is used in too many places so for now instead of changing it we just create another
+     * method {@link BaseCmd#getActualCommandName()} that returns the value from {@link APICommand#name()}
+     *
+     * @return
+     */
     public abstract String getCommandName();
 
+
+    /**
+     * Gets the CommandName based on the class annotations: the value from {@link APICommand#name()}
+     *
+     * @return the value from {@link APICommand#name()}
+     */
+    public String getActualCommandName() {
+        String cmdName = null;
+        if (this.getClass().getAnnotation(APICommand.class) != null) {
+            cmdName = this.getClass().getAnnotation(APICommand.class).name();
+        } else {
+            cmdName = this.getClass().getName();
+        }
+       return cmdName;
+    }
+
     /**
      * For commands the API framework needs to know the owner of the object being acted upon. This method is
      * used to determine that information.
@@ -245,7 +278,7 @@ public abstract class BaseCmd {
         return _responseObject;
     }
 
-    public void setResponseObject(Object responseObject) {
+    public void setResponseObject(final Object responseObject) {
         _responseObject = responseObject;
     }
 
@@ -253,7 +286,7 @@ public abstract class BaseCmd {
         return _mgr;
     }
 
-    public static String getDateString(Date date) {
+    public static String getDateString(final Date date) {
         if (date == null) {
             return "";
         }
@@ -264,101 +297,86 @@ public abstract class BaseCmd {
         return formattedString;
     }
 
-    // FIXME: move this to a utils method so that maps can be unpacked and integer/long values can be appropriately cast
-    @SuppressWarnings({"unchecked", "rawtypes"})
-    public Map<String, Object> unpackParams(Map<String, String> params) {
-        Map<String, Object> lowercaseParams = new HashMap<String, Object>();
-        for (String key : params.keySet()) {
-            int arrayStartIndex = key.indexOf('[');
-            int arrayStartLastIndex = key.lastIndexOf('[');
-            if (arrayStartIndex != arrayStartLastIndex) {
-                throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key +
-                    "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
-            }
+    protected List<Field> getAllFieldsForClass(final Class<?> clazz) {
+        List<Field> filteredFields = fieldsForCmdClass.get(clazz);
 
-            if (arrayStartIndex > 0) {
-                int arrayEndIndex = key.indexOf(']');
-                int arrayEndLastIndex = key.lastIndexOf(']');
-                if ((arrayEndIndex < arrayStartIndex) || (arrayEndIndex != arrayEndLastIndex)) {
-                    // malformed parameter
-                    throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key +
-                        "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
-                }
+        // If list of fields was not cached yet
+        if (filteredFields == null) {
+            final List<Field> allFields = ReflectUtil.getAllFieldsForClass(this.getClass(), BaseCmd.class);
+            filteredFields = new ArrayList<Field>();
 
-                // Now that we have an array object, check for a field name in the case of a complex object
-                int fieldIndex = key.indexOf('.');
-                String fieldName = null;
-                if (fieldIndex < arrayEndIndex) {
-                    throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key +
-                        "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
-                } else {
-                    fieldName = key.substring(fieldIndex + 1);
+            for (final Field field : allFields) {
+                final Parameter parameterAnnotation = field.getAnnotation(Parameter.class);
+                if ((parameterAnnotation != null) && parameterAnnotation.expose()) {
+                    filteredFields.add(field);
                 }
+            }
 
-                // parse the parameter name as the text before the first '[' character
-                String paramName = key.substring(0, arrayStartIndex);
-                paramName = paramName.toLowerCase();
-
-                Map<Integer, Map> mapArray = null;
-                Map<String, Object> mapValue = null;
-                String indexStr = key.substring(arrayStartIndex + 1, arrayEndIndex);
-                int index = 0;
-                boolean parsedIndex = false;
-                try {
-                    if (indexStr != null) {
-                        index = Integer.parseInt(indexStr);
-                        parsedIndex = true;
-                    }
-                } catch (NumberFormatException nfe) {
-                    s_logger.warn("Invalid parameter " + key + " received, unable to parse object array, returning an error.");
-                }
+            // Cache the prepared list for future use
+            fieldsForCmdClass.put(clazz, filteredFields);
+        }
+        return filteredFields;
+    }
 
-                if (!parsedIndex) {
-                    throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key +
-                        "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
-                }
+    protected Account getCurrentContextAccount() {
+        return CallContext.current().getCallingAccount();
+    }
 
-                Object value = lowercaseParams.get(paramName);
-                if (value == null) {
-                    // for now, assume object array with sub fields
-                    mapArray = new HashMap<Integer, Map>();
-                    mapValue = new HashMap<String, Object>();
-                    mapArray.put(Integer.valueOf(index), mapValue);
-                } else if (value instanceof Map) {
-                    mapArray = (HashMap)value;
-                    mapValue = mapArray.get(Integer.valueOf(index));
-                    if (mapValue == null) {
-                        mapValue = new HashMap<String, Object>();
-                        mapArray.put(Integer.valueOf(index), mapValue);
+    /**
+     * This method doesn't return all the @{link Parameter}, but only the ones exposed
+     * and allowed for current @{link RoleType}. This method will get the fields for a given
+     * Cmd class only once and never again, so in case of a dynamic update the result would
+     * be obsolete (this might be a plugin update. It is agreed upon that we will not do
+     * upgrades dynamically but in case we come back on that decision we need to revisit this)
+     *
+     * @return
+     */
+    public List<Field> getParamFields() {
+        final List<Field> allFields = getAllFieldsForClass(this.getClass());
+        final List<Field> validFields = new ArrayList<Field>();
+        final Account caller = getCurrentContextAccount();
+
+        for (final Field field : allFields) {
+            final Parameter parameterAnnotation = field.getAnnotation(Parameter.class);
+
+            //TODO: Annotate @Validate on API Cmd classes, FIXME how to process Validate
+            final RoleType[] allowedRoles = parameterAnnotation.authorized();
+            boolean roleIsAllowed = true;
+            if (allowedRoles.length > 0) {
+                roleIsAllowed = false;
+                for (final RoleType allowedRole : allowedRoles) {
+                    if (allowedRole.getValue() == caller.getType()) {
+                        roleIsAllowed = true;
+                        break;
                     }
                 }
+            }
 
-                // we are ready to store the value for a particular field into the map for this object
-                mapValue.put(fieldName, params.get(key));
-
-                lowercaseParams.put(paramName, mapArray);
+            if (roleIsAllowed) {
+                validFields.add(field);
             } else {
-                lowercaseParams.put(key.toLowerCase(), params.get(key));
+                s_logger.debug("Ignoring paremeter " + parameterAnnotation.name() + " as the caller is not authorized to pass it in");
             }
         }
-        return lowercaseParams;
+
+        return validFields;
     }
 
-    protected long getInstanceIdFromJobSuccessResult(String result) {
+    protected long getInstanceIdFromJobSuccessResult(final String result) {
         s_logger.debug("getInstanceIdFromJobSuccessResult not overridden in subclass " + this.getClass().getName());
         return 0;
     }
 
-    public static boolean isAdmin(short accountType) {
+    public static boolean isAdmin(final short accountType) {
         return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) ||
             (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN));
     }
 
-    public static boolean isRootAdmin(short accountType) {
+    public static boolean isRootAdmin(final short accountType) {
         return ((accountType == Account.ACCOUNT_TYPE_ADMIN));
     }
 
-    public void setFullUrlParams(Map<String, String> map) {
+    public void setFullUrlParams(final Map<String, String> map) {
         fullUrlParams = map;
     }
 
@@ -366,18 +384,18 @@ public abstract class BaseCmd {
         return fullUrlParams;
     }
 
-    public Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly) {
+    public Long finalyzeAccountId(final String accountName, final Long domainId, final Long projectId, final boolean enabledOnly) {
         if (accountName != null) {
             if (domainId == null) {
                 throw new InvalidParameterValueException("Account must be specified with domainId parameter");
             }
 
-            Domain domain = _domainService.getDomain(domainId);
+            final Domain domain = _domainService.getDomain(domainId);
             if (domain == null) {
                 throw new InvalidParameterValueException("Unable to find domain by id");
             }
 
-            Account account = _accountService.getActiveAccountByName(accountName, domainId);
+            final Account account = _accountService.getActiveAccountByName(accountName, domainId);
             if (account != null && account.getType() != Account.ACCOUNT_TYPE_PROJECT) {
                 if (!enabledOnly || account.getState() == Account.State.enabled) {
                     return account.getId();
@@ -394,12 +412,12 @@ public abstract class BaseCmd {
         }
 
         if (projectId != null) {
-            Project project = _projectService.getProject(projectId);
+            final Project project = _projectService.getProject(projectId);
             if (project != null) {
                 if (!enabledOnly || project.getState() == Project.State.Active) {
                     return project.getProjectAccountId();
                 } else {
-                    PermissionDeniedException ex =
+                    final PermissionDeniedException ex =
                         new PermissionDeniedException("Can't add resources to the project with specified projectId in state=" + project.getState() +
                             " as it's no longer active");
                     ex.addProxyObject(project.getUuid(), "projectId");
@@ -413,6 +431,13 @@ public abstract class BaseCmd {
     }
 
     /**
+     * To be overwritten by any class who needs specific validation
+     */
+    public void validateSpecificParameters(final Map<String, String> params){
+        // To be overwritten by any class who needs specific validation
+    }
+
+    /**
      * display flag is used to control the display of the resource only to the end user. It doesnt affect Root Admin.
      * @return display flag
      */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/api/src/org/apache/cloudstack/api/BaseListCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/BaseListCmd.java b/api/src/org/apache/cloudstack/api/BaseListCmd.java
index c1a4b4c..f280003 100644
--- a/api/src/org/apache/cloudstack/api/BaseListCmd.java
+++ b/api/src/org/apache/cloudstack/api/BaseListCmd.java
@@ -16,7 +16,10 @@
 // under the License.
 package org.apache.cloudstack.api;
 
+import java.util.Map;
+
 import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.utils.exception.CSExceptionErrorCode;
 
 public abstract class BaseListCmd extends BaseCmd {
 
@@ -83,7 +86,7 @@ public abstract class BaseListCmd extends BaseCmd {
 
     public Long getPageSizeVal() {
         Long defaultPageSize = s_maxPageSize;
-        Integer pageSizeInt = getPageSize();
+        final Integer pageSizeInt = getPageSize();
         if (pageSizeInt != null) {
             defaultPageSize = pageSizeInt.longValue();
         }
@@ -96,12 +99,12 @@ public abstract class BaseListCmd extends BaseCmd {
 
     public Long getStartIndex() {
         Long startIndex = Long.valueOf(0);
-        Long pageSizeVal = getPageSizeVal();
+        final Long pageSizeVal = getPageSizeVal();
 
         if (pageSizeVal == null) {
             startIndex = null;
         } else if (page != null) {
-            int pageNum = page.intValue();
+            final int pageNum = page.intValue();
             if (pageNum > 0) {
                 startIndex = Long.valueOf(pageSizeVal * (pageNum - 1));
             }
@@ -112,4 +115,25 @@ public abstract class BaseListCmd extends BaseCmd {
     public ApiCommandJobType getInstanceType() {
         return ApiCommandJobType.None;
     }
+
+    @Override
+    public void validateSpecificParameters(final Map<String, String> params){
+        super.validateSpecificParameters(params);
+
+        final Object pageSizeObj = params.get(ApiConstants.PAGE_SIZE);
+        Long pageSize = null;
+        if (pageSizeObj != null) {
+            pageSize = Long.valueOf((String)pageSizeObj);
+        }
+
+        if (params.get(ApiConstants.PAGE) == null &&
+                pageSize != null &&
+                !pageSize.equals(BaseListCmd.s_pageSizeUnlimited)) {
+            final ServerApiException ex = new ServerApiException(ApiErrorCode.PARAM_ERROR, "\"page\" parameter is required when \"pagesize\" is specified");
+            ex.setCSErrorCode(CSExceptionErrorCode.getCSErrCode(ex.getClass().getName()));
+            throw ex;
+        } else if (pageSize == null && (params.get(ApiConstants.PAGE) != null)) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "\"pagesize\" parameter is required when \"page\" is specified");
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/api/test/org/apache/cloudstack/api/BaseCmdTest.java
----------------------------------------------------------------------
diff --git a/api/test/org/apache/cloudstack/api/BaseCmdTest.java b/api/test/org/apache/cloudstack/api/BaseCmdTest.java
new file mode 100644
index 0000000..edf5776
--- /dev/null
+++ b/api/test/org/apache/cloudstack/api/BaseCmdTest.java
@@ -0,0 +1,69 @@
+// 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;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+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;
+
+public class BaseCmdTest {
+
+    private static final String NON_EXPECTED_COMMAND_NAME = "Non expected command name";
+    protected static final String CMD1_NAME = "Cmd1Name";
+    protected static final String CMD2_NAME = "Cmd2Name";
+    protected static final String CMD1_RESPONSE = "cmd1response";
+    protected static final String CMD2_RESPONSE = "cmd2response";
+
+    @Test
+    public void testGetActualCommandName(){
+        BaseCmd cmd1 = new Cmd1();
+        BaseCmd cmd2 = new Cmd2();
+
+        assertEquals(NON_EXPECTED_COMMAND_NAME, CMD1_NAME, cmd1.getActualCommandName());
+        assertEquals(NON_EXPECTED_COMMAND_NAME, CMD2_NAME, cmd2.getActualCommandName());
+    }
+}
+
+@APICommand(name=BaseCmdTest.CMD1_NAME, responseObject=BaseResponse.class)
+class Cmd1 extends BaseCmd {
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException,
+            NetworkRuleConflictException {
+    }
+    @Override
+    public String getCommandName() {
+        return BaseCmdTest.CMD1_RESPONSE;
+    }
+    @Override
+    public long getEntityOwnerId() {
+        return 0;
+    }
+}
+
+@APICommand(name=BaseCmdTest.CMD2_NAME, responseObject=BaseResponse.class)
+class Cmd2 extends Cmd1 {
+    @Override
+    public String getCommandName() {
+        return BaseCmdTest.CMD2_RESPONSE;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml
----------------------------------------------------------------------
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
index fd2f5fb..91401e3 100644
--- 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
@@ -50,6 +50,18 @@
 
     <bean id="apiDispatcher" class="com.cloud.api.ApiDispatcher" />
 
+    <bean id="dispatchChainFactory" class="com.cloud.api.dispatch.DispatchChainFactory" />
+
+    <bean id="paramProcessWorker" class="com.cloud.api.dispatch.ParamProcessWorker" />
+
+    <bean id="paramUnpackWorker" class="com.cloud.api.dispatch.ParamUnpackWorker" />
+
+    <bean id="paramGenericValidationWorker" class="com.cloud.api.dispatch.ParamGenericValidationWorker" />
+
+    <bean id="specificCmdValidationWorker" class="com.cloud.api.dispatch.SpecificCmdValidationWorker" />
+
+    <bean id="commandCreationWorker" class="com.cloud.api.dispatch.CommandCreationWorker" />
+
     <bean id="apiResponseHelper" class="com.cloud.api.ApiResponseHelper" />
 
     <bean id="apiServer" class="com.cloud.api.ApiServer">

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/src/com/cloud/api/ApiDispatcher.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java
index 5bdefe7..5d4b4d3 100755
--- a/server/src/com/cloud/api/ApiDispatcher.java
+++ b/server/src/com/cloud/api/ApiDispatcher.java
@@ -16,127 +16,72 @@
 // under the License.
 package com.cloud.api;
 
-import static org.apache.commons.lang.StringUtils.isNotBlank;
-
-import java.lang.reflect.Field;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.regex.Matcher;
 
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.acl.InfrastructureEntity;
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
 import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
 import org.apache.cloudstack.api.BaseAsyncCmd;
 import org.apache.cloudstack.api.BaseAsyncCreateCmd;
 import org.apache.cloudstack.api.BaseAsyncCustomIdCmd;
 import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.BaseCmd.CommandType;
 import org.apache.cloudstack.api.BaseCustomIdCmd;
-import org.apache.cloudstack.api.BaseListCmd;
-import org.apache.cloudstack.api.EntityReference;
-import org.apache.cloudstack.api.InternalIdentity;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.admin.resource.ArchiveAlertsCmd;
-import org.apache.cloudstack.api.command.admin.resource.DeleteAlertsCmd;
-import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd;
-import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd;
-import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.framework.jobs.AsyncJob;
 import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 import org.apache.log4j.Logger;
 
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.ReflectUtil;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.exception.CSExceptionErrorCode;
-import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.api.dispatch.DispatchChain;
+import com.cloud.api.dispatch.DispatchChainFactory;
+import com.cloud.api.dispatch.DispatchTask;
 
 public class ApiDispatcher {
     private static final Logger s_logger = Logger.getLogger(ApiDispatcher.class.getName());
 
     Long _createSnapshotQueueSizeLimit;
+
     @Inject
-    AsyncJobManager _asyncMgr = null;
-    @Inject
-    AccountManager _accountMgr = null;
-    @Inject
-    EntityManager _entityMgr = null;
+    AsyncJobManager _asyncMgr;
 
-    private static ApiDispatcher s_instance;
+    @Inject()
+    protected DispatchChainFactory dispatchChainFactory;
 
-    public static ApiDispatcher getInstance() {
-        return s_instance;
-    }
+    protected DispatchChain standardDispatchChain;
+
+    protected DispatchChain asyncCreationDispatchChain;
 
     public ApiDispatcher() {
     }
 
     @PostConstruct
-    void init() {
-        s_instance = this;
+    public void setup() {
+        standardDispatchChain = dispatchChainFactory.getStandardDispatchChain();
+        asyncCreationDispatchChain = dispatchChainFactory.getAsyncCreationDispatchChain();
     }
 
-    public void setCreateSnapshotQueueSizeLimit(Long snapshotLimit) {
+    public void setCreateSnapshotQueueSizeLimit(final Long snapshotLimit) {
         _createSnapshotQueueSizeLimit = snapshotLimit;
     }
 
-    public void dispatchCreateCmd(BaseAsyncCreateCmd cmd, Map<String, String> params) throws Exception {
-        processParameters(cmd, params);
-        CallContext.current().setEventDisplayEnabled(cmd.isDisplayResourceEnabled());
-        cmd.create();
 
+    public void dispatchCreateCmd(final BaseAsyncCreateCmd cmd, final Map<String, String> params) throws Exception {
+        asyncCreationDispatchChain.dispatch(new DispatchTask(cmd, params));
+        CallContext.current().setEventDisplayEnabled(cmd.isDisplayResourceEnabled());
     }
 
-    private void doAccessChecks(BaseCmd cmd, Map<Object, AccessType> entitiesToAccess) {
-        Account caller = CallContext.current().getCallingAccount();
-        Account owner = _accountMgr.getActiveAccountById(cmd.getEntityOwnerId());
+    public void dispatch(final BaseCmd cmd, final Map<String, String> params, final boolean execute) throws Exception {
+        // Let the chain of responsibility dispatch gradually
+        standardDispatchChain.dispatch(new DispatchTask(cmd, params));
 
-        if (cmd instanceof BaseAsyncCreateCmd) {
-            //check that caller can access the owner account.
-            _accountMgr.checkAccess(caller, null, true, owner);
-        }
-
-        if (!entitiesToAccess.isEmpty()) {
-            //check that caller can access the owner account.
-            _accountMgr.checkAccess(caller, null, true, owner);
-            for (Object entity : entitiesToAccess.keySet()) {
-                if (entity instanceof ControlledEntity) {
-                    _accountMgr.checkAccess(caller, entitiesToAccess.get(entity), true, (ControlledEntity)entity);
-                } else if (entity instanceof InfrastructureEntity) {
-                    //FIXME: Move this code in adapter, remove code from Account manager
-                }
-            }
-        }
-    }
-
-    public void dispatch(BaseCmd cmd, Map<String, String> params, boolean execute) throws Exception {
-        processParameters(cmd, params);
-        CallContext ctx = CallContext.current();
+        final CallContext ctx = CallContext.current();
         ctx.setEventDisplayEnabled(cmd.isDisplayResourceEnabled());
 
+        // TODO This if shouldn't be here. Use polymorphism and move it to validateSpecificParameters
         if (cmd instanceof BaseAsyncCmd) {
 
-            BaseAsyncCmd asyncCmd = (BaseAsyncCmd)cmd;
-            String startEventId = params.get("ctxStartEventId");
+            final BaseAsyncCmd asyncCmd = (BaseAsyncCmd)cmd;
+            final String startEventId = params.get(ApiConstants.CTX_START_EVENT_ID);
             ctx.setStartEventId(Long.valueOf(startEventId));
 
             // Synchronise job on the object if needed
@@ -160,6 +105,7 @@ public class ApiDispatcher {
             }
         }
 
+        // TODO This if shouldn't be here. Use polymorphism and move it to validateSpecificParameters
         if (cmd instanceof BaseAsyncCustomIdCmd) {
             ((BaseAsyncCustomIdCmd)cmd).checkUuid();
         } else if (cmd instanceof BaseCustomIdCmd) {
@@ -167,392 +113,6 @@ public class ApiDispatcher {
         }
 
         cmd.execute();
-
     }
 
-    @SuppressWarnings({"unchecked", "rawtypes"})
-    public static void processParameters(BaseCmd cmd, Map<String, String> params) {
-        Map<Object, AccessType> entitiesToAccess = new HashMap<Object, AccessType>();
-        Map<String, Object> unpackedParams = cmd.unpackParams(params);
-
-        if (cmd instanceof BaseListCmd) {
-            Object pageSizeObj = unpackedParams.get(ApiConstants.PAGE_SIZE);
-            Long pageSize = null;
-            if (pageSizeObj != null) {
-                pageSize = Long.valueOf((String)pageSizeObj);
-            }
-
-            if ((unpackedParams.get(ApiConstants.PAGE) == null) && (pageSize != null && !pageSize.equals(BaseListCmd.s_pageSizeUnlimited))) {
-                ServerApiException ex = new ServerApiException(ApiErrorCode.PARAM_ERROR, "\"page\" parameter is required when \"pagesize\" is specified");
-                ex.setCSErrorCode(CSExceptionErrorCode.getCSErrCode(ex.getClass().getName()));
-                throw ex;
-            } else if (pageSize == null && (unpackedParams.get(ApiConstants.PAGE) != null)) {
-                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "\"pagesize\" parameter is required when \"page\" is specified");
-            }
-        }
-
-        List<Field> fields = ReflectUtil.getAllFieldsForClass(cmd.getClass(), BaseCmd.class);
-
-        for (Field field : fields) {
-            Parameter parameterAnnotation = field.getAnnotation(Parameter.class);
-            if ((parameterAnnotation == null) || !parameterAnnotation.expose()) {
-                continue;
-            }
-
-            //TODO: Annotate @Validate on API Cmd classes, FIXME how to process Validate
-            RoleType[] allowedRoles = parameterAnnotation.authorized();
-            if (allowedRoles.length > 0) {
-                boolean permittedParameter = false;
-                Account caller = CallContext.current().getCallingAccount();
-                for (RoleType allowedRole : allowedRoles) {
-                    if (allowedRole.getValue() == caller.getType()) {
-                        permittedParameter = true;
-                        break;
-                    }
-                }
-                if (!permittedParameter) {
-                    s_logger.debug("Ignoring paremeter " + parameterAnnotation.name() + " as the caller is not authorized to pass it in");
-                    continue;
-                }
-            }
-
-            Object paramObj = unpackedParams.get(parameterAnnotation.name());
-            if (paramObj == null) {
-                if (parameterAnnotation.required()) {
-                    throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to execute API command " +
-                        cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) + " due to missing parameter " + parameterAnnotation.name());
-                }
-                continue;
-            }
-
-            // marshall the parameter into the correct type and set the field value
-            try {
-                setFieldValue(field, cmd, paramObj, parameterAnnotation);
-            } catch (IllegalArgumentException argEx) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Unable to execute API command " + cmd.getCommandName() + " due to invalid value " + paramObj + " for parameter " +
-                        parameterAnnotation.name());
-                }
-                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to execute API command " +
-                    cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) + " due to invalid value " + paramObj + " for parameter " +
-                    parameterAnnotation.name());
-            } catch (ParseException parseEx) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Invalid date parameter " + paramObj + " passed to command " + cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8));
-                }
-                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to parse date " + paramObj + " for command " +
-                    cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) + ", please pass dates in the format mentioned in the api documentation");
-            } catch (InvalidParameterValueException invEx) {
-                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to execute API command " +
-                    cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) + " due to invalid value. " + invEx.getMessage());
-            } catch (CloudRuntimeException cloudEx) {
-                s_logger.error("CloudRuntimeException", cloudEx);
-                // FIXME: Better error message? This only happens if the API command is not executable, which typically
-                //means
-                // there was
-                // and IllegalAccessException setting one of the parameters.
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Internal error executing API command " +
-                    cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8));
-            }
-
-            //check access on the resource this field points to
-            try {
-                ACL checkAccess = field.getAnnotation(ACL.class);
-                CommandType fieldType = parameterAnnotation.type();
-
-                if (checkAccess != null) {
-                    // Verify that caller can perform actions in behalf of vm owner
-                    //acumulate all Controlled Entities together.
-
-                    //parse the array of resource types and in case of map check access on key or value or both as specified in @acl
-                    //implement external dao for classes that need findByName
-                    //for maps, specify access to be checkd on key or value.
-
-                    // find the controlled entity DBid by uuid
-                    if (parameterAnnotation.entityType() != null) {
-                        Class<?>[] entityList = parameterAnnotation.entityType()[0].getAnnotation(EntityReference.class).value();
-
-                        for (Class entity : entityList) {
-                            // Check if the parameter type is a single
-                            // Id or list of id's/name's
-                            switch (fieldType) {
-                                case LIST:
-                                    CommandType listType = parameterAnnotation.collectionType();
-                                    switch (listType) {
-                                        case LONG:
-                                        case UUID:
-                                            List<Long> listParam = (List<Long>)field.get(cmd);
-                                            for (Long entityId : listParam) {
-                                                Object entityObj = s_instance._entityMgr.findById(entity, entityId);
-                                                entitiesToAccess.put(entityObj, checkAccess.accessType());
-                                            }
-                                            break;
-                                        /*
-                                         * case STRING: List<String> listParam =
-                                         * new ArrayList<String>(); listParam =
-                                         * (List)field.get(cmd); for(String
-                                         * entityName: listParam){
-                                         * ControlledEntity entityObj =
-                                         * (ControlledEntity
-                                         * )daoClassInstance(entityId);
-                                         * entitiesToAccess.add(entityObj); }
-                                         * break;
-                                         */
-                                        default:
-                                            break;
-                                    }
-                                    break;
-                                case LONG:
-                                case UUID:
-                                    Object entityObj = s_instance._entityMgr.findById(entity, (Long)field.get(cmd));
-                                    entitiesToAccess.put(entityObj, checkAccess.accessType());
-                                    break;
-                                default:
-                                    break;
-                            }
-
-                            if (ControlledEntity.class.isAssignableFrom(entity)) {
-                                if (s_logger.isDebugEnabled()) {
-                                    s_logger.debug("ControlledEntity name is:" + entity.getName());
-                                }
-                            }
-
-                            if (InfrastructureEntity.class.isAssignableFrom(entity)) {
-                                if (s_logger.isDebugEnabled()) {
-                                    s_logger.debug("InfrastructureEntity name is:" + entity.getName());
-                                }
-                            }
-                        }
-
-                    }
-
-                }
-
-            } catch (IllegalArgumentException e) {
-                s_logger.error("Error initializing command " + cmd.getCommandName() + ", field " + field.getName() + " is not accessible.");
-                throw new CloudRuntimeException("Internal error initializing parameters for command " + cmd.getCommandName() + " [field " + field.getName() +
-                    " is not accessible]");
-            } catch (IllegalAccessException e) {
-                s_logger.error("Error initializing command " + cmd.getCommandName() + ", field " + field.getName() + " is not accessible.");
-                throw new CloudRuntimeException("Internal error initializing parameters for command " + cmd.getCommandName() + " [field " + field.getName() +
-                    " is not accessible]");
-            }
-
-        }
-
-        //check access on the entities.
-        getInstance().doAccessChecks(cmd, entitiesToAccess);
-
-    }
-
-    private static Long translateUuidToInternalId(String uuid, Parameter annotation) {
-        if (uuid.equals("-1")) {
-            // FIXME: This is to handle a lot of hardcoded special cases where -1 is sent
-            // APITODO: Find and get rid of all hardcoded params in API Cmds and service layer
-            return -1L;
-        }
-        Long internalId = null;
-        // If annotation's empty, the cmd existed before 3.x try conversion to long
-        boolean isPre3x = annotation.since().isEmpty();
-        // Match against Java's UUID regex to check if input is uuid string
-        boolean isUuid = uuid.matches("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$");
-        // Enforce that it's uuid for newly added apis from version 3.x
-        if (!isPre3x && !isUuid)
-            return null;
-        // Allow both uuid and internal id for pre3x apis
-        if (isPre3x && !isUuid) {
-            try {
-                internalId = Long.parseLong(uuid);
-            } catch (NumberFormatException e) {
-                internalId = null;
-            }
-            if (internalId != null)
-                return internalId;
-        }
-        // There may be multiple entities defined on the @EntityReference of a Response.class
-        // UUID CommandType would expect only one entityType, so use the first entityType
-        Class<?>[] entities = annotation.entityType()[0].getAnnotation(EntityReference.class).value();
-        // Go through each entity which is an interface to a VO class and get a VO object
-        // Try to getId() for the object using reflection, break on first non-null value
-        for (Class<?> entity : entities) {
-            // For backward compatibility, we search within removed entities and let service layer deal
-            // with removed ones, return empty response or error
-            Object objVO = s_instance._entityMgr.findByUuidIncludingRemoved(entity, uuid);
-            if (objVO == null) {
-                continue;
-            }
-            // Invoke the getId method, get the internal long ID
-            // If that fails hide exceptions as the uuid may not exist
-            try {
-                internalId = ((InternalIdentity)objVO).getId();
-            } catch (IllegalArgumentException e) {
-            } catch (NullPointerException e) {
-            }
-            // Return on first non-null Id for the uuid entity
-            if (internalId != null)
-                break;
-        }
-        if (internalId == null) {
-            if (s_logger.isDebugEnabled())
-                s_logger.debug("Object entity uuid = " + uuid + " does not exist in the database.");
-            throw new InvalidParameterValueException("Invalid parameter " + annotation.name() + " value=" + uuid +
-                " due to incorrect long value format, or entity does not exist or due to incorrect parameter annotation for the field in api cmd class.");
-        }
-        return internalId;
-    }
-
-    @SuppressWarnings({"unchecked", "rawtypes"})
-    private static void setFieldValue(Field field, BaseCmd cmdObj, Object paramObj, Parameter annotation) throws IllegalArgumentException, ParseException {
-        try {
-            field.setAccessible(true);
-            CommandType fieldType = annotation.type();
-            switch (fieldType) {
-                case BOOLEAN:
-                    field.set(cmdObj, Boolean.valueOf(paramObj.toString()));
-                    break;
-                case DATE:
-                    // This piece of code is for maintaining backward compatibility
-                    // and support both the date formats(Bug 9724)
-                    // Do the date messaging for ListEventsCmd only
-                    if (cmdObj instanceof ListEventsCmd || cmdObj instanceof DeleteEventsCmd || cmdObj instanceof ArchiveEventsCmd ||
-                        cmdObj instanceof ArchiveAlertsCmd || cmdObj instanceof DeleteAlertsCmd) {
-                        boolean isObjInNewDateFormat = isObjInNewDateFormat(paramObj.toString());
-                        if (isObjInNewDateFormat) {
-                            DateFormat newFormat = BaseCmd.NEW_INPUT_FORMAT;
-                            synchronized (newFormat) {
-                                field.set(cmdObj, newFormat.parse(paramObj.toString()));
-                            }
-                        } else {
-                            DateFormat format = BaseCmd.INPUT_FORMAT;
-                            synchronized (format) {
-                                Date date = format.parse(paramObj.toString());
-                                if (field.getName().equals("startDate")) {
-                                    date = messageDate(date, 0, 0, 0);
-                                } else if (field.getName().equals("endDate")) {
-                                    date = messageDate(date, 23, 59, 59);
-                                }
-                                field.set(cmdObj, date);
-                            }
-                        }
-                    } else {
-                        DateFormat format = BaseCmd.INPUT_FORMAT;
-                        synchronized (format) {
-                        format.setLenient(false);
-                            field.set(cmdObj, format.parse(paramObj.toString()));
-                        }
-                    }
-                    break;
-                case FLOAT:
-                    // Assuming that the parameters have been checked for required before now,
-                    // we ignore blank or null values and defer to the command to set a default
-                    // value for optional parameters ...
-                    if (paramObj != null && isNotBlank(paramObj.toString())) {
-                        field.set(cmdObj, Float.valueOf(paramObj.toString()));
-                    }
-                    break;
-                case INTEGER:
-                    // Assuming that the parameters have been checked for required before now,
-                    // we ignore blank or null values and defer to the command to set a default
-                    // value for optional parameters ...
-                    if (paramObj != null && isNotBlank(paramObj.toString())) {
-                        field.set(cmdObj, Integer.valueOf(paramObj.toString()));
-                    }
-                    break;
-                case LIST:
-                    List listParam = new ArrayList();
-                    StringTokenizer st = new StringTokenizer(paramObj.toString(), ",");
-                    while (st.hasMoreTokens()) {
-                        String token = st.nextToken();
-                        CommandType listType = annotation.collectionType();
-                        switch (listType) {
-                            case INTEGER:
-                                listParam.add(Integer.valueOf(token));
-                                break;
-                            case UUID:
-                                if (token.isEmpty())
-                                    break;
-                                Long internalId = translateUuidToInternalId(token, annotation);
-                                listParam.add(internalId);
-                                break;
-                            case LONG: {
-                                listParam.add(Long.valueOf(token));
-                            }
-                                break;
-                            case SHORT:
-                                listParam.add(Short.valueOf(token));
-                            case STRING:
-                                listParam.add(token);
-                                break;
-                        }
-                    }
-                    field.set(cmdObj, listParam);
-                    break;
-                case UUID:
-                    if (paramObj.toString().isEmpty())
-                        break;
-                    Long internalId = translateUuidToInternalId(paramObj.toString(), annotation);
-                    field.set(cmdObj, internalId);
-                    break;
-                case LONG:
-                    field.set(cmdObj, Long.valueOf(paramObj.toString()));
-                    break;
-                case SHORT:
-                    field.set(cmdObj, Short.valueOf(paramObj.toString()));
-                    break;
-                case STRING:
-                    if ((paramObj != null) && paramObj.toString().length() > annotation.length()) {
-                        s_logger.error("Value greater than max allowed length " + annotation.length() + " for param: " + field.getName());
-                        throw new InvalidParameterValueException("Value greater than max allowed length " + annotation.length() + " for param: " + field.getName());
-                    }
-                    field.set(cmdObj, paramObj.toString());
-                    break;
-                case TZDATE:
-                    field.set(cmdObj, DateUtil.parseTZDateString(paramObj.toString()));
-                    break;
-                case MAP:
-                default:
-                    field.set(cmdObj, paramObj);
-                    break;
-            }
-        } catch (IllegalAccessException ex) {
-            s_logger.error("Error initializing command " + cmdObj.getCommandName() + ", field " + field.getName() + " is not accessible.");
-            throw new CloudRuntimeException("Internal error initializing parameters for command " + cmdObj.getCommandName() + " [field " + field.getName() +
-                " is not accessible]");
-        }
-    }
-
-    private static boolean isObjInNewDateFormat(String string) {
-        Matcher matcher = BaseCmd.newInputDateFormat.matcher(string);
-        return matcher.matches();
-    }
-
-    private static Date messageDate(Date date, int hourOfDay, int minute, int second) {
-        Calendar cal = Calendar.getInstance();
-        cal.setTime(date);
-        cal.set(Calendar.HOUR_OF_DAY, hourOfDay);
-        cal.set(Calendar.MINUTE, minute);
-        cal.set(Calendar.SECOND, second);
-        return cal.getTime();
-    }
-
-    public static void plugService(Field field, BaseCmd cmd) {
-
-        Class<?> fc = field.getType();
-        Object instance = null;
-
-        if (instance == null) {
-            throw new CloudRuntimeException("Unable to plug service " + fc.getSimpleName() + " in command " + cmd.getClass().getSimpleName());
-        }
-
-        try {
-            field.setAccessible(true);
-            field.set(cmd, instance);
-        } catch (IllegalArgumentException e) {
-            s_logger.error("IllegalArgumentException at plugService for command " + cmd.getCommandName() + ", field " + field.getName());
-            throw new CloudRuntimeException("Internal error at plugService for command " + cmd.getCommandName() + " [Illegal argumet at field " + field.getName() + "]");
-        } catch (IllegalAccessException e) {
-            s_logger.error("Error at plugService for command " + cmd.getCommandName() + ", field " + field.getName() + " is not accessible.");
-            throw new CloudRuntimeException("Internal error at plugService for command " + cmd.getCommandName() + " [field " + field.getName() + " is not accessible]");
-        }
-    }
 }


[42/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
-add check to ensure 'Connectivity' service provider specified in
createVpcOffering actually supports 'DistributedRouter' capability

- enable OVS to support 'DistributedRouter' capability


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c7529d81
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c7529d81
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c7529d81

Branch: refs/heads/distributedrouter
Commit: c7529d8150ec3860cb6503b2eaf272594318c737
Parents: 7ce4237
Author: Murali Reddy <mu...@gmail.com>
Authored: Tue Mar 4 17:17:18 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Tue Mar 11 18:36:56 2014 +0530

----------------------------------------------------------------------
 .../com/cloud/network/element/OvsElement.java   |  5 +-
 .../com/cloud/network/vpc/VpcManagerImpl.java   | 52 ++++++++++++++++++++
 2 files changed, 56 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7529d81/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
index 03eeedd..05e81a1 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
@@ -246,7 +246,10 @@ StaticNatServiceProvider, IpDeployer {
         Map<Service, Map<Capability, String>> capabilities = new HashMap<Service, Map<Capability, String>>();
 
         // L2 Support : SDN provisioning
-        capabilities.put(Service.Connectivity, null);
+        Map<Capability, String> connectivityCapabilities = new HashMap<Capability, String>();
+        connectivityCapabilities.put(Capability.DistributedRouter, null);
+        capabilities.put(Service.Connectivity, connectivityCapabilities);
+
 
         // L3 Support : Port Forwarding
         capabilities.put(Service.PortForwarding, null);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7529d81/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index 0b70faa..5abc5e8 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -65,6 +65,7 @@ import com.cloud.exception.PermissionDeniedException;
 import com.cloud.exception.ResourceAllocationException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.element.NetworkElement;
 import com.cloud.network.IpAddress;
 import com.cloud.network.IpAddressManager;
 import com.cloud.network.Network;
@@ -376,6 +377,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
             }
         }
 
+        validateConnectivtyServiceCapablitlies(svcProviderMap.get(Service.Connectivity), serviceCapabilitystList);
         boolean supportsDistributedRouter = isVpcOfferingSupportsDistributedRouter(serviceCapabilitystList);
 
         VpcOffering offering = createVpcOffering(name, displayText, svcProviderMap, false, null,
@@ -460,6 +462,56 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
         return supportsDistributedRouter;
     }
 
+    private void validateConnectivtyServiceCapablitlies(Set<Provider> providers, Map serviceCapabilitystList) {
+
+        if (serviceCapabilitystList != null && !serviceCapabilitystList.isEmpty()) {
+            Collection serviceCapabilityCollection = serviceCapabilitystList.values();
+            Iterator iter = serviceCapabilityCollection.iterator();
+            Map<Network.Capability, String> capabilityMap = null;
+
+            while (iter.hasNext()) {
+                HashMap<String, String> svcCapabilityMap = (HashMap<String, String>)iter.next();
+                Network.Capability capability = null;
+                String svc = svcCapabilityMap.get("service");
+                String capabilityName = svcCapabilityMap.get("capabilitytype");
+                String capabilityValue = svcCapabilityMap.get("capabilityvalue");
+                if (capabilityName != null) {
+                    capability = Network.Capability.getCapability(capabilityName);
+                }
+
+                if ((capability == null) || (capabilityName == null) || (capabilityValue == null)) {
+                    throw new InvalidParameterValueException("Invalid capability:" + capabilityName + " capability value:" + capabilityValue);
+                }
+
+                if (!svc.equalsIgnoreCase(Service.Connectivity.getName())) {
+                    throw new InvalidParameterValueException("Invalid Service:" + svc + " specified. Only for 'Connectivity' service capabilities can be specified");
+                }
+
+                if (!capabilityName.equalsIgnoreCase("DistributedRouter")) {
+                    throw new InvalidParameterValueException("Invalid Capability:" + capabilityName + " specified. Only 'DistributedRouter' capability can be specified.");
+                }
+
+                if (!capabilityValue.equalsIgnoreCase("true") && capabilityValue.equalsIgnoreCase("false")) {
+                    throw new InvalidParameterValueException("Invalid Capability value:" + capabilityValue + " specified.");
+                }
+            }
+
+            if (providers != null && !providers.isEmpty()) {
+                for (Provider provider: providers) {
+                    NetworkElement element = _ntwkModel.getElementImplementingProvider(provider.getName());
+                    Map<Service, Map<Network.Capability, String>> capabilities = element.getCapabilities();
+                    if (capabilities != null && !capabilities.isEmpty()) {
+                        Map<Network.Capability, String> connectivityCapabilities =  capabilities.get(Service.Connectivity);
+                        if (connectivityCapabilities == null || (connectivityCapabilities != null && !connectivityCapabilities.keySet().contains(Network.Capability.DistributedRouter))) {
+                            throw new InvalidParameterValueException("Provider: " + provider.getName() + " does not support "
+                                    + Network.Capability.DistributedRouter.getName() + " capability.");
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     @Override
     public Vpc getActiveVpc(long vpcId) {
         return _vpcDao.getActiveVpcById(vpcId);


[02/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
CLOUDSTACK-6047: Add testing for VR aggregation commands


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/ccea5703
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/ccea5703
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/ccea5703

Branch: refs/heads/distributedrouter
Commit: ccea5703df45ef12602421cd45510f5841ddb641
Parents: 60dc254
Author: Sheng Yang <sh...@citrix.com>
Authored: Tue Mar 4 14:28:41 2014 -0800
Committer: Sheng Yang <sh...@citrix.com>
Committed: Thu Mar 6 16:22:23 2014 -0800

----------------------------------------------------------------------
 .../VirtualRoutingResourceTest.java             | 480 +++++++++++++++----
 .../debian/config/opt/cloud/bin/vr_cfg.sh       |   2 +-
 2 files changed, 390 insertions(+), 92 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ccea5703/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java
----------------------------------------------------------------------
diff --git a/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java b/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java
index c980c9d..9b116dd 100644
--- a/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java
+++ b/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java
@@ -23,6 +23,7 @@ import com.cloud.agent.api.routing.CreateIpAliasCommand;
 import com.cloud.agent.api.routing.DeleteIpAliasCommand;
 import com.cloud.agent.api.routing.DhcpEntryCommand;
 import com.cloud.agent.api.routing.DnsMasqConfigCommand;
+import com.cloud.agent.api.routing.FinishAggregationCommand;
 import com.cloud.agent.api.routing.GroupAnswer;
 import com.cloud.agent.api.routing.IpAliasTO;
 import com.cloud.agent.api.routing.IpAssocCommand;
@@ -40,6 +41,7 @@ import com.cloud.agent.api.routing.SetSourceNatCommand;
 import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
 import com.cloud.agent.api.routing.SetStaticRouteCommand;
 import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
+import com.cloud.agent.api.routing.StartAggregationCommand;
 import com.cloud.agent.api.routing.VmDataCommand;
 import com.cloud.agent.api.routing.VpnUsersCfgCommand;
 import com.cloud.agent.api.to.DhcpTO;
@@ -67,6 +69,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader;
 import javax.naming.ConfigurationException;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.UUID;
 
@@ -81,26 +84,29 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
     NetworkElementCommand _currentCmd;
     int _count;
     String _file;
+    boolean _aggregated = false;
 
-    String ROUTERIP = "10.2.3.4";
+    String ROUTER_IP = "169.254.3.4";
+    String ROUTER_GUEST_IP = "10.200.1.1";
+    String ROUTER_NAME = "r-4-VM";
 
     @Override
     public ExecutionResult executeInVR(String routerIp, String script, String args) {
-        assertEquals(routerIp, ROUTERIP);
+        assertEquals(routerIp, ROUTER_IP);
         verifyCommand(_currentCmd, script, args);
         return new ExecutionResult(true, null);
     }
 
     @Override
     public ExecutionResult createFileInVR(String routerIp, String path, String filename, String content) {
-        assertEquals(routerIp, ROUTERIP);
+        assertEquals(routerIp, ROUTER_IP);
         verifyFile(_currentCmd, path, filename, content);
         return new ExecutionResult(true, null);
     }
 
     @Override
     public ExecutionResult prepareCommand(NetworkElementCommand cmd) {
-        cmd.setRouterAccessIp(ROUTERIP);
+        cmd.setRouterAccessIp(ROUTER_IP);
         _currentCmd = cmd;
         if (cmd instanceof IpAssocVpcCommand) {
             return prepareNetworkElementCommand((IpAssocVpcCommand)cmd);
@@ -131,6 +137,14 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         }
     }
 
+    private void verifyFile(NetworkElementCommand cmd, String path, String filename, String content) {
+        if (cmd instanceof FinishAggregationCommand) {
+            verifyFile((FinishAggregationCommand)cmd, path, filename, content);
+        } else if (cmd instanceof LoadBalancerConfigCommand) {
+            verifyFile((LoadBalancerConfigCommand)cmd, path, filename, content);
+        }
+    }
+
     protected void verifyCommand(NetworkElementCommand cmd, String script, String args) {
         if (cmd instanceof SetPortForwardingRulesVpcCommand) {
             verifyArgs((SetPortForwardingRulesVpcCommand) cmd, script, args);
@@ -175,6 +189,12 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         } else if (cmd instanceof IpAssocCommand) {
             verifyArgs((IpAssocCommand)cmd, script, args);
         }
+
+        if (cmd instanceof StartAggregationCommand) {
+            return;
+        } else if (cmd instanceof FinishAggregationCommand) {
+            verifyArgs((FinishAggregationCommand)cmd, script, args);
+        }
     }
 
     private void verifyArgs(VpnUsersCfgCommand cmd, String script, String args) {
@@ -203,11 +223,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
 
     @Test
     public void testSetPortForwardingRulesVpcCommand() {
-        List<PortForwardingRuleTO> pfRules = new ArrayList<>();
-        pfRules.add(new PortForwardingRuleTO(1, "64.1.1.10", 22, 80, "10.10.1.10", 22, 80, "TCP", false, false));
-        pfRules.add(new PortForwardingRuleTO(2, "64.1.1.11", 8080, 8080, "10.10.1.11", 8080, 8080, "UDP", true, false));
-        SetPortForwardingRulesVpcCommand cmd = new SetPortForwardingRulesVpcCommand(pfRules);
-        assertEquals(cmd.getAnswersCount(), 2);
+        SetPortForwardingRulesVpcCommand cmd = generateSetPortForwardingRulesVpcCommand();
 
         // Reset rule check count
         _count = 0;
@@ -218,6 +234,16 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         assertTrue(answer.getResult());
     }
 
+    protected SetPortForwardingRulesVpcCommand generateSetPortForwardingRulesVpcCommand() {
+        List<PortForwardingRuleTO> pfRules = new ArrayList<>();
+        pfRules.add(new PortForwardingRuleTO(1, "64.1.1.10", 22, 80, "10.10.1.10", 22, 80, "TCP", false, false));
+        pfRules.add(new PortForwardingRuleTO(2, "64.1.1.11", 8080, 8080, "10.10.1.11", 8080, 8080, "UDP", true, false));
+        SetPortForwardingRulesVpcCommand cmd = new SetPortForwardingRulesVpcCommand(pfRules);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        assertEquals(cmd.getAnswersCount(), 2);
+        return cmd;
+    }
+
     private void verifyArgs(SetPortForwardingRulesVpcCommand cmd, String script, String args) {
         assertTrue(script.equals(VRScripts.VPC_PORTFORWARDING));
         _count ++;
@@ -235,12 +261,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
 
     @Test
     public void testSetPortForwardingRulesCommand() {
-        List<PortForwardingRuleTO> pfRules = new ArrayList<>();
-        pfRules.add(new PortForwardingRuleTO(1, "64.1.1.10", 22, 80, "10.10.1.10", 22, 80, "TCP", false, false));
-        pfRules.add(new PortForwardingRuleTO(2, "64.1.1.11", 8080, 8080, "10.10.1.11", 8080, 8080, "UDP", true, false));
-        SetPortForwardingRulesCommand cmd = new SetPortForwardingRulesCommand(pfRules);
-        assertEquals(cmd.getAnswersCount(), 2);
-
+        SetPortForwardingRulesCommand cmd = generateSetPortForwardingRulesCommand();
         // Reset rule check count
         _count = 0;
 
@@ -250,6 +271,16 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         assertTrue(answer.getResult());
     }
 
+    protected SetPortForwardingRulesCommand generateSetPortForwardingRulesCommand() {
+        List<PortForwardingRuleTO> pfRules = new ArrayList<>();
+        pfRules.add(new PortForwardingRuleTO(1, "64.1.1.10", 22, 80, "10.10.1.10", 22, 80, "TCP", false, false));
+        pfRules.add(new PortForwardingRuleTO(2, "64.1.1.11", 8080, 8080, "10.10.1.11", 8080, 8080, "UDP", true, false));
+        SetPortForwardingRulesCommand cmd = new SetPortForwardingRulesCommand(pfRules);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        assertEquals(cmd.getAnswersCount(), 2);
+        return cmd;
+    }
+
     private void verifyArgs(SetPortForwardingRulesCommand cmd, String script, String args) {
         assertTrue(script.equals(VRScripts.FIREWALL_NAT));
         _count ++;
@@ -267,14 +298,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
 
     @Test
     public void testIpAssocCommand() {
-        List<IpAddressTO> ips = new ArrayList<IpAddressTO>();
-        ips.add(new IpAddressTO(1, "64.1.1.10", true, true, true, "vlan://64", "64.1.1.1", "255.255.255.0", "01:23:45:67:89:AB", 1000, false));
-        ips.add(new IpAddressTO(2, "64.1.1.11", false, false, false, "vlan://64", "64.1.1.1", "255.255.255.0", "01:23:45:67:89:AB", 1000, false));
-        ips.add(new IpAddressTO(3, "65.1.1.11", true, false, false, "vlan://65", "65.1.1.1", "255.255.255.0", "11:23:45:67:89:AB", 1000, false));
-        IpAddressTO[] ipArray = ips.toArray(new IpAddressTO[ips.size()]);
-        IpAssocCommand cmd = new IpAssocCommand(ipArray);
-        assertEquals(cmd.getAnswersCount(), 3);
-
+        IpAssocCommand cmd = generateIpAssocCommand();
         _count = 0;
 
         Answer answer = _resource.executeRequest(cmd);
@@ -292,16 +316,22 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         return new ExecutionResult(true, null);
     }
 
-    @Test
-    public void testIpAssocVpcCommand() {
-        List<IpAddressTO> ips = new ArrayList<IpAddressTO>();
+    protected IpAssocCommand generateIpAssocCommand() {
+        List<IpAddressTO> ips = new ArrayList<>();
         ips.add(new IpAddressTO(1, "64.1.1.10", true, true, true, "vlan://64", "64.1.1.1", "255.255.255.0", "01:23:45:67:89:AB", 1000, false));
-        ips.add(new IpAddressTO(2, "64.1.1.11", false, false, true, "vlan://64", "64.1.1.1", "255.255.255.0", "01:23:45:67:89:AB", 1000, false));
+        ips.add(new IpAddressTO(2, "64.1.1.11", false, false, false, "vlan://64", "64.1.1.1", "255.255.255.0", "01:23:45:67:89:AB", 1000, false));
         ips.add(new IpAddressTO(3, "65.1.1.11", true, false, false, "vlan://65", "65.1.1.1", "255.255.255.0", "11:23:45:67:89:AB", 1000, false));
         IpAddressTO[] ipArray = ips.toArray(new IpAddressTO[ips.size()]);
-        IpAssocVpcCommand cmd = new IpAssocVpcCommand(ipArray);
-        assertEquals(cmd.getAnswersCount(), 6);
+        IpAssocCommand cmd = new IpAssocCommand(ipArray);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        assertEquals(cmd.getAnswersCount(), 3);
 
+        return cmd;
+    }
+
+    @Test
+    public void testIpAssocVpcCommand() {
+        IpAssocVpcCommand cmd = generateIpAssocVpcCommand();
         _count = 0;
 
         Answer answer = _resource.executeRequest(cmd);
@@ -319,6 +349,19 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         return new ExecutionResult(true, null);
     }
 
+    protected IpAssocVpcCommand generateIpAssocVpcCommand() {
+        List<IpAddressTO> ips = new ArrayList<IpAddressTO>();
+        ips.add(new IpAddressTO(1, "64.1.1.10", true, true, true, "vlan://64", "64.1.1.1", "255.255.255.0", "01:23:45:67:89:AB", 1000, false));
+        ips.add(new IpAddressTO(2, "64.1.1.11", false, false, true, "vlan://64", "64.1.1.1", "255.255.255.0", "01:23:45:67:89:AB", 1000, false));
+        ips.add(new IpAddressTO(3, "65.1.1.11", true, false, false, "vlan://65", "65.1.1.1", "255.255.255.0", "11:23:45:67:89:AB", 1000, false));
+        IpAddressTO[] ipArray = ips.toArray(new IpAddressTO[ips.size()]);
+        IpAssocVpcCommand cmd = new IpAssocVpcCommand(ipArray);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        assertEquals(cmd.getAnswersCount(), 6);
+
+        return cmd;
+    }
+
     private void verifyArgs(IpAssocCommand cmd, String script, String args) {
         if (cmd instanceof IpAssocVpcCommand) {
             _count ++;
@@ -367,8 +410,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
 
     @Test
     public void testSourceNatCommand() {
-        IpAddressTO ip = new IpAddressTO(1, "64.1.1.10", true, true, true, "vlan://64", "64.1.1.1", "255.255.255.0", "01:23:45:67:89:AB", 1000, false);
-        SetSourceNatCommand cmd = new SetSourceNatCommand(ip, true);
+        SetSourceNatCommand cmd = generateSetSourceNatCommand();
         Answer answer = _resource.executeRequest(cmd);
         assertTrue(answer.getResult());
     }
@@ -379,6 +421,13 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         return new ExecutionResult(true, null);
     }
 
+    protected SetSourceNatCommand generateSetSourceNatCommand() {
+        IpAddressTO ip = new IpAddressTO(1, "64.1.1.10", true, true, true, "vlan://64", "64.1.1.1", "255.255.255.0", "01:23:45:67:89:AB", 1000, false);
+        SetSourceNatCommand cmd = new SetSourceNatCommand(ip, true);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        return cmd;
+    }
+
     private void verifyArgs(SetSourceNatCommand cmd, String script, String args) {
         assertEquals(script, VRScripts.VPC_SOURCE_NAT);
         assertEquals(args, "-A -l 64.1.1.10 -c eth1");
@@ -386,6 +435,18 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
 
     @Test
     public void testNetworkACLCommand() {
+        SetNetworkACLCommand cmd = generateSetNetworkACLCommand();
+        _count = 0;
+
+        Answer answer = _resource.executeRequest(cmd);
+        assertTrue(answer.getResult());
+
+        cmd.setAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY, String.valueOf(VpcGateway.Type.Private));
+        answer = _resource.executeRequest(cmd);
+        assertTrue(answer.getResult());
+    }
+
+    protected SetNetworkACLCommand generateSetNetworkACLCommand() {
         List<NetworkACLTO> acls = new ArrayList<>();
         List<String> cidrs = new ArrayList<>();
         cidrs.add("192.168.0.1/24");
@@ -397,16 +458,10 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         nic.setMac("01:23:45:67:89:AB");
         nic.setIp("192.168.1.1");
         nic.setNetmask("255.255.255.0");
-
-        _count = 0;
-
         SetNetworkACLCommand cmd = new SetNetworkACLCommand(acls, nic);
-        Answer answer = _resource.executeRequest(cmd);
-        assertTrue(answer.getResult());
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
 
-        cmd.setAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY, String.valueOf(VpcGateway.Type.Private));
-        answer = _resource.executeRequest(cmd);
-        assertTrue(answer.getResult());
+        return cmd;
     }
 
     private void verifyArgs(SetNetworkACLCommand cmd, String script, String args) {
@@ -435,6 +490,18 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
 
     @Test
     public void testSetupGuestNetworkCommand() {
+        SetupGuestNetworkCommand cmd = generateSetupGuestNetworkCommand();
+        Answer answer = _resource.executeRequest(cmd);
+        assertTrue(answer.getResult());
+    }
+
+    private ExecutionResult prepareNetworkElementCommand(SetupGuestNetworkCommand cmd) {
+        NicTO nic = cmd.getNic();
+        nic.setDeviceId(4);
+        return new ExecutionResult(true, null);
+    }
+
+    protected SetupGuestNetworkCommand generateSetupGuestNetworkCommand() {
         NicTO nic = new NicTO();
         nic.setMac("01:23:45:67:89:AB");
         nic.setIp("10.1.1.1");
@@ -443,16 +510,9 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         SetupGuestNetworkCommand cmd = new SetupGuestNetworkCommand("10.1.1.10-10.1.1.20", "cloud.test", false, 0, "8.8.8.8", "8.8.4.4", true, nic);
         cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, "10.1.1.2");
         cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY, "10.1.1.1");
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
 
-        Answer answer = _resource.executeRequest(cmd);
-        assertTrue(answer.getResult());
-
-    }
-
-    private ExecutionResult prepareNetworkElementCommand(SetupGuestNetworkCommand cmd) {
-        NicTO nic = cmd.getNic();
-        nic.setDeviceId(4);
-        return new ExecutionResult(true, null);
+        return cmd;
     }
 
     private void verifyArgs(SetupGuestNetworkCommand cmd, String script, String args) {
@@ -462,13 +522,20 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
 
     @Test
     public void testSetMonitorServiceCommand() {
+        SetMonitorServiceCommand cmd = generateSetMonitorServiceCommand();
+        Answer answer = _resource.executeRequest(cmd);
+        assertTrue(answer.getResult());
+    }
+
+    protected SetMonitorServiceCommand generateSetMonitorServiceCommand() {
         List<MonitorServiceTO> services = new ArrayList<>();
         services.add(new MonitorServiceTO("service", "process", "name", "path", "file", true));
         services.add(new MonitorServiceTO("service_2", "process_2", "name_2", "path_2", "file_2", false));
 
         SetMonitorServiceCommand cmd = new SetMonitorServiceCommand(services);
-        Answer answer = _resource.executeRequest(cmd);
-        assertTrue(answer.getResult());
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+
+        return cmd;
     }
 
     private void verifyArgs(SetMonitorServiceCommand cmd, String script, String args) {
@@ -481,14 +548,17 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         _count = 0;
 
         Site2SiteVpnCfgCommand cmd = new Site2SiteVpnCfgCommand(true, "64.10.1.10", "64.10.1.1", "192.168.1.1/16", "124.10.1.10", "192.168.100.1/24", "3des-sha1,aes128-sha1;modp1536", "3des-sha1,aes128-md5", "psk", Long.valueOf(1800), Long.valueOf(1800), true, false);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
         Answer answer = _resource.executeRequest(cmd);
         assertTrue(answer.getResult());
 
         cmd = new Site2SiteVpnCfgCommand(true, "64.10.1.10", "64.10.1.1", "192.168.1.1/16", "124.10.1.10", "192.168.100.1/24", "3des-sha1,aes128-sha1;modp1536", "3des-sha1,aes128-md5", "psk", Long.valueOf(1800), Long.valueOf(1800), false, true);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
         answer = _resource.executeRequest(cmd);
         assertTrue(answer.getResult());
 
         cmd = new Site2SiteVpnCfgCommand(false, "64.10.1.10", "64.10.1.1", "192.168.1.1/16", "124.10.1.10", "192.168.100.1/24", "3des-sha1,aes128-sha1;modp1536", "3des-sha1,aes128-md5", "psk", Long.valueOf(1800), Long.valueOf(1800), false, true);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
         answer = _resource.executeRequest(cmd);
         assertTrue(answer.getResult());
     }
@@ -516,20 +586,35 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
     public void testRemoteAccessVpnCfgCommand() {
         _count = 0;
 
+        Answer answer = _resource.executeRequest(generateRemoteAccessVpnCfgCommand1());
+        assertTrue(answer.getResult());
+
+        answer = _resource.executeRequest(generateRemoteAccessVpnCfgCommand2());
+        assertTrue(answer.getResult());
+
+        answer = _resource.executeRequest(generateRemoteAccessVpnCfgCommand3());
+        assertTrue(answer.getResult());
+    }
+
+    protected RemoteAccessVpnCfgCommand generateRemoteAccessVpnCfgCommand1() {
         RemoteAccessVpnCfgCommand cmd = new RemoteAccessVpnCfgCommand(true, "124.10.10.10", "10.10.1.1", "10.10.1.10-10.10.1.20", "sharedkey", false);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
         cmd.setLocalCidr("10.1.1.1/24");
-        Answer answer = _resource.executeRequest(cmd);
-        assertTrue(answer.getResult());
+        return cmd;
+    }
 
-        cmd = new RemoteAccessVpnCfgCommand(false, "124.10.10.10", "10.10.1.1", "10.10.1.10-10.10.1.20", "sharedkey", false);
+    protected RemoteAccessVpnCfgCommand generateRemoteAccessVpnCfgCommand2() {
+        RemoteAccessVpnCfgCommand cmd = new RemoteAccessVpnCfgCommand(false, "124.10.10.10", "10.10.1.1", "10.10.1.10-10.10.1.20", "sharedkey", false);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
         cmd.setLocalCidr("10.1.1.1/24");
-        answer = _resource.executeRequest(cmd);
-        assertTrue(answer.getResult());
+        return cmd;
+    }
 
-        cmd = new RemoteAccessVpnCfgCommand(true, "124.10.10.10", "10.10.1.1", "10.10.1.10-10.10.1.20", "sharedkey", true);
+    protected RemoteAccessVpnCfgCommand generateRemoteAccessVpnCfgCommand3() {
+        RemoteAccessVpnCfgCommand cmd = new RemoteAccessVpnCfgCommand(true, "124.10.10.10", "10.10.1.1", "10.10.1.10-10.10.1.20", "sharedkey", true);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
         cmd.setLocalCidr("10.1.1.1/24");
-        answer = _resource.executeRequest(cmd);
-        assertTrue(answer.getResult());
+        return cmd;
     }
 
     private void verifyArgs(RemoteAccessVpnCfgCommand cmd, String script, String args) {
@@ -556,6 +641,15 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
     public void testFirewallRulesCommand() {
         _count = 0;
 
+        Answer answer = _resource.executeRequest(generateSetFirewallRulesCommand());
+        assertTrue(answer.getResult());
+        assertTrue(answer instanceof GroupAnswer);
+        assertEquals(((GroupAnswer) answer).getResults().length, 3);
+
+        //TODO Didn't test egress rule because not able to generate FirewallRuleVO object
+    }
+
+    protected SetFirewallRulesCommand generateSetFirewallRulesCommand() {
         List<FirewallRuleTO> rules = new ArrayList<>();
         List<String> sourceCidrs = new ArrayList<>();
         sourceCidrs.add("10.10.1.1/24");
@@ -564,12 +658,9 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         rules.add(new FirewallRuleTO(2, "64.10.10.10", "ICMP", 0, 0, false, false, Purpose.Firewall, sourceCidrs, -1, -1));
         rules.add(new FirewallRuleTO(3, "64.10.10.10", "ICMP", 0, 0, true, true, Purpose.Firewall, sourceCidrs, -1, -1));
         SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(rules);
-        Answer answer = _resource.executeRequest(cmd);
-        assertTrue(answer.getResult());
-        assertTrue(answer instanceof GroupAnswer);
-        assertEquals(((GroupAnswer) answer).getResults().length, 3);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
 
-        //TODO Didn't test egress rule because not able to generate FirewallRuleVO object
+        return cmd;
     }
 
     private void verifyArgs(SetFirewallRulesCommand cmd, String script, String args) {
@@ -579,6 +670,11 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
 
     @Test
     public void testVmDataCommand() {
+        Answer answer = _resource.executeRequest(generateVmDataCommand());
+        assertTrue(answer.getResult());
+    }
+
+    protected VmDataCommand generateVmDataCommand() {
         VmDataCommand cmd = new VmDataCommand("10.1.10.4", "i-4-VM", true);
         cmd.addVmData("userdata", "user-data", "user-data");
         cmd.addVmData("metadata", "service-offering", "serviceOffering");
@@ -592,8 +688,9 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         cmd.addVmData("metadata", "public-keys", "publickey");
         cmd.addVmData("metadata", "cloud-identifier", "CloudStack-{test}");
 
-        Answer answer = _resource.executeRequest(cmd);
-        assertTrue(answer.getResult());
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+
+        return cmd;
     }
 
     private void verifyArgs(VmDataCommand cmd, String script, String args) {
@@ -608,11 +705,16 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
 
     @Test
     public void testSavePasswordCommand() {
-        SavePasswordCommand cmd = new SavePasswordCommand("123pass", "10.1.10.4", "i-4-VM", true);
-        Answer answer = _resource.executeRequest(cmd);
+        Answer answer = _resource.executeRequest(generateSavePasswordCommand());
         assertTrue(answer.getResult());
     }
 
+    protected SavePasswordCommand generateSavePasswordCommand() {
+        SavePasswordCommand cmd = new SavePasswordCommand("123pass", "10.1.10.4", "i-4-VM", true);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        return cmd;
+    }
+
     private void verifyArgs(SavePasswordCommand cmd, String script, String args) {
         assertEquals(script, VRScripts.PASSWORD);
         assertEquals(args, "-v 10.1.10.4 -p 123pass");
@@ -621,21 +723,37 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
     @Test
     public void testDhcpEntryCommand() {
         _count = 0;
-        DhcpEntryCommand cmd = new DhcpEntryCommand("12:34:56:78:90:AB", "10.1.10.2", "vm1", null, true);
-        Answer answer = _resource.executeRequest(cmd);
+
+        Answer answer = _resource.executeRequest(generateDhcpEntryCommand1());
         assertTrue(answer.getResult());
 
-        cmd = new DhcpEntryCommand("12:34:56:78:90:AB", null, "vm1", "2001:db8:0:0:0:ff00:42:8329", true);
-        cmd.setDuid(NetUtils.getDuidLL(cmd.getVmMac()));
-        answer = _resource.executeRequest(cmd);
+        answer = _resource.executeRequest(generateDhcpEntryCommand2());
         assertTrue(answer.getResult());
 
-        cmd = new DhcpEntryCommand("12:34:56:78:90:AB", "10.1.10.2", "vm1", "2001:db8:0:0:0:ff00:42:8329", true);
-        cmd.setDuid(NetUtils.getDuidLL(cmd.getVmMac()));
-        answer = _resource.executeRequest(cmd);
+        answer = _resource.executeRequest(generateDhcpEntryCommand3());
         assertTrue(answer.getResult());
     }
 
+    protected DhcpEntryCommand generateDhcpEntryCommand1() {
+        DhcpEntryCommand cmd = new DhcpEntryCommand("12:34:56:78:90:AB", "10.1.10.2", "vm1", null, true);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        return cmd;
+    }
+
+    protected DhcpEntryCommand generateDhcpEntryCommand2() {
+        DhcpEntryCommand cmd = new DhcpEntryCommand("12:34:56:78:90:AB", null, "vm1", "2001:db8:0:0:0:ff00:42:8329", true);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setDuid(NetUtils.getDuidLL(cmd.getVmMac()));
+        return cmd;
+    }
+
+    protected DhcpEntryCommand generateDhcpEntryCommand3() {
+        DhcpEntryCommand cmd = new DhcpEntryCommand("12:34:56:78:90:AB", "10.1.10.2", "vm1", "2001:db8:0:0:0:ff00:42:8329", true);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setDuid(NetUtils.getDuidLL(cmd.getVmMac()));
+        return cmd;
+    }
+
     private void verifyArgs(DhcpEntryCommand cmd, String script, String args) {
         _count ++;
         assertEquals(script, VRScripts.DHCP);
@@ -656,13 +774,19 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
 
     @Test
     public void testCreateIpAliasCommand() {
+        Answer answer = _resource.executeRequest(generateCreateIpAliasCommand());
+        assertTrue(answer.getResult());
+    }
+
+    protected CreateIpAliasCommand generateCreateIpAliasCommand() {
         List<IpAliasTO> aliases = new ArrayList<>();
         aliases.add(new IpAliasTO("169.254.3.10", "255.255.255.0", "1"));
         aliases.add(new IpAliasTO("169.254.3.11", "255.255.255.0", "2"));
         aliases.add(new IpAliasTO("169.254.3.12", "255.255.255.0", "3"));
         CreateIpAliasCommand cmd = new CreateIpAliasCommand("169.254.3.10", aliases);
-        Answer answer = _resource.executeRequest(cmd);
-        assertTrue(answer.getResult());
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+
+        return cmd;
     }
 
     private void verifyArgs(CreateIpAliasCommand cmd, String script, String args) {
@@ -672,13 +796,18 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
 
     @Test
     public void testDeleteIpAliasCommand() {
+        Answer answer = _resource.executeRequest(generateDeleteIpAliasCommand());
+        assertTrue(answer.getResult());
+    }
+
+    protected DeleteIpAliasCommand generateDeleteIpAliasCommand() {
         List<IpAliasTO> aliases = new ArrayList<>();
         aliases.add(new IpAliasTO("169.254.3.10", "255.255.255.0", "1"));
         aliases.add(new IpAliasTO("169.254.3.11", "255.255.255.0", "2"));
         aliases.add(new IpAliasTO("169.254.3.12", "255.255.255.0", "3"));
         DeleteIpAliasCommand cmd = new DeleteIpAliasCommand("169.254.10.1", aliases, aliases);
-        Answer answer = _resource.executeRequest(cmd);
-        assertTrue(answer.getResult());
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        return cmd;
     }
 
     private void verifyArgs(DeleteIpAliasCommand cmd, String script, String args) {
@@ -688,12 +817,17 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
 
     @Test
     public void testDnsMasqConfigCommand() {
-        List<DhcpTO> dhcps = new ArrayList<DhcpTO>();
+        Answer answer = _resource.executeRequest(generateDnsMasqConfigCommand());
+        assertTrue(answer.getResult());
+    }
+
+    protected DnsMasqConfigCommand generateDnsMasqConfigCommand() {
+        List<DhcpTO> dhcps = new ArrayList<>();
         dhcps.add(new DhcpTO("10.1.20.2", "10.1.20.1", "255.255.255.0", "10.1.20.5"));
         dhcps.add(new DhcpTO("10.1.21.2", "10.1.21.1", "255.255.255.0", "10.1.21.5"));
         DnsMasqConfigCommand cmd = new DnsMasqConfigCommand(dhcps);
-        Answer answer = _resource.executeRequest(cmd);
-        assertTrue(answer.getResult());
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        return cmd;
     }
 
     private void verifyArgs(DnsMasqConfigCommand cmd, String script, String args) {
@@ -706,6 +840,14 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         _count = 0;
         _file = "";
 
+        Answer answer = _resource.executeRequest(generateLoadBalancerConfigCommand1());
+        assertTrue(answer.getResult());
+
+        answer = _resource.executeRequest(generateLoadBalancerConfigCommand2());
+        assertTrue(answer.getResult());
+    }
+
+    protected LoadBalancerConfigCommand generateLoadBalancerConfigCommand1() {
         List<LoadBalancerTO> lbs = new ArrayList<>();
         List<LbDestination> dests = new ArrayList<>();
         dests.add(new LbDestination(80, 8080, "10.1.10.2", false));
@@ -716,19 +858,27 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         NicTO nic = new NicTO();
         LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(arrayLbs, "64.10.2.10", "10.1.10.2", "192.168.1.2", nic, null, "1000", false);
         cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, "10.1.10.2");
-        Answer answer = _resource.executeRequest(cmd);
-        assertTrue(answer.getResult());
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        return cmd;
+    }
 
+    protected LoadBalancerConfigCommand generateLoadBalancerConfigCommand2() {
+        List<LoadBalancerTO> lbs = new ArrayList<>();
+        List<LbDestination> dests = new ArrayList<>();
+        dests.add(new LbDestination(80, 8080, "10.1.10.2", false));
+        dests.add(new LbDestination(80, 8080, "10.1.10.2", true));
+        lbs.add(new LoadBalancerTO(UUID.randomUUID().toString(), "64.10.1.10", 80, "tcp", "algo", false, false, false, dests));
+        LoadBalancerTO[] arrayLbs = new LoadBalancerTO[lbs.size()];
+        lbs.toArray(arrayLbs);
+        NicTO nic = new NicTO();
         nic.setIp("10.1.10.2");
-        cmd = new LoadBalancerConfigCommand(arrayLbs, "64.10.2.10", "10.1.10.2", "192.168.1.2", nic, Long.valueOf(1), "1000", false);
-        answer = _resource.executeRequest(cmd);
-        assertTrue(answer.getResult());
+        LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(arrayLbs, "64.10.2.10", "10.1.10.2", "192.168.1.2", nic, Long.valueOf(1), "1000", false);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, "10.1.10.2");
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        return cmd;
     }
 
-    private void verifyFile(NetworkElementCommand cmd, String path, String filename, String content) {
-        if (!(cmd instanceof LoadBalancerConfigCommand)) {
-            fail("Only LB command would call this!");
-        }
+    protected void verifyFile(LoadBalancerConfigCommand cmd, String path, String filename, String content) {
         _count ++;
         switch (_count) {
             case 1:
@@ -795,5 +945,153 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         }
     }
 
+    @Test
+    public void testAggregationCommands() {
+        List<NetworkElementCommand> cmds = new LinkedList<>();
+        StartAggregationCommand startCmd = new StartAggregationCommand(ROUTER_NAME, ROUTER_IP, ROUTER_GUEST_IP);
+        cmds.add(startCmd);
+        cmds.add(generateIpAssocCommand());
+        cmds.add(generateIpAssocVpcCommand());
+
+        cmds.add(generateSetFirewallRulesCommand());
+
+        cmds.add(generateSetPortForwardingRulesCommand());
+        cmds.add(generateSetPortForwardingRulesVpcCommand());
+
+        cmds.add(generateCreateIpAliasCommand());
+        cmds.add(generateDeleteIpAliasCommand());
+        cmds.add(generateDnsMasqConfigCommand());
+
+        cmds.add(generateRemoteAccessVpnCfgCommand1());
+        cmds.add(generateRemoteAccessVpnCfgCommand2());
+        cmds.add(generateRemoteAccessVpnCfgCommand3());
+
+        //cmds.add(generateLoadBalancerConfigCommand1());
+        //cmds.add(generateLoadBalancerConfigCommand2());
+
+        cmds.add(generateSetPortForwardingRulesCommand());
+        cmds.add(generateSetPortForwardingRulesVpcCommand());
+
+        cmds.add(generateDhcpEntryCommand1());
+        cmds.add(generateDhcpEntryCommand2());
+        cmds.add(generateDhcpEntryCommand3());
+
+        cmds.add(generateSavePasswordCommand());
+        cmds.add(generateVmDataCommand());
+
+        FinishAggregationCommand finishCmd = new FinishAggregationCommand(ROUTER_NAME, ROUTER_IP, ROUTER_GUEST_IP);
+        cmds.add(finishCmd);
+
+        for (NetworkElementCommand cmd : cmds) {
+            Answer answer = _resource.executeRequest(cmd);
+            if (!(cmd instanceof FinishAggregationCommand)) {
+                assertTrue(answer.getResult());
+            } else {
+
+            }
+        }
+    }
+
+    private void verifyArgs(FinishAggregationCommand cmd, String script, String args) {
+        assertEquals(script, VRScripts.VR_CFG);
+        assertTrue(args.startsWith("-c /var/cache/cloud/VR-"));
+        assertTrue(args.endsWith(".cfg"));
+    }
+
+    protected void verifyFile(FinishAggregationCommand cmd, String path, String filename, String content) {
+        assertEquals(path, "/var/cache/cloud/");
+        assertTrue(filename.startsWith("VR-"));
+        assertTrue(filename.endsWith(".cfg"));
+        assertEquals(content, "#Apache CloudStack Virtual Router Config File\n" +
+                "<version>\n" +
+                "1.0\n" +
+                "</version>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/ipassoc.sh -A -s -f -l 64.1.1.10/24 -c eth2 -g 64.1.1.1\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/ipassoc.sh -D -l 64.1.1.11/24 -c eth2 -g 64.1.1.1\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/ipassoc.sh -A -l 65.1.1.11/24 -c eth2 -g 65.1.1.1\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/vpc_ipassoc.sh  -A  -l 64.1.1.10 -c eth2 -g 64.1.1.1 -m 24 -n 64.1.1.0\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/vpc_privateGateway.sh  -A  -l 64.1.1.10 -c eth2\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/vpc_ipassoc.sh  -D  -l 64.1.1.11 -c eth2 -g 64.1.1.1 -m 24 -n 64.1.1.0\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/vpc_privateGateway.sh  -D  -l 64.1.1.11 -c eth2\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/vpc_ipassoc.sh  -A  -l 65.1.1.11 -c eth2 -g 65.1.1.1 -m 24 -n 65.1.1.0\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/firewall_ingress.sh  -F -a 64.10.10.10:ICMP:0:0:10.10.1.1/24-10.10.1.2/24:,64.10.10.10:TCP:22:80:10.10.1.1/24-10.10.1.2/24:,64.10.10.10:reverted:0:0:0:,\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/firewall_nat.sh -A -P tcp -l 64.1.1.10 -p 22:80 -r 10.10.1.10 -d 22:80\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/firewall_nat.sh -D -P udp -l 64.1.1.11 -p 8080:8080 -r 10.10.1.11 -d 8080:8080\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/vpc_portforwarding.sh -A -P tcp -l 64.1.1.10 -p 22:80 -r 10.10.1.10 -d 22-80\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/vpc_portforwarding.sh -D -P udp -l 64.1.1.11 -p 8080:8080 -r 10.10.1.11 -d 8080-8080\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/createipAlias.sh 1:169.254.3.10:255.255.255.0-2:169.254.3.11:255.255.255.0-3:169.254.3.12:255.255.255.0-\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/deleteipAlias.sh 1:169.254.3.10:255.255.255.0-2:169.254.3.11:255.255.255.0-3:169.254.3.12:255.255.255.0-- 1:169.254.3.10:255.255.255.0-2:169.254.3.11:255.255.255.0-3:169.254.3.12:255.255.255.0-\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/dnsmasq.sh 10.1.20.2:10.1.20.1:255.255.255.0:10.1.20.5-10.1.21.2:10.1.21.1:255.255.255.0:10.1.21.5-\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/vpn_l2tp.sh -r 10.10.1.10-10.10.1.20 -p sharedkey -s 124.10.10.10 -l 10.10.1.1 -c  -C 10.1.1.1/24 -i eth2\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/vpn_l2tp.sh -d  -s 124.10.10.10 -C 10.1.1.1/24 -i eth2\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/vpn_l2tp.sh -r 10.10.1.10-10.10.1.20 -p sharedkey -s 124.10.10.10 -l 10.10.1.1 -c  -C 10.1.1.1/24 -i eth1\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/firewall_nat.sh -A -P tcp -l 64.1.1.10 -p 22:80 -r 10.10.1.10 -d 22:80\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/firewall_nat.sh -D -P udp -l 64.1.1.11 -p 8080:8080 -r 10.10.1.11 -d 8080:8080\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/vpc_portforwarding.sh -A -P tcp -l 64.1.1.10 -p 22:80 -r 10.10.1.10 -d 22-80\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/vpc_portforwarding.sh -D -P udp -l 64.1.1.11 -p 8080:8080 -r 10.10.1.11 -d 8080-8080\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/edithosts.sh  -m 12:34:56:78:90:AB -4 10.1.10.2 -h vm1\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/edithosts.sh  -m 12:34:56:78:90:AB -h vm1 -6 2001:db8:0:0:0:ff00:42:8329 -u 00:03:00:01:12:34:56:78:90:AB\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/edithosts.sh  -m 12:34:56:78:90:AB -4 10.1.10.2 -h vm1 -6 2001:db8:0:0:0:ff00:42:8329 -u 00:03:00:01:12:34:56:78:90:AB\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/savepassword.sh -v 10.1.10.4 -p 123pass\n" +
+                "</script>\n" +
+                "<script>\n" +
+                "/opt/cloud/bin/vmdata.py -d eyIxMC4xLjEwLjQiOltbInVzZXJkYXRhIiwidXNlci1kYXRhIiwidXNlci1kYXRhIl0sWyJtZXRhZGF0YSIsInNlcnZpY2Utb2ZmZXJpbmciLCJzZXJ2aWNlT2ZmZXJpbmciXSxbIm1ldGFkYXRhIiwiYXZhaWxhYmlsaXR5LXpvbmUiLCJ6b25lTmFtZSJdLFsibWV0YWRhdGEiLCJsb2NhbC1pcHY0IiwiMTAuMS4xMC40Il0sWyJtZXRhZGF0YSIsImxvY2FsLWhvc3RuYW1lIiwidGVzdC12bSJdLFsibWV0YWRhdGEiLCJwdWJsaWMtaXB2NCIsIjExMC4xLjEwLjQiXSxbIm1ldGFkYXRhIiwicHVibGljLWhvc3RuYW1lIiwiaG9zdG5hbWUiXSxbIm1ldGFkYXRhIiwiaW5zdGFuY2UtaWQiLCJpLTQtVk0iXSxbIm1ldGFkYXRhIiwidm0taWQiLCI0Il0sWyJtZXRhZGF0YSIsInB1YmxpYy1rZXlzIiwicHVibGlja2V5Il0sWyJtZXRhZGF0YSIsImNsb3VkLWlkZW50aWZpZXIiLCJDbG91ZFN0YWNrLXt0ZXN0fSJdXX0=\n" +
+                "</script>" +
+                "\n");
+    }
+
 }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ccea5703/systemvm/patches/debian/config/opt/cloud/bin/vr_cfg.sh
----------------------------------------------------------------------
diff --git a/systemvm/patches/debian/config/opt/cloud/bin/vr_cfg.sh b/systemvm/patches/debian/config/opt/cloud/bin/vr_cfg.sh
index 8994a06..dffa45a 100755
--- a/systemvm/patches/debian/config/opt/cloud/bin/vr_cfg.sh
+++ b/systemvm/patches/debian/config/opt/cloud/bin/vr_cfg.sh
@@ -62,7 +62,7 @@ do
         then
             log_it "VR config: executing failed: $line"
             # expose error info to mgmt server
-            echo "VR config: execution failed: \"$line\", check $log in VR for details "
+            echo "VR config: execution failed: \"$line\", check $log in VR for details " 1>&2
             exit 1
         fi
         #skip </script>


[38/50] [abbrv] CLOUDSTACK-4760 : Enabling GPU support for XenServer. CLOUDSTACK-4762 : Enabling VGPU support for XenServer.

Posted by mu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/server/src/com/cloud/network/NetworkUsageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkUsageManagerImpl.java b/server/src/com/cloud/network/NetworkUsageManagerImpl.java
index e9b0393..13eb210 100755
--- a/server/src/com/cloud/network/NetworkUsageManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkUsageManagerImpl.java
@@ -57,6 +57,7 @@ import com.cloud.event.UsageEventVO;
 import com.cloud.event.dao.UsageEventDao;
 import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.gpu.dao.HostGpuGroupsDao;
 import com.cloud.host.DetailVO;
 import com.cloud.host.Host;
 import com.cloud.host.HostVO;
@@ -116,6 +117,8 @@ public class NetworkUsageManagerImpl extends ManagerBase implements NetworkUsage
     @Inject
     HostDetailsDao _detailsDao;
     @Inject
+    HostGpuGroupsDao _hostGpuGroupsDao;
+    @Inject
     AccountManager _accountMgr;
     @Inject
     NetworkDao _networksDao = null;
@@ -537,6 +540,7 @@ public class NetworkUsageManagerImpl extends ManagerBase implements NetworkUsage
         long hostId = host.getId();
         _agentMgr.disconnectWithoutInvestigation(hostId, Status.Event.Remove);
         _detailsDao.deleteDetails(hostId);
+        _hostGpuGroupsDao.deleteGpuEntries(hostId);
         host.setGuid(null);
         _hostDao.update(hostId, host);
         _hostDao.remove(hostId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/server/src/com/cloud/resource/ResourceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java
index adad85c..2625885 100755
--- a/server/src/com/cloud/resource/ResourceManagerImpl.java
+++ b/server/src/com/cloud/resource/ResourceManagerImpl.java
@@ -30,11 +30,6 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.google.gson.Gson;
-
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.command.admin.cluster.AddClusterCmd;
 import org.apache.cloudstack.api.command.admin.cluster.DeleteClusterCmd;
@@ -51,10 +46,14 @@ 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.commons.lang.ObjectUtils;
+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.Command;
+import com.cloud.agent.api.GetGPUStatsAnswer;
+import com.cloud.agent.api.GetGPUStatsCommand;
 import com.cloud.agent.api.GetHostStatsAnswer;
 import com.cloud.agent.api.GetHostStatsCommand;
 import com.cloud.agent.api.MaintainAnswer;
@@ -64,6 +63,7 @@ import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.StartupRoutingCommand;
 import com.cloud.agent.api.UnsupportedAnswer;
 import com.cloud.agent.api.UpdateHostPasswordCommand;
+import com.cloud.agent.api.to.GPUDeviceTO;
 import com.cloud.agent.transport.Request;
 import com.cloud.api.ApiDBUtils;
 import com.cloud.capacity.Capacity;
@@ -97,6 +97,11 @@ import com.cloud.exception.DiscoveryException;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.PermissionDeniedException;
 import com.cloud.exception.ResourceInUseException;
+import com.cloud.gpu.GPU.vGPUType;
+import com.cloud.gpu.HostGpuGroupsVO;
+import com.cloud.gpu.VGPUTypesVO;
+import com.cloud.gpu.dao.HostGpuGroupsDao;
+import com.cloud.gpu.dao.VGPUTypesDao;
 import com.cloud.ha.HighAvailabilityManager;
 import com.cloud.ha.HighAvailabilityManager.WorkType;
 import com.cloud.host.DetailVO;
@@ -137,11 +142,14 @@ import com.cloud.utils.UriUtils;
 import com.cloud.utils.component.Manager;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Filter;
 import com.cloud.utils.db.GenericSearchBuilder;
 import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.JoinBuilder;
 import com.cloud.utils.db.QueryBuilder;
 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;
@@ -158,6 +166,7 @@ import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachine.State;
 import com.cloud.vm.VirtualMachineManager;
 import com.cloud.vm.dao.VMInstanceDao;
+import com.google.gson.Gson;
 
 @Component
 @Local({ResourceManager.class, ResourceService.class})
@@ -193,6 +202,10 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
     @Inject
     private GuestOSCategoryDao _guestOSCategoryDao;
     @Inject
+    protected HostGpuGroupsDao _hostGpuGroupsDao;
+    @Inject
+    protected VGPUTypesDao _vgpuTypesDao;
+    @Inject
     private PrimaryDataStoreDao _storagePoolDao;
     @Inject
     private DataCenterIpAddressDao _privateIPAddressDao;
@@ -244,6 +257,8 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
 
     private GenericSearchBuilder<HostVO, String> _hypervisorsInDC;
 
+    private SearchBuilder<HostGpuGroupsVO> _gpuAvailability;
+
     private void insertListener(Integer event, ResourceListener listener) {
         List<ResourceListener> lst = _lifeCycleListeners.get(event);
         if (lst == null) {
@@ -827,6 +842,9 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
                 // delete host details
                 _hostDetailsDao.deleteDetails(hostId);
 
+                // if host is GPU enabled, delete GPU entries
+                _hostGpuGroupsDao.deleteGpuEntries(hostId);
+
                 host.setGuid(null);
                 Long clusterId = host.getClusterId();
                 host.setClusterId(null);
@@ -1329,6 +1347,14 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
         _hypervisorsInDC.and("type", _hypervisorsInDC.entity().getType(), SearchCriteria.Op.EQ);
         _hypervisorsInDC.done();
 
+        _gpuAvailability = _hostGpuGroupsDao.createSearchBuilder();
+        _gpuAvailability.and("hostId", _gpuAvailability.entity().getHostId(), Op.EQ);
+        SearchBuilder<VGPUTypesVO> join1 = _vgpuTypesDao.createSearchBuilder();
+        join1.and("vgpuType", join1.entity().getVgpuType(), Op.EQ);
+        join1.and("remainingCapacity", join1.entity().getRemainingCapacity(), Op.GT);
+        _gpuAvailability.join("groupId", join1, _gpuAvailability.entity().getId(), join1.entity().getGpuGroupId(), JoinBuilder.JoinType.INNER);
+        _gpuAvailability.done();
+
         return true;
     }
 
@@ -1958,6 +1984,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
         host.setSpeed(ssCmd.getSpeed());
         host.setHypervisorType(hyType);
         host.setHypervisorVersion(ssCmd.getHypervisorVersion());
+        host.setGpuGroups(ssCmd.getGpuGroupDetails());
         return host;
     }
 
@@ -2474,6 +2501,66 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
     }
 
     @Override
+    public List<HostGpuGroupsVO> listAvailableGPUDevice(long hostId, String vgpuType) {
+        if (vgpuType == null) {
+            vgpuType = vGPUType.passthrough.getType();
+        }
+        Filter searchFilter = new Filter(VGPUTypesVO.class, "remainingCapacity", false, null, null);
+        SearchCriteria<HostGpuGroupsVO> sc = _gpuAvailability.create();
+        sc.setParameters("hostId", hostId);
+        sc.setJoinParameters("groupId", "vgpuType", vgpuType);
+        sc.setJoinParameters("groupId", "remainingCapacity", 0);
+        return _hostGpuGroupsDao.customSearch(sc, searchFilter);
+    }
+
+    @Override
+    public boolean isGPUDeviceAvailable(long hostId, String vgpuType) {
+        if(!listAvailableGPUDevice(hostId, vgpuType).isEmpty()) {
+            return true;
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Host ID: "+ hostId +" does not have GPU device available");
+            }
+            return false;
+        }
+    }
+
+    @Override
+    public GPUDeviceTO getGPUDevice(long hostId, String vgpuType) {
+        HostGpuGroupsVO gpuDevice = listAvailableGPUDevice(hostId, vgpuType).get(0);
+        return new GPUDeviceTO(gpuDevice.getGroupName(), vgpuType, null);
+    }
+
+    @Override
+    public void updateGPUDetails(long hostId, HashMap<String, HashMap<String, Long>> groupDetails) {
+        // Update GPU group capacity
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+        _hostGpuGroupsDao.persist(hostId, new ArrayList<String>(groupDetails.keySet()));
+        _vgpuTypesDao.persist(hostId, groupDetails);
+        txn.commit();
+    }
+
+    @Override
+    public HashMap<String, HashMap<String, Long>> getGPUStatistics(HostVO host) {
+        Answer answer = _agentMgr.easySend(host.getId(), new GetGPUStatsCommand(host.getGuid(), host.getName()));
+        if (answer != null && (answer instanceof UnsupportedAnswer)) {
+            return null;
+        }
+        if (answer == null || !answer.getResult()) {
+            String msg = "Unable to obtain GPU stats for host " + host.getName();
+            s_logger.warn(msg);
+            return null;
+        } else {
+            // now construct the result object
+            if (answer instanceof GetGPUStatsAnswer) {
+                return ((GetGPUStatsAnswer)answer).getGroupDetails();
+            }
+        }
+        return null;
+    }
+
+    @Override
     @DB
     @ActionEvent(eventType = EventTypes.EVENT_HOST_RESERVATION_RELEASE, eventDescription = "releasing host reservation", async = true)
     public boolean releaseHostReservation(final Long hostId) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 49a9eb5..663d4e5 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -508,6 +508,7 @@ import com.cloud.exception.OperationTimedoutException;
 import com.cloud.exception.PermissionDeniedException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.exception.VirtualMachineMigrationException;
+import com.cloud.gpu.GPU;
 import com.cloud.ha.HighAvailabilityManager;
 import com.cloud.host.DetailVO;
 import com.cloud.host.Host;
@@ -539,6 +540,7 @@ import com.cloud.server.ResourceTag.ResourceObjectType;
 import com.cloud.server.auth.UserAuthenticator;
 import com.cloud.service.ServiceOfferingVO;
 import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.service.dao.ServiceOfferingDetailsDao;
 import com.cloud.storage.DiskOfferingVO;
 import com.cloud.storage.GuestOS;
 import com.cloud.storage.GuestOSCategoryVO;
@@ -700,6 +702,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
     private ResourceTagDao _resourceTagDao;
     @Inject
     private ImageStoreDao _imgStoreDao;
+    @Inject
+    private ServiceOfferingDetailsDao _serviceOfferingDetailsDao;
+
 
     @Inject
     private ProjectManager _projectMgr;
@@ -1059,6 +1064,13 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
             throw ex;
         }
 
+        if(_serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.pciDevice.toString()) != null) {
+            s_logger.info(" Live Migration of GPU enabled VM : " + vm.getInstanceName()+ " is not supported");
+            // Return empty list.
+            return new Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Host, Boolean>>(new Pair<List <? extends Host>,
+                    Integer>(new ArrayList<HostVO>(), new Integer(0)), new ArrayList<Host>(), new HashMap<Host, Boolean>());
+        }
+
         if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && !vm.getHypervisorType().equals(HypervisorType.KVM)
                 && !vm.getHypervisorType().equals(HypervisorType.Ovm) && !vm.getHypervisorType().equals(HypervisorType.Hyperv)) {
             if (s_logger.isDebugEnabled()) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/server/src/com/cloud/server/StatsCollector.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java
index 548587c..067ed00 100755
--- a/server/src/com/cloud/server/StatsCollector.java
+++ b/server/src/com/cloud/server/StatsCollector.java
@@ -54,6 +54,7 @@ import com.cloud.agent.api.VmStatsEntry;
 import com.cloud.cluster.ManagementServerHostVO;
 import com.cloud.cluster.dao.ManagementServerHostDao;
 import com.cloud.exception.StorageUnavailableException;
+import com.cloud.gpu.dao.HostGpuGroupsDao;
 import com.cloud.host.Host;
 import com.cloud.host.HostStats;
 import com.cloud.host.HostVO;
@@ -175,6 +176,8 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
     private AutoScaleVmProfileDao _asProfileDao;
     @Inject
     private ServiceOfferingDao _serviceOfferingDao;
+    @Inject
+    private HostGpuGroupsDao _hostGpuGroupsDao;
 
     private ConcurrentHashMap<Long, HostStats> _hostStats = new ConcurrentHashMap<Long, HostStats>();
     private final ConcurrentHashMap<Long, VmStats> _VmStats = new ConcurrentHashMap<Long, VmStats>();
@@ -188,6 +191,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
     long volumeStatsInterval = -1L;
     long autoScaleStatsInterval = -1L;
     int vmDiskStatsInterval = 0;
+    List<Long> hostIds = null;
 
     private ScheduledExecutorService _diskStatsUpdateExecutor;
     private int _usageAggregationRange = 1440;
@@ -325,6 +329,23 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
                     }
                 }
                 _hostStats = hostStats;
+                // Get a subset of hosts with GPU support from the list of "hosts"
+                List<HostVO> gpuEnabledHosts = new ArrayList<HostVO>();
+                if (hostIds != null) {
+                    for (HostVO host : hosts) {
+                        if (hostIds.contains(host.getId())) {
+                            gpuEnabledHosts.add(host);
+                        }
+                    }
+                } else {
+                    // Check for all the hosts managed by CloudStack.
+                    gpuEnabledHosts = hosts;
+                }
+                for (HostVO host : gpuEnabledHosts) {
+                    HashMap<String, HashMap<String, Long>> groupDetails = _resourceMgr.getGPUStatistics(host);
+                    _resourceMgr.updateGPUDetails(host.getId(), groupDetails);
+                }
+                hostIds = _hostGpuGroupsDao.listHostIds();
             } catch (Throwable t) {
                 s_logger.error("Error trying to retrieve host stats", t);
             }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index 17461c0..acc922f 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -92,12 +92,14 @@ import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.PermissionDeniedException;
 import com.cloud.exception.ResourceAllocationException;
 import com.cloud.exception.StorageUnavailableException;
+import com.cloud.gpu.GPU;
 import com.cloud.host.HostVO;
 import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.hypervisor.HypervisorCapabilitiesVO;
 import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
 import com.cloud.org.Grouping;
+import com.cloud.service.dao.ServiceOfferingDetailsDao;
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.dao.DiskOfferingDao;
 import com.cloud.storage.dao.SnapshotDao;
@@ -171,6 +173,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
     @Inject
     private SnapshotDao _snapshotDao;
     @Inject
+    protected ServiceOfferingDetailsDao _serviceOfferingDetailsDao;
+    @Inject
     StoragePoolDetailsDao storagePoolDetailsDao;
     @Inject
     private UserVmDao _userVmDao;
@@ -1466,6 +1470,10 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
         }
 
         if (vm != null && vm.getState() == State.Running) {
+            // Check if the VM is GPU enabled.
+            if(_serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.pciDevice.toString()) != null) {
+                throw new InvalidParameterValueException("Live Migration of GPU enabled VM is not supported");
+            }
             // Check if the underlying hypervisor supports storage motion.
             Long hostId = vm.getHostId();
             if (hostId != null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index d1df3c1..be00aa8 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -137,6 +137,7 @@ import com.cloud.exception.ResourceAllocationException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.exception.StorageUnavailableException;
 import com.cloud.exception.VirtualMachineMigrationException;
+import com.cloud.gpu.GPU;
 import com.cloud.ha.HighAvailabilityManager;
 import com.cloud.host.Host;
 import com.cloud.host.HostVO;
@@ -3853,6 +3854,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
             ex.addProxyObject(vm.getUuid(), "vmId");
             throw ex;
         }
+
+        if(serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.pciDevice.toString()) != null) {
+            throw new InvalidParameterValueException("Live Migration of GPU enabled VM is not supported");
+        }
+
         if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && !vm.getHypervisorType().equals(HypervisorType.KVM)
                 && !vm.getHypervisorType().equals(HypervisorType.Ovm) && !vm.getHypervisorType().equals(HypervisorType.Hyperv)
                 && !vm.getHypervisorType().equals(HypervisorType.Simulator)) {
@@ -4164,6 +4170,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
             throw ex;
         }
 
+        if(serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.pciDevice.toString()) != null) {
+            throw new InvalidParameterValueException("Live Migration of GPU enabled VM is not supported");
+        }
+
         if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && !vm.getHypervisorType().equals(HypervisorType.KVM)
                 && !vm.getHypervisorType().equals(HypervisorType.Ovm) && !vm.getHypervisorType().equals(HypervisorType.Simulator)) {
             throw new InvalidParameterValueException("Unsupported hypervisor type for vm migration, we support" + " XenServer/VMware/KVM only");

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/server/test/com/cloud/resource/MockResourceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/resource/MockResourceManagerImpl.java b/server/test/com/cloud/resource/MockResourceManagerImpl.java
index 5599e8c..e6bf9a2 100644
--- a/server/test/com/cloud/resource/MockResourceManagerImpl.java
+++ b/server/test/com/cloud/resource/MockResourceManagerImpl.java
@@ -17,6 +17,7 @@
 
 package com.cloud.resource;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -35,6 +36,7 @@ import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd;
 
 import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.to.GPUDeviceTO;
 import com.cloud.dc.DataCenterVO;
 import com.cloud.dc.HostPodVO;
 import com.cloud.dc.PodCluster;
@@ -42,6 +44,7 @@ import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.DiscoveryException;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.ResourceInUseException;
+import com.cloud.gpu.HostGpuGroupsVO;
 import com.cloud.host.Host;
 import com.cloud.host.Host.Type;
 import com.cloud.host.HostStats;
@@ -554,4 +557,32 @@ public class MockResourceManagerImpl extends ManagerBase implements ResourceMana
         return false;
     }
 
+    @Override
+    public boolean isGPUDeviceAvailable(long hostId, String vgpuType) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public GPUDeviceTO getGPUDevice(long hostId, String vgpuType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public List<HostGpuGroupsVO> listAvailableGPUDevice(long hostId, String vgpuType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void updateGPUDetails(long hostId, HashMap<String, HashMap<String, Long>> deviceDetails) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public HashMap<String, HashMap<String, Long>> getGPUStatistics(HostVO host) {
+        // TODO Auto-generated method stub
+        return null;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/server/test/com/cloud/vm/DeploymentPlanningManagerImplTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vm/DeploymentPlanningManagerImplTest.java b/server/test/com/cloud/vm/DeploymentPlanningManagerImplTest.java
index 751a3bd..fb63766 100644
--- a/server/test/com/cloud/vm/DeploymentPlanningManagerImplTest.java
+++ b/server/test/com/cloud/vm/DeploymentPlanningManagerImplTest.java
@@ -78,7 +78,9 @@ import com.cloud.exception.AffinityConflictException;
 import com.cloud.exception.InsufficientServerCapacityException;
 import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.resource.ResourceManager;
 import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDetailsDao;
 import com.cloud.storage.StorageManager;
 import com.cloud.storage.dao.DiskOfferingDao;
 import com.cloud.storage.dao.GuestOSCategoryDao;
@@ -239,6 +241,16 @@ public class DeploymentPlanningManagerImplTest {
         }
 
         @Bean
+        public ResourceManager resourceManager() {
+            return Mockito.mock(ResourceManager.class);
+        }
+
+        @Bean
+        public ServiceOfferingDetailsDao serviceOfferingDetailsDao() {
+            return Mockito.mock(ServiceOfferingDetailsDao.class);
+        }
+
+        @Bean
         public DataStoreManager cataStoreManager() {
             return Mockito.mock(DataStoreManager.class);
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/server/test/resources/createNetworkOffering.xml
----------------------------------------------------------------------
diff --git a/server/test/resources/createNetworkOffering.xml b/server/test/resources/createNetworkOffering.xml
index c6228da..6ae1978 100644
--- a/server/test/resources/createNetworkOffering.xml
+++ b/server/test/resources/createNetworkOffering.xml
@@ -43,7 +43,9 @@
     </bean>
 
     <bean class="org.apache.cloudstack.networkoffering.ChildTestConfiguration" />
-    <bean id="UservmDetailsDaoImpl" class="com.cloud.vm.dao.UserVmDetailsDaoImpl" />
+    <bean id="UservmDetailsDaoImpl" class="com.cloud.vm.dao.UserVmDetailsDaoImpl" />
+    <bean id="hostGpuGroupsDaoImpl" class="com.cloud.gpu.dao.HostGpuGroupsDaoImpl" />
+    <bean id="vGPUTypesDaoImpl" class="com.cloud.gpu.dao.VGPUTypesDaoImpl" />
     <bean id="usageEventDaoImpl" class="com.cloud.event.dao.UsageEventDaoImpl" />
     <bean id="usageEventDetailsDaoImpl" class="com.cloud.event.dao.UsageEventDetailsDaoImpl" />
 </beans>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/setup/db/db/schema-430to440.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql
index be49b83..ee4cf21 100644
--- a/setup/db/db/schema-430to440.sql
+++ b/setup/db/db/schema-430to440.sql
@@ -592,4 +592,22 @@ CREATE VIEW `cloud`.`event_view` AS
         `cloud`.`event` eve ON event.start_id = eve.id;
 
 
+DROP TABLE IF EXISTS `cloud`.`host_gpu_groups`;
+CREATE TABLE `cloud`.`host_gpu_groups` (
+  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+  `group_name` varchar(255) NOT NULL,
+  `host_id` bigint(20) unsigned NOT NULL,
+  PRIMARY KEY (`id`),
+  CONSTRAINT `fk_host_gpu_groups__host_id` FOREIGN KEY (`host_id`) REFERENCES `host` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB CHARSET=utf8;
+
+DROP TABLE IF EXISTS `cloud`.`vgpu_types`;
+CREATE TABLE `cloud`.`vgpu_types` (
+  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+  `gpu_group_id` bigint(20) unsigned NOT NULL,
+  `vgpu_type` varchar(40) NOT NULL COMMENT 'vgpu type supported by this gpu group',
+  `remaining_vm_capacity` bigint(20) unsigned DEFAULT NULL COMMENT 'remaining vgpu can be created with this vgpu_type on the given gpu group',
+  PRIMARY KEY (`id`),
+  CONSTRAINT `fk_vgpu_types__gpu_group_id` FOREIGN KEY (`gpu_group_id`) REFERENCES `host_gpu_groups` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB CHARSET=utf8;
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/test/integration/smoke/test_deploy_vgpu_enabled_vm.py
----------------------------------------------------------------------
diff --git a/test/integration/smoke/test_deploy_vgpu_enabled_vm.py b/test/integration/smoke/test_deploy_vgpu_enabled_vm.py
new file mode 100644
index 0000000..a09e87e
--- /dev/null
+++ b/test/integration/smoke/test_deploy_vgpu_enabled_vm.py
@@ -0,0 +1,227 @@
+# 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.
+
+#Test from the Marvin - Testing in Python wiki
+
+#All tests inherit from cloudstackTestCase
+from marvin.cloudstackTestCase import cloudstackTestCase
+
+#Import Integration Libraries
+
+#base - contains all resources as entities and defines create, delete, list operations on them
+from marvin.integration.lib.base import Account, VirtualMachine, ServiceOffering
+
+#utils - utility classes for common cleanup, external library wrappers etc
+from marvin.integration.lib.utils import cleanup_resources
+
+#common - commonly used methods for all tests are listed here
+from marvin.integration.lib.common import get_zone, get_domain, get_template
+
+from nose.plugins.attrib import attr
+
+class Services:
+    """Test VM Life Cycle Services
+    """
+
+    def __init__(self):
+        self.services = {
+                "disk_offering":{
+                    "displaytext": "Small",
+                    "name": "Small",
+                    "disksize": 1
+                },
+                "account": {
+                    "email": "test@test.com",
+                    "firstname": "Test",
+                    "lastname": "User",
+                    "username": "test",
+                    # Random characters are appended in create account to
+                    # ensure unique username generated each time
+                    "password": "password",
+                },
+                "vgpu260q":   # Create a virtual machine instance with vgpu type as 260q
+                {
+                    "displayname": "testserver",
+                    "username": "root", # VM creds for SSH
+                    "password": "password",
+                    "ssh_port": 22,
+                    "hypervisor": 'XenServer',
+                    "privateport": 22,
+                    "publicport": 22,
+                    "protocol": 'TCP',
+                },
+                "vgpu140q":   # Create a virtual machine instance with vgpu type as 140q
+                {
+                    "displayname": "testserver",
+                    "username": "root",
+                    "password": "password",
+                    "ssh_port": 22,
+                    "hypervisor": 'XenServer',
+                    "privateport": 22,
+                    "publicport": 22,
+                    "protocol": 'TCP',
+                },
+                "service_offerings":
+                {
+                 "vgpu260qwin":
+                   {
+                        "name": "Windows Instance with vGPU260Q",
+                        "displaytext": "Windows Instance with vGPU260Q",
+                        "cpunumber": 2,
+                        "cpuspeed": 1600, # in MHz
+                        "memory": 3072, # In MBs
+                    },
+                 "vgpu140qwin":
+                    {
+                     # Small service offering ID to for change VM
+                     # service offering from medium to small
+                        "name": "Windows Instance with vGPU140Q",
+                        "displaytext": "Windows Instance with vGPU140Q",
+                        "cpunumber": 2,
+                        "cpuspeed": 1600,
+                        "memory": 3072,
+                    }
+                },
+            "diskdevice": ['/dev/vdc',  '/dev/vdb', '/dev/hdb', '/dev/hdc', '/dev/xvdd', '/dev/cdrom', '/dev/sr0', '/dev/cdrom1' ],
+            # Disk device where ISO is attached to instance
+            "mount_dir": "/mnt/tmp",
+            "sleep": 60,
+            "timeout": 10,
+            #Migrate VM to hostid
+            "ostype": 'Windows 7 (32-bit)',
+            # CentOS 5.3 (64-bit)
+        }
+
+
+class TestDeployvGPUenabledVM(cloudstackTestCase):
+    """Test deploy a vGPU enabled VM into a user account
+    """
+
+    def setUp(self):
+        self.services = Services().services
+        self.apiclient = self.testClient.getApiClient()
+
+        # Get Zone, Domain and Default Built-in template
+        self.domain = get_domain(self.apiclient, self.services)
+        self.zone = get_zone(self.apiclient, self.services)
+        self.services["mode"] = self.zone.networktype
+        # Before running this test, register a windows template with ostype as 'Windows 7 (32-bit)'
+        self.template = get_template(self.apiclient, self.zone.id, self.services["ostype"], templatetype='USER')
+
+        #create a user account
+        self.account = Account.create(
+            self.apiclient,
+            self.services["account"],
+            domainid=self.domain.id
+        )
+
+        self.services["vgpu260q"]["zoneid"] = self.zone.id
+        self.services["vgpu260q"]["template"] = self.template.id
+
+        self.services["vgpu140q"]["zoneid"] = self.zone.id
+        self.services["vgpu140q"]["template"] = self.template.id
+        #create a service offering
+        self.service_offering = ServiceOffering.create(
+                self.apiclient,
+                self.services["service_offerings"]["vgpu260qwin"],
+                serviceofferingdetails={'pciDevice': 'VGPU'}
+        )
+        #build cleanup list
+        self.cleanup = [
+            self.service_offering,
+            self.account
+        ]
+
+    @attr(tags = ['advanced', 'simulator', 'basic', 'vgpu'])
+    def test_deploy_vgpu_enabled_vm(self):
+        """Test Deploy Virtual Machine
+
+        # Validate the following:
+        # 1. Virtual Machine is accessible via SSH
+        # 2. Virtual Machine is vGPU enabled (via SSH)
+        # 3. listVirtualMachines returns accurate information
+        """
+        self.virtual_machine = VirtualMachine.create(
+            self.apiclient,
+            self.services["vgpu260q"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            serviceofferingid=self.service_offering.id,
+            mode=self.services['mode']
+        )
+
+        list_vms = VirtualMachine.list(self.apiclient, id=self.virtual_machine.id)
+
+        self.debug(
+            "Verify listVirtualMachines response for virtual machine: %s"\
+            % self.virtual_machine.id
+        )
+
+        self.assertEqual(
+            isinstance(list_vms, list),
+            True,
+            "List VM response was not a valid list"
+        )
+        self.assertNotEqual(
+            len(list_vms),
+            0,
+            "List VM response was empty"
+        )
+
+        vm = list_vms[0]
+        self.assertEqual(
+            vm.id,
+            self.virtual_machine.id,
+            "Virtual Machine ids do not match"
+        )
+        self.assertEqual(
+            vm.name,
+            self.virtual_machine.name,
+            "Virtual Machine names do not match"
+        )
+        self.assertEqual(
+            vm.state,
+            "Running",
+            msg="VM is not in Running state"
+        )
+        list_hosts = list_hosts(
+               self.apiclient,
+               id=vm.hostid
+               )
+        hostip = list_hosts[0].ipaddress
+        try:
+            sshClient = SshClient(host=hostip, port=22, user='root',passwd=self.services["host_password"])
+            res = sshClient.execute("xe vgpu-list vm-name-label=%s params=type-uuid %s" % (
+                                   vm.instancename
+                                 ))
+            self.debug("SSH result: %s" % res)
+        except Exception as e:
+            self.fail("SSH Access failed for %s: %s" % \
+                      (hostip, e)
+                      )
+        result = str(res)
+        self.assertEqual(
+                    result.count("type-uuid"),
+                    1,
+                    "VM is vGPU enabled."
+                    )
+
+    def tearDown(self):
+        try:
+            cleanup_resources(self.apiclient, self.cleanup)
+        except Exception as e:
+            self.debug("Warning! Exception in tearDown: %s" % e)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/tools/marvin/marvin/integration/lib/base.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/integration/lib/base.py b/tools/marvin/marvin/integration/lib/base.py
index 7449d8c..27a26b8 100755
--- a/tools/marvin/marvin/integration/lib/base.py
+++ b/tools/marvin/marvin/integration/lib/base.py
@@ -1462,6 +1462,9 @@ class ServiceOffering:
         if "deploymentplanner" in services:
             cmd.deploymentplanner = services["deploymentplanner"]
 
+        if "serviceofferingdetails" in services:
+            cmd.serviceofferingdetails.append({services['serviceofferingdetails']})
+
         if "isvolatile" in services:
             cmd.isvolatile = services["isvolatile"]
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/ui/scripts/configuration.js
----------------------------------------------------------------------
diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js
index e3c35af..8666042 100644
--- a/ui/scripts/configuration.js
+++ b/ui/scripts/configuration.js
@@ -361,6 +361,71 @@
                                         }
                                     },
 
+                                    pciDevice: {
+                                        label: 'GPU Type',
+                                        select: function(args) {
+                                            var items = [];
+                                            items.push({
+                                                id: '',
+                                                description: ''
+                                            });
+                                            items.push({
+                                                id: 'GPU_Passthrough',
+                                                description: 'GPU-Passthrough'
+                                            });
+                                            items.push({
+                                                id: 'VGPU',
+                                                description: 'VGPU'
+                                            });
+                                            args.response.success({
+                                                data: items
+                                            });
+                                            args.$select.change(function() {
+                                                var $form = $(this).closest('form');
+                                                var $fields = $form.find('.field');
+                                                if (($(this).val() == "") || $(this).val() == "GPU-Passthrough") {
+                                                  $form.find('[rel=vgpuType]').hide();
+                                                } else if ($(this).val() == "VGPU") {
+                                                  $form.find('[rel=vgpuType]').css('display', 'block');
+                                                }
+                                            });
+                                        }
+                                    },
+
+                                    vgpuType: {
+                                        label: 'VGPU Type',
+                                        select: function(args) {
+                                            var items = [];
+                                            items.push({
+                                                id: '',
+                                                description: ''
+                                            });
+                                            items.push({
+                                                id: 'GRID K100',
+                                                description: 'GRID K100'
+                                            });
+                                            items.push({
+                                                id: 'GRID K140Q',
+                                                description: 'GRID K140Q'
+                                            });
+                                            items.push({
+                                                id: 'GRID K200',
+                                                description: 'GRID K200'
+                                            });
+                                            items.push({
+                                                id: 'GRID K240Q',
+                                                description: 'GRID K240Q'
+                                            });
+                                            items.push({
+                                                id: 'GRID K260Q',
+                                                description: 'GRID K260Q'
+                                            });
+                                            args.response.success({
+                                                data: items
+                                            });
+                                        }
+                                    },
+
                                     domainId: {
                                         label: 'label.domain',
                                         docID: 'helpComputeOfferingDomain',
@@ -428,6 +493,14 @@
                                     array1.push("&serviceofferingdetails[0].ImplicitDedicationMode" + "=" + args.data.plannerMode);
                                 }
 
+                                if (args.data.pciDevice != "") {
+                                    array1.push("&serviceofferingdetails[1].pciDevice" + "=" + args.data.pciDevice);
+                                }
+
+                                if (args.data.pciDevice == "VGPU") {
+                                    array1.push("&serviceofferingdetails[2].vgpuType" + "=" + args.data.vgpuType);
+                                }
+
                                 if (args.data.networkRate != null && args.data.networkRate.length > 0) {
                                     $.extend(data, {
                                         networkrate: args.data.networkRate

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/ui/scripts/instances.js
----------------------------------------------------------------------
diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js
index e5b2e85..10d2591 100644
--- a/ui/scripts/instances.js
+++ b/ui/scripts/instances.js
@@ -1804,7 +1804,9 @@
                             memory: {
                             	label: 'label.memory.mb'
                             },
-                            
+                            vgpu: {
+                                label: 'VGPU'
+                            },
                             haenable: {
                                 label: 'label.ha.enabled',
                                 converter: cloudStack.converters.toBooleanText


[50/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
integration tests for VPC's enabled for distributed routing


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/6b5e234a
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/6b5e234a
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/6b5e234a

Branch: refs/heads/distributedrouter
Commit: 6b5e234aa1832cef2ba3008fce877bd59c7874c8
Parents: a29b5c6
Author: Murali Reddy <mu...@gmail.com>
Authored: Tue Mar 11 18:29:36 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Tue Mar 11 18:41:23 2014 +0530

----------------------------------------------------------------------
 build/simulator.properties                      |  28 -
 .../test_vpc_distributed_routing_offering.py    | 512 +++++++++++++++++++
 tools/marvin/marvin/integration/lib/base.py     |  15 +
 3 files changed, 527 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5e234a/build/simulator.properties
----------------------------------------------------------------------
diff --git a/build/simulator.properties b/build/simulator.properties
deleted file mode 100644
index d65d05c..0000000
--- a/build/simulator.properties
+++ /dev/null
@@ -1,28 +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.
-
-DBUSER=cloud
-DBPW=cloud
-MSLOG=vmops.log
-APISERVERLOG=api.log
-DBHOST=localhost
-DBROOTPW=
-AGENTLOGDIR=logs
-AGENTLOG=logs/agent.log
-MSMNTDIR=/mnt
-COMPONENTS-SPEC=components-simulator.xml
-AWSAPILOG=awsapi.log

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5e234a/test/integration/component/test_vpc_distributed_routing_offering.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_vpc_distributed_routing_offering.py b/test/integration/component/test_vpc_distributed_routing_offering.py
new file mode 100644
index 0000000..0fa7de7
--- /dev/null
+++ b/test/integration/component/test_vpc_distributed_routing_offering.py
@@ -0,0 +1,512 @@
+# 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.
+import unittest
+
+""" Component tests for inter VLAN functionality
+"""
+#Import Local Modules
+import marvin
+from nose.plugins.attrib import attr
+from marvin.cloudstackTestCase import *
+from marvin.cloudstackAPI import *
+from marvin.integration.lib.utils import *
+from marvin.integration.lib.base import *
+from marvin.integration.lib.common import *
+from marvin.sshClient import SshClient
+import datetime
+
+
+class Services:
+    """Test inter VLAN services
+    """
+
+    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": 100,
+                                    "memory": 128,
+                                    },
+                         "network_offering": {
+                                    "name": 'VPC Network offering',
+                                    "displaytext": 'VPC Network off',
+                                    "guestiptype": 'Isolated',
+                                    "supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Lb,UserData,StaticNat,NetworkACL, Connectivity',
+                                    "traffictype": 'GUEST',
+                                    "availability": 'Optional',
+                                    "useVpc": 'on',
+                                    "serviceProviderList": {
+                                            "Vpn": 'VpcVirtualRouter',
+                                            "Dhcp": 'VpcVirtualRouter',
+                                            "Dns": 'VpcVirtualRouter',
+                                            "SourceNat": 'VpcVirtualRouter',
+                                            "PortForwarding": 'VpcVirtualRouter',
+                                            "Lb": 'VpcVirtualRouter',
+                                            "UserData": 'VpcVirtualRouter',
+                                            "StaticNat": 'VpcVirtualRouter',
+                                            "NetworkACL": 'VpcVirtualRouter',
+                                            "Connectivity": 'Ovs'
+                                        },
+                                },
+                         "vpc_offering": {
+                                    "name": 'VPC off',
+                                    "displaytext": 'VPC off',
+                                    "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat,Connectivity',
+                                    "serviceProviderList": {
+                                            "Vpn": 'VpcVirtualRouter',
+                                            "Dhcp": 'VpcVirtualRouter',
+                                            "Dns": 'VpcVirtualRouter',
+                                            "SourceNat": 'VpcVirtualRouter',
+                                            "PortForwarding": 'VpcVirtualRouter',
+                                            "Lb": 'VpcVirtualRouter',
+                                            "UserData": 'VpcVirtualRouter',
+                                            "StaticNat": 'VpcVirtualRouter',
+                                            "Connectivity": 'Ovs'
+                                        },
+                                    "serviceCapabilityList": {
+                                        "Connectivity": {
+                                            "DistributedRouter": "true"
+                                        },
+                                    },
+                                },
+                         "vpc": {
+                                 "name": "TestVPC",
+                                 "displaytext": "TestVPC",
+                                 "cidr": '10.0.0.1/24'
+                                 },
+                         "network": {
+                                  "name": "Test Network",
+                                  "displaytext": "Test Network",
+                                  "netmask": '255.255.255.0'
+                                },
+                         "lbrule": {
+                                    "name": "SSH",
+                                    "alg": "leastconn",
+                                    # Algorithm used for load balancing
+                                    "privateport": 22,
+                                    "publicport": 2222,
+                                    "openfirewall": False,
+                                    "startport": 2222,
+                                    "endport": 2222,
+                                    "cidrlist": '0.0.0.0/0',
+                                    "protocol": 'TCP'
+                                },
+                         "natrule": {
+                                    "privateport": 22,
+                                    "publicport": 22,
+                                    "startport": 22,
+                                    "endport": 22,
+                                    "protocol": "TCP",
+                                    "cidrlist": '0.0.0.0/0',
+                                },
+                         "fw_rule": {
+                                    "startport": 1,
+                                    "endport": 6000,
+                                    "cidr": '0.0.0.0/0',
+                                    # Any network (For creating FW rule)
+                                    "protocol": "TCP"
+                                },
+                         "virtual_machine": {
+                                    "displayname": "Test VM",
+                                    "username": "root",
+                                    "password": "password",
+                                    "ssh_port": 22,
+                                    "hypervisor": 'XenServer',
+                                    # Hypervisor type should be same as
+                                    # hypervisor type of cluster
+                                    "privateport": 22,
+                                    "publicport": 22,
+                                    "protocol": 'TCP',
+                                },
+                         "ostype": 'CentOS 5.3 (64-bit)',
+                         # Cent OS 5.3 (64 bit)
+                         "sleep": 60,
+                         "timeout": 10,
+                    }
+
+
+class TestVPCDistributedRouterOffering(cloudstackTestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.api_client = super(
+                               TestVPCDistributedRouterOffering,
+                               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["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._cleanup = [
+                        cls.service_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
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        self.dbclient = self.testClient.getDbConnection()
+        self.account = Account.create(
+                                     self.apiclient,
+                                     self.services["account"],
+                                     admin=True,
+                                     domainid=self.domain.id
+                                     )
+        self.cleanup = []
+        self.cleanup.insert(0, self.account)
+        return
+
+    def tearDown(self):
+        try:
+            cleanup_resources(self.apiclient, self.cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    def validate_vpc_offering(self, vpc_offering):
+        """Validates the VPC offering"""
+
+        self.debug("Check if the VPC offering is created successfully?")
+        vpc_offs = VpcOffering.list(
+                                    self.apiclient,
+                                    id=vpc_offering.id
+                                    )
+        self.assertEqual(
+                         isinstance(vpc_offs, list),
+                         True,
+                         "List VPC offerings should return a valid list"
+                         )
+        self.assertEqual(
+                 vpc_offering.name,
+                 vpc_offs[0].name,
+                "Name of the VPC offering should match with listVPCOff data"
+                )
+        self.assertEqual(
+                 vpc_offering.name,
+                 vpc_offs[0].name,
+                "Name of the VPC offering should match with listVPCOff data"
+                )
+        self.assertEqual(
+                 vpc_offs[0].distributedvpcrouter,True,
+                 "VPC offering is not set up for Distributed routing"
+                )
+        self.debug(
+                "VPC offering is created successfully - %s" %
+                                                        vpc_offering.name)
+        return
+
+    def validate_vpc_network(self, network):
+        """Validates the VPC network"""
+
+        self.debug("Check if the VPC network is created successfully?")
+        vpc_networks = VPC.list(
+                                    self.apiclient,
+                                    id=network.id
+                          )
+        self.assertEqual(
+                         isinstance(vpc_networks, list),
+                         True,
+                         "List VPC network should return a valid list"
+                         )
+        self.assertEqual(
+                 network.name,
+                 vpc_networks[0].name,
+                 "Name of the VPC network should match with listVPC data"
+                )
+        self.debug("VPC network created successfully - %s" % network.name)
+        return
+
+    @attr(tags=["advanced", "intervlan"])
+    def test_01_create_vpc_offering_with_distributedrouter_service_capability(self):
+        """ Test create VPC offering
+        """
+
+        # Steps for validation
+        # 1. Create VPC Offering by specifying all supported Services
+        # 2. VPC offering should be created successfully.
+
+        self.debug("Creating inter VPC offering")
+        vpc_off = VpcOffering.create(
+                                     self.apiclient,
+                                     self.services["vpc_offering"]
+                                     )
+
+        self.debug("Check if the VPC offering is created successfully?")
+        self.cleanup.append(vpc_off)
+        self.validate_vpc_offering(vpc_off)
+        return
+
+    @attr(tags=["advanced", "intervlan"])
+    def test_02_create_vpc_from_offering_with_distributedrouter_service_capability(self):
+        """ Test create VPC offering
+        """
+
+        # Steps for validation
+        # 1. Create VPC Offering by specifying all supported Services
+        # 2. VPC offering should be created successfully.
+
+        self.debug("Creating inter VPC offering")
+        vpc_off = VpcOffering.create(
+                                     self.apiclient,
+                                     self.services["vpc_offering"]
+                                     )
+        vpc_off.update(self.apiclient, state='Enabled')
+        vpc = VPC.create(
+                         self.apiclient,
+                         self.services["vpc"],
+                         vpcofferingid=vpc_off.id,
+                         zoneid=self.zone.id,
+                         account=self.account.name,
+                         domainid=self.account.domainid
+                         )
+        self.assertEqual(vpc.distributedvpcrouter, True, "VPC created should have 'distributedvpcrouter' set to True")
+
+        try:
+            vpc.delete(self.apiclient)
+        except Exception as e:
+            self.fail("Failed to delete VPC network - %s" % e)
+        return
+
+    @attr(tags=["advanced", "intervlan"])
+    def test_03_deploy_vms_in_vpc_with_distributedrouter(self):
+        """Test deploy virtual machines in VPC networks"""
+
+        # 1. Create VPC Offering by specifying all supported Services
+        #   (Vpn,dhcpdns,UserData, SourceNat,Static NAT and PF,LB,NetworkAcl)
+        # 2. Create a VPC using the above VPC offering
+        # 3. Create a network as part of this VPC.
+        # 4. Deploy few Vms.
+        # 5. Create a LB rule for this VM.
+        # 6. Create a PF rule for this VM.
+        # 7. Create a  Static Nat rule for this VM.
+        # 8. Create Ingress rules on the network to open the above created
+        #    LB PF and Static Nat rule
+        # 9. Create Egress Network ACL for this network to access google.com.
+        # 10. Enable VPN services
+
+        self.debug("Creating a VPC offering..")
+        vpc_off = VpcOffering.create(
+                                     self.apiclient,
+                                     self.services["vpc_offering"]
+                                     )
+
+        vpc_off.update(self.apiclient, state='Enabled')
+
+        self.debug("creating a VPC network in the account: %s" %
+                                                    self.account.name)
+        vpc = VPC.create(
+                         self.apiclient,
+                         self.services["vpc"],
+                         vpcofferingid=vpc_off.id,
+                         zoneid=self.zone.id,
+                         account=self.account.name,
+                         domainid=self.account.domainid
+                         )
+        self.validate_vpc_network(vpc)
+
+        self.network_offering = NetworkOffering.create(
+                                            self.apiclient,
+                                            self.services["network_offering"],
+                                            conservemode=False
+                                            )
+        # Enable Network offering
+        self.network_offering.update(self.apiclient, state='Enabled')
+
+        gateway = vpc.cidr.split('/')[0]
+        # Split the cidr to retrieve gateway
+        # for eg. cidr = 10.0.0.1/24
+        # Gateway = 10.0.0.1
+
+        # Creating network using the network offering created
+        self.debug("Creating network with network offering: %s" %
+                                                    self.network_offering.id)
+        network = Network.create(
+                                self.apiclient,
+                                self.services["network"],
+                                accountid=self.account.name,
+                                domainid=self.account.domainid,
+                                networkofferingid=self.network_offering.id,
+                                zoneid=self.zone.id,
+                                gateway=gateway,
+                                vpcid=vpc.id
+                                )
+        self.debug("Created network with ID: %s" % network.id)
+        # Spawn an instance in that network
+        virtual_machine = VirtualMachine.create(
+                                  self.apiclient,
+                                  self.services["virtual_machine"],
+                                  accountid=self.account.name,
+                                  domainid=self.account.domainid,
+                                  serviceofferingid=self.service_offering.id,
+                                  networkids=[str(network.id)]
+                                  )
+        self.debug("Deployed VM in network: %s" % network.id)
+
+        self.debug("Associating public IP for network: %s" % network.name)
+        public_ip = PublicIPAddress.create(
+                                self.apiclient,
+                                accountid=self.account.name,
+                                zoneid=self.zone.id,
+                                domainid=self.account.domainid,
+                                networkid=network.id,
+                                vpcid=vpc.id
+                                )
+        self.debug("Associated %s with network %s" % (
+                                        public_ip.ipaddress.ipaddress,
+                                        network.id
+                                        ))
+
+        self.debug("Creating LB rule for IP address: %s" %
+                                        public_ip.ipaddress.ipaddress)
+
+        lb_rule = LoadBalancerRule.create(
+                                    self.apiclient,
+                                    self.services["lbrule"],
+                                    ipaddressid=public_ip.ipaddress.id,
+                                    accountid=self.account.name,
+                                    networkid=network.id,
+                                    vpcid=vpc.id,
+                                    domainid=self.account.domainid
+                                )
+
+        self.debug("Associating public IP for network: %s" % vpc.name)
+        public_ip_2 = PublicIPAddress.create(
+                                self.apiclient,
+                                accountid=self.account.name,
+                                zoneid=self.zone.id,
+                                domainid=self.account.domainid,
+                                networkid=network.id,
+                                vpcid=vpc.id
+                                )
+        self.debug("Associated %s with network %s" % (
+                                        public_ip_2.ipaddress.ipaddress,
+                                        network.id
+                                        ))
+
+        nat_rule = NATRule.create(
+                                  self.apiclient,
+                                  virtual_machine,
+                                  self.services["natrule"],
+                                  ipaddressid=public_ip_2.ipaddress.id,
+                                  openfirewall=False,
+                                  networkid=network.id,
+                                  vpcid=vpc.id
+                                  )
+
+        self.debug("Adding NetwrokACl rules to make PF and LB accessible")
+        networkacl_1 = NetworkACL.create(
+                self.apiclient,
+                networkid=network.id,
+                services=self.services["natrule"],
+                traffictype='Ingress'
+                )
+
+        networkacl_2 = NetworkACL.create(
+                                self.apiclient,
+                                networkid=network.id,
+                                services=self.services["lbrule"],
+                                traffictype='Ingress'
+                                )
+        self.debug("Checking if we can SSH into VM?")
+        try:
+            virtual_machine.get_ssh_client(
+                ipaddress=public_ip_2.ipaddress.ipaddress,
+                )
+            self.debug("SSH into VM is successfully")
+        except Exception as e:
+            self.fail("Failed to SSH into VM - %s, %s" %
+                    (public_ip_2.ipaddress.ipaddress, e))
+
+        self.debug("Associating public IP for network: %s" % network.name)
+        public_ip_3 = PublicIPAddress.create(
+                                self.apiclient,
+                                accountid=self.account.name,
+                                zoneid=self.zone.id,
+                                domainid=self.account.domainid,
+                                networkid=network.id,
+                                vpcid=vpc.id
+                                )
+        self.debug("Associated %s with network %s" % (
+                                        public_ip_3.ipaddress.ipaddress,
+                                        network.id
+                                        ))
+        self.debug("Enabling static NAT for IP: %s" %
+                                            public_ip_3.ipaddress.ipaddress)
+        try:
+            StaticNATRule.enable(
+                              self.apiclient,
+                              ipaddressid=public_ip_3.ipaddress.id,
+                              virtualmachineid=virtual_machine.id,
+                              networkid=network.id
+                              )
+            self.debug("Static NAT enabled for IP: %s" %
+                                            public_ip_3.ipaddress.ipaddress)
+        except Exception as e:
+            self.fail("Failed to enable static NAT on IP: %s - %s" % (
+                                            public_ip_3.ipaddress.ipaddress, e))
+
+        public_ips = PublicIPAddress.list(
+                                          self.apiclient,
+                                          networkid=network.id,
+                                          listall=True,
+                                          isstaticnat=True,
+                                          account=self.account.name,
+                                          domainid=self.account.domainid
+                                          )
+        self.assertEqual(
+                         isinstance(public_ips, list),
+                         True,
+                         "List public Ip for network should list the Ip addr"
+                         )
+        self.assertEqual(
+                         public_ips[0].ipaddress,
+                         public_ip_3.ipaddress.ipaddress,
+                         "List public Ip for network should list the Ip addr"
+                         )
+        # TODO: Remote Access VPN is not yet supported in VPC
+        return
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5e234a/tools/marvin/marvin/integration/lib/base.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/integration/lib/base.py b/tools/marvin/marvin/integration/lib/base.py
index 27a26b8..d2181fb 100755
--- a/tools/marvin/marvin/integration/lib/base.py
+++ b/tools/marvin/marvin/integration/lib/base.py
@@ -3081,6 +3081,21 @@ class VpcOffering:
         cmd.name = "-".join([services["name"], random_gen()])
         cmd.displaytext = services["displaytext"]
         cmd.supportedServices = services["supportedservices"]
+        if "serviceProviderList" in services:
+            for service, provider in services["serviceProviderList"].items():
+                cmd.serviceproviderlist.append({
+                                            'service': service,
+                                            'provider': provider
+                                           })
+        if "serviceCapabilityList" in services:
+            cmd.servicecapabilitylist = []
+            for service, capability in services["serviceCapabilityList"].items():
+                for ctype, value in capability.items():
+                    cmd.servicecapabilitylist.append({
+                                            'service': service,
+                                            'capabilitytype': ctype,
+                                            'capabilityvalue': value
+                                           })
         return VpcOffering(apiclient.createVPCOffering(cmd).__dict__)
 
     def update(self, apiclient, name=None, displaytext=None, state=None):


[04/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
CLOUDSTACK-6047: Fix FindBugs warning


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/78b148d0
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/78b148d0
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/78b148d0

Branch: refs/heads/distributedrouter
Commit: 78b148d0fccdf61e1c6c103e4dfa6b80b0fe9931
Parents: 2de67df
Author: Sheng Yang <sh...@citrix.com>
Authored: Thu Mar 6 19:27:46 2014 -0800
Committer: Sheng Yang <sh...@citrix.com>
Committed: Thu Mar 6 19:27:46 2014 -0800

----------------------------------------------------------------------
 .../cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/78b148d0/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
index 49e6812..f22a0db 100755
--- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
+++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
@@ -1091,6 +1091,7 @@ public class VirtualRoutingResource {
                 List<ConfigItem> cfg = generateCommandCfg(command);
                 if (cfg == null) {
                     s_logger.warn("Unknown commands for VirtualRoutingResource, but continue: " + cmd.toString());
+                    continue;
                 }
 
                 for (ConfigItem c : cfg) {


[21/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
CLOUDSTACK-6147: Adding first set of test caess for Dynamic Compute Offering feature

Signed-off-by: SrikanteswaraRao Talluri <ta...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/3f7b628c
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/3f7b628c
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/3f7b628c

Branch: refs/heads/distributedrouter
Commit: 3f7b628c707cd9c30542efd670416be5fbb473f0
Parents: 3b3ae02
Author: Gaurav Aradhye <ga...@clogeny.com>
Authored: Fri Feb 28 01:46:24 2014 -0500
Committer: SrikanteswaraRao Talluri <ta...@apache.org>
Committed: Mon Mar 10 11:20:44 2014 +0530

----------------------------------------------------------------------
 .../component/test_dynamic_compute_offering.py  | 409 +++++++++++++++++++
 tools/marvin/marvin/integration/lib/base.py     |  29 +-
 tools/marvin/marvin/integration/lib/common.py   |  14 +
 3 files changed, 451 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f7b628c/test/integration/component/test_dynamic_compute_offering.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_dynamic_compute_offering.py b/test/integration/component/test_dynamic_compute_offering.py
new file mode 100644
index 0000000..75cf0d6
--- /dev/null
+++ b/test/integration/component/test_dynamic_compute_offering.py
@@ -0,0 +1,409 @@
+# 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 Dynamic Compute Offering Feature
+
+    Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Dynamic+ComputeOffering
+
+    Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-6147
+
+    Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Dynamic+Compute+Offering+FS
+"""
+from marvin.cloudstackTestCase import cloudstackTestCase
+from marvin.integration.lib.utils import (cleanup_resources,
+                                          validateList)
+from marvin.integration.lib.base import (ServiceOffering,
+                                         VirtualMachine,
+                                         Account)
+from marvin.integration.lib.common import (get_domain,
+                                           get_zone,
+                                           get_template,
+                                           verifyComputeOfferingCreation)
+
+from nose.plugins.attrib import attr
+from marvin.codes import PASS, ADMIN_ACCOUNT, USER_ACCOUNT
+from ddt import ddt, data
+
+@ddt
+class TestDynamicServiceOffering(cloudstackTestCase):
+    """Test Dynamic Service Offerings
+    """
+
+    @classmethod
+    def setUpClass(cls):
+        cloudstackTestClient = super(TestDynamicServiceOffering,cls).getClsTestClient()
+        cls.api_client = cloudstackTestClient.getApiClient()
+
+        # Fill services from the external config file
+        cls.services = cloudstackTestClient.getConfigParser().parsedDict
+
+        # Get Zone, Domain and templates
+        cls.domain = get_domain(cls.api_client, cls.services)
+        cls.zone = get_zone(cls.api_client, cls.services)
+        cls.mode = str(cls.zone.networktype).lower()
+        cls.template = get_template(
+                            cls.api_client,
+                            cls.zone.id,
+                            cls.services["ostype"]
+                            )
+        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+        cls.services["virtual_machine"]["template"] = cls.template.id
+        cls._cleanup = []
+        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
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        self.dbclient = self.testClient.getDbConnection()
+        self.cleanup_co = []
+        self.cleanup = []
+        return
+
+    def tearDown(self):
+        try:
+            # Clean up compute offerings
+            cleanup_resources(self.apiclient, self.cleanup)
+
+            # Clean up compute offerings
+            cleanup_resources(self.apiclient, self.cleanup_co)
+
+            self.cleanup_co[:] = []
+            self.cleanup[:] = []
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    @attr(tags=["basic","advanced"])
+    def test_create_normal_compute_offering(self):
+        """ Create normal compute offering with non zero values for cpu,
+            cpu number and memory"""
+
+        # Steps:
+        # 1. Create normal compute offering with non zero values for cpu number,
+        #    cpu speed, memory
+
+        # Validations:
+        # 1. Compute offering should be created
+
+        self.services["service_offering"]["cpunumber"] = 2
+        self.services["service_offering"]["cpuspeed"] = 256
+        self.services["service_offering"]["memory"] = 128
+
+        serviceOffering = ServiceOffering.create(self.api_client,
+                                                 self.services["service_offering"]
+                                                 )
+        self.assertEqual(verifyComputeOfferingCreation(self.apiclient, serviceOffering.id),
+                         PASS, "Compute Offering verification failed")
+
+        self.cleanup_co.append(serviceOffering)
+        return
+
+    @attr(tags=["basic","advanced"])
+    def test_create_dynamic_compute_offering(self):
+        """ Create dynamic compute offering with cpunumber, cpuspeed and memory
+            not specified"""
+
+        # Steps:
+        # 1. Create dynamic compute offering with values for cpu number,
+        #    cpu speed, memory not specified
+
+        # Validations:
+        # 1. Compute offering should be created
+
+        self.services["service_offering"]["cpunumber"] = ""
+        self.services["service_offering"]["cpuspeed"] = ""
+        self.services["service_offering"]["memory"] = ""
+
+        serviceOffering = ServiceOffering.create(self.api_client,
+                                                 self.services["service_offering"]
+                                                 )
+        self.assertEqual(verifyComputeOfferingCreation(self.apiclient, serviceOffering.id),
+                         PASS, "Compute Offering verification failed")
+
+        self.cleanup_co.append(serviceOffering)
+        return
+
+    @attr(tags=["basic","advanced"])
+    def test_create_dynamic_compute_offering_no_cpunumber(self):
+        """ Create dynamic compute offering with only cpunumber unspecified"""
+
+        # Validations:
+        # 1. Compute Offering creation should fail
+
+        self.services["service_offering"]["cpunumber"] = ""
+        self.services["service_offering"]["cpuspeed"] = 256
+        self.services["service_offering"]["memory"] = 128
+
+        try:
+            serviceOffering = ServiceOffering.create(self.api_client,
+                                                 self.services["service_offering"]
+                                                 )
+            self.cleanup_co.append(serviceOffering)
+            self.fail("Compute Offering creation succeded, it should have failed")
+        except Exception:
+            self.debug("Compute Offering Creation failed as expected")
+        return
+
+    @attr(tags=["basic","advanced"])
+    def test_create_dynamic_compute_offering_no_cpuspeed(self):
+        """ Create dynamic compute offering with only cpuspeed unspecified"""
+
+        # Validations:
+        # 1. Compute offering creation should fail
+
+        self.services["service_offering"]["cpunumber"] = 2
+        self.services["service_offering"]["cpuspeed"] = ""
+        self.services["service_offering"]["memory"] = 128
+
+        try:
+            serviceOffering = ServiceOffering.create(self.api_client,
+                                                 self.services["service_offering"]
+                                                 )
+            self.cleanup_co.append(serviceOffering)
+            self.fail("Compute Offering creation succeded, it should have failed")
+        except Exception:
+            self.debug("Compute Offering Creation failed as expected")
+        return
+
+    @attr(tags=["basic","advanced"])
+    def test_create_dynamic_compute_offering_no_memory(self):
+        """ Create dynamic compute offering with only memory unspecified"""
+
+        # Validations:
+        # 1. Compute offering creation should fail
+
+        self.services["service_offering"]["cpunumber"] = 2
+        self.services["service_offering"]["cpuspeed"] = 256
+        self.services["service_offering"]["memory"] = ""
+
+        try:
+            serviceOffering = ServiceOffering.create(self.api_client,
+                                                 self.services["service_offering"]
+                                                 )
+            self.cleanup_co.append(serviceOffering)
+            self.fail("Compute Offering creation succeded, it should have failed")
+        except Exception:
+            self.debug("Compute Offering Creation failed as expected")
+        return
+
+    @data(ADMIN_ACCOUNT, USER_ACCOUNT)
+    @attr(tags=["basic","advanced"])
+    def test_deploy_virtual_machines_static_offering(self, value):
+        """Test deploy VM with static offering"""
+
+        # Steps:
+        # 1. Create admin/user account and create its user api client
+        # 2. Create a static compute offering
+        # 3. Deploy a VM with account api client and static service offering
+        # 4. Repeat step 3 but also pass custom values for cpu number, cpu speed and memory
+        #    while deploying VM
+
+        # Validations:
+        # 1. Step 3 should succeed
+        # 2. Step 4 should fail
+
+        isadmin=True
+        if value == USER_ACCOUNT:
+            isadmin=False
+
+        # Create Account
+        self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin)
+        apiclient = self.testClient.createUserApiClient(
+                                    UserName=self.account.name,
+                                    DomainName=self.account.domain)
+        self.cleanup.append(self.account)
+
+        # Create service offering
+        self.services["service_offering"]["cpunumber"] = 2
+        self.services["service_offering"]["cpuspeed"] = 256
+        self.services["service_offering"]["memory"] = 128
+
+        serviceOffering = ServiceOffering.create(self.apiclient,
+                                                 self.services["service_offering"])
+
+        self.cleanup_co.append(serviceOffering)
+
+        # Deploy VM with static service offering
+        try:
+            VirtualMachine.create(apiclient,self.services["virtual_machine"],
+                                                    serviceofferingid=serviceOffering.id,
+                                                    accountid=self.account.name,domainid=self.account.domainid)
+        except Exception as e:
+            self.fail("vm creation failed: %s" % e)
+
+        # Deploy VM with static service offering, also with custom values
+        try:
+            VirtualMachine.create(apiclient,self.services["virtual_machine"],
+                serviceofferingid=serviceOffering.id,
+                customcpunumber=4,
+                customcpuspeed=512,
+                custommemory=256,
+                accountid=self.account.name,domainid=self.account.domainid)
+            self.fail("VM creation should have failed, it succeeded")
+        except Exception as e:
+            self.debug("vm creation failed as expected: %s" % e)
+        return
+
+    @data(ADMIN_ACCOUNT, USER_ACCOUNT)
+    @attr(tags=["basic","advanced"])
+    def test_deploy_virtual_machines_dynamic_offering(self, value):
+        """Test deploy VM with dynamic compute offering"""
+
+        # Steps:
+        # 1. Create admin/user account and create its user api client
+        # 2. Create a dynamic service offering
+        # 3. Deploy a VM with account api client and dynamic service offering
+        #    without providing custom values for cpu number, cpu speed and memory
+        # 4. Deploy a VM with account api client and dynamic service offering providing
+        #    custom values for cpu number, cpu speed and memory
+        # 5. Deploy a VM with account api client and dynamic service offering providing
+        #    custom values only for cpu number
+
+        # Validations:
+        # 1. Step 3 should fail
+        # 2. Step 4 should succeed
+        # 3. Step 5 should fail
+
+        isadmin=True
+        if value == USER_ACCOUNT:
+            isadmin=False
+
+        # Create Account and its api client
+        self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin)
+        apiclient = self.testClient.createUserApiClient(
+                                    UserName=self.account.name,
+                                    DomainName=self.account.domain)
+        self.cleanup.append(self.account)
+
+        # Create dynamic service offering
+        self.services["service_offering"]["cpunumber"] = ""
+        self.services["service_offering"]["cpuspeed"] = ""
+        self.services["service_offering"]["memory"] = ""
+
+        serviceOffering = ServiceOffering.create(self.apiclient,
+                                                 self.services["service_offering"])
+
+        self.cleanup_co.append(serviceOffering)
+
+        # Deploy VM with dynamic compute offering without providing custom values for
+        # cpu number, cpu speed and memory
+        try:
+            VirtualMachine.create(apiclient,self.services["virtual_machine"],
+                                                    serviceofferingid=serviceOffering.id,
+                                                    accountid=self.account.name,domainid=self.account.domainid)
+            self.fail("VM creation succeded, it should have failed")
+        except Exception as e:
+            self.debug("vm creation failed as expected with error: %s" % e)
+
+        # Deploy VM with dynamic compute offering providing custom values for
+        # cpu number, cpu speed and memory
+        try:
+            VirtualMachine.create(apiclient,self.services["virtual_machine"],
+                serviceofferingid=serviceOffering.id,
+                customcpunumber=2,
+                customcpuspeed=256,
+                custommemory=128,
+                accountid=self.account.name,domainid=self.account.domainid)
+        except Exception as e:
+            self.fail("vm creation failed: %s" % e)
+
+        # Deploy VM with dynamic compute offering providing custom values for only
+        # cpu number
+        try:
+            VirtualMachine.create(apiclient,self.services["virtual_machine"],
+                serviceofferingid=serviceOffering.id,
+                customcpunumber=2,
+                accountid=self.account.name,domainid=self.account.domainid)
+            self.fail("VM deployment should have failed, it succeded")
+        except Exception as e:
+            self.debug("vm creation failed as expected: %s" % e)
+        return
+
+    @data(ADMIN_ACCOUNT, USER_ACCOUNT)
+    @attr(tags=["basic","advanced"])
+    def test_check_vm_stats(self, value):
+        """Deploy VM with dynamic service offering and check VM stats"""
+
+        # Steps:
+        # 1. Create admin/user account and create its user api client
+        # 2. Create a dynamic service offering
+        # 3. Deploy a VM with account api client and dynamic service offering
+        #    providing custom values for cpu number, cpu speed and memory
+        # 4. List the VM and verify the dynamic parameters are same as passed
+
+        isadmin=True
+        if value == USER_ACCOUNT:
+            isadmin=False
+
+        # Create Account and api client
+        self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin)
+        apiclient = self.testClient.createUserApiClient(
+                                    UserName=self.account.name,
+                                    DomainName=self.account.domain)
+        self.cleanup.append(self.account)
+
+        # Create dynamic compute offering
+        self.services["service_offering"]["cpunumber"] = ""
+        self.services["service_offering"]["cpuspeed"] = ""
+        self.services["service_offering"]["memory"] = ""
+
+        serviceOffering = ServiceOffering.create(self.apiclient,
+                                                 self.services["service_offering"])
+
+        self.cleanup_co.append(serviceOffering)
+
+        # Custom values
+        customcpunumber = 2
+        customcpuspeed = 256
+        custommemory = 128
+
+        # Deploy VM with dynamic service offering and the custom values
+        try:
+            virtualMachine = VirtualMachine.create(apiclient,self.services["virtual_machine"],
+                serviceofferingid=serviceOffering.id,
+                customcpunumber=customcpunumber,
+                customcpuspeed=customcpuspeed,
+                custommemory=custommemory,
+                accountid=self.account.name,domainid=self.account.domainid)
+        except Exception as e:
+            self.fail("vm creation failed: %s" % e)
+
+        vmlist = VirtualMachine.list(self.apiclient, id=virtualMachine.id)
+        self.assertEqual(validateList(vmlist)[0], PASS, "vm list validation failed")
+        vm = vmlist[0]
+
+        # Verify the custom values
+        self.assertEqual(str(vm.cpunumber), str(customcpunumber), "vm cpu number %s\
+                 not matching with provided custom cpu number %s" % \
+                 (vm.cpunumber, customcpunumber))
+
+        self.assertEqual(str(vm.cpuspeed), str(customcpuspeed), "vm cpu speed %s\
+                 not matching with provided custom cpu speed %s" % \
+                 (vm.cpuspeed, customcpuspeed))
+
+        self.assertEqual(str(vm.memory), str(custommemory), "vm memory %s\
+                 not matching with provided custom memory %s" % \
+                 (vm.memory, custommemory))
+        return

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f7b628c/tools/marvin/marvin/integration/lib/base.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/integration/lib/base.py b/tools/marvin/marvin/integration/lib/base.py
index 0a7ad94..7449d8c 100755
--- a/tools/marvin/marvin/integration/lib/base.py
+++ b/tools/marvin/marvin/integration/lib/base.py
@@ -324,7 +324,8 @@ class VirtualMachine:
                     domainid=None, zoneid=None, networkids=None, serviceofferingid=None,
                     securitygroupids=None, projectid=None, startvm=None,
                     diskofferingid=None, affinitygroupnames=None, affinitygroupids=None, group=None,
-                    hostid=None, keypair=None, ipaddress=None, mode='default', method='GET'):
+                    hostid=None, keypair=None, ipaddress=None, mode='default', method='GET',
+                    customcpunumber=None, customcpuspeed=None, custommemory=None):
         """Create the instance"""
 
         cmd = deployVirtualMachine.deployVirtualMachineCmd()
@@ -412,6 +413,17 @@ class VirtualMachine:
         if "userdata" in services:
             cmd.userdata = base64.urlsafe_b64encode(services["userdata"])
 
+        cmd.details = [{"cpuNumber": "","cpuSpeed":"","memory":""}]
+
+        if customcpunumber:
+            cmd.details[0]["cpuNumber"] = customcpunumber
+
+        if customcpuspeed:
+            cmd.details[0]["cpuSpeed"] = customcpuspeed
+
+        if custommemory:
+            cmd.details[0]["memory"] = custommemory
+
         if group:
             cmd.group = group
 
@@ -636,6 +648,21 @@ class VirtualMachine:
 
         return apiclient.updateVMAffinityGroup(cmd)
 
+    def scale(self, apiclient, serviceOfferingId,
+            customcpunumber=None, customcpuspeed=None, custommemory=None):
+        """Change service offering of the instance"""
+        cmd = scaleVirtualMachine.scaleVirtualMachineCmd()
+        cmd.id = self.id
+        cmd.serviceofferingid = serviceOfferingId
+        cmd.details = [{"cpuNumber": "","cpuSpeed":"","memory":""}]
+        if customcpunumber:
+            cmd.details[0]["cpuNumber"] = customcpunumber
+        if customcpuspeed:
+            cmd.details[0]["cpuSpeed"] = customcpuspeed
+        if custommemory:
+            cmd.details[0]["memory"] = custommemory
+        return apiclient.scaleVirtualMachine(cmd)
+
 
 class Volume:
     """Manage Volume Life cycle

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f7b628c/tools/marvin/marvin/integration/lib/common.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/integration/lib/common.py b/tools/marvin/marvin/integration/lib/common.py
index d3d634b..3b292bf 100644
--- a/tools/marvin/marvin/integration/lib/common.py
+++ b/tools/marvin/marvin/integration/lib/common.py
@@ -985,3 +985,17 @@ def verifyNetworkState(apiclient, networkid, state):
     assert validateList(networks)[0] == PASS, "Networks list validation failed, list is %s" % networks
     assert str(networks[0].state).lower() == state, "network state should be %s, it is %s" % (state, networks[0].state)
     return
+
+def verifyComputeOfferingCreation(apiclient, computeofferingid):
+    """List Compute offerings by ID and verify that the offering exists"""
+
+    cmd = listServiceOfferings.listServiceOfferingsCmd()
+    cmd.id = computeofferingid
+    serviceOfferings = None
+    try:
+        serviceOfferings = apiclient.listServiceOfferings(cmd)
+    except Exception as e:
+       return FAIL
+    if not (isinstance(serviceOfferings, list) and len(serviceOfferings) > 0):
+       return FAIL
+    return PASS


[41/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
-introduces 'DistributedRouter' as capability to 'Connectivity' service.
-create VPC offering to permit 'DistributedRouter' as capability to
connectivity service


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/7ce42371
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/7ce42371
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/7ce42371

Branch: refs/heads/distributedrouter
Commit: 7ce423714552d70b8e5bbe682045759f99ea179f
Parents: 991e1eb
Author: Murali Reddy <mu...@gmail.com>
Authored: Tue Mar 4 16:42:17 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Tue Mar 11 18:36:56 2014 +0530

----------------------------------------------------------------------
 api/src/com/cloud/network/Network.java          |  3 +-
 api/src/com/cloud/network/vpc/VpcOffering.java  |  5 ++
 .../network/vpc/VpcProvisioningService.java     |  6 +-
 .../org/apache/cloudstack/api/ApiConstants.java |  3 +-
 .../command/admin/vpc/CreateVPCOfferingCmd.java | 10 +++-
 .../api/response/VpcOfferingResponse.java       |  8 +++
 .../com/cloud/network/vpc/VpcOfferingVO.java    | 12 +++-
 .../management/ContrailManagerImpl.java         |  2 +-
 server/src/com/cloud/api/ApiResponseHelper.java |  1 +
 .../com/cloud/network/vpc/VpcManagerImpl.java   | 63 +++++++++++++++++---
 setup/db/db/schema-430to440.sql                 |  1 +
 11 files changed, 99 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7ce42371/api/src/com/cloud/network/Network.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java
index 6dc6752..3283a55 100644
--- a/api/src/com/cloud/network/Network.java
+++ b/api/src/com/cloud/network/Network.java
@@ -57,7 +57,7 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
         public static final Service PortForwarding = new Service("PortForwarding");
         public static final Service SecurityGroup = new Service("SecurityGroup");
         public static final Service NetworkACL = new Service("NetworkACL", Capability.SupportedProtocols);
-        public static final Service Connectivity = new Service("Connectivity");
+        public static final Service Connectivity = new Service("Connectivity", Capability.DistributedRouter);
 
         private final String name;
         private final Capability[] caps;
@@ -186,6 +186,7 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
         public static final Capability SslTermination = new Capability("SslTermination");
         public static final Capability LbSchemes = new Capability("LbSchemes");
         public static final Capability DhcpAccrossMultipleSubnets = new Capability("DhcpAccrossMultipleSubnets");
+        public static final Capability DistributedRouter = new Capability("DistributedRouter");
 
         private final String name;
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7ce42371/api/src/com/cloud/network/vpc/VpcOffering.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/vpc/VpcOffering.java b/api/src/com/cloud/network/vpc/VpcOffering.java
index 6e75a2f..a0a1b15 100644
--- a/api/src/com/cloud/network/vpc/VpcOffering.java
+++ b/api/src/com/cloud/network/vpc/VpcOffering.java
@@ -55,4 +55,9 @@ public interface VpcOffering extends InternalIdentity, Identity {
      */
     Long getServiceOfferingId();
 
+    /**
+     *
+     * @return true if the offering provides a distributed router capable of one-hop forwarding
+     */
+    boolean supportsDistributedRouter();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7ce42371/api/src/com/cloud/network/vpc/VpcProvisioningService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/vpc/VpcProvisioningService.java b/api/src/com/cloud/network/vpc/VpcProvisioningService.java
index 174b71f..e545275 100644
--- a/api/src/com/cloud/network/vpc/VpcProvisioningService.java
+++ b/api/src/com/cloud/network/vpc/VpcProvisioningService.java
@@ -23,8 +23,10 @@ public interface VpcProvisioningService {
 
     public VpcOffering getVpcOffering(long vpcOfferingId);
 
-    public VpcOffering createVpcOffering(String name, String displayText, List<String> supportedServices, Map<String, List<String>> serviceProviders,
-        Long serviceOfferingId);
+    public VpcOffering createVpcOffering(String name, String displayText, List<String> supportedServices,
+                                         Map<String, List<String>> serviceProviders,
+                                         Map serviceCapabilitystList,
+                                         Long serviceOfferingId);
 
     List<? extends VpcOffering> listVpcOfferings(Long id, String name, String displayText, List<String> supportedServicesStr, Boolean isDefault, String keyword,
         String state, Long startIndex, Long pageSizeVal);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7ce42371/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index 0a3fafd..3cd3e82 100755
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -586,7 +586,8 @@ public class ApiConstants {
     public static final String VGPU = "vgpu";
     public static final String VGPUTYPE = "vgputype";
     public static final String REMAININGCAPACITY = "remainingcapacity";
-
+    public static final String DISTRIBUTED_VPC_ROUTER = "distributedvpcrouter";
+ 
     public enum HostDetails {
         all, capacity, events, stats, min;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7ce42371/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java
index 6b2c4ba..5b3090b 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java
@@ -66,6 +66,9 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd {
         + "If not specified, the provider for the service will be mapped to the default provider on the physical network")
     private Map<String, String> serviceProviderList;
 
+    @Parameter(name = ApiConstants.SERVICE_CAPABILITY_LIST, type = CommandType.MAP, description = "desired service capabilities as part of vpc offering")
+    private Map serviceCapabilitystList;
+
     @Parameter(name = ApiConstants.SERVICE_OFFERING_ID,
                type = CommandType.UUID,
                entityType = ServiceOfferingResponse.class,
@@ -112,13 +115,18 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd {
         return serviceProviderMap;
     }
 
+    public Map<String, List<String>> getServiceCapabilitystList() {
+        return serviceCapabilitystList;
+    }
+
     public Long getServiceOfferingId() {
         return serviceOfferingId;
     }
 
     @Override
     public void create() throws ResourceAllocationException {
-        VpcOffering vpcOff = _vpcProvSvc.createVpcOffering(getVpcOfferingName(), getDisplayText(), getSupportedServices(), getServiceProviders(), getServiceOfferingId());
+        VpcOffering vpcOff = _vpcProvSvc.createVpcOffering(getVpcOfferingName(), getDisplayText(),
+                getSupportedServices(), getServiceProviders(), getServiceCapabilitystList(), getServiceOfferingId());
         if (vpcOff != null) {
             setEntityId(vpcOff.getId());
             setEntityUuid(vpcOff.getUuid());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7ce42371/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java
index 17e4dfd..89697f0 100644
--- a/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java
@@ -59,6 +59,10 @@ public class VpcOfferingResponse extends BaseResponse {
     @Param(description = "the list of supported services", responseObject = ServiceResponse.class)
     private List<ServiceResponse> services;
 
+    @SerializedName(ApiConstants.DISTRIBUTED_VPC_ROUTER)
+    @Param(description = " indicates if the vpc offering supports distributed router for one-hop forwarding")
+    private Boolean supportsDistributedRouter;
+
     public void setId(String id) {
         this.id = id;
     }
@@ -86,4 +90,8 @@ public class VpcOfferingResponse extends BaseResponse {
     public void setState(String state) {
         this.state = state;
     }
+
+    public void setSupportsDistributedRouter(Boolean supportsDistributedRouter) {
+        this.supportsDistributedRouter = supportsDistributedRouter;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7ce42371/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java b/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java
index 3a676e6..53f6f60 100644
--- a/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java
+++ b/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java
@@ -67,6 +67,9 @@ public class VpcOfferingVO implements VpcOffering {
     @Column(name = "service_offering_id")
     Long serviceOfferingId;
 
+    @Column(name = "supports_distributed_router")
+    boolean supportsDistributedRouter=false;
+
     public VpcOfferingVO() {
         this.uuid = UUID.randomUUID().toString();
     }
@@ -80,9 +83,11 @@ public class VpcOfferingVO implements VpcOffering {
         this.state = State.Disabled;
     }
 
-    public VpcOfferingVO(String name, String displayText, boolean isDefault, Long serviceOfferingId) {
+    public VpcOfferingVO(String name, String displayText, boolean isDefault, Long serviceOfferingId,
+                         boolean supportsDistributedRouter) {
         this(name, displayText, serviceOfferingId);
         this.isDefault = isDefault;
+        this.supportsDistributedRouter = supportsDistributedRouter;
     }
 
     @Override
@@ -145,4 +150,9 @@ public class VpcOfferingVO implements VpcOffering {
     public Long getServiceOfferingId() {
         return serviceOfferingId;
     }
+
+    @Override
+    public boolean supportsDistributedRouter() {
+        return supportsDistributedRouter;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7ce42371/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java
index 01be7db..bf083fd 100644
--- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java
@@ -281,7 +281,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager
         for (String svc: services) {
             serviceProviderMap.put(svc, providerSet);
         }
-        vpcOffer = _vpcProvSvc.createVpcOffering(juniperVPCOfferingName, juniperVPCOfferingDisplayText, services, serviceProviderMap, null);
+        vpcOffer = _vpcProvSvc.createVpcOffering(juniperVPCOfferingName, juniperVPCOfferingDisplayText, services, serviceProviderMap, null, null);
         ((VpcOfferingVO)vpcOffer).setState(VpcOffering.State.Enabled);
         long id = vpcOffer.getId();
         _vpcOffDao.update(id, (VpcOfferingVO)vpcOffer);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7ce42371/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index 81bfe21..73c9c6b 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -2748,6 +2748,7 @@ public class ApiResponseHelper implements ResponseGenerator {
         response.setDisplayText(offering.getDisplayText());
         response.setIsDefault(offering.isDefault());
         response.setState(offering.getState().name());
+        response.setSupportsDistributedRouter(offering.supportsDistributedRouter());
 
         Map<Service, Set<Provider>> serviceProviderMap = ApiDBUtils.listVpcOffServices(offering.getId());
         List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7ce42371/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index 762cc6f..0b70faa 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -18,8 +18,10 @@ package com.cloud.network.vpc;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -231,7 +233,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
                             svcProviderMap.put(svc, defaultProviders);
                         }
                     }
-                    createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap, true, State.Enabled, null);
+                    createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap, true, State.Enabled, null, false);
                 }
 
                 //configure default vpc offering with Netscaler as LB Provider
@@ -250,7 +252,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
                             svcProviderMap.put(svc, defaultProviders);
                         }
                     }
-                    createVpcOffering(VpcOffering.defaultVPCNSOfferingName, VpcOffering.defaultVPCNSOfferingName, svcProviderMap, false, State.Enabled, null);
+                    createVpcOffering(VpcOffering.defaultVPCNSOfferingName, VpcOffering.defaultVPCNSOfferingName, svcProviderMap, false, State.Enabled, null, false);
                 }
             }
         });
@@ -299,8 +301,10 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
 
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_VPC_OFFERING_CREATE, eventDescription = "creating vpc offering", create = true)
-    public VpcOffering createVpcOffering(String name, String displayText, List<String> supportedServices, Map<String, List<String>> serviceProviders,
-        Long serviceOfferingId) {
+    public VpcOffering createVpcOffering(String name, String displayText, List<String> supportedServices,
+                                         Map<String, List<String>> serviceProviders,
+                                         Map serviceCapabilitystList,
+                                         Long serviceOfferingId) {
         Map<Network.Service, Set<Network.Provider>> svcProviderMap = new HashMap<Network.Service, Set<Network.Provider>>();
         Set<Network.Provider> defaultProviders = new HashSet<Network.Provider>();
         defaultProviders.add(Provider.VPCVirtualRouter);
@@ -372,20 +376,25 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
             }
         }
 
-        VpcOffering offering = createVpcOffering(name, displayText, svcProviderMap, false, null, serviceOfferingId);
+        boolean supportsDistributedRouter = isVpcOfferingSupportsDistributedRouter(serviceCapabilitystList);
+
+        VpcOffering offering = createVpcOffering(name, displayText, svcProviderMap, false, null,
+                serviceOfferingId,supportsDistributedRouter);
         CallContext.current().setEventDetails(" Id: " + offering.getId() + " Name: " + name);
 
         return offering;
     }
 
     @DB
-    protected VpcOffering createVpcOffering(final String name, final String displayText, final Map<Network.Service, Set<Network.Provider>> svcProviderMap,
-        final boolean isDefault, final State state, final Long serviceOfferingId) {
+    protected VpcOffering createVpcOffering(final String name, final String displayText,
+                                            final Map<Network.Service, Set<Network.Provider>> svcProviderMap,
+                                            final boolean isDefault, final State state, final Long serviceOfferingId,
+                                            final boolean supportsDistributedRouter) {
         return Transaction.execute(new TransactionCallback<VpcOffering>() {
             @Override
             public VpcOffering doInTransaction(TransactionStatus status) {
                 // create vpc offering object
-                VpcOfferingVO offering = new VpcOfferingVO(name, displayText, isDefault, serviceOfferingId);
+                VpcOfferingVO offering = new VpcOfferingVO(name, displayText, isDefault, serviceOfferingId, supportsDistributedRouter);
 
                 if (state != null) {
                     offering.setState(state);
@@ -413,6 +422,44 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
         });
     }
 
+    private boolean isVpcOfferingSupportsDistributedRouter(Map serviceCapabilitystList) {
+        boolean supportsDistributedRouter = false;
+        if (serviceCapabilitystList != null && !serviceCapabilitystList.isEmpty()) {
+            Collection serviceCapabilityCollection = serviceCapabilitystList.values();
+            Iterator iter = serviceCapabilityCollection.iterator();
+            Map<Network.Capability, String> capabilityMap = null;
+
+            while (iter.hasNext()) {
+                HashMap<String, String> svcCapabilityMap = (HashMap<String, String>)iter.next();
+                Network.Capability capability = null;
+                String svc = svcCapabilityMap.get("service");
+                String capabilityName = svcCapabilityMap.get("capabilitytype");
+                String capabilityValue = svcCapabilityMap.get("capabilityvalue");
+                if (capabilityName != null) {
+                    capability = Network.Capability.getCapability(capabilityName);
+                }
+
+                if ((capability == null) || (capabilityName == null) || (capabilityValue == null)) {
+                    throw new InvalidParameterValueException("Invalid capability:" + capabilityName + " capability value:" + capabilityValue);
+                }
+
+                if (!svc.equalsIgnoreCase(Service.Connectivity.getName())) {
+                    throw new InvalidParameterValueException("Invalid Service:" + svc + " specified. Only for 'Connectivity' service capabilities can be specified");
+                }
+
+                if (!capabilityName.equalsIgnoreCase("DistributedRouter")) {
+                    throw new InvalidParameterValueException("Invalid Capability:" + capabilityName + " specified. Only 'DistributedRouter' capability can be specified.");
+                }
+
+                if (!capabilityValue.equalsIgnoreCase("true") && capabilityValue.equalsIgnoreCase("false")) {
+                    throw new InvalidParameterValueException("Invalid Capability value:" + capabilityValue + " specified.");
+                }
+                supportsDistributedRouter = capabilityValue.equalsIgnoreCase("true");
+            }
+        }
+        return supportsDistributedRouter;
+    }
+
     @Override
     public Vpc getActiveVpc(long vpcId) {
         return _vpcDao.getActiveVpcById(vpcId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7ce42371/setup/db/db/schema-430to440.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql
index ee4cf21..ff9c47f 100644
--- a/setup/db/db/schema-430to440.sql
+++ b/setup/db/db/schema-430to440.sql
@@ -611,3 +611,4 @@ CREATE TABLE `cloud`.`vgpu_types` (
   CONSTRAINT `fk_vgpu_types__gpu_group_id` FOREIGN KEY (`gpu_group_id`) REFERENCES `host_gpu_groups` (`id`) ON DELETE CASCADE
 ) ENGINE=InnoDB CHARSET=utf8;
 
+ALTER TABLE `cloud`.`vpc_offerings` ADD COLUMN supports_distributed_router boolean default false;


[33/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
CLOUDSTACK-6220: Fix cloudstack init scripts so that they
don't use fully qualified path as script name. Fix for
commit 9dd57c22b02afcddb1d6c8ddc3e1b578961454e3


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/d033ca48
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/d033ca48
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/d033ca48

Branch: refs/heads/distributedrouter
Commit: d033ca486bf9bc22a2afe314d00150ec6019c809
Parents: bf9375b
Author: Marcus Sorensen <ma...@betterservers.com>
Authored: Mon Mar 10 15:34:55 2014 -0600
Committer: Marcus Sorensen <ma...@betterservers.com>
Committed: Mon Mar 10 15:34:55 2014 -0600

----------------------------------------------------------------------
 agent/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-agent.in          | 2 +-
 agent/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-agent.in          | 2 +-
 agent/distro/opensuse/sles/SYSCONFDIR/init.d/cloud-agent.in        | 2 +-
 agent/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-agent.in            | 2 +-
 agent/distro/sles/SYSCONFDIR/init.d/cloud-agent.in                 | 2 +-
 packaging/centos63/cloud-agent.rc                                  | 2 +-
 packaging/centos63/cloud-ipallocator.rc                            | 2 +-
 python/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in   | 2 +-
 python/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in   | 2 +-
 python/distro/opensuse/SYSCONFDIR/init.d/cloud-ipallocator.in      | 2 +-
 python/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in     | 2 +-
 python/distro/sles/SYSCONFDIR/init.d/cloud-ipallocator.in          | 2 +-
 python/distro/ubuntu/SYSCONFDIR/init.d/cloud-ipallocator.in        | 2 +-
 .../distro/centos/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in    | 2 +-
 .../distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in    | 2 +-
 systemvm/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in | 2 +-
 systemvm/distro/ubuntu/SYSCONFDIR/init.d/cloud-console-proxy.in    | 2 +-
 17 files changed, 17 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d033ca48/agent/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-agent.in
----------------------------------------------------------------------
diff --git a/agent/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-agent.in b/agent/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-agent.in
index 60e1e04..704ef6b 100755
--- a/agent/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-agent.in
+++ b/agent/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-agent.in
@@ -26,7 +26,7 @@
 
 # set environment variables
 
-SHORTNAME="$0"
+SHORTNAME="basename $0"
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d033ca48/agent/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-agent.in
----------------------------------------------------------------------
diff --git a/agent/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-agent.in b/agent/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-agent.in
index 60e1e04..704ef6b 100755
--- a/agent/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-agent.in
+++ b/agent/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-agent.in
@@ -26,7 +26,7 @@
 
 # set environment variables
 
-SHORTNAME="$0"
+SHORTNAME="basename $0"
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d033ca48/agent/distro/opensuse/sles/SYSCONFDIR/init.d/cloud-agent.in
----------------------------------------------------------------------
diff --git a/agent/distro/opensuse/sles/SYSCONFDIR/init.d/cloud-agent.in b/agent/distro/opensuse/sles/SYSCONFDIR/init.d/cloud-agent.in
index 2422268..e684888 100644
--- a/agent/distro/opensuse/sles/SYSCONFDIR/init.d/cloud-agent.in
+++ b/agent/distro/opensuse/sles/SYSCONFDIR/init.d/cloud-agent.in
@@ -33,7 +33,7 @@
 
 # set environment variables
 
-SHORTNAME="$0"
+SHORTNAME="basename $0"
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d033ca48/agent/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-agent.in
----------------------------------------------------------------------
diff --git a/agent/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-agent.in b/agent/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-agent.in
index 60e1e04..704ef6b 100644
--- a/agent/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-agent.in
+++ b/agent/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-agent.in
@@ -26,7 +26,7 @@
 
 # set environment variables
 
-SHORTNAME="$0"
+SHORTNAME="basename $0"
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d033ca48/agent/distro/sles/SYSCONFDIR/init.d/cloud-agent.in
----------------------------------------------------------------------
diff --git a/agent/distro/sles/SYSCONFDIR/init.d/cloud-agent.in b/agent/distro/sles/SYSCONFDIR/init.d/cloud-agent.in
index 2422268..e684888 100644
--- a/agent/distro/sles/SYSCONFDIR/init.d/cloud-agent.in
+++ b/agent/distro/sles/SYSCONFDIR/init.d/cloud-agent.in
@@ -33,7 +33,7 @@
 
 # set environment variables
 
-SHORTNAME="$0"
+SHORTNAME="basename $0"
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d033ca48/packaging/centos63/cloud-agent.rc
----------------------------------------------------------------------
diff --git a/packaging/centos63/cloud-agent.rc b/packaging/centos63/cloud-agent.rc
index 40c358e..af1c624 100755
--- a/packaging/centos63/cloud-agent.rc
+++ b/packaging/centos63/cloud-agent.rc
@@ -26,7 +26,7 @@
 
 # set environment variables
 
-SHORTNAME="$0"
+SHORTNAME="basename $0"
 PIDFILE=/var/run/"$SHORTNAME".pid
 LOCKFILE=/var/lock/subsys/"$SHORTNAME"
 LOGDIR=/var/log/cloudstack/agent

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d033ca48/packaging/centos63/cloud-ipallocator.rc
----------------------------------------------------------------------
diff --git a/packaging/centos63/cloud-ipallocator.rc b/packaging/centos63/cloud-ipallocator.rc
index 9a24d8d..9d1adb4 100755
--- a/packaging/centos63/cloud-ipallocator.rc
+++ b/packaging/centos63/cloud-ipallocator.rc
@@ -25,7 +25,7 @@
 
 # set environment variables
 
-SHORTNAME="$0"
+SHORTNAME="basename $0"
 PIDFILE=/var/run/"$SHORTNAME".pid
 LOCKFILE=/var/lock/subsys/"$SHORTNAME"
 LOGFILE=/var/log/cloudstack/ipallocator/ipallocator.log

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d033ca48/python/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
----------------------------------------------------------------------
diff --git a/python/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in b/python/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
index b6720f5..ae8d215 100755
--- a/python/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
+++ b/python/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
@@ -25,7 +25,7 @@
 
 # set environment variables
 
-SHORTNAME="$0"
+SHORTNAME="basename $0"
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@IPALOCATORLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d033ca48/python/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
----------------------------------------------------------------------
diff --git a/python/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in b/python/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
index aa7e8cf..49fd9b6 100755
--- a/python/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
+++ b/python/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
@@ -25,7 +25,7 @@
 
 # set environment variables
 
-SHORTNAME="$0"
+SHORTNAME="basename $0"
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d033ca48/python/distro/opensuse/SYSCONFDIR/init.d/cloud-ipallocator.in
----------------------------------------------------------------------
diff --git a/python/distro/opensuse/SYSCONFDIR/init.d/cloud-ipallocator.in b/python/distro/opensuse/SYSCONFDIR/init.d/cloud-ipallocator.in
index 7aa456d..901d5845 100755
--- a/python/distro/opensuse/SYSCONFDIR/init.d/cloud-ipallocator.in
+++ b/python/distro/opensuse/SYSCONFDIR/init.d/cloud-ipallocator.in
@@ -32,7 +32,7 @@
 
 # set environment variables
 
-SHORTNAME="$0"
+SHORTNAME="basename $0"
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d033ca48/python/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
----------------------------------------------------------------------
diff --git a/python/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in b/python/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
index aa7e8cf..49fd9b6 100644
--- a/python/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
+++ b/python/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
@@ -25,7 +25,7 @@
 
 # set environment variables
 
-SHORTNAME="$0"
+SHORTNAME="basename $0"
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d033ca48/python/distro/sles/SYSCONFDIR/init.d/cloud-ipallocator.in
----------------------------------------------------------------------
diff --git a/python/distro/sles/SYSCONFDIR/init.d/cloud-ipallocator.in b/python/distro/sles/SYSCONFDIR/init.d/cloud-ipallocator.in
index 7aa456d..901d5845 100755
--- a/python/distro/sles/SYSCONFDIR/init.d/cloud-ipallocator.in
+++ b/python/distro/sles/SYSCONFDIR/init.d/cloud-ipallocator.in
@@ -32,7 +32,7 @@
 
 # set environment variables
 
-SHORTNAME="$0"
+SHORTNAME="basename $0"
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d033ca48/python/distro/ubuntu/SYSCONFDIR/init.d/cloud-ipallocator.in
----------------------------------------------------------------------
diff --git a/python/distro/ubuntu/SYSCONFDIR/init.d/cloud-ipallocator.in b/python/distro/ubuntu/SYSCONFDIR/init.d/cloud-ipallocator.in
index ec84962..5ec6da0 100755
--- a/python/distro/ubuntu/SYSCONFDIR/init.d/cloud-ipallocator.in
+++ b/python/distro/ubuntu/SYSCONFDIR/init.d/cloud-ipallocator.in
@@ -26,7 +26,7 @@
 
 # set environment variables
 
-SHORTNAME="$0"
+SHORTNAME="basename $0"
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d033ca48/systemvm/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
----------------------------------------------------------------------
diff --git a/systemvm/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in b/systemvm/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
index 76ee681..e43f641 100644
--- a/systemvm/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
+++ b/systemvm/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
@@ -26,7 +26,7 @@
 
 # set environment variables
 
-SHORTNAME="$0"
+SHORTNAME="basename $0"
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@CPLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d033ca48/systemvm/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
----------------------------------------------------------------------
diff --git a/systemvm/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in b/systemvm/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
index 76ee681..e43f641 100644
--- a/systemvm/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
+++ b/systemvm/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
@@ -26,7 +26,7 @@
 
 # set environment variables
 
-SHORTNAME="$0"
+SHORTNAME="basename $0"
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@CPLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d033ca48/systemvm/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
----------------------------------------------------------------------
diff --git a/systemvm/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in b/systemvm/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
index 76ee681..e43f641 100644
--- a/systemvm/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
+++ b/systemvm/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
@@ -26,7 +26,7 @@
 
 # set environment variables
 
-SHORTNAME="$0"
+SHORTNAME="basename $0"
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@CPLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d033ca48/systemvm/distro/ubuntu/SYSCONFDIR/init.d/cloud-console-proxy.in
----------------------------------------------------------------------
diff --git a/systemvm/distro/ubuntu/SYSCONFDIR/init.d/cloud-console-proxy.in b/systemvm/distro/ubuntu/SYSCONFDIR/init.d/cloud-console-proxy.in
index c83f00a..87a653e 100755
--- a/systemvm/distro/ubuntu/SYSCONFDIR/init.d/cloud-console-proxy.in
+++ b/systemvm/distro/ubuntu/SYSCONFDIR/init.d/cloud-console-proxy.in
@@ -27,7 +27,7 @@
 
 # set environment variables
 
-SHORTNAME="$0"
+SHORTNAME="basename $0"
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@CPLOG@


[25/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
unneeded imports removed

Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/0aca7cfa
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/0aca7cfa
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/0aca7cfa

Branch: refs/heads/distributedrouter
Commit: 0aca7cfab6f9fe70b9ace590da91e9b7661438f7
Parents: 2386ad7
Author: Daan Hoogland <da...@onecht.net>
Authored: Mon Mar 10 10:56:37 2014 +0100
Committer: Daan Hoogland <da...@onecht.net>
Committed: Mon Mar 10 10:56:37 2014 +0100

----------------------------------------------------------------------
 server/test/com/cloud/network/vpc/VpcManagerImplTest.java | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0aca7cfa/server/test/com/cloud/network/vpc/VpcManagerImplTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/network/vpc/VpcManagerImplTest.java b/server/test/com/cloud/network/vpc/VpcManagerImplTest.java
index 189b793..3918a37 100644
--- a/server/test/com/cloud/network/vpc/VpcManagerImplTest.java
+++ b/server/test/com/cloud/network/vpc/VpcManagerImplTest.java
@@ -20,27 +20,22 @@ package com.cloud.network.vpc;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.when;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.cloudstack.context.CallContext;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
-import static org.mockito.Mockito.when;
-
 import com.cloud.network.Network.Provider;
 import com.cloud.network.Network.Service;
 import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
-import com.cloud.user.Account;
-import com.cloud.user.User;
 
 public class VpcManagerImplTest {
 


[32/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
CLOUDSTACK-6214: apply network rules when plug new guest nic to router for the network in Setup state
Conflicts:
	server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java
	server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java

Conflicts:
	api/src/com/cloud/network/VpcVirtualNetworkApplianceService.java
	server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java
	server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
	server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/bf9375b8
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/bf9375b8
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/bf9375b8

Branch: refs/heads/distributedrouter
Commit: bf9375b8b9c437bf314d0459233f17860d85d3f3
Parents: 1d74daf
Author: Alena Prokharchyk <al...@citrix.com>
Authored: Fri Mar 7 15:06:35 2014 -0800
Committer: Alena Prokharchyk <al...@citrix.com>
Committed: Mon Mar 10 11:42:24 2014 -0700

----------------------------------------------------------------------
 .../VpcVirtualNetworkApplianceService.java      |  8 +++--
 .../element/VpcVirtualRouterElement.java        | 14 ++++++--
 .../VpcVirtualNetworkApplianceManagerImpl.java  | 34 +++++++++++++++++---
 .../MockVpcVirtualNetworkApplianceManager.java  |  7 ++--
 4 files changed, 51 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bf9375b8/api/src/com/cloud/network/VpcVirtualNetworkApplianceService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/VpcVirtualNetworkApplianceService.java b/api/src/com/cloud/network/VpcVirtualNetworkApplianceService.java
index eee62ce..382c460 100644
--- a/api/src/com/cloud/network/VpcVirtualNetworkApplianceService.java
+++ b/api/src/com/cloud/network/VpcVirtualNetworkApplianceService.java
@@ -16,10 +16,13 @@
 // under the License.
 package com.cloud.network;
 
+import java.util.Map;
+
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.network.router.VirtualRouter;
+import com.cloud.vm.VirtualMachineProfile;
 
 public interface VpcVirtualNetworkApplianceService extends VirtualNetworkApplianceService {
 
@@ -27,13 +30,14 @@ public interface VpcVirtualNetworkApplianceService extends VirtualNetworkApplian
      * @param router
      * @param network
      * @param isRedundant
+     * @param params TODO
      * @return
      * @throws ConcurrentOperationException
      * @throws ResourceUnavailableException
      * @throws InsufficientCapacityException
      */
-    boolean addVpcRouterToGuestNetwork(VirtualRouter router, Network network, boolean isRedundant) throws ConcurrentOperationException, ResourceUnavailableException,
-        InsufficientCapacityException;
+    boolean addVpcRouterToGuestNetwork(VirtualRouter router, Network network, boolean isRedundant, Map<VirtualMachineProfile.Param, Object> params)
+            throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
 
     /**
      * @param router

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bf9375b8/server/src/com/cloud/network/element/VpcVirtualRouterElement.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java
index 5695a2c..b433fe4 100644
--- a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java
+++ b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java
@@ -36,6 +36,7 @@ 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.Network.State;
 import com.cloud.network.NetworkModel;
 import com.cloud.network.PublicIpAddress;
 import com.cloud.network.RemoteAccessVpn;
@@ -179,7 +180,11 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc
         DomainRouterVO router = routers.get(0);
         //Add router to guest network if needed
         if (!_networkMgr.isVmPartOfNetwork(router.getId(), network.getId())) {
-            if (!_vpcRouterMgr.addVpcRouterToGuestNetwork(router, network, false)) {
+            Map<VirtualMachineProfile.Param, Object> paramsForRouter = new HashMap<VirtualMachineProfile.Param, Object>(1);
+            if (network.getState() == State.Setup) {
+                paramsForRouter.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true);
+            }
+            if (!_vpcRouterMgr.addVpcRouterToGuestNetwork(router, network, false, paramsForRouter)) {
                 throw new CloudRuntimeException("Failed to add VPC router " + router + " to guest network " + network);
             } else {
                 s_logger.debug("Successfully added VPC router " + router + " to guest network " + network);
@@ -220,7 +225,12 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc
             DomainRouterVO router = routers.get(0);
             //Add router to guest network if needed
             if (!_networkMgr.isVmPartOfNetwork(router.getId(), network.getId())) {
-                if (!_vpcRouterMgr.addVpcRouterToGuestNetwork(router, network, false)) {
+                Map<VirtualMachineProfile.Param, Object> paramsForRouter = new HashMap<VirtualMachineProfile.Param, Object>(1);
+                // need to reprogram guest network if it comes in a setup state
+                if (network.getState() == State.Setup) {
+                    paramsForRouter.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true);
+                }
+                if (!_vpcRouterMgr.addVpcRouterToGuestNetwork(router, network, false, paramsForRouter)) {
                     throw new CloudRuntimeException("Failed to add VPC router " + router + " to guest network " + network);
                 } else {
                     s_logger.debug("Successfully added VPC router " + router + " to guest network " + network);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bf9375b8/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
index bed30df..f7fdd08 100644
--- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
@@ -36,6 +36,7 @@ import org.springframework.stereotype.Component;
 
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
+import com.cloud.agent.api.Command.OnError;
 import com.cloud.agent.api.NetworkUsageCommand;
 import com.cloud.agent.api.PlugNicCommand;
 import com.cloud.agent.api.SetupGuestNetworkCommand;
@@ -246,9 +247,8 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
     }
 
     @Override
-    public boolean addVpcRouterToGuestNetwork(VirtualRouter router, Network network, boolean isRedundant) throws ConcurrentOperationException,
-        ResourceUnavailableException, InsufficientCapacityException {
-
+    public boolean addVpcRouterToGuestNetwork(VirtualRouter router, Network network, boolean isRedundant, Map<VirtualMachineProfile.Param, Object> params)
+            throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
         if (network.getTrafficType() != TrafficType.Guest) {
             s_logger.warn("Network " + network + " is not of type " + TrafficType.Guest);
             return false;
@@ -257,16 +257,23 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
         //Add router to the Guest network
         boolean result = true;
         try {
+
+            // 1) add nic to the router
             _routerDao.addRouterToGuestNetwork(router, network);
 
             NicProfile guestNic = _itMgr.addVmToNetwork(router, network, null);
-            //setup guest network
+            //2) setup guest network
             if (guestNic != null) {
                 result = setupVpcGuestNetwork(network, router, true, guestNic);
             } else {
                 s_logger.warn("Failed to add router " + router + " to guest network " + network);
                 result = false;
             }
+            //3) apply networking rules
+            if (result && params.get(Param.ReProgramGuestNetworks) != null
+                    && (Boolean) params.get(Param.ReProgramGuestNetworks) == true) {
+                sendNetworkRulesToRouter(router.getId(), network.getId());
+            }
         } catch (Exception ex) {
             s_logger.warn("Failed to add router " + router + " to network " + network + " due to ", ex);
             result = false;
@@ -885,6 +892,25 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
         }
     }
 
+
+    protected boolean sendNetworkRulesToRouter(long routerId, long networkId)
+            throws ResourceUnavailableException {
+        DomainRouterVO router = _routerDao.findById(routerId);
+        Commands cmds = new Commands(OnError.Continue);
+
+        VirtualRouterProvider vrProvider = _vrProviderDao.findById(router.getElementId());
+        if (vrProvider == null) {
+            throw new CloudRuntimeException("Cannot find related virtual router provider of router: " + router.getHostName());
+        }
+        Provider provider = Network.Provider.getProvider(vrProvider.getType().toString());
+        if (provider == null) {
+            throw new CloudRuntimeException("Cannot find related provider of virtual router provider: " + vrProvider.getType().toString());
+        }
+
+        finalizeNetworkRulesForNetwork(cmds, router, provider, networkId);
+        return sendCommandsToRouter(router, cmds);
+    }
+
     @Override
     public boolean setupPrivateGateway(PrivateGateway gateway, VirtualRouter router) throws ConcurrentOperationException, ResourceUnavailableException {
         boolean result = true;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bf9375b8/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java b/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
index 4802cff..e0c599d 100644
--- a/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
+++ b/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
@@ -23,10 +23,9 @@ import java.util.Map;
 import javax.ejb.Local;
 import javax.naming.ConfigurationException;
 
-import org.springframework.stereotype.Component;
-
 import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
 import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd;
+import org.springframework.stereotype.Component;
 
 import com.cloud.deploy.DeployDestination;
 import com.cloud.exception.ConcurrentOperationException;
@@ -313,8 +312,8 @@ public class MockVpcVirtualNetworkApplianceManager extends ManagerBase implement
      * @see com.cloud.network.VpcVirtualNetworkApplianceService#addVpcRouterToGuestNetwork(com.cloud.network.router.VirtualRouter, com.cloud.network.Network, boolean)
      */
     @Override
-    public boolean addVpcRouterToGuestNetwork(VirtualRouter router, Network network, boolean isRedundant) throws ConcurrentOperationException,
-        ResourceUnavailableException, InsufficientCapacityException {
+    public boolean addVpcRouterToGuestNetwork(VirtualRouter router, Network network, boolean isRedundant, Map<VirtualMachineProfile.Param, Object> params)
+            throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
         // TODO Auto-generated method stub
         return false;
     }


[11/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
rats

Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c257fb0e
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c257fb0e
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c257fb0e

Branch: refs/heads/distributedrouter
Commit: c257fb0e3efbb6eb3ae1e102397ebdcb989b5b51
Parents: c211f0b
Author: Daan Hoogland <da...@onecht.net>
Authored: Fri Mar 7 19:27:58 2014 +0100
Committer: Daan Hoogland <da...@onecht.net>
Committed: Fri Mar 7 19:27:58 2014 +0100

----------------------------------------------------------------------
 .../src/com/cloud/api/dispatch/DispatchTask.java   | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c257fb0e/server/src/com/cloud/api/dispatch/DispatchTask.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/dispatch/DispatchTask.java b/server/src/com/cloud/api/dispatch/DispatchTask.java
index 2a8a4bd..f6cb183 100644
--- a/server/src/com/cloud/api/dispatch/DispatchTask.java
+++ b/server/src/com/cloud/api/dispatch/DispatchTask.java
@@ -1,3 +1,20 @@
+// 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.api.dispatch;
 
 import java.util.Map;


[16/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
Adding license header

Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/548c8108
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/548c8108
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/548c8108

Branch: refs/heads/distributedrouter
Commit: 548c81082b377e87cc6ba18ac21fe297af8996c5
Parents: c427e8d
Author: Mike Tutkowski <mi...@solidfire.com>
Authored: Fri Mar 7 16:43:03 2014 -0700
Committer: Mike Tutkowski <mi...@solidfire.com>
Committed: Fri Mar 7 16:43:03 2014 -0700

----------------------------------------------------------------------
 api/src/com/cloud/offering/DiskOfferingInfo.java | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/548c8108/api/src/com/cloud/offering/DiskOfferingInfo.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/offering/DiskOfferingInfo.java b/api/src/com/cloud/offering/DiskOfferingInfo.java
index e9e7da1..75a520e 100644
--- a/api/src/com/cloud/offering/DiskOfferingInfo.java
+++ b/api/src/com/cloud/offering/DiskOfferingInfo.java
@@ -1,3 +1,21 @@
+/*
+ * 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.offering;
 
 public class DiskOfferingInfo {


[20/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
CLOUDSTACK-5626: Simplifying VM Migrate code

Signed-off-by: SrikanteswaraRao Talluri <ta...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/3b3ae024
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/3b3ae024
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/3b3ae024

Branch: refs/heads/distributedrouter
Commit: 3b3ae024591fae4db9a6ca991d4838d98b96154e
Parents: 09c3753
Author: Gaurav Aradhye <ga...@clogeny.com>
Authored: Thu Mar 6 21:38:41 2014 -0500
Committer: SrikanteswaraRao Talluri <ta...@apache.org>
Committed: Mon Mar 10 11:18:26 2014 +0530

----------------------------------------------------------------------
 .../component/test_cpu_domain_limits.py         |  11 +-
 test/integration/component/test_cpu_limits.py   |  15 ++-
 .../component/test_cpu_project_limits.py        |   7 +-
 .../integration/component/test_memory_limits.py |  15 ++-
 .../component/test_mm_domain_limits.py          |   7 +-
 .../component/test_mm_project_limits.py         |   7 +-
 .../component/test_vpc_vm_life_cycle.py         | 108 ++++---------------
 tools/marvin/marvin/codes.py                    |   1 +
 tools/marvin/marvin/integration/lib/common.py   |  25 +++--
 9 files changed, 80 insertions(+), 116 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3b3ae024/test/integration/component/test_cpu_domain_limits.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_cpu_domain_limits.py b/test/integration/component/test_cpu_domain_limits.py
index c427e4f..1247a79 100644
--- a/test/integration/component/test_cpu_domain_limits.py
+++ b/test/integration/component/test_cpu_domain_limits.py
@@ -30,10 +30,11 @@ from marvin.integration.lib.base import (
 from marvin.integration.lib.common import (get_domain,
                                         get_zone,
                                         get_template,
-                                        find_suitable_host,
+                                        findSuitableHostForMigration,
                                         get_resource_type
                                         )
 from marvin.integration.lib.utils import cleanup_resources
+from marvin.codes import ERROR_NO_HOST_FOR_MIGRATION
 
 class Services:
     """Test resource limit services
@@ -329,7 +330,9 @@ class TestDomainCPULimitsUpdateResources(cloudstackTestCase):
             self.assertEqual(resource_count, expected_resource_count,
                 "Initial resource count should match with the expected resource count")
 
-            host = find_suitable_host(self.apiclient, vm)
+            host = findSuitableHostForMigration(self.apiclient, vm.id)
+            if host is None:
+                self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
             self.debug("Migrating instance: %s to host: %s" %
                        (vm.name, host.name))
             try:
@@ -477,7 +480,9 @@ class TestDomainCPULimitsUpdateResources(cloudstackTestCase):
             self.assertEqual(resource_count_after_delete, expected_resource_count,
                 "Resource count should match with the expected count")
 
-            host = find_suitable_host(self.apiclient, vm_2)
+            host = findSuitableHostForMigration(self.apiclient, vm_2.id)
+            if host is None:
+                self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
             self.debug("Migrating instance: %s to host: %s" % (vm_2.name,
                                                                host.name))
             try:

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3b3ae024/test/integration/component/test_cpu_limits.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_cpu_limits.py b/test/integration/component/test_cpu_limits.py
index bdf2869..f043773 100644
--- a/test/integration/component/test_cpu_limits.py
+++ b/test/integration/component/test_cpu_limits.py
@@ -30,10 +30,11 @@ from marvin.integration.lib.base import (
 from marvin.integration.lib.common import (get_domain,
                                         get_zone,
                                         get_template,
-                                        find_suitable_host,
+                                        findSuitableHostForMigration,
                                         get_resource_type
                                         )
 from marvin.integration.lib.utils import cleanup_resources
+from marvin.codes import ERROR_NO_HOST_FOR_MIGRATION
 
 
 class Services:
@@ -251,7 +252,9 @@ class TestCPULimits(cloudstackTestCase):
         self.assertEqual(resource_count, expected_resource_count,
                          "Resource count should match with the expected resource count")
 
-        host = find_suitable_host(self.apiclient, self.vm)
+        host = findSuitableHostForMigration(self.apiclient, self.vm.id)
+        if host is None:
+            self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
         self.debug("Migrating instance: %s to host: %s" % (self.vm.name, host.name))
         try:
             self.vm.migrate(self.apiclient, host.id)
@@ -570,7 +573,9 @@ class TestDomainCPULimitsConfiguration(cloudstackTestCase):
         self.assertEqual(resource_count, expected_resource_count,
             "Initial resource count should with the expected resource count")
 
-        host = find_suitable_host(self.apiclient, vm)
+        host = findSuitableHostForMigration(self.apiclient, vm.id)
+        if host is None:
+            self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
         self.debug("Migrating instance: %s to host: %s" %
                    (vm.name, host.name))
         try:
@@ -725,7 +730,9 @@ class TestDomainCPULimitsConfiguration(cloudstackTestCase):
             self.assertEqual(resource_count_after_delete, expected_resource_count,
                 "Resource count should be less than before after deleting the instance")
 
-            host = find_suitable_host(self.apiclient, vm_2)
+            host = findSuitableHostForMigration(self.apiclient, vm_2.id)
+            if host is None:
+                self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
             self.debug("Migrating instance: %s to host: %s" % (vm_2.name,
                                                                host.name))
             try:

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3b3ae024/test/integration/component/test_cpu_project_limits.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_cpu_project_limits.py b/test/integration/component/test_cpu_project_limits.py
index a8a1b3c..ed7cd88 100644
--- a/test/integration/component/test_cpu_project_limits.py
+++ b/test/integration/component/test_cpu_project_limits.py
@@ -30,10 +30,11 @@ from marvin.integration.lib.base import (
 from marvin.integration.lib.common import (get_domain,
                                         get_zone,
                                         get_template,
-                                        find_suitable_host,
+                                        findSuitableHostForMigration,
                                         get_resource_type
                                         )
 from marvin.integration.lib.utils import cleanup_resources
+from marvin.codes import ERROR_NO_HOST_FOR_MIGRATION
 
 class Services:
     """Test resource limit services
@@ -291,7 +292,9 @@ class TestProjectsCPULimits(cloudstackTestCase):
         self.assertEqual(resource_count, expected_resource_count,
                          "Resource count should match with the expected resource count")
 
-        host = find_suitable_host(self.apiclient, self.vm)
+        host = findSuitableHostForMigration(self.apiclient, self.vm.id)
+        if host is None:
+            self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
         self.debug("Migrating instance: %s to host: %s" %
                                                     (self.vm.name, host.name))
         try:

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3b3ae024/test/integration/component/test_memory_limits.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_memory_limits.py b/test/integration/component/test_memory_limits.py
index 7921e4b..231307f 100644
--- a/test/integration/component/test_memory_limits.py
+++ b/test/integration/component/test_memory_limits.py
@@ -30,10 +30,11 @@ from marvin.integration.lib.common import (get_domain,
                                         get_zone,
                                         get_template,
                                         wait_for_cleanup,
-                                        find_suitable_host,
+                                        findSuitableHostForMigration,
                                         get_resource_type
                                         )
 from marvin.integration.lib.utils import cleanup_resources
+from marvin.codes import ERROR_NO_HOST_FOR_MIGRATION
 
 class Services:
     """Test memory resource limit services
@@ -248,7 +249,9 @@ class TestMemoryLimits(cloudstackTestCase):
         self.assertEqual(resource_count, expected_resource_count,
                          "Resource count should match with the expected resource count")
 
-        host = find_suitable_host(self.apiclient, self.vm)
+        host = findSuitableHostForMigration(self.apiclient, self.vm.id)
+        if host is None:
+            self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
         self.debug("Migrating instance: %s to host: %s" % (self.vm.name, host.name))
         try:
             self.vm.migrate(self.apiclient, host.id)
@@ -587,7 +590,9 @@ class TestDomainMemoryLimitsConfiguration(cloudstackTestCase):
             self.assertEqual(resource_count, expected_resource_count,
                          "Initial resource count should with the expected resource count")
 
-            host = find_suitable_host(self.apiclient, vm)
+            host = findSuitableHostForMigration(self.apiclient, vm.id)
+            if host is None:
+                self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
             self.debug("Migrating instance: %s to host: %s" %
                                                         (vm.name, host.name))
             try:
@@ -743,7 +748,9 @@ class TestDomainMemoryLimitsConfiguration(cloudstackTestCase):
             self.assertEqual(resource_count_after_delete, expected_resource_count,
                          "Resource count should match with the expected resource count")
 
-            host = find_suitable_host(self.apiclient, vm_2)
+            host = findSuitableHostForMigration(self.apiclient, vm_2.id)
+            if host is None:
+                self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
             self.debug("Migrating instance: %s to host: %s" % (vm_2.name,
                                                                host.name))
             try:

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3b3ae024/test/integration/component/test_mm_domain_limits.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_mm_domain_limits.py b/test/integration/component/test_mm_domain_limits.py
index 68660c1..a2b7395 100644
--- a/test/integration/component/test_mm_domain_limits.py
+++ b/test/integration/component/test_mm_domain_limits.py
@@ -30,11 +30,12 @@ from marvin.integration.lib.common import (get_domain,
                                         get_zone,
                                         get_template,
 					                    wait_for_cleanup,
-                                        find_suitable_host,
+                                        findSuitableHostForMigration,
                                         get_resource_type,
                                         update_resource_count
                                         )
 from marvin.integration.lib.utils import cleanup_resources
+from marvin.codes import ERROR_NO_HOST_FOR_MIGRATION
 
 class Services:
     """Test memory resource limit services
@@ -388,7 +389,9 @@ class TestDomainMemoryLimits(cloudstackTestCase):
             self.assertEqual(resource_count, expected_resource_count,
                          "Resource count should match with the expected resource count")
 
-            host = find_suitable_host(self.apiclient, vm)
+            host = findSuitableHostForMigration(self.apiclient, vm.id)
+            if host is None:
+                self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
             self.debug("Migrating instance: %s to host: %s" %
                                                         (vm.name, host.name))
             try:

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3b3ae024/test/integration/component/test_mm_project_limits.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_mm_project_limits.py b/test/integration/component/test_mm_project_limits.py
index c314011..29a3b54 100644
--- a/test/integration/component/test_mm_project_limits.py
+++ b/test/integration/component/test_mm_project_limits.py
@@ -30,10 +30,11 @@ from marvin.integration.lib.common import (get_domain,
                                         get_zone,
                                         get_template,
 					                    wait_for_cleanup,
-                                        find_suitable_host,
+                                        findSuitableHostForMigration,
                                         get_resource_type
                                         )
 from marvin.integration.lib.utils import cleanup_resources
+from marvin.codes import ERROR_NO_HOST_FOR_MIGRATION
 
 class Services:
     """Test memory resource limit services
@@ -291,7 +292,9 @@ class TestProjectsMemoryLimits(cloudstackTestCase):
         resource_count = project_list[0].memorytotal
         self.debug(resource_count)
 
-        host = find_suitable_host(self.apiclient, self.vm)
+        host = findSuitableHostForMigration(self.apiclient, self.vm.id)
+        if host is None:
+            self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
         self.debug("Migrating instance: %s to host: %s" %
                                                     (self.vm.name, host.name))
         try:

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3b3ae024/test/integration/component/test_vpc_vm_life_cycle.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_vpc_vm_life_cycle.py b/test/integration/component/test_vpc_vm_life_cycle.py
index 01373ac..e40067e 100644
--- a/test/integration/component/test_vpc_vm_life_cycle.py
+++ b/test/integration/component/test_vpc_vm_life_cycle.py
@@ -41,9 +41,10 @@ from marvin.integration.lib.common import (get_domain,
                                            get_free_vlan,
                                            wait_for_cleanup,
                                            list_virtual_machines,
-                                           list_hosts)
+                                           list_hosts,
+                                           findSuitableHostForMigration)
 
-from marvin.codes import PASS
+from marvin.codes import PASS, ERROR_NO_HOST_FOR_MIGRATION
 
 import time
 
@@ -715,35 +716,13 @@ class TestVMLifeCycleVPC(cloudstackTestCase):
         #    works as expected.
         # 3. Make sure that we are able to access google.com from this user Vm
 
-        vm_list = VirtualMachine.list(self.apiclient, id=self.vm_1.id)
-        self.assertEqual(validateList(vm_list)[0], PASS, "vm list validation failed, vm list is %s" % vm_list)
-
-        vm_hostid = vm_list[0].hostid
-
-        self.debug("Checking if the host is available for migration?")
-        hosts = Host.list(
-                          self.apiclient,
-                          zoneid=self.zone.id,
-                          type='Routing'
-                          )
-
-        self.assertEqual(
-                         isinstance(hosts, list),
-                         True,
-                         "List hosts should return a valid list"
-                         )
-        if len(hosts) < 2:
-            raise unittest.SkipTest(
-            "No host available for migration. Test requires atleast 2 hosts")
-
-        # Remove the host of current VM from the hosts list
-        hosts[:] = [host for host in hosts if host.id != vm_hostid]
-
-        host = hosts[0]
-
         self.debug("Validating if the network rules work properly or not?")
         self.validate_network_rules()
 
+        host = findSuitableHostForMigration(self.apiclient, self.vm_1.id)
+        if host is None:
+            self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
+
         self.debug("Migrating VM-ID: %s to Host: %s" % (
                                                         self.vm_1.id,
                                                         host.id
@@ -1506,30 +1485,13 @@ class TestVMLifeCycleSharedNwVPC(cloudstackTestCase):
         #    works as expected.
         # 3. Make sure that we are able to access google.com from this user Vm
 
-        self.debug("Checking if the host is available for migration?")
-        hosts = Host.list(
-                          self.apiclient,
-                          zoneid=self.zone.id,
-                          type='Routing'
-                          )
-
-        self.assertEqual(
-                         isinstance(hosts, list),
-                         True,
-                         "List hosts should return a valid list"
-                         )
-        if len(hosts) < 2:
-            raise unittest.SkipTest(
-            "No host available for migration. Test requires atleast 2 hosts")
-
-        # Remove the host of current VM from the hosts list
-        hosts[:] = [host for host in hosts if host.id != self.vm_1.hostid]
-
-        host = hosts[0]
-
         self.debug("Validating if network rules are coonfigured properly?")
         self.validate_network_rules()
 
+        host = findSuitableHostForMigration(self.apiclient, self.vm_1.id)
+        if host is None:
+            self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
+
         self.debug("Migrating VM-ID: %s to Host: %s" % (
                                                         self.vm_1.id,
                                                         host.id
@@ -2559,30 +2521,13 @@ class TestVMLifeCycleStoppedVPCVR(cloudstackTestCase):
         #    works as expected.
         # 3. Make sure that we are able to access google.com from this user Vm
 
-        self.debug("Checking if the host is available for migration?")
-        hosts = Host.list(
-                          self.apiclient,
-                          zoneid=self.zone.id,
-                          type='Routing'
-                          )
-
-        self.assertEqual(
-                         isinstance(hosts, list),
-                         True,
-                         "List hosts should return a valid list"
-                         )
-        if len(hosts) < 2:
-            raise unittest.SkipTest(
-            "No host available for migration. Test requires atleast 2 hosts")
-
-        # Remove the host of current VM from the hosts list
-        hosts[:] = [host for host in hosts if host.id != self.vm_1.hostid]
-
-        host = hosts[0]
-
         self.debug("Validating if the network rules work properly or not?")
         self.validate_network_rules()
 
+        host = findSuitableHostForMigration(self.apiclient, self.vm_1.id)
+        if host is None:
+            self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
+
         self.debug("Migrating VM-ID: %s on Host: %s to Host: %s" % (
                                                         self.vm_1.id,
                                                         self.vm_1.hostid,
@@ -3459,28 +3404,13 @@ class TestVMLifeCycleDiffHosts(cloudstackTestCase):
         #    works as expected.
         # 3. Make sure that we are able to access google.com from this user Vm
 
-        self.debug("Checking if the host is available for migration?")
-        hosts = Host.listForMigration(
-                          self.apiclient,
-                          virtualmachineid=self.vm_1.id,
-                          )
-        self.debug("Hosts vm can be migrated to are : %s" %(hosts))
-        self.assertEqual(
-                         isinstance(hosts, list),
-                         True,
-                         "List hosts should return a valid list"
-                         )
-        # Remove the host of current VM from the hosts list
-        hosts[:] = [host for host in hosts if host.id != self.vm_1.hostid]
-        if len(hosts) <= 0:
-            self.skipTest(
-            "No host available for migration. Test requires atleast 2 hosts tagged with host1")
-
-        host = hosts[0]
-
         self.debug("Validating if the network rules work properly or not?")
         self.validate_network_rules()
 
+        host = findSuitableHostForMigration(self.apiclient, self.vm_1.id)
+        if host is None:
+            self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
+
         self.debug("Migrating VM-ID: %s to Host: %s" % (
                                                         self.vm_1.id,
                                                         host.id

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3b3ae024/tools/marvin/marvin/codes.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/codes.py b/tools/marvin/marvin/codes.py
index 3882f0d..e4a0f6a 100644
--- a/tools/marvin/marvin/codes.py
+++ b/tools/marvin/marvin/codes.py
@@ -51,3 +51,4 @@ BASIC_ZONE = "basic"
 ISOLATED_NETWORK = "ISOLATED"
 SHARED_NETWORK = "SHARED"
 VPC_NETWORK = "VPC"
+ERROR_NO_HOST_FOR_MIGRATION = "Could not find suitable host for migration, please ensure setup has required no. of hosts"

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3b3ae024/tools/marvin/marvin/integration/lib/common.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/integration/lib/common.py b/tools/marvin/marvin/integration/lib/common.py
index b2da3ff..d3d634b 100644
--- a/tools/marvin/marvin/integration/lib/common.py
+++ b/tools/marvin/marvin/integration/lib/common.py
@@ -712,18 +712,23 @@ def update_resource_count(apiclient, domainid, accountid=None,
                               )
         return
 
-def find_suitable_host(apiclient, vm):
-        """Returns a suitable host for VM migration"""
+def findSuitableHostForMigration(apiclient, vmid):
+    """Returns a suitable host for VM migration"""
+    suitableHost = None
+    try:
+        hosts = Host.listForMigration(apiclient, virtualmachineid=vmid,
+                )
+    except Exception as e:
+        raise Exception("Exception while getting hosts list suitable for migration: %s" % e)
 
-        hosts = Host.list(apiclient,
-                          virtualmachineid=vm.id,
-                          listall=True)
+    suitablehosts = []
+    if isinstance(hosts, list) and len(hosts) > 0:
+        suitablehosts = [host for host in hosts if (str(host.resourcestate).lower() == "enabled"\
+                and str(host.state).lower() == "up")]
+        if len(suitablehosts)>0:
+            suitableHost = suitablehosts[0]
 
-        if isinstance(hosts, list):
-            assert len(hosts) > 0, "List host should return valid response"
-        else:
-            raise Exception("Exception: List host should return valid response")
-        return hosts[0]
+    return suitableHost
 
 def get_resource_type(resource_id):
         """Returns resource type"""


[14/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
Update plugins side nav icon


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/e37a6cd1
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/e37a6cd1
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/e37a6cd1

Branch: refs/heads/distributedrouter
Commit: e37a6cd115e9c5f3ea50e1c77cc474bb5eb5c5d7
Parents: 7b0c5cf
Author: Brian Federle <br...@citrix.com>
Authored: Fri Mar 7 11:49:48 2014 -0800
Committer: Brian Federle <br...@citrix.com>
Committed: Fri Mar 7 11:50:00 2014 -0800

----------------------------------------------------------------------
 ui/images/sprites.png | Bin 211703 -> 211543 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e37a6cd1/ui/images/sprites.png
----------------------------------------------------------------------
diff --git a/ui/images/sprites.png b/ui/images/sprites.png
index 0af9a29..ab39670 100644
Binary files a/ui/images/sprites.png and b/ui/images/sprites.png differ


[26/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
findbugs: output vlanids in errormessage instead of array object pointer

Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/579cb9c4
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/579cb9c4
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/579cb9c4

Branch: refs/heads/distributedrouter
Commit: 579cb9c479b67e9385f1235f4f71f2fef81b0bd0
Parents: 0aca7cf
Author: Daan Hoogland <da...@onecht.net>
Authored: Mon Mar 10 13:04:10 2014 +0100
Committer: Daan Hoogland <da...@onecht.net>
Committed: Mon Mar 10 13:04:10 2014 +0100

----------------------------------------------------------------------
 server/src/com/cloud/network/IpAddressManagerImpl.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/579cb9c4/server/src/com/cloud/network/IpAddressManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/IpAddressManagerImpl.java b/server/src/com/cloud/network/IpAddressManagerImpl.java
index 8903d1d..ed709e9 100644
--- a/server/src/com/cloud/network/IpAddressManagerImpl.java
+++ b/server/src/com/cloud/network/IpAddressManagerImpl.java
@@ -693,7 +693,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                     errorMessage.append(", vlanId id=" + Arrays.toString(dedicatedVlanDbIds.toArray()));
                 } else if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
                     sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
-                    errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray());
+                    errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
                 } else {
                     if (podId != null) {
                         InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);


[07/50] [abbrv] Dispatcher corrections, refactoring and tests

Posted by mu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/src/com/cloud/network/as/AutoScaleManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java
index 208b4a4..2fa3821 100644
--- a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java
+++ b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java
@@ -53,10 +53,12 @@ import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
 import org.apache.cloudstack.config.ApiServiceConfiguration;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+
 import org.apache.log4j.Logger;
 
 import com.cloud.api.ApiDBUtils;
-import com.cloud.api.ApiDispatcher;
+import com.cloud.api.dispatch.DispatchChainFactory;
+import com.cloud.api.dispatch.DispatchTask;
 import com.cloud.configuration.ConfigurationManager;
 import com.cloud.dc.DataCenter;
 import com.cloud.dc.DataCenter.NetworkType;
@@ -118,14 +120,17 @@ import com.cloud.utils.db.TransactionStatus;
 import com.cloud.utils.net.NetUtils;
 import com.cloud.vm.UserVmManager;
 import com.cloud.vm.UserVmService;
+
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
 
 @Local(value = {AutoScaleService.class, AutoScaleManager.class})
 public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScaleManager, AutoScaleService {
     private static final Logger s_logger = Logger.getLogger(AutoScaleManagerImpl.class);
-    private ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1);
+    private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1);
 
+    @Inject()
+    protected DispatchChainFactory dispatchChainFactory = null;
     @Inject
     EntityManager _entityMgr;
     @Inject
@@ -179,35 +184,35 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
     @Inject
     LoadBalancingRulesService _loadBalancingRulesService;
 
-    public List<AutoScaleCounter> getSupportedAutoScaleCounters(long networkid) {
-        String capability = _lbRulesMgr.getLBCapability(networkid, Capability.AutoScaleCounters.getName());
+    public List<AutoScaleCounter> getSupportedAutoScaleCounters(final long networkid) {
+        final String capability = _lbRulesMgr.getLBCapability(networkid, Capability.AutoScaleCounters.getName());
         if (capability == null) {
             return null;
         }
-        Gson gson = new Gson();
-        java.lang.reflect.Type listType = new TypeToken<List<AutoScaleCounter>>() {
+        final Gson gson = new Gson();
+        final java.lang.reflect.Type listType = new TypeToken<List<AutoScaleCounter>>() {
         }.getType();
-        List<AutoScaleCounter> result = gson.fromJson(capability, listType);
+        final List<AutoScaleCounter> result = gson.fromJson(capability, listType);
         return result;
     }
 
-    public void validateAutoScaleCounters(long networkid, List<Counter> counters, List<Pair<String, String>> counterParamPassed) {
-        List<AutoScaleCounter> supportedCounters = getSupportedAutoScaleCounters(networkid);
+    public void validateAutoScaleCounters(final long networkid, final List<Counter> counters, final List<Pair<String, String>> counterParamPassed) {
+        final List<AutoScaleCounter> supportedCounters = getSupportedAutoScaleCounters(networkid);
         if (supportedCounters == null) {
             throw new InvalidParameterException("AutoScale is not supported in the network");
         }
-        for (Counter counter : counters) {
-            String counterName = counter.getSource().name().toString();
+        for (final Counter counter : counters) {
+            final String counterName = counter.getSource().name().toString();
             boolean isCounterSupported = false;
-            for (AutoScaleCounter autoScaleCounter : supportedCounters) {
+            for (final AutoScaleCounter autoScaleCounter : supportedCounters) {
                 if (autoScaleCounter.getName().equals(counterName)) {
                     isCounterSupported = true;
-                    List<AutoScaleCounterParam> counterParams = autoScaleCounter.getParamList();
-                    for (AutoScaleCounterParam autoScaleCounterParam : counterParams) {
-                        boolean isRequiredParameter = autoScaleCounterParam.getRequired();
+                    final List<AutoScaleCounterParam> counterParams = autoScaleCounter.getParamList();
+                    for (final AutoScaleCounterParam autoScaleCounterParam : counterParams) {
+                        final boolean isRequiredParameter = autoScaleCounterParam.getRequired();
                         if (isRequiredParameter) {
                             boolean isRequiredParamPresent = false;
-                            for (Pair<String, String> pair : counterParamPassed) {
+                            for (final Pair<String, String> pair : counterParamPassed) {
                                 if (pair.first().equals(autoScaleCounterParam.getParamName()))
                                     isRequiredParamPresent = true;
 
@@ -227,9 +232,9 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
         }
     }
 
-    private <VO extends ControlledEntity> VO getEntityInDatabase(Account caller, String paramName, Long id, GenericDao<VO, Long> dao) {
+    private <VO extends ControlledEntity> VO getEntityInDatabase(final Account caller, final String paramName, final Long id, final GenericDao<VO, Long> dao) {
 
-        VO vo = dao.findById(id);
+        final VO vo = dao.findById(id);
 
         if (vo == null) {
             throw new InvalidParameterValueException("Unable to find " + paramName);
@@ -240,27 +245,27 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
         return vo;
     }
 
-    private boolean isAutoScaleScaleUpPolicy(AutoScalePolicy policyVO) {
+    private boolean isAutoScaleScaleUpPolicy(final AutoScalePolicy policyVO) {
         return policyVO.getAction().equals("scaleup");
     }
 
-    private List<AutoScalePolicyVO> getAutoScalePolicies(String paramName, List<Long> policyIds, List<Counter> counters, int interval, boolean scaleUpPolicies) {
-        SearchBuilder<AutoScalePolicyVO> policySearch = _autoScalePolicyDao.createSearchBuilder();
+    private List<AutoScalePolicyVO> getAutoScalePolicies(final String paramName, final List<Long> policyIds, final List<Counter> counters, final int interval, final boolean scaleUpPolicies) {
+        final SearchBuilder<AutoScalePolicyVO> policySearch = _autoScalePolicyDao.createSearchBuilder();
         policySearch.and("ids", policySearch.entity().getId(), Op.IN);
         policySearch.done();
-        SearchCriteria<AutoScalePolicyVO> sc = policySearch.create();
+        final SearchCriteria<AutoScalePolicyVO> sc = policySearch.create();
 
         sc.setParameters("ids", policyIds.toArray(new Object[0]));
-        List<AutoScalePolicyVO> policies = _autoScalePolicyDao.search(sc, null);
+        final List<AutoScalePolicyVO> policies = _autoScalePolicyDao.search(sc, null);
 
         int prevQuietTime = 0;
 
-        for (AutoScalePolicyVO policy : policies) {
-            int quietTime = policy.getQuietTime();
+        for (final AutoScalePolicyVO policy : policies) {
+            final int quietTime = policy.getQuietTime();
             if (prevQuietTime == 0) {
                 prevQuietTime = quietTime;
             }
-            int duration = policy.getDuration();
+            final int duration = policy.getDuration();
             if (duration < interval) {
                 throw new InvalidParameterValueException("duration : " + duration + " specified in a policy cannot be less than vm group's interval : " + interval);
             }
@@ -278,11 +283,11 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
                     throw new InvalidParameterValueException("Only scaledown policies can be specified in scaledownpolicyids");
                 }
             }
-            List<AutoScalePolicyConditionMapVO> policyConditionMapVOs = _autoScalePolicyConditionMapDao.listByAll(policy.getId(), null);
-            for (AutoScalePolicyConditionMapVO policyConditionMapVO : policyConditionMapVOs) {
-                long conditionid = policyConditionMapVO.getConditionId();
-                Condition condition = _conditionDao.findById(conditionid);
-                Counter counter = _counterDao.findById(condition.getCounterid());
+            final List<AutoScalePolicyConditionMapVO> policyConditionMapVOs = _autoScalePolicyConditionMapDao.listByAll(policy.getId(), null);
+            for (final AutoScalePolicyConditionMapVO policyConditionMapVO : policyConditionMapVOs) {
+                final long conditionid = policyConditionMapVO.getConditionId();
+                final Condition condition = _conditionDao.findById(conditionid);
+                final Counter counter = _counterDao.findById(condition.getCounterid());
                 counters.add(counter);
             }
         }
@@ -291,11 +296,11 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
 
     @DB
     protected AutoScaleVmProfileVO checkValidityAndPersist(AutoScaleVmProfileVO vmProfile) {
-        long templateId = vmProfile.getTemplateId();
-        long autoscaleUserId = vmProfile.getAutoScaleUserId();
-        int destroyVmGraceperiod = vmProfile.getDestroyVmGraceperiod();
+        final long templateId = vmProfile.getTemplateId();
+        final long autoscaleUserId = vmProfile.getAutoScaleUserId();
+        final int destroyVmGraceperiod = vmProfile.getDestroyVmGraceperiod();
 
-        VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, templateId);
+        final VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, templateId);
         // Make sure a valid template ID was specified
         if (template == null) {
             throw new InvalidParameterValueException("Unable to use the given template.");
@@ -305,14 +310,14 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
             throw new InvalidParameterValueException("Destroy Vm Grace Period cannot be less than 0.");
         }
 
-        User user = _userDao.findById(autoscaleUserId);
+        final User user = _userDao.findById(autoscaleUserId);
         if (user.getAccountId() != vmProfile.getAccountId()) {
             throw new InvalidParameterValueException("AutoScale User id does not belong to the same account");
         }
 
-        String apiKey = user.getApiKey();
-        String secretKey = user.getSecretKey();
-        String csUrl = ApiServiceConfiguration.ApiServletPath.value();
+        final String apiKey = user.getApiKey();
+        final String secretKey = user.getSecretKey();
+        final String csUrl = ApiServiceConfiguration.ApiServletPath.value();
 
         if (apiKey == null) {
             throw new InvalidParameterValueException("apiKey for user: " + user.getUsername() + " is empty. Please generate it");
@@ -333,39 +338,40 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
 
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMPROFILE_CREATE, eventDescription = "creating autoscale vm profile", create = true)
-    public AutoScaleVmProfile createAutoScaleVmProfile(CreateAutoScaleVmProfileCmd cmd) {
+    public AutoScaleVmProfile createAutoScaleVmProfile(final CreateAutoScaleVmProfileCmd cmd) {
 
-        Account owner = _accountDao.findById(cmd.getAccountId());
-        Account caller = CallContext.current().getCallingAccount();
+        final Account owner = _accountDao.findById(cmd.getAccountId());
+        final Account caller = CallContext.current().getCallingAccount();
         _accountMgr.checkAccess(caller, null, true, owner);
 
-        long zoneId = cmd.getZoneId();
-        long serviceOfferingId = cmd.getServiceOfferingId();
-        long autoscaleUserId = cmd.getAutoscaleUserId();
+        final long zoneId = cmd.getZoneId();
+        final long serviceOfferingId = cmd.getServiceOfferingId();
+        final long autoscaleUserId = cmd.getAutoscaleUserId();
 
-        DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
+        final DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
 
         if (zone == null) {
             throw new InvalidParameterValueException("Unable to find zone by id");
         }
 
-        ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
+        final ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
         if (serviceOffering == null) {
             throw new InvalidParameterValueException("Unable to find service offering by id");
         }
 
         // validations
-        HashMap<String, String> deployParams = cmd.getDeployParamMap();
+        final HashMap<String, String> deployParams = cmd.getDeployParamMap();
         if (deployParams.containsKey("networks") && deployParams.get("networks").length() > 0) {
             throw new InvalidParameterValueException(
                 "'networks' is not a valid parameter, network for an AutoScaled VM is chosen automatically. An autoscaled VM is deployed in the loadbalancer's network");
         }
+
         /*
          * Just for making sure the values are right in other deploy params.
          * For ex. if projectId is given as a string instead of an long value, this
          * will be throwing an error.
          */
-        ApiDispatcher.processParameters(new DeployVMCmd(), deployParams);
+        dispatchChainFactory.getStandardDispatchChain().dispatch(new DispatchTask(new DeployVMCmd(), deployParams));
 
         AutoScaleVmProfileVO profileVO =
             new AutoScaleVmProfileVO(cmd.getZoneId(), cmd.getDomainId(), cmd.getAccountId(), cmd.getServiceOfferingId(), cmd.getTemplateId(), cmd.getOtherDeployParams(),
@@ -383,13 +389,13 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
 
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMPROFILE_UPDATE, eventDescription = "updating autoscale vm profile")
-    public AutoScaleVmProfile updateAutoScaleVmProfile(UpdateAutoScaleVmProfileCmd cmd) {
-        Long profileId = cmd.getId();
-        Long templateId = cmd.getTemplateId();
-        Long autoscaleUserId = cmd.getAutoscaleUserId();
-        Map counterParamList = cmd.getCounterParamList();
+    public AutoScaleVmProfile updateAutoScaleVmProfile(final UpdateAutoScaleVmProfileCmd cmd) {
+        final Long profileId = cmd.getId();
+        final Long templateId = cmd.getTemplateId();
+        final Long autoscaleUserId = cmd.getAutoscaleUserId();
+        final Map counterParamList = cmd.getCounterParamList();
 
-        Integer destroyVmGraceperiod = cmd.getDestroyVmGraceperiod();
+        final Integer destroyVmGraceperiod = cmd.getDestroyVmGraceperiod();
 
         AutoScaleVmProfileVO vmProfile = getEntityInDatabase(CallContext.current().getCallingAccount(), "Auto Scale Vm Profile", profileId, _autoScaleVmProfileDao);
 
@@ -434,13 +440,13 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
 
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMPROFILE_DELETE, eventDescription = "deleting autoscale vm profile")
-    public boolean deleteAutoScaleVmProfile(long id) {
+    public boolean deleteAutoScaleVmProfile(final long id) {
         /* Check if entity is in database */
         getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Profile", id, _autoScaleVmProfileDao);
         if (_autoScaleVmGroupDao.isProfileInUse(id)) {
             throw new InvalidParameterValueException("Cannot delete AutoScale Vm Profile when it is in use by one more vm groups");
         }
-        boolean success = _autoScaleVmProfileDao.remove(id);
+        final boolean success = _autoScaleVmProfileDao.remove(id);
         if (success) {
             s_logger.info("Successfully deleted AutoScale Vm Profile with Id: " + id);
         }
@@ -456,8 +462,8 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
         Long zoneId = cmd.getZoneId();
         Boolean display = cmd.getDisplay();
 
-        SearchWrapper<AutoScaleVmProfileVO> searchWrapper = new SearchWrapper<AutoScaleVmProfileVO>(_autoScaleVmProfileDao, AutoScaleVmProfileVO.class, cmd, cmd.getId());
-        SearchBuilder<AutoScaleVmProfileVO> sb = searchWrapper.getSearchBuilder();
+        final SearchWrapper<AutoScaleVmProfileVO> searchWrapper = new SearchWrapper<AutoScaleVmProfileVO>(_autoScaleVmProfileDao, AutoScaleVmProfileVO.class, cmd, cmd.getId());
+        final SearchBuilder<AutoScaleVmProfileVO> sb = searchWrapper.getSearchBuilder();
 
         sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
         sb.and("templateId", sb.entity().getTemplateId(), SearchCriteria.Op.EQ);
@@ -507,19 +513,19 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
 
         return Transaction.execute(new TransactionCallback<AutoScalePolicyVO>() {
             @Override
-            public AutoScalePolicyVO doInTransaction(TransactionStatus status) {
-                AutoScalePolicyVO autoScalePolicyVO = _autoScalePolicyDao.persist(autoScalePolicyVOFinal);
+            public AutoScalePolicyVO doInTransaction(final TransactionStatus status) {
+                final AutoScalePolicyVO autoScalePolicyVO = _autoScalePolicyDao.persist(autoScalePolicyVOFinal);
 
                 if (conditionIds != null) {
-                    SearchBuilder<ConditionVO> conditionsSearch = _conditionDao.createSearchBuilder();
+                    final SearchBuilder<ConditionVO> conditionsSearch = _conditionDao.createSearchBuilder();
                     conditionsSearch.and("ids", conditionsSearch.entity().getId(), Op.IN);
                     conditionsSearch.done();
-                    SearchCriteria<ConditionVO> sc = conditionsSearch.create();
+                    final SearchCriteria<ConditionVO> sc = conditionsSearch.create();
 
                     sc.setParameters("ids", conditionIds.toArray(new Object[0]));
-                    List<ConditionVO> conditions = _conditionDao.search(sc, null);
+                    final List<ConditionVO> conditions = _conditionDao.search(sc, null);
 
-                    ControlledEntity[] sameOwnerEntities = conditions.toArray(new ControlledEntity[conditions.size() + 1]);
+                    final ControlledEntity[] sameOwnerEntities = conditions.toArray(new ControlledEntity[conditions.size() + 1]);
                     sameOwnerEntities[sameOwnerEntities.length - 1] = autoScalePolicyVO;
                     _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, sameOwnerEntities);
 
@@ -528,8 +534,8 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
                         throw new InvalidParameterValueException("Unable to find the condition specified");
                     }
 
-                    ArrayList<Long> counterIds = new ArrayList<Long>();
-                    for (ConditionVO condition : conditions) {
+                    final ArrayList<Long> counterIds = new ArrayList<Long>();
+                    for (final 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");
@@ -540,8 +546,8 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
                     /* 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);
+                    for (final Long conditionId : conditionIds) {
+                        final AutoScalePolicyConditionMapVO policyConditionMapVO = new AutoScalePolicyConditionMapVO(autoScalePolicyVO.getId(), conditionId);
                         _autoScalePolicyConditionMapDao.persist(policyConditionMapVO);
                     }
                 }
@@ -553,9 +559,9 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
 
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEPOLICY_CREATE, eventDescription = "creating autoscale policy", create = true)
-    public AutoScalePolicy createAutoScalePolicy(CreateAutoScalePolicyCmd cmd) {
+    public AutoScalePolicy createAutoScalePolicy(final CreateAutoScalePolicyCmd cmd) {
 
-        int duration = cmd.getDuration();
+        final int duration = cmd.getDuration();
         Integer quietTime = cmd.getQuietTime();
         String action = cmd.getAction();
 
@@ -588,7 +594,7 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
 
         return Transaction.execute(new TransactionCallback<Boolean>() {
             @Override
-            public Boolean doInTransaction(TransactionStatus status) {
+            public Boolean doInTransaction(final TransactionStatus status) {
                 boolean success = true;
                 success = _autoScalePolicyDao.remove(id);
                 if (!success) {
@@ -607,11 +613,11 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
         });
     }
 
-    public void checkCallerAccess(String accountName, Long domainId) {
-        Account caller = CallContext.current().getCallingAccount();
-        Account owner = _accountDao.findActiveAccount(accountName, domainId);
+    public void checkCallerAccess(final String accountName, final Long domainId) {
+        final Account caller = CallContext.current().getCallingAccount();
+        final Account owner = _accountDao.findActiveAccount(accountName, domainId);
         if (owner == null) {
-            List<String> idList = new ArrayList<String>();
+            final List<String> idList = new ArrayList<String>();
             idList.add(ApiDBUtils.findDomainById(domainId).getUuid());
             throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain with specifed domainId");
         }
@@ -628,23 +634,23 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
         ListProjectResourcesCriteria listProjectResourcesCriteria;
         Filter searchFilter;
 
-        public SearchWrapper(GenericDao<VO, Long> dao, Class<VO> entityClass, BaseListAccountResourcesCmd cmd, Long id) {
+        public SearchWrapper(final GenericDao<VO, Long> dao, final Class<VO> entityClass, final BaseListAccountResourcesCmd cmd, final Long id) {
             this.dao = dao;
             this.searchBuilder = dao.createSearchBuilder();
             domainId = cmd.getDomainId();
-            String accountName = cmd.getAccountName();
+            final String accountName = cmd.getAccountName();
             isRecursive = cmd.isRecursive();
-            boolean listAll = cmd.listAll();
-            long startIndex = cmd.getStartIndex();
-            long pageSizeVal = cmd.getPageSizeVal();
-            Account caller = CallContext.current().getCallingAccount();
+            final boolean listAll = cmd.listAll();
+            final long startIndex = cmd.getStartIndex();
+            final long pageSizeVal = cmd.getPageSizeVal();
+            final Account caller = CallContext.current().getCallingAccount();
 
-            Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject =
+            final Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject =
                 new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive, null);
             _accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedAccounts, domainIdRecursiveListProject, listAll, false);
             domainId = domainIdRecursiveListProject.first();
             isRecursive = domainIdRecursiveListProject.second();
-            ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+            final ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
             _accountMgr.buildACLSearchBuilder(searchBuilder, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
             searchFilter = new Filter(entityClass, "id", false, startIndex, pageSizeVal);
         }
@@ -665,30 +671,30 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
     }
 
     @Override
-    public List<? extends AutoScalePolicy> listAutoScalePolicies(ListAutoScalePoliciesCmd cmd) {
-        SearchWrapper<AutoScalePolicyVO> searchWrapper = new SearchWrapper<AutoScalePolicyVO>(_autoScalePolicyDao, AutoScalePolicyVO.class, cmd, cmd.getId());
-        SearchBuilder<AutoScalePolicyVO> sb = searchWrapper.getSearchBuilder();
-        Long id = cmd.getId();
-        Long conditionId = cmd.getConditionId();
-        String action = cmd.getAction();
-        Long vmGroupId = cmd.getVmGroupId();
+    public List<? extends AutoScalePolicy> listAutoScalePolicies(final ListAutoScalePoliciesCmd cmd) {
+        final SearchWrapper<AutoScalePolicyVO> searchWrapper = new SearchWrapper<AutoScalePolicyVO>(_autoScalePolicyDao, AutoScalePolicyVO.class, cmd, cmd.getId());
+        final SearchBuilder<AutoScalePolicyVO> sb = searchWrapper.getSearchBuilder();
+        final Long id = cmd.getId();
+        final Long conditionId = cmd.getConditionId();
+        final String action = cmd.getAction();
+        final Long vmGroupId = cmd.getVmGroupId();
 
         sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
         sb.and("action", sb.entity().getAction(), SearchCriteria.Op.EQ);
 
         if (conditionId != null) {
-            SearchBuilder<AutoScalePolicyConditionMapVO> asPolicyConditionSearch = _autoScalePolicyConditionMapDao.createSearchBuilder();
+            final SearchBuilder<AutoScalePolicyConditionMapVO> asPolicyConditionSearch = _autoScalePolicyConditionMapDao.createSearchBuilder();
             asPolicyConditionSearch.and("conditionId", asPolicyConditionSearch.entity().getConditionId(), SearchCriteria.Op.EQ);
             sb.join("asPolicyConditionSearch", asPolicyConditionSearch, sb.entity().getId(), asPolicyConditionSearch.entity().getPolicyId(), JoinBuilder.JoinType.INNER);
         }
 
         if (vmGroupId != null) {
-            SearchBuilder<AutoScaleVmGroupPolicyMapVO> asVmGroupPolicySearch = _autoScaleVmGroupPolicyMapDao.createSearchBuilder();
+            final SearchBuilder<AutoScaleVmGroupPolicyMapVO> asVmGroupPolicySearch = _autoScaleVmGroupPolicyMapDao.createSearchBuilder();
             asVmGroupPolicySearch.and("vmGroupId", asVmGroupPolicySearch.entity().getVmGroupId(), SearchCriteria.Op.EQ);
             sb.join("asVmGroupPolicySearch", asVmGroupPolicySearch, sb.entity().getId(), asVmGroupPolicySearch.entity().getPolicyId(), JoinBuilder.JoinType.INNER);
         }
 
-        SearchCriteria<AutoScalePolicyVO> sc = searchWrapper.buildSearchCriteria();
+        final SearchCriteria<AutoScalePolicyVO> sc = searchWrapper.buildSearchCriteria();
 
         if (id != null) {
             sc.setParameters("id", id);
@@ -711,11 +717,11 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
 
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEPOLICY_UPDATE, eventDescription = "updating autoscale policy")
-    public AutoScalePolicy updateAutoScalePolicy(UpdateAutoScalePolicyCmd cmd) {
-        Long policyId = cmd.getId();
-        Integer duration = cmd.getDuration();
-        Integer quietTime = cmd.getQuietTime();
-        List<Long> conditionIds = cmd.getConditionIds();
+    public AutoScalePolicy updateAutoScalePolicy(final UpdateAutoScalePolicyCmd cmd) {
+        final Long policyId = cmd.getId();
+        final Integer duration = cmd.getDuration();
+        final Integer quietTime = cmd.getQuietTime();
+        final List<Long> conditionIds = cmd.getConditionIds();
         AutoScalePolicyVO policy = getEntityInDatabase(CallContext.current().getCallingAccount(), "Auto Scale Policy", policyId, _autoScalePolicyDao);
 
         if (duration != null) {
@@ -726,9 +732,9 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
             policy.setQuietTime(quietTime);
         }
 
-        List<AutoScaleVmGroupPolicyMapVO> vmGroupPolicyList = _autoScaleVmGroupPolicyMapDao.listByPolicyId(policyId);
-        for (AutoScaleVmGroupPolicyMapVO vmGroupPolicy : vmGroupPolicyList) {
-            AutoScaleVmGroupVO vmGroupVO = _autoScaleVmGroupDao.findById(vmGroupPolicy.getVmGroupId());
+        final List<AutoScaleVmGroupPolicyMapVO> vmGroupPolicyList = _autoScaleVmGroupPolicyMapDao.listByPolicyId(policyId);
+        for (final AutoScaleVmGroupPolicyMapVO vmGroupPolicy : vmGroupPolicyList) {
+            final AutoScaleVmGroupVO vmGroupVO = _autoScaleVmGroupDao.findById(vmGroupPolicy.getVmGroupId());
             if (vmGroupVO == null) {
                 s_logger.warn("Stale database entry! There is an entry in VmGroupPolicyMap but the vmGroup is missing:" + vmGroupPolicy.getVmGroupId());
 
@@ -750,9 +756,9 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
 
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_CREATE, eventDescription = "creating autoscale vm group", create = true)
-    public AutoScaleVmGroup createAutoScaleVmGroup(CreateAutoScaleVmGroupCmd cmd) {
-        int minMembers = cmd.getMinMembers();
-        int maxMembers = cmd.getMaxMembers();
+    public AutoScaleVmGroup createAutoScaleVmGroup(final CreateAutoScaleVmGroupCmd cmd) {
+        final int minMembers = cmd.getMinMembers();
+        final int maxMembers = cmd.getMaxMembers();
         Integer interval = cmd.getInterval();
         Boolean forDisplay = cmd.getDisplay();
 
@@ -760,9 +766,9 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
             interval = NetUtils.DEFAULT_AUTOSCALE_POLICY_INTERVAL_TIME;
         }
 
-        LoadBalancerVO loadBalancer = getEntityInDatabase(CallContext.current().getCallingAccount(), ApiConstants.LBID, cmd.getLbRuleId(), _lbDao);
+        final LoadBalancerVO loadBalancer = getEntityInDatabase(CallContext.current().getCallingAccount(), ApiConstants.LBID, cmd.getLbRuleId(), _lbDao);
 
-        Long zoneId = _ipAddressDao.findById(loadBalancer.getSourceIpAddressId()).getDataCenterId();
+        final Long zoneId = _ipAddressDao.findById(loadBalancer.getSourceIpAddressId()).getDataCenterId();
 
         if (_autoScaleVmGroupDao.isAutoScaleLoadBalancer(loadBalancer.getId())) {
             throw new InvalidParameterValueException("an AutoScaleVmGroup is already attached to the lb rule, the existing vm group has to be first deleted");
@@ -787,23 +793,23 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
     }
 
     @Override
-    public boolean configureAutoScaleVmGroup(CreateAutoScaleVmGroupCmd cmd) throws ResourceUnavailableException {
+    public boolean configureAutoScaleVmGroup(final CreateAutoScaleVmGroupCmd cmd) throws ResourceUnavailableException {
         return configureAutoScaleVmGroup(cmd.getEntityId(), AutoScaleVmGroup.State_New);
     }
 
-    public boolean isLoadBalancerBasedAutoScaleVmGroup(AutoScaleVmGroup vmGroup) {
+    public boolean isLoadBalancerBasedAutoScaleVmGroup(final AutoScaleVmGroup vmGroup) {
         return vmGroup.getLoadBalancerId() != null;
     }
 
-    private boolean configureAutoScaleVmGroup(long vmGroupid, String currentState) throws ResourceUnavailableException {
-        AutoScaleVmGroup vmGroup = _autoScaleVmGroupDao.findById(vmGroupid);
+    private boolean configureAutoScaleVmGroup(final long vmGroupid, final String currentState) throws ResourceUnavailableException {
+        final AutoScaleVmGroup vmGroup = _autoScaleVmGroupDao.findById(vmGroupid);
 
         if (isLoadBalancerBasedAutoScaleVmGroup(vmGroup)) {
             try {
                 return _lbRulesMgr.configureLbAutoScaleVmGroup(vmGroupid, currentState);
-            } catch (ResourceUnavailableException re) {
+            } catch (final ResourceUnavailableException re) {
                 throw re;
-            } catch (Exception e) {
+            } catch (final Exception e) {
                 s_logger.warn("Exception during configureLbAutoScaleVmGroup in lb rules manager", e);
                 return false;
             }
@@ -817,20 +823,20 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
     @DB
     @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_DELETE, eventDescription = "deleting autoscale vm group")
     public boolean deleteAutoScaleVmGroup(final long id) {
-        AutoScaleVmGroupVO autoScaleVmGroupVO = getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Group", id, _autoScaleVmGroupDao);
+        final AutoScaleVmGroupVO autoScaleVmGroupVO = getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Group", id, _autoScaleVmGroupDao);
 
         if (autoScaleVmGroupVO.getState().equals(AutoScaleVmGroup.State_New)) {
             /* This condition is for handling failures during creation command */
             return _autoScaleVmGroupDao.remove(id);
         }
-        String bakupState = autoScaleVmGroupVO.getState();
+        final String bakupState = autoScaleVmGroupVO.getState();
         autoScaleVmGroupVO.setState(AutoScaleVmGroup.State_Revoke);
         _autoScaleVmGroupDao.persist(autoScaleVmGroupVO);
         boolean success = false;
 
         try {
             success = configureAutoScaleVmGroup(id, bakupState);
-        } catch (ResourceUnavailableException e) {
+        } catch (final ResourceUnavailableException e) {
             autoScaleVmGroupVO.setState(bakupState);
             _autoScaleVmGroupDao.persist(autoScaleVmGroupVO);
         } finally {
@@ -842,7 +848,7 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
 
         return Transaction.execute(new TransactionCallback<Boolean>() {
             @Override
-            public Boolean doInTransaction(TransactionStatus status) {
+            public Boolean doInTransaction(final TransactionStatus status) {
                 boolean success = _autoScaleVmGroupDao.remove(id);
 
                 if (!success) {
@@ -872,8 +878,8 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
         Long zoneId = cmd.getZoneId();
         Boolean forDisplay = cmd.getDisplay();
 
-        SearchWrapper<AutoScaleVmGroupVO> searchWrapper = new SearchWrapper<AutoScaleVmGroupVO>(_autoScaleVmGroupDao, AutoScaleVmGroupVO.class, cmd, cmd.getId());
-        SearchBuilder<AutoScaleVmGroupVO> sb = searchWrapper.getSearchBuilder();
+        final SearchWrapper<AutoScaleVmGroupVO> searchWrapper = new SearchWrapper<AutoScaleVmGroupVO>(_autoScaleVmGroupDao, AutoScaleVmGroupVO.class, cmd, cmd.getId());
+        final SearchBuilder<AutoScaleVmGroupVO> sb = searchWrapper.getSearchBuilder();
 
         sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
         sb.and("loadBalancerId", sb.entity().getLoadBalancerId(), SearchCriteria.Op.EQ);
@@ -882,12 +888,12 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
         sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ);
 
         if (policyId != null) {
-            SearchBuilder<AutoScaleVmGroupPolicyMapVO> asVmGroupPolicySearch = _autoScaleVmGroupPolicyMapDao.createSearchBuilder();
+            final SearchBuilder<AutoScaleVmGroupPolicyMapVO> asVmGroupPolicySearch = _autoScaleVmGroupPolicyMapDao.createSearchBuilder();
             asVmGroupPolicySearch.and("policyId", asVmGroupPolicySearch.entity().getPolicyId(), SearchCriteria.Op.EQ);
             sb.join("asVmGroupPolicySearch", asVmGroupPolicySearch, sb.entity().getId(), asVmGroupPolicySearch.entity().getVmGroupId(), JoinBuilder.JoinType.INNER);
         }
 
-        SearchCriteria<AutoScaleVmGroupVO> sc = searchWrapper.buildSearchCriteria();
+        final SearchCriteria<AutoScaleVmGroupVO> sc = searchWrapper.buildSearchCriteria();
         if (id != null) {
             sc.setParameters("id", id);
         }
@@ -912,14 +918,14 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
     @DB
     protected AutoScaleVmGroupVO checkValidityAndPersist(final AutoScaleVmGroupVO vmGroup, final List<Long> passedScaleUpPolicyIds,
         final List<Long> passedScaleDownPolicyIds) {
-        int minMembers = vmGroup.getMinMembers();
-        int maxMembers = vmGroup.getMaxMembers();
-        int interval = vmGroup.getInterval();
-        List<Counter> counters = new ArrayList<Counter>();
-        List<AutoScalePolicyVO> policies = new ArrayList<AutoScalePolicyVO>();
+        final int minMembers = vmGroup.getMinMembers();
+        final int maxMembers = vmGroup.getMaxMembers();
+        final int interval = vmGroup.getInterval();
+        final List<Counter> counters = new ArrayList<Counter>();
+        final List<AutoScalePolicyVO> policies = new ArrayList<AutoScalePolicyVO>();
         final List<Long> policyIds = new ArrayList<Long>();
-        List<Long> currentScaleUpPolicyIds = new ArrayList<Long>();
-        List<Long> currentScaleDownPolicyIds = new ArrayList<Long>();
+        final List<Long> currentScaleUpPolicyIds = new ArrayList<Long>();
+        final List<Long> currentScaleDownPolicyIds = new ArrayList<Long>();
         if (vmGroup.getCreated() != null) {
             ApiDBUtils.getAutoScaleVmGroupPolicyIds(vmGroup.getId(), currentScaleUpPolicyIds, currentScaleDownPolicyIds);
         }
@@ -958,26 +964,26 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
             getAutoScalePolicies("scaledownpolicyid", currentScaleDownPolicyIds, counters, interval, false);
             policyIds.addAll(currentScaleDownPolicyIds);
         }
-        AutoScaleVmProfileVO profileVO =
+        final AutoScaleVmProfileVO profileVO =
             getEntityInDatabase(CallContext.current().getCallingAccount(), ApiConstants.VMPROFILE_ID, vmGroup.getProfileId(), _autoScaleVmProfileDao);
 
-        LoadBalancerVO loadBalancer = getEntityInDatabase(CallContext.current().getCallingAccount(), ApiConstants.LBID, vmGroup.getLoadBalancerId(), _lbDao);
+        final LoadBalancerVO loadBalancer = getEntityInDatabase(CallContext.current().getCallingAccount(), ApiConstants.LBID, vmGroup.getLoadBalancerId(), _lbDao);
         validateAutoScaleCounters(loadBalancer.getNetworkId(), counters, profileVO.getCounterParams());
 
-        ControlledEntity[] sameOwnerEntities = policies.toArray(new ControlledEntity[policies.size() + 2]);
+        final ControlledEntity[] sameOwnerEntities = policies.toArray(new ControlledEntity[policies.size() + 2]);
         sameOwnerEntities[sameOwnerEntities.length - 2] = loadBalancer;
         sameOwnerEntities[sameOwnerEntities.length - 1] = profileVO;
         _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, sameOwnerEntities);
 
         return Transaction.execute(new TransactionCallback<AutoScaleVmGroupVO>() {
             @Override
-            public AutoScaleVmGroupVO doInTransaction(TransactionStatus status) {
-                AutoScaleVmGroupVO vmGroupNew = _autoScaleVmGroupDao.persist(vmGroup);
+            public AutoScaleVmGroupVO doInTransaction(final TransactionStatus status) {
+                final AutoScaleVmGroupVO vmGroupNew = _autoScaleVmGroupDao.persist(vmGroup);
 
                 if (passedScaleUpPolicyIds != null || passedScaleDownPolicyIds != null) {
                     _autoScaleVmGroupPolicyMapDao.removeByGroupId(vmGroupNew.getId());
 
-                    for (Long policyId : policyIds) {
+                    for (final Long policyId : policyIds) {
                         _autoScaleVmGroupPolicyMapDao.persist(new AutoScaleVmGroupPolicyMapVO(vmGroupNew.getId(), policyId));
                     }
                 }
@@ -990,15 +996,15 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
 
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_UPDATE, eventDescription = "updating autoscale vm group")
-    public AutoScaleVmGroup updateAutoScaleVmGroup(UpdateAutoScaleVmGroupCmd cmd) {
-        Long vmGroupId = cmd.getId();
-        Integer minMembers = cmd.getMinMembers();
-        Integer maxMembers = cmd.getMaxMembers();
-        Integer interval = cmd.getInterval();
-        Boolean forDisplay = cmd.getDisplay();
+    public AutoScaleVmGroup updateAutoScaleVmGroup(final UpdateAutoScaleVmGroupCmd cmd) {
+        final Long vmGroupId = cmd.getId();
+        final Integer minMembers = cmd.getMinMembers();
+        final Integer maxMembers = cmd.getMaxMembers();
+        final Integer interval = cmd.getInterval();
+        final Boolean forDisplay = cmd.getDisplay();
 
-        List<Long> scaleUpPolicyIds = cmd.getScaleUpPolicyIds();
-        List<Long> scaleDownPolicyIds = cmd.getScaleDownPolicyIds();
+        final List<Long> scaleUpPolicyIds = cmd.getScaleUpPolicyIds();
+        final List<Long> scaleDownPolicyIds = cmd.getScaleDownPolicyIds();
 
         AutoScaleVmGroupVO vmGroupVO = getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Group", vmGroupId, _autoScaleVmGroupDao);
 
@@ -1039,7 +1045,7 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
     @Override
     @DB
     @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_ENABLE, eventDescription = "enabling autoscale vm group")
-    public AutoScaleVmGroup enableAutoScaleVmGroup(Long id) {
+    public AutoScaleVmGroup enableAutoScaleVmGroup(final Long id) {
         AutoScaleVmGroupVO vmGroup = getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Group", id, _autoScaleVmGroupDao);
         boolean success = false;
         if (!vmGroup.getState().equals(AutoScaleVmGroup.State_Disabled)) {
@@ -1050,7 +1056,7 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
             vmGroup.setState(AutoScaleVmGroup.State_Enabled);
             vmGroup = _autoScaleVmGroupDao.persist(vmGroup);
             success = configureAutoScaleVmGroup(id, AutoScaleVmGroup.State_Disabled);
-        } catch (ResourceUnavailableException e) {
+        } catch (final ResourceUnavailableException e) {
             vmGroup.setState(AutoScaleVmGroup.State_Disabled);
             _autoScaleVmGroupDao.persist(vmGroup);
         } finally {
@@ -1066,7 +1072,7 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_DISABLE, eventDescription = "disabling autoscale vm group")
     @DB
-    public AutoScaleVmGroup disableAutoScaleVmGroup(Long id) {
+    public AutoScaleVmGroup disableAutoScaleVmGroup(final Long id) {
         AutoScaleVmGroupVO vmGroup = getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Group", id, _autoScaleVmGroupDao);
         boolean success = false;
         if (!vmGroup.getState().equals(AutoScaleVmGroup.State_Enabled)) {
@@ -1077,7 +1083,7 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
             vmGroup.setState(AutoScaleVmGroup.State_Disabled);
             vmGroup = _autoScaleVmGroupDao.persist(vmGroup);
             success = configureAutoScaleVmGroup(id, AutoScaleVmGroup.State_Enabled);
-        } catch (ResourceUnavailableException e) {
+        } catch (final ResourceUnavailableException e) {
             vmGroup.setState(AutoScaleVmGroup.State_Enabled);
             _autoScaleVmGroupDao.persist(vmGroup);
         } finally {
@@ -1093,14 +1099,14 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_COUNTER_CREATE, eventDescription = "Counter", create = true)
     @DB
-    public Counter createCounter(CreateCounterCmd cmd) {
-        String source = cmd.getSource().toLowerCase();
-        String name = cmd.getName();
+    public Counter createCounter(final CreateCounterCmd cmd) {
+        final String source = cmd.getSource().toLowerCase();
+        final String name = cmd.getName();
         Counter.Source src;
         // Validate Source
         try {
             src = Counter.Source.valueOf(source);
-        } catch (Exception ex) {
+        } catch (final Exception ex) {
             throw new InvalidParameterValueException("The Source " + source + " does not exist; Unable to create Counter");
         }
 
@@ -1115,21 +1121,21 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
 
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_CONDITION_CREATE, eventDescription = "Condition", create = true)
-    public Condition createCondition(CreateConditionCmd cmd) {
+    public Condition createCondition(final CreateConditionCmd cmd) {
         checkCallerAccess(cmd.getAccountName(), cmd.getDomainId());
-        String opr = cmd.getRelationalOperator().toUpperCase();
-        long cid = cmd.getCounterId();
-        long threshold = cmd.getThreshold();
+        final String opr = cmd.getRelationalOperator().toUpperCase();
+        final long cid = cmd.getCounterId();
+        final long threshold = cmd.getThreshold();
         Condition.Operator op;
         // Validate Relational Operator
         try {
             op = Condition.Operator.valueOf(opr);
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             throw new InvalidParameterValueException("The Operator " + opr + " does not exist; Unable to create Condition.");
         }
         // TODO - Validate threshold
 
-        CounterVO counter = _counterDao.findById(cid);
+        final CounterVO counter = _counterDao.findById(cid);
 
         if (counter == null) {
             throw new InvalidParameterValueException("Unable to find counter");
@@ -1144,29 +1150,29 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
     }
 
     @Override
-    public List<? extends Counter> listCounters(ListCountersCmd cmd) {
-        String name = cmd.getName();
-        Long id = cmd.getId();
+    public List<? extends Counter> listCounters(final ListCountersCmd cmd) {
+        final String name = cmd.getName();
+        final Long id = cmd.getId();
         String source = cmd.getSource();
         if (source != null)
             source = source.toLowerCase();
 
-        Filter searchFilter = new Filter(CounterVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+        final Filter searchFilter = new Filter(CounterVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
 
-        List<CounterVO> counters = _counterDao.listCounters(id, name, source, cmd.getKeyword(), searchFilter);
+        final List<CounterVO> counters = _counterDao.listCounters(id, name, source, cmd.getKeyword(), searchFilter);
 
         return counters;
     }
 
     @Override
-    public List<? extends Condition> listConditions(ListConditionsCmd cmd) {
-        Long id = cmd.getId();
-        Long counterId = cmd.getCounterId();
-        Long policyId = cmd.getPolicyId();
-        SearchWrapper<ConditionVO> searchWrapper = new SearchWrapper<ConditionVO>(_conditionDao, ConditionVO.class, cmd, cmd.getId());
-        SearchBuilder<ConditionVO> sb = searchWrapper.getSearchBuilder();
+    public List<? extends Condition> listConditions(final ListConditionsCmd cmd) {
+        final Long id = cmd.getId();
+        final Long counterId = cmd.getCounterId();
+        final Long policyId = cmd.getPolicyId();
+        final SearchWrapper<ConditionVO> searchWrapper = new SearchWrapper<ConditionVO>(_conditionDao, ConditionVO.class, cmd, cmd.getId());
+        final SearchBuilder<ConditionVO> sb = searchWrapper.getSearchBuilder();
         if (policyId != null) {
-            SearchBuilder<AutoScalePolicyConditionMapVO> asPolicyConditionSearch = _autoScalePolicyConditionMapDao.createSearchBuilder();
+            final SearchBuilder<AutoScalePolicyConditionMapVO> asPolicyConditionSearch = _autoScalePolicyConditionMapDao.createSearchBuilder();
             asPolicyConditionSearch.and("policyId", asPolicyConditionSearch.entity().getPolicyId(), SearchCriteria.Op.EQ);
             sb.join("asPolicyConditionSearch", asPolicyConditionSearch, sb.entity().getId(), asPolicyConditionSearch.entity().getConditionId(),
                 JoinBuilder.JoinType.INNER);
@@ -1176,7 +1182,7 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
         sb.and("counterId", sb.entity().getCounterid(), SearchCriteria.Op.EQ);
 
         // now set the SC criteria...
-        SearchCriteria<ConditionVO> sc = searchWrapper.buildSearchCriteria();
+        final SearchCriteria<ConditionVO> sc = searchWrapper.buildSearchCriteria();
 
         if (id != null) {
             sc.setParameters("id", id);
@@ -1195,22 +1201,22 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
 
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_COUNTER_DELETE, eventDescription = "counter")
-    public boolean deleteCounter(long counterId) throws ResourceInUseException {
+    public boolean deleteCounter(final long counterId) throws ResourceInUseException {
         // Verify Counter id
-        CounterVO counter = _counterDao.findById(counterId);
+        final CounterVO counter = _counterDao.findById(counterId);
         if (counter == null) {
             throw new InvalidParameterValueException("Unable to find Counter");
         }
 
         // Verify if it is used in any Condition
 
-        ConditionVO condition = _conditionDao.findByCounterId(counterId);
+        final ConditionVO condition = _conditionDao.findByCounterId(counterId);
         if (condition != null) {
             s_logger.info("Cannot delete counter " + counter.getName() + " as it is being used in a condition.");
             throw new ResourceInUseException("Counter is in use.");
         }
 
-        boolean success = _counterDao.remove(counterId);
+        final boolean success = _counterDao.remove(counterId);
         if (success) {
             s_logger.info("Successfully deleted counter with Id: " + counterId);
         }
@@ -1220,9 +1226,9 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
 
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_CONDITION_DELETE, eventDescription = "condition")
-    public boolean deleteCondition(long conditionId) throws ResourceInUseException {
+    public boolean deleteCondition(final long conditionId) throws ResourceInUseException {
         /* Check if entity is in database */
-        ConditionVO condition = getEntityInDatabase(CallContext.current().getCallingAccount(), "Condition", conditionId, _conditionDao);
+        final ConditionVO condition = getEntityInDatabase(CallContext.current().getCallingAccount(), "Condition", conditionId, _conditionDao);
         if (condition == null) {
             throw new InvalidParameterValueException("Unable to find Condition");
         }
@@ -1232,7 +1238,7 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
             s_logger.info("Cannot delete condition " + conditionId + " as it is being used in a condition.");
             throw new ResourceInUseException("Cannot delete Condition when it is in use by one or more AutoScale Policies.");
         }
-        boolean success = _conditionDao.remove(conditionId);
+        final boolean success = _conditionDao.remove(conditionId);
         if (success) {
             s_logger.info("Successfully deleted condition " + condition.getId());
         }
@@ -1240,7 +1246,7 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
     }
 
     @Override
-    public void cleanUpAutoScaleResources(Long accountId) {
+    public void cleanUpAutoScaleResources(final Long accountId) {
         // cleans Autoscale VmProfiles, AutoScale Policies and Conditions belonging to an account
         int count = 0;
         count = _autoScaleVmProfileDao.removeByAccountId(accountId);
@@ -1257,10 +1263,10 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
         }
     }
 
-    private boolean checkConditionUp(AutoScaleVmGroupVO asGroup, Integer numVm) {
+    private boolean checkConditionUp(final AutoScaleVmGroupVO asGroup, final Integer numVm) {
         // check maximum
-        Integer currentVM = _autoScaleVmGroupVmMapDao.countByGroup(asGroup.getId());
-        Integer maxVm = asGroup.getMaxMembers();
+        final Integer currentVM = _autoScaleVmGroupVmMapDao.countByGroup(asGroup.getId());
+        final Integer maxVm = asGroup.getMaxMembers();
         if (currentVM + numVm > maxVm) {
             s_logger.warn("number of VM will greater than the maximum in this group if scaling up, so do nothing more");
             return false;
@@ -1268,9 +1274,9 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
         return true;
     }
 
-    private boolean checkConditionDown(AutoScaleVmGroupVO asGroup) {
-        Integer currentVM = _autoScaleVmGroupVmMapDao.countByGroup(asGroup.getId());
-        Integer minVm = asGroup.getMinMembers();
+    private boolean checkConditionDown(final AutoScaleVmGroupVO asGroup) {
+        final Integer currentVM = _autoScaleVmGroupVmMapDao.countByGroup(asGroup.getId());
+        final Integer minVm = asGroup.getMinMembers();
         if (currentVM - 1 < minVm) {
             s_logger.warn("number of VM will less than the minimum in this group if scaling down, so do nothing more");
             return false;
@@ -1278,29 +1284,29 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
         return true;
     }
 
-    private long createNewVM(AutoScaleVmGroupVO asGroup) {
-        AutoScaleVmProfileVO profileVo = _autoScaleVmProfileDao.findById(asGroup.getProfileId());
-        long templateId = profileVo.getTemplateId();
-        long serviceOfferingId = profileVo.getServiceOfferingId();
+    private long createNewVM(final AutoScaleVmGroupVO asGroup) {
+        final AutoScaleVmProfileVO profileVo = _autoScaleVmProfileDao.findById(asGroup.getProfileId());
+        final long templateId = profileVo.getTemplateId();
+        final long serviceOfferingId = profileVo.getServiceOfferingId();
         if (templateId == -1) {
             return -1;
         }
         // create new VM into DB
         try {
             //Verify that all objects exist before passing them to the service
-            Account owner = _accountService.getActiveAccountById(profileVo.getAccountId());
+            final Account owner = _accountService.getActiveAccountById(profileVo.getAccountId());
 
-            DataCenter zone = _entityMgr.findById(DataCenter.class, profileVo.getZoneId());
+            final DataCenter zone = _entityMgr.findById(DataCenter.class, profileVo.getZoneId());
             if (zone == null) {
                 throw new InvalidParameterValueException("Unable to find zone by id=" + profileVo.getZoneId());
             }
 
-            ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
+            final ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
             if (serviceOffering == null) {
                 throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
             }
 
-            VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, templateId);
+            final VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, templateId);
             // Make sure a valid template ID was specified
             if (template == null) {
                 throw new InvalidParameterValueException("Unable to use template " + templateId);
@@ -1313,7 +1319,7 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
             }
 
             UserVm vm = null;
-            IpAddresses addrs = new IpAddresses(null, null);
+            final IpAddresses addrs = new IpAddresses(null, null);
             if (zone.getNetworkType() == NetworkType.Basic) {
                 vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, null, owner, "autoScaleVm-" + asGroup.getId() + "-" +
                     getCurrentTimeStampString(),
@@ -1339,41 +1345,41 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
             } else {
                 return -1;
             }
-        } catch (InsufficientCapacityException ex) {
+        } catch (final InsufficientCapacityException ex) {
             s_logger.info(ex);
             s_logger.trace(ex.getMessage(), ex);
             throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());
-        } catch (ResourceUnavailableException ex) {
+        } catch (final ResourceUnavailableException ex) {
             s_logger.warn("Exception: ", ex);
             throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
-        } catch (ConcurrentOperationException ex) {
+        } catch (final ConcurrentOperationException ex) {
             s_logger.warn("Exception: ", ex);
             throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-        } catch (ResourceAllocationException ex) {
+        } catch (final ResourceAllocationException ex) {
             s_logger.warn("Exception: ", ex);
             throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage());
         }
     }
 
     private String getCurrentTimeStampString() {
-        Date current = new Date();
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+        final Date current = new Date();
+        final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
 
         return sdf.format(current);
     }
 
-    private boolean startNewVM(long vmId) {
+    private boolean startNewVM(final long vmId) {
         try {
             CallContext.current().setEventDetails("Vm Id: " + vmId);
             _userVmManager.startVirtualMachine(vmId, null, null);
-        } catch (ResourceUnavailableException ex) {
+        } catch (final ResourceUnavailableException ex) {
             s_logger.warn("Exception: ", ex);
             throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
-        } catch (ConcurrentOperationException ex) {
+        } catch (final ConcurrentOperationException ex) {
             s_logger.warn("Exception: ", ex);
             throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-        } catch (InsufficientCapacityException ex) {
-            StringBuilder message = new StringBuilder(ex.getMessage());
+        } catch (final InsufficientCapacityException ex) {
+            final StringBuilder message = new StringBuilder(ex.getMessage());
             if (ex instanceof InsufficientServerCapacityException) {
                 if (((InsufficientServerCapacityException)ex).isAffinityApplied()) {
                     message.append(", Please check the affinity groups provided, there may not be sufficient capacity to follow them");
@@ -1386,14 +1392,14 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
         return true;
     }
 
-    private boolean assignLBruleToNewVm(long vmId, AutoScaleVmGroupVO asGroup) {
-        List<Long> lstVmId = new ArrayList<Long>();
-        long lbId = asGroup.getLoadBalancerId();
+    private boolean assignLBruleToNewVm(final long vmId, final AutoScaleVmGroupVO asGroup) {
+        final List<Long> lstVmId = new ArrayList<Long>();
+        final long lbId = asGroup.getLoadBalancerId();
 
-        List<LoadBalancerVMMapVO> LbVmMapVos = _lbVmMapDao.listByLoadBalancerId(lbId);
+        final List<LoadBalancerVMMapVO> LbVmMapVos = _lbVmMapDao.listByLoadBalancerId(lbId);
         if ((LbVmMapVos != null) && (LbVmMapVos.size() > 0)) {
-            for (LoadBalancerVMMapVO LbVmMapVo : LbVmMapVos) {
-                long instanceId = LbVmMapVo.getInstanceId();
+            for (final LoadBalancerVMMapVO LbVmMapVo : LbVmMapVos) {
+                final long instanceId = LbVmMapVo.getInstanceId();
                 if (instanceId == vmId) {
                     s_logger.warn("the new VM is already mapped to LB rule. What's wrong?");
                     return true;
@@ -1405,17 +1411,17 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
 
     }
 
-    private long removeLBrule(AutoScaleVmGroupVO asGroup) {
-        long lbId = asGroup.getLoadBalancerId();
+    private long removeLBrule(final AutoScaleVmGroupVO asGroup) {
+        final long lbId = asGroup.getLoadBalancerId();
         long instanceId = -1;
-        List<LoadBalancerVMMapVO> LbVmMapVos = _lbVmMapDao.listByLoadBalancerId(lbId);
+        final List<LoadBalancerVMMapVO> LbVmMapVos = _lbVmMapDao.listByLoadBalancerId(lbId);
         if ((LbVmMapVos != null) && (LbVmMapVos.size() > 0)) {
-            for (LoadBalancerVMMapVO LbVmMapVo : LbVmMapVos) {
+            for (final LoadBalancerVMMapVO LbVmMapVo : LbVmMapVos) {
                 instanceId = LbVmMapVo.getInstanceId();
             }
         }
         // take last VM out of the list
-        List<Long> lstVmId = new ArrayList<Long>();
+        final List<Long> lstVmId = new ArrayList<Long>();
         if (instanceId != -1)
             lstVmId.add(instanceId);
         if (_loadBalancingRulesService.removeFromLoadBalancer(lbId, lstVmId))
@@ -1425,8 +1431,8 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
     }
 
     @Override
-    public void doScaleUp(long groupId, Integer numVm) {
-        AutoScaleVmGroupVO asGroup = _autoScaleVmGroupDao.findById(groupId);
+    public void doScaleUp(final long groupId, final Integer numVm) {
+        final AutoScaleVmGroupVO asGroup = _autoScaleVmGroupDao.findById(groupId);
         if (asGroup == null) {
             s_logger.error("Can not find the groupid " + groupId + " for scaling up");
             return;
@@ -1435,7 +1441,7 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
             return;
         }
         for (int i = 0; i < numVm; i++) {
-            long vmId = createNewVM(asGroup);
+            final long vmId = createNewVM(asGroup);
             if (vmId == -1) {
                 s_logger.error("Can not deploy new VM for scaling up in the group "
                     + asGroup.getId() + ". Waiting for next round");
@@ -1444,14 +1450,14 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
             if (startNewVM(vmId)) {
                 if (assignLBruleToNewVm(vmId, asGroup)) {
                     // persist to DB
-                    AutoScaleVmGroupVmMapVO GroupVmVO = new AutoScaleVmGroupVmMapVO(
+                    final AutoScaleVmGroupVmMapVO GroupVmVO = new AutoScaleVmGroupVmMapVO(
                         asGroup.getId(), vmId);
                     _autoScaleVmGroupVmMapDao.persist(GroupVmVO);
                     // update last_quiettime
-                    List<AutoScaleVmGroupPolicyMapVO> GroupPolicyVOs = _autoScaleVmGroupPolicyMapDao
+                    final List<AutoScaleVmGroupPolicyMapVO> GroupPolicyVOs = _autoScaleVmGroupPolicyMapDao
                         .listByVmGroupId(groupId);
-                    for (AutoScaleVmGroupPolicyMapVO GroupPolicyVO : GroupPolicyVOs) {
-                        AutoScalePolicyVO vo = _autoScalePolicyDao
+                    for (final AutoScaleVmGroupPolicyMapVO GroupPolicyVO : GroupPolicyVOs) {
+                        final AutoScalePolicyVO vo = _autoScalePolicyDao
                             .findById(GroupPolicyVO.getPolicyId());
                         if (vo.getAction().equals("scaleup")) {
                             vo.setLastQuiteTime(new Date());
@@ -1473,7 +1479,7 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
 
     @Override
     public void doScaleDown(final long groupId) {
-        AutoScaleVmGroupVO asGroup = _autoScaleVmGroupDao.findById(groupId);
+        final AutoScaleVmGroupVO asGroup = _autoScaleVmGroupDao.findById(groupId);
         if (asGroup == null) {
             s_logger.error("Can not find the groupid " + groupId + " for scaling up");
             return;
@@ -1483,14 +1489,14 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
         }
         final long vmId = removeLBrule(asGroup);
         if (vmId != -1) {
-            long profileId = asGroup.getProfileId();
+            final long profileId = asGroup.getProfileId();
 
             // update group-vm mapping
             _autoScaleVmGroupVmMapDao.remove(groupId, vmId);
             // update last_quiettime
-            List<AutoScaleVmGroupPolicyMapVO> GroupPolicyVOs = _autoScaleVmGroupPolicyMapDao.listByVmGroupId(groupId);
-            for (AutoScaleVmGroupPolicyMapVO GroupPolicyVO : GroupPolicyVOs) {
-                AutoScalePolicyVO vo = _autoScalePolicyDao.findById(GroupPolicyVO.getPolicyId());
+            final List<AutoScaleVmGroupPolicyMapVO> GroupPolicyVOs = _autoScaleVmGroupPolicyMapDao.listByVmGroupId(groupId);
+            for (final AutoScaleVmGroupPolicyMapVO GroupPolicyVO : GroupPolicyVOs) {
+                final AutoScalePolicyVO vo = _autoScalePolicyDao.findById(GroupPolicyVO.getPolicyId());
                 if (vo.getAction().equals("scaledown")) {
                     vo.setLastQuiteTime(new Date());
                     _autoScalePolicyDao.persist(vo);
@@ -1499,8 +1505,8 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
             }
 
             // get destroyvmgrace param
-            AutoScaleVmProfileVO asProfile = _autoScaleVmProfileDao.findById(profileId);
-            Integer destroyVmGracePeriod = asProfile.getDestroyVmGraceperiod();
+            final AutoScaleVmProfileVO asProfile = _autoScaleVmProfileDao.findById(profileId);
+            final Integer destroyVmGracePeriod = asProfile.getDestroyVmGraceperiod();
             if (destroyVmGracePeriod >= 0) {
                 _executor.schedule(new Runnable() {
                     @Override
@@ -1509,9 +1515,9 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
 
                             _userVmManager.destroyVm(vmId);
 
-                        } catch (ResourceUnavailableException e) {
+                        } catch (final ResourceUnavailableException e) {
                             e.printStackTrace();
-                        } catch (ConcurrentOperationException e) {
+                        } catch (final ConcurrentOperationException e) {
                             e.printStackTrace();
                         }
                     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index 8486f06..3c99867 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -105,7 +105,6 @@ import com.cloud.agent.api.to.StaticNatRuleTO;
 import com.cloud.agent.manager.Commands;
 import com.cloud.alert.AlertManager;
 import com.cloud.api.ApiAsyncJobDispatcher;
-import com.cloud.api.ApiDispatcher;
 import com.cloud.api.ApiGsonHelper;
 import com.cloud.cluster.ManagementServerHostVO;
 import com.cloud.cluster.dao.ManagementServerHostDao;
@@ -4195,7 +4194,6 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
         for(DomainRouterVO router: routers){
             if(!checkRouterVersion(router)){
                     s_logger.debug("Upgrading template for router: "+router.getId());
-                    ApiDispatcher.getInstance();
                     Map<String, String> params = new HashMap<String, String>();
                     params.put("ctxUserId", "1");
                     params.put("ctxAccountId", "" + router.getAccountId());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
index a85c052..447697f 100644
--- a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
+++ b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
@@ -82,6 +82,8 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
     protected VolumeDao _volsDao;
     @Inject
     protected ConfigurationDao _configDao;
+    @Inject
+    protected ApiDispatcher _dispatcher;
 
     protected AsyncJobDispatcher _asyncDispatcher;
 
@@ -95,21 +97,21 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
         return _asyncDispatcher;
     }
 
-    public void setAsyncJobDispatcher(AsyncJobDispatcher dispatcher) {
+    public void setAsyncJobDispatcher(final AsyncJobDispatcher dispatcher) {
         _asyncDispatcher = dispatcher;
     }
 
-    private Date getNextScheduledTime(long policyId, Date currentTimestamp) {
-        SnapshotPolicyVO policy = _snapshotPolicyDao.findById(policyId);
+    private Date getNextScheduledTime(final long policyId, final Date currentTimestamp) {
+        final SnapshotPolicyVO policy = _snapshotPolicyDao.findById(policyId);
         Date nextTimestamp = null;
         if (policy != null) {
-            short intervalType = policy.getInterval();
-            IntervalType type = DateUtil.getIntervalType(intervalType);
-            String schedule = policy.getSchedule();
-            String timezone = policy.getTimezone();
+            final short intervalType = policy.getInterval();
+            final IntervalType type = DateUtil.getIntervalType(intervalType);
+            final String schedule = policy.getSchedule();
+            final String timezone = policy.getTimezone();
             nextTimestamp = DateUtil.getNextRunTime(type, schedule, timezone, currentTimestamp);
-            String currentTime = DateUtil.displayDateInTimezone(DateUtil.GMT_TIMEZONE, currentTimestamp);
-            String nextScheduledTime = DateUtil.displayDateInTimezone(DateUtil.GMT_TIMEZONE, nextTimestamp);
+            final String currentTime = DateUtil.displayDateInTimezone(DateUtil.GMT_TIMEZONE, currentTimestamp);
+            final String nextScheduledTime = DateUtil.displayDateInTimezone(DateUtil.GMT_TIMEZONE, nextTimestamp);
             s_logger.debug("Current time is " + currentTime + ". NextScheduledTime of policyId " + policyId + " is " + nextScheduledTime);
         }
         return nextTimestamp;
@@ -119,7 +121,7 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
      * {@inheritDoc}
      */
     @Override
-    public void poll(Date currentTimestamp) {
+    public void poll(final Date currentTimestamp) {
         // We don't maintain the time. The timer task does.
         _currentTimestamp = currentTimestamp;
 
@@ -151,12 +153,12 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
     }
 
     private void checkStatusOfCurrentlyExecutingSnapshots() {
-        SearchCriteria<SnapshotScheduleVO> sc = _snapshotScheduleDao.createSearchCriteria();
+        final SearchCriteria<SnapshotScheduleVO> sc = _snapshotScheduleDao.createSearchCriteria();
         sc.addAnd("asyncJobId", SearchCriteria.Op.NNULL);
-        List<SnapshotScheduleVO> snapshotSchedules = _snapshotScheduleDao.search(sc, null);
-        for (SnapshotScheduleVO snapshotSchedule : snapshotSchedules) {
-            Long asyncJobId = snapshotSchedule.getAsyncJobId();
-            AsyncJobVO asyncJob = _asyncJobDao.findById(asyncJobId);
+        final List<SnapshotScheduleVO> snapshotSchedules = _snapshotScheduleDao.search(sc, null);
+        for (final SnapshotScheduleVO snapshotSchedule : snapshotSchedules) {
+            final Long asyncJobId = snapshotSchedule.getAsyncJobId();
+            final AsyncJobVO asyncJob = _asyncJobDao.findById(asyncJobId);
             switch (asyncJob.getStatus()) {
                 case SUCCEEDED:
                     // The snapshot has been successfully backed up.
@@ -167,7 +169,7 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
                     break;
                 case FAILED:
                     // Check the snapshot status.
-                    Long snapshotId = snapshotSchedule.getSnapshotId();
+                    final Long snapshotId = snapshotSchedule.getSnapshotId();
                     if (snapshotId == null) {
                         // createSnapshotAsync exited, successfully or unsuccessfully,
                         // even before creating a snapshot record
@@ -175,7 +177,7 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
                         // Schedule the next snapshot.
                         scheduleNextSnapshotJob(snapshotSchedule);
                     } else {
-                        SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
+                        final SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
                         if (snapshot == null || snapshot.getRemoved() != null) {
                             // This snapshot has been deleted successfully from the primary storage
                             // Again no cleanup needs to be done.
@@ -219,16 +221,16 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
         String displayTime = DateUtil.displayDateInTimezone(DateUtil.GMT_TIMEZONE, _currentTimestamp);
         s_logger.debug("Snapshot scheduler.poll is being called at " + displayTime);
 
-        List<SnapshotScheduleVO> snapshotsToBeExecuted = _snapshotScheduleDao.getSchedulesToExecute(_currentTimestamp);
+        final List<SnapshotScheduleVO> snapshotsToBeExecuted = _snapshotScheduleDao.getSchedulesToExecute(_currentTimestamp);
         s_logger.debug("Got " + snapshotsToBeExecuted.size() + " snapshots to be executed at " + displayTime);
 
-        for (SnapshotScheduleVO snapshotToBeExecuted : snapshotsToBeExecuted) {
+        for (final SnapshotScheduleVO snapshotToBeExecuted : snapshotsToBeExecuted) {
             SnapshotScheduleVO tmpSnapshotScheduleVO = null;
-            long snapshotScheId = snapshotToBeExecuted.getId();
-            long policyId = snapshotToBeExecuted.getPolicyId();
-            long volumeId = snapshotToBeExecuted.getVolumeId();
+            final long snapshotScheId = snapshotToBeExecuted.getId();
+            final long policyId = snapshotToBeExecuted.getPolicyId();
+            final long volumeId = snapshotToBeExecuted.getVolumeId();
             try {
-                VolumeVO volume = _volsDao.findById(volumeId);
+                final VolumeVO volume = _volsDao.findById(volumeId);
                 if (volume.getPoolId() == null) {
                     // this volume is not attached
                     continue;
@@ -237,26 +239,26 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
                     _snapshotScheduleDao.remove(snapshotToBeExecuted.getId());
                 }
                 if (s_logger.isDebugEnabled()) {
-                    Date scheduledTimestamp = snapshotToBeExecuted.getScheduledTimestamp();
+                    final Date scheduledTimestamp = snapshotToBeExecuted.getScheduledTimestamp();
                     displayTime = DateUtil.displayDateInTimezone(DateUtil.GMT_TIMEZONE, scheduledTimestamp);
                     s_logger.debug("Scheduling 1 snapshot for volume " + volumeId + " for schedule id: " + snapshotToBeExecuted.getId() + " at " + displayTime);
                 }
 
                 tmpSnapshotScheduleVO = _snapshotScheduleDao.acquireInLockTable(snapshotScheId);
-                Long eventId =
+                final Long eventId =
                     ActionEventUtils.onScheduledActionEvent(User.UID_SYSTEM, volume.getAccountId(), EventTypes.EVENT_SNAPSHOT_CREATE, "creating snapshot for volume Id:" +
                         volumeId, true, 0);
 
-                Map<String, String> params = new HashMap<String, String>();
+                final Map<String, String> params = new HashMap<String, String>();
                 params.put(ApiConstants.VOLUME_ID, "" + volumeId);
                 params.put(ApiConstants.POLICY_ID, "" + policyId);
                 params.put("ctxUserId", "1");
                 params.put("ctxAccountId", "" + volume.getAccountId());
                 params.put("ctxStartEventId", String.valueOf(eventId));
 
-                CreateSnapshotCmd cmd = new CreateSnapshotCmd();
+                final CreateSnapshotCmd cmd = new CreateSnapshotCmd();
                 ComponentContext.inject(cmd);
-                ApiDispatcher.getInstance().dispatchCreateCmd(cmd, params);
+                _dispatcher.dispatchCreateCmd(cmd, params);
                 params.put("id", "" + cmd.getEntityId());
                 params.put("ctxStartEventId", "1");
 
@@ -265,11 +267,12 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
                         cmd.getInstanceType() != null ? cmd.getInstanceType().toString() : null);
                 job.setDispatcher(_asyncDispatcher.getName());
 
-                long jobId = _asyncMgr.submitAsyncJob(job);
+                final long jobId = _asyncMgr.submitAsyncJob(job);
 
                 tmpSnapshotScheduleVO.setAsyncJobId(jobId);
                 _snapshotScheduleDao.update(snapshotScheId, tmpSnapshotScheduleVO);
-            } catch (Exception e) {
+            } catch (final Exception e) {
+                // TODO Logging this exception is enough?
                 s_logger.warn("Scheduling snapshot failed due to " + e.toString());
             } finally {
                 if (tmpSnapshotScheduleVO != null) {
@@ -279,16 +282,16 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
         }
     }
 
-    private Date scheduleNextSnapshotJob(SnapshotScheduleVO snapshotSchedule) {
+    private Date scheduleNextSnapshotJob(final SnapshotScheduleVO snapshotSchedule) {
         if (snapshotSchedule == null) {
             return null;
         }
-        Long policyId = snapshotSchedule.getPolicyId();
+        final Long policyId = snapshotSchedule.getPolicyId();
         if (policyId.longValue() == Snapshot.MANUAL_POLICY_ID) {
             // Don't need to schedule the next job for this.
             return null;
         }
-        SnapshotPolicyVO snapshotPolicy = _snapshotPolicyDao.findById(policyId);
+        final SnapshotPolicyVO snapshotPolicy = _snapshotPolicyDao.findById(policyId);
         if (snapshotPolicy == null) {
             _snapshotScheduleDao.expunge(snapshotSchedule.getId());
         }
@@ -297,15 +300,15 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
 
     @Override
     @DB
-    public Date scheduleNextSnapshotJob(SnapshotPolicyVO policy) {
+    public Date scheduleNextSnapshotJob(final SnapshotPolicyVO policy) {
         if (policy == null) {
             return null;
         }
-        long policyId = policy.getId();
+        final long policyId = policy.getId();
         if (policyId == Snapshot.MANUAL_POLICY_ID) {
             return null;
         }
-        Date nextSnapshotTimestamp = getNextScheduledTime(policyId, _currentTimestamp);
+        final Date nextSnapshotTimestamp = getNextScheduledTime(policyId, _currentTimestamp);
         SnapshotScheduleVO spstSchedVO = _snapshotScheduleDao.findOneByVolumePolicy(policy.getVolumeId(), policy.getId());
         if (spstSchedVO == null) {
             spstSchedVO = new SnapshotScheduleVO(policy.getVolumeId(), policyId, nextSnapshotTimestamp);
@@ -329,9 +332,9 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
 
     @Override
     @DB
-    public boolean removeSchedule(Long volumeId, Long policyId) {
+    public boolean removeSchedule(final Long volumeId, final Long policyId) {
         // We can only remove schedules which are in the future. Not which are already executed in the past.
-        SnapshotScheduleVO schedule = _snapshotScheduleDao.getCurrentSchedule(volumeId, policyId, false);
+        final SnapshotScheduleVO schedule = _snapshotScheduleDao.getCurrentSchedule(volumeId, policyId, false);
         boolean success = true;
         if (schedule != null) {
             success = _snapshotScheduleDao.remove(schedule.getId());
@@ -343,18 +346,18 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
     }
 
     @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
 
         _snapshotPollInterval = NumbersUtil.parseInt(_configDao.getValue("snapshot.poll.interval"), 300);
-        boolean snapshotsRecurringTest = Boolean.parseBoolean(_configDao.getValue("snapshot.recurring.test"));
+        final boolean snapshotsRecurringTest = Boolean.parseBoolean(_configDao.getValue("snapshot.recurring.test"));
         if (snapshotsRecurringTest) {
             // look for some test values in the configuration table so that snapshots can be taken more frequently (QA test code)
-            int minutesPerHour = NumbersUtil.parseInt(_configDao.getValue("snapshot.test.minutes.per.hour"), 60);
-            int hoursPerDay = NumbersUtil.parseInt(_configDao.getValue("snapshot.test.hours.per.day"), 24);
-            int daysPerWeek = NumbersUtil.parseInt(_configDao.getValue("snapshot.test.days.per.week"), 7);
-            int daysPerMonth = NumbersUtil.parseInt(_configDao.getValue("snapshot.test.days.per.month"), 30);
-            int weeksPerMonth = NumbersUtil.parseInt(_configDao.getValue("snapshot.test.weeks.per.month"), 4);
-            int monthsPerYear = NumbersUtil.parseInt(_configDao.getValue("snapshot.test.months.per.year"), 12);
+            final int minutesPerHour = NumbersUtil.parseInt(_configDao.getValue("snapshot.test.minutes.per.hour"), 60);
+            final int hoursPerDay = NumbersUtil.parseInt(_configDao.getValue("snapshot.test.hours.per.day"), 24);
+            final int daysPerWeek = NumbersUtil.parseInt(_configDao.getValue("snapshot.test.days.per.week"), 7);
+            final int daysPerMonth = NumbersUtil.parseInt(_configDao.getValue("snapshot.test.days.per.month"), 30);
+            final int weeksPerMonth = NumbersUtil.parseInt(_configDao.getValue("snapshot.test.weeks.per.month"), 4);
+            final int monthsPerYear = NumbersUtil.parseInt(_configDao.getValue("snapshot.test.months.per.year"), 12);
 
             _testTimerTask = new TestClock(this, minutesPerHour, hoursPerDay, daysPerWeek, daysPerMonth, weeksPerMonth, monthsPerYear);
         }
@@ -369,8 +372,8 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
     @DB
     public boolean start() {
         // reschedule all policies after management restart
-        List<SnapshotPolicyVO> policyInstances = _snapshotPolicyDao.listAll();
-        for (SnapshotPolicyVO policyInstance : policyInstances) {
+        final List<SnapshotPolicyVO> policyInstances = _snapshotPolicyDao.listAll();
+        for (final SnapshotPolicyVO policyInstance : policyInstances) {
             if (policyInstance.getId() != Snapshot.MANUAL_POLICY_ID) {
                 scheduleNextSnapshotJob(policyInstance);
             }
@@ -381,13 +384,13 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
             // Else it becomes too confusing.
             _testClockTimer.schedule(_testTimerTask, 100 * 1000L, 60 * 1000L);
         } else {
-            TimerTask timerTask = new ManagedContextTimerTask() {
+            final TimerTask timerTask = new ManagedContextTimerTask() {
                 @Override
                 protected void runInContext() {
                     try {
-                        Date currentTimestamp = new Date();
+                        final Date currentTimestamp = new Date();
                         poll(currentTimestamp);
-                    } catch (Throwable t) {
+                    } catch (final Throwable t) {
                         s_logger.warn("Catch throwable in snapshot scheduler ", t);
                     }
                 }


[47/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
some bug fixes


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c00a3b7d
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c00a3b7d
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c00a3b7d

Branch: refs/heads/distributedrouter
Commit: c00a3b7d08d8635d2a61f78d67150f83ce0e8f70
Parents: 92c9d3b
Author: Murali Reddy <mu...@gmail.com>
Authored: Mon Mar 10 22:16:46 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Tue Mar 11 18:38:46 2014 +0530

----------------------------------------------------------------------
 .../xen/resource/CitrixResourceBase.java        |  14 ++-
 .../api/OvsVpcLogicalTopologyConfigCommand.java |  33 +++++
 .../OvsVpcPhysicalTopologyConfigCommand.java    |   7 +-
 .../com/cloud/network/element/OvsElement.java   |  18 ---
 .../cloud/network/guru/OvsGuestNetworkGuru.java |   2 +-
 .../network/ovs/OvsNetworkTopologyGuru.java     |  10 ++
 .../network/ovs/OvsNetworkTopologyGuruImpl.java | 126 ++++++++++++++++++-
 .../cloud/network/ovs/OvsTunnelManagerImpl.java | 125 ++++++++++++------
 .../xenserver/cloudstack_pluginlib.py           |   4 +-
 scripts/vm/hypervisor/xenserver/ovstunnel       |  14 +--
 .../network/guru/ExternalGuestNetworkGuru.java  |   4 +
 11 files changed, 279 insertions(+), 78 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c00a3b7d/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
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 8585996..2315b31 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
@@ -998,7 +998,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
     /**
      * This method creates a XenServer network and configures it for being used as a L2-in-L3 tunneled network
      */
-    private synchronized Network configureTunnelNetwork(Connection conn, long networkId, long hostId, String bridgeName) {
+    private synchronized Network configureTunnelNetwork(Connection conn, Long networkId, long hostId, String bridgeName) {
         try {
             Network nw = findOrCreateTunnelNetwork(conn, bridgeName);
             String nwName = bridgeName;
@@ -1037,7 +1037,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
                 String[] res = result.split(":");
                 if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) {
                     //TODO: Should make this error not fatal?
-                    throw new CloudRuntimeException("Unable to pre-configure OVS bridge " + bridge + " for network ID:" + networkId + " - " + res);
+                    throw new CloudRuntimeException("Unable to pre-configure OVS bridge " + bridge );
                 }
             }
             return nw;
@@ -1089,7 +1089,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
                 _isOvs = true;
                 return setupvSwitchNetwork(conn);
             } else {
-                return findOrCreateTunnelNetwork(conn, getOvsTunnelNetworkName(BroadcastDomainType.getValue(uri)));
+                return findOrCreateTunnelNetwork(conn, getOvsTunnelNetworkName(uri.getAuthority()));
             }
         } else if (type == BroadcastDomainType.Storage) {
             if (uri == null) {
@@ -1113,7 +1113,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
 
     private String getOvsTunnelNetworkName(String broadcastUri) {
         if (broadcastUri.contains(".")) {
-            String[] parts = broadcastUri.split(".");
+            String[] parts = broadcastUri.split("\\.");
             return "OVS-DR-VPC-Bridge"+parts[0];
          } else {
             try {
@@ -5265,7 +5265,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             }
 
             String bridge = nw.getBridge(conn);
-            String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge", bridge, "in_port", cmd.getInPortName());
+            String result = callHostPlugin(conn, "ovstunnel", "destroy_tunnel", "bridge", bridge, "in_port", cmd.getInPortName());
+
             if (result.equalsIgnoreCase("SUCCESS")) {
                 return new Answer(cmd, true, result);
             } else {
@@ -5281,7 +5282,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         Connection conn = getConnection();
         try {
             String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge",
-                    cmd.getBridgeName(), "host-id", ((Long)cmd.getHostId()).toString());
+                    cmd.getBridgeName(), "host-id", ((Long)cmd.getHostId()).toString(), "config",
+                    cmd.getjsonVpcConfig());
             if (result.equalsIgnoreCase("SUCCESS")) {
                 return new Answer(cmd, true, result);
             } else {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c00a3b7d/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java
new file mode 100644
index 0000000..2fafb6e
--- /dev/null
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java
@@ -0,0 +1,33 @@
+// 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.api;
+
+/**
+ * This command represents view of how a VPC is laid out (on which hosts, which VM is on which host etc)
+ * on the physical infrastructure.
+ */
+public class OvsVpcLogicalTopologyConfigCommand extends Command {
+
+    public OvsVpcLogicalTopologyConfigCommand() {
+
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        return false;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c00a3b7d/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
index 35d4c6e..e6f4383 100644
--- a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
@@ -20,8 +20,11 @@ import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
 /**
- * This command represents view of how a VPC is laid out (on which hosts, which VM is on which host etc)
- * on the physical infrastructure.
+ * This command represents physical view of how a VPC is laid out on the physical infrastructure.
+ *   - on which hypervisor hosts VPC spans (host is running in at least one VM from the VPC)
+ *   - information of tiers, so we can figure how one VM can talk to a different VM in same tier or different tier
+ *   - information on all the VM's in the VPC.
+ *   - information of NIC's of each VM in the VPC
  */
 public class OvsVpcPhysicalTopologyConfigCommand extends Command {
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c00a3b7d/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
index c28d908..036c319 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
@@ -75,7 +75,6 @@ import com.cloud.vm.NicProfile;
 import com.cloud.vm.ReservationContext;
 import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.UserVmVO;
 import com.cloud.vm.VirtualMachine;
 
 @Local(value = {NetworkElement.class, ConnectivityProvider.class,
@@ -205,23 +204,6 @@ StaticNatServiceProvider, IpDeployer {
             return false;
         }
 
-        List<UserVmVO> userVms = _userVmDao.listByAccountIdAndHostId(vm.getVirtualMachine().getAccountId(),
-                vm.getVirtualMachine().getHostId());
-        if (vm.getType() == VirtualMachine.Type.User) {
-            if (userVms.size() > 1) {
-                return true;
-            }
-
-            List<DomainRouterVO> routers = _routerDao.findByNetwork(network.getId());
-            for (DomainRouterVO router : routers) {
-                if (router.getHostId().equals(vm.getVirtualMachine().getHostId())) {
-                    return true;
-                }
-            }
-        } else if (vm.getType() == VirtualMachine.Type.DomainRouter && userVms.size() != 0) {
-            return true;
-        }
-
         HostVO host = _hostDao.findById(vm.getVirtualMachine().getHostId());
         _ovsTunnelMgr.checkAndRemoveHostFromTunnelNetwork(network, host);
         return true;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c00a3b7d/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
index 2814c2a..9d2efe6 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
@@ -154,7 +154,7 @@ public class OvsGuestNetworkGuru extends GuestNetworkGuru {
         if (network.getVpcId() != null && isVpcEnabledForDistributedRouter(network.getVpcId())) {
             String keyStr = BroadcastDomainType.getValue(implemented.getBroadcastUri());
             Long vpcid= network.getVpcId();
-            implemented.setBroadcastUri(BroadcastDomainType.Vswitch.toUri(vpcid.toString()+keyStr));
+            implemented.setBroadcastUri(BroadcastDomainType.Vswitch.toUri(vpcid.toString() + "." + keyStr));
         }
 
         return implemented;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c00a3b7d/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
index c410d10..122175c 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
@@ -38,6 +38,11 @@ public interface OvsNetworkTopologyGuru extends Manager {
     public  List<Long> getVpcOnHost(long hostId);
 
     /**
+     * get the list of all active Vm id's in a network
+     */
+    public List<Long> getAllActiveVmsInNetwork(long networkId);
+
+    /**
      * get the list of all active Vm id's in the VPC for all ther tiers
      */
     public List<Long> getAllActiveVmsInVpc(long vpcId);
@@ -46,4 +51,9 @@ public interface OvsNetworkTopologyGuru extends Manager {
      * get the list of all Vm id's in the VPC for all the tiers that are running on the host
      */
     public List<Long> getActiveVmsInVpcOnHost(long vpcId, long hostId);
+
+    /**
+     * get the list of all Vm id's in the network that are running on the host
+     */
+    public List<Long> getActiveVmsInNetworkOnHost(long vpcId, long hostId);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c00a3b7d/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
index 7560e35..7715641 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
@@ -1,14 +1,24 @@
 package com.cloud.network.ovs;
 
+import com.cloud.network.Network;
+import com.cloud.network.Networks;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.vpc.VpcManager;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.vm.DomainRouterVO;
 import com.cloud.vm.UserVmVO;
 import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.Nic;
 import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.NicDao;
 import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import javax.ejb.Local;
 import javax.inject.Inject;
 import org.springframework.stereotype.Component;
@@ -21,6 +31,14 @@ public class OvsNetworkTopologyGuruImpl extends ManagerBase implements OvsNetwor
     UserVmDao _userVmDao;
     @Inject
     DomainRouterDao _routerDao;
+    @Inject
+    VpcManager _vpcMgr;
+    @Inject
+    VMInstanceDao _vmInstanceDao;
+    @Inject
+    NicDao _nicDao;
+    @Inject
+    NetworkDao _networkDao;
 
     /**
      * get the list of hypervisor hosts on which VM's belonging to a network currently spans
@@ -52,23 +70,121 @@ public class OvsNetworkTopologyGuruImpl extends ManagerBase implements OvsNetwor
         return  hostIds;
     }
 
+    /**
+     * get the list of hypervisor hosts on which VM's belonging to a VPC currently spans
+     */
     @Override
-    public List<Long> getVpcSpannedHosts(long vpId) {
-        return null;
+    public List<Long> getVpcSpannedHosts(long vpcId) {
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        List<Long> vpcHostIds = new ArrayList<>();
+        for (Network vpcNetwork : vpcNetworks) {
+            List<Long> networkHostIds = new ArrayList<Long>();
+            networkHostIds = getNetworkSpanedHosts(vpcNetwork.getId());
+            if (networkHostIds != null && !networkHostIds.isEmpty()) {
+                for (Long hostId : networkHostIds) {
+                    if (!vpcHostIds.contains(hostId)) {
+                        vpcHostIds.add(hostId);
+                    }
+                }
+            }
+        }
+        return vpcHostIds;
     }
 
     @Override
     public List<Long> getVpcOnHost(long hostId) {
-        return null;
+        List<Long> vpcIds = new ArrayList<>();
+        List<VMInstanceVO> vmInstances = _vmInstanceDao.listByHostId(hostId);
+        for (VMInstanceVO instance : vmInstances) {
+            List<NicVO> nics = _nicDao.listByVmId(instance.getId());
+            for (Nic nic: nics) {
+                Network network = _networkDao.findById(nic.getNetworkId());
+                if (network.getTrafficType() == Networks.TrafficType.Guest && network.getVpcId() != null) {
+                    if (!vpcIds.contains(network.getVpcId())) {
+                        vpcIds.add(network.getVpcId());
+                    }
+                }
+            }
+        }
+        return vpcIds;
+    }
+
+    @Override
+    public List<Long> getAllActiveVmsInNetwork(long networkId) {
+        List <Long> vmIds = new ArrayList<>();
+        List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(networkId,
+                VirtualMachine.State.Running, VirtualMachine.State.Starting, VirtualMachine.State.Stopping, VirtualMachine.State.Unknown,
+                VirtualMachine.State.Migrating);
+        // Find routers for the network
+        List<DomainRouterVO> routers = _routerDao.findByNetwork(networkId);
+        List<VMInstanceVO> ins = new ArrayList<VMInstanceVO>();
+
+        if (vms != null) {
+            for (UserVmVO vm : vms) {
+                vmIds.add(vm.getId());
+            }
+        }
+        if (routers.size() != 0) {
+            for (DomainRouterVO router: routers) {
+                vmIds.add(router.getId());
+            }
+        }
+        return  vmIds;
     }
 
     @Override
     public List<Long> getAllActiveVmsInVpc(long vpcId) {
-        return null;
+
+        Set<Long> vmIdsSet = new HashSet<>();
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        for (Network network : vpcNetworks) {
+            List<Long> networkVmIds = getAllActiveVmsInNetwork(network.getId());
+            if (networkVmIds  != null && !networkVmIds.isEmpty()) {
+                vmIdsSet.addAll(networkVmIds);
+            }
+        }
+        List<Long> vmIds = new ArrayList<>();
+        vmIds.addAll(vmIdsSet);
+        return vmIds;
     }
 
     @Override
     public List<Long> getActiveVmsInVpcOnHost(long vpcId, long hostId) {
-        return null;
+        Set<Long> vmIdsSet = new HashSet<>();
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        for (Network network : vpcNetworks) {
+            List<Long> networkVmIds = getActiveVmsInNetworkOnHost(network.getId(), hostId);
+            if (networkVmIds  != null && !networkVmIds.isEmpty()) {
+                vmIdsSet.addAll(networkVmIds);
+            }
+        }
+        List<Long> vmIds = new ArrayList<>();
+        vmIds.addAll(vmIdsSet);
+        return vmIds;
+    }
+
+    @Override
+    public List<Long> getActiveVmsInNetworkOnHost(long networkId, long hostId) {
+        List <Long> vmIds = new ArrayList<>();
+        List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(networkId,
+                VirtualMachine.State.Running, VirtualMachine.State.Starting, VirtualMachine.State.Stopping, VirtualMachine.State.Unknown,
+                VirtualMachine.State.Migrating);
+        // Find routers for the network
+        List<DomainRouterVO> routers = _routerDao.findByNetwork(networkId);
+        List<VMInstanceVO> ins = new ArrayList<VMInstanceVO>();
+
+        if (vms != null) {
+            for (UserVmVO vm : vms) {
+                if (vm.getHostId() == hostId)
+                    vmIds.add(vm.getId());
+            }
+        }
+        if (routers.size() != 0) {
+            for (DomainRouterVO router: routers) {
+                if (router.getHostId() == hostId)
+                    vmIds.add(router.getId());
+            }
+        }
+        return  vmIds;
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c00a3b7d/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
index ae37095..82dbfed 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
@@ -18,10 +18,10 @@ package com.cloud.network.ovs;
 
 import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.vpc.VpcManager;
+import com.cloud.vm.dao.VMInstanceDao;
 import com.cloud.vm.Nic;
 import com.cloud.vm.NicVO;
 import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.dao.VMInstanceDao;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -260,9 +260,9 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         int key = 0;
         try {
             //The GRE key is actually in the host part of the URI
-            String keyStr = BroadcastDomainType.getValue(network.getBroadcastUri());
+            String keyStr = network.getBroadcastUri().getAuthority();
             if (keyStr.contains(".")) {
-                String[] parts = keyStr.split(".");
+                String[] parts = keyStr.split("\\.");
                 key = Integer.parseInt(parts[1]);
             } else {
                 key = Integer.parseInt(keyStr);
@@ -445,34 +445,72 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
     @Override
     public void checkAndRemoveHostFromTunnelNetwork(Network nw, Host host) {
 
-        try {
-            /* Now we are last one on host, destroy the bridge with all
-             * the tunnels for this network  */
-            int key = getGreKey(nw);
-            String bridgeName = generateBridgeName(nw, key);
-            Command cmd = new OvsDestroyBridgeCommand(nw.getId(), bridgeName);
-            s_logger.debug("Destroying bridge for network " + nw.getId() + " on host:" + host.getId());
-            Answer ans = _agentMgr.send(host.getId(), cmd);
-            handleDestroyBridgeAnswer(ans, host.getId(), nw.getId());
-
-            /* Then ask hosts have peer tunnel with me to destroy them */
-            List<OvsTunnelNetworkVO> peers =
-                    _tunnelNetworkDao.listByToNetwork(host.getId(),
-                            nw.getId());
-            for (OvsTunnelNetworkVO p : peers) {
-                // If the tunnel was not successfully created don't bother to remove it
-                if (p.getState().equals(OvsTunnel.State.Established.name())) {
-                    cmd = new OvsDestroyTunnelCommand(p.getNetworkId(), bridgeName,
-                            p.getPortName());
-                    s_logger.debug("Destroying tunnel to " + host.getId() +
-                            " from " + p.getFrom());
-                    ans = _agentMgr.send(p.getFrom(), cmd);
-                    handleDestroyTunnelAnswer(ans, p.getFrom(),
-                            p.getTo(), p.getNetworkId());
+        if (nw.getVpcId() != null && isVpcEnabledForDistributedRouter(nw.getVpcId())) {
+            List<Long> vmIds = _ovsNetworkToplogyGuru.getActiveVmsInVpcOnHost(nw.getVpcId(), host.getId());
+            if (vmIds != null && !vmIds.isEmpty()) {
+                return;
+            }
+            List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(nw.getVpcId());
+            try {
+                for (Network network: vpcNetworks) {
+                    int key = getGreKey(nw);
+                    String bridgeName = generateBridgeName(nw, key);
+                    /* Then ask hosts have peer tunnel with me to destroy them */
+                    List<OvsTunnelNetworkVO> peers = _tunnelNetworkDao.listByToNetwork(host.getId(),nw.getId());
+                    for (OvsTunnelNetworkVO p : peers) {
+                        // If the tunnel was not successfully created don't bother to remove it
+                        if (p.getState().equals(OvsTunnel.State.Established.name())) {
+                            Command cmd= new OvsDestroyTunnelCommand(p.getNetworkId(), bridgeName,
+                                    p.getPortName());
+                            s_logger.debug("Destroying tunnel to " + host.getId() +
+                                    " from " + p.getFrom());
+                            Answer ans = _agentMgr.send(p.getFrom(), cmd);
+                            handleDestroyTunnelAnswer(ans, p.getFrom(), p.getTo(), p.getNetworkId());
+                        }
+                    }
                 }
+
+                Command cmd = new OvsDestroyBridgeCommand(nw.getId(), generateBridgeNameForVpc(nw.getVpcId()));
+                s_logger.debug("Destroying bridge for network " + nw.getId() + " on host:" + host.getId());
+                Answer ans = _agentMgr.send(host.getId(), cmd);
+                handleDestroyBridgeAnswer(ans, host.getId(), nw.getId());
+            } catch (Exception e) {
+
+            }
+        } else {
+            List<Long> vmIds = _ovsNetworkToplogyGuru.getActiveVmsInNetworkOnHost(nw.getId(), host.getId());
+            if (vmIds != null && !vmIds.isEmpty()) {
+                return;
+            }
+            try {
+                /* Now we are last one on host, destroy the bridge with all
+                * the tunnels for this network  */
+                int key = getGreKey(nw);
+                String bridgeName = generateBridgeName(nw, key);
+                Command cmd = new OvsDestroyBridgeCommand(nw.getId(), bridgeName);
+                s_logger.debug("Destroying bridge for network " + nw.getId() + " on host:" + host.getId());
+                Answer ans = _agentMgr.send(host.getId(), cmd);
+                handleDestroyBridgeAnswer(ans, host.getId(), nw.getId());
+
+                /* Then ask hosts have peer tunnel with me to destroy them */
+                List<OvsTunnelNetworkVO> peers =
+                        _tunnelNetworkDao.listByToNetwork(host.getId(),
+                                nw.getId());
+                for (OvsTunnelNetworkVO p : peers) {
+                    // If the tunnel was not successfully created don't bother to remove it
+                    if (p.getState().equals(OvsTunnel.State.Established.name())) {
+                        cmd = new OvsDestroyTunnelCommand(p.getNetworkId(), bridgeName,
+                                p.getPortName());
+                        s_logger.debug("Destroying tunnel to " + host.getId() +
+                                " from " + p.getFrom());
+                        ans = _agentMgr.send(p.getFrom(), cmd);
+                        handleDestroyTunnelAnswer(ans, p.getFrom(),
+                                p.getTo(), p.getNetworkId());
+                    }
+                }
+            } catch (Exception e) {
+                s_logger.warn(String.format("Destroy tunnel failed", e));
             }
-        } catch (Exception e) {
-            s_logger.warn(String.format("Destroy tunnel failed", e));
         }
     }
 
@@ -514,9 +552,9 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         List<Long> hostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
         List<Long> vmIds = _ovsNetworkToplogyGuru.getAllActiveVmsInVpc(vpcId);
 
-        List<OvsVpcPhysicalTopologyConfigCommand.Host> hosts = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Host>();
-        List<OvsVpcPhysicalTopologyConfigCommand.Tier> tiers = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Tier>();
-        List<OvsVpcPhysicalTopologyConfigCommand.Vm> vms = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Vm>();
+        List<OvsVpcPhysicalTopologyConfigCommand.Host> hosts = new ArrayList<>();
+        List<OvsVpcPhysicalTopologyConfigCommand.Tier> tiers = new ArrayList<>();
+        List<OvsVpcPhysicalTopologyConfigCommand.Vm> vms = new ArrayList<>();
 
         for (Long hostId : hostIds) {
             HostVO hostDetails = _hostDao.findById(hostId);
@@ -533,10 +571,10 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         }
 
         for (Network network: vpcNetworks) {
-            String key = BroadcastDomainType.getValue(network.getBroadcastUri());
+            String key = network.getBroadcastUri().getAuthority();
             long gre_key;
             if (key.contains(".")) {
-                String[] parts = key.split(".");
+                String[] parts = key.split("\\.");
                 gre_key = Long.parseLong(parts[1]);
             } else {
                 try {
@@ -580,6 +618,7 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
         List<Long> vpcSpannedHostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
         String bridgeName=generateBridgeNameForVpc(vpcId);
+        boolean bridgeNotSetup = true;
 
         for (Network vpcNetwork: vpcNetworks) {
             int key = getGreKey(vpcNetwork);
@@ -643,7 +682,7 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
                             + " to create gre tunnel to " + i);
                     Answer[] answers = _agentMgr.send(hostId, cmds);
                     handleCreateTunnelAnswer(answers);
-                    noHost = false;
+                    bridgeNotSetup = false;
                 }
 
                 for (Long i : fromHostIds) {
@@ -656,7 +695,7 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
                             + hostId);
                     Answer[] answers = _agentMgr.send(i, cmds);
                     handleCreateTunnelAnswer(answers);
-                    noHost = false;
+                    bridgeNotSetup = false;
                 }
             } catch (GreTunnelException | OperationTimedoutException | AgentUnavailableException e) {
                 // I really thing we should do a better handling of these exceptions
@@ -664,6 +703,20 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
             }
         }
 
+        // If no tunnels have been configured, perform the bridge setup
+        // anyway. This will ensure VIF rules will be triggered
+        if (bridgeNotSetup) {
+            try {
+                Commands cmds = new Commands(new OvsSetupBridgeCommand(bridgeName, hostId, null));
+                s_logger.debug("Ask host " + hostId + " to configure bridge for vpc");
+                Answer[] answers = _agentMgr.send(hostId, cmds);
+                handleSetupBridgeAnswer(answers);
+            } catch (OperationTimedoutException | AgentUnavailableException e) {
+                // I really thing we should do a better handling of these exceptions
+                s_logger.warn("Ovs Tunnel network created tunnel failed", e);
+            }
+        }
+
         OvsVpcPhysicalTopologyConfigCommand topologyConfigCommand = prepareVpcTopologyUpdate(vpcId);
         for (Long id: vpcSpannedHostIds) {
             if (!sendVpcTopologyChangeUpdate(topologyConfigCommand, id, bridgeName)) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c00a3b7d/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
index d2b95dc..dbcc288 100644
--- a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
+++ b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
@@ -21,7 +21,7 @@ import ConfigParser
 import logging
 import os
 import subprocess
-import json
+import simplejson as json
 
 from time import localtime, asctime
 
@@ -181,7 +181,7 @@ def _build_flow_expr(**kwargs):
     proto = 'proto' in kwargs and ",%s" % kwargs['proto'] or ''
     ip = ('nw_src' in kwargs or 'nw_dst' in kwargs) and ',ip' or ''
     flow = (flow + in_port + dl_type + dl_src + dl_dst +
-            (ip or proto) + nw_src + nw_dst)
+            (ip or proto) + nw_src + nw_dst + table)
     return flow
 
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c00a3b7d/scripts/vm/hypervisor/xenserver/ovstunnel
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/ovstunnel b/scripts/vm/hypervisor/xenserver/ovstunnel
index 64a2d36..9ef0f7b 100755
--- a/scripts/vm/hypervisor/xenserver/ovstunnel
+++ b/scripts/vm/hypervisor/xenserver/ovstunnel
@@ -137,8 +137,8 @@ def setup_ovs_bridge_for_distributed_routing(session, args):
 
     logging.debug("About to manually create the bridge:%s" % bridge)
     # create a bridge with the same name as the xapi network
-    res = lib.do_cmd([lib.VSCTL_PATH, "--", "--may-exist", "add-br", bridge,
-                                     "--", "set", "bridge", bridge])
+    res = lib.do_cmd([lib.VSCTL_PATH, "--", "--may-exist", "add-br", bridge])
+
     logging.debug("Bridge has been manually created:%s" % res)
     # TODO: Make sure xs-network-uuid is set into external_ids
     lib.do_cmd([lib.VSCTL_PATH, "set", "Bridge", bridge,
@@ -149,12 +149,8 @@ def setup_ovs_bridge_for_distributed_routing(session, args):
         result = "FAILURE:%s" % res
     else:
         # Verify the bridge actually exists, with the gre_key properly set
-        res = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge",
-                                          bridge, "other_config:gre_key"])
-        if key in res:
-            result = "SUCCESS:%s" % bridge
-        else:
-            result = "FAILURE:%s" % res
+        res = lib.do_cmd([lib.VSCTL_PATH, "list", "bridge", bridge])
+
         # Finally note in the xenapi network object that the network has
         # been configured
         xs_nw_uuid = lib.do_cmd([lib.XE_PATH, "network-list",
@@ -191,6 +187,8 @@ def setup_ovs_bridge_for_distributed_routing(session, args):
         # add a default rule in egress table to forward packet to L3 lookup table
         lib.add_flow(bridge, priority=0, table=5, actions='drop')
 
+        result = "SUCCESS: successfully setup bridge with flow rules"
+
     logging.debug("Setup_ovs_bridge completed with result:%s" % result)
     return result
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c00a3b7d/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
index 414eb7b..13246a7 100644
--- a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
+++ b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
@@ -107,6 +107,10 @@ public class ExternalGuestNetworkGuru extends GuestNetworkGuru {
     @Override
     public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
 
+        if (_networkModel.areServicesSupportedByNetworkOffering(offering.getId(), Network.Service.Connectivity)) {
+            return null;
+        }
+
         NetworkVO config = (NetworkVO)super.design(offering, plan, userSpecified, owner);
         if (config == null) {
             return null;


[34/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
CLOUDSTACK-6220: Take 2, Fix cloudstack init scripts so that they
    don't use fully qualified path as script name. Fix for
    commit 9dd57c22b02afcddb1d6c8ddc3e1b578961454e3


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/a4d3ec47
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/a4d3ec47
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/a4d3ec47

Branch: refs/heads/distributedrouter
Commit: a4d3ec476fce815ef32e8273c7311850b5617f06
Parents: d033ca4
Author: Marcus Sorensen <ma...@betterservers.com>
Authored: Mon Mar 10 16:11:04 2014 -0600
Committer: Marcus Sorensen <ma...@betterservers.com>
Committed: Mon Mar 10 16:11:52 2014 -0600

----------------------------------------------------------------------
 agent/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-agent.in          | 2 +-
 agent/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-agent.in          | 2 +-
 agent/distro/opensuse/sles/SYSCONFDIR/init.d/cloud-agent.in        | 2 +-
 agent/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-agent.in            | 2 +-
 agent/distro/sles/SYSCONFDIR/init.d/cloud-agent.in                 | 2 +-
 packaging/centos63/cloud-agent.rc                                  | 2 +-
 packaging/centos63/cloud-ipallocator.rc                            | 2 +-
 python/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in   | 2 +-
 python/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in   | 2 +-
 python/distro/opensuse/SYSCONFDIR/init.d/cloud-ipallocator.in      | 2 +-
 python/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in     | 2 +-
 python/distro/sles/SYSCONFDIR/init.d/cloud-ipallocator.in          | 2 +-
 python/distro/ubuntu/SYSCONFDIR/init.d/cloud-ipallocator.in        | 2 +-
 .../distro/centos/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in    | 2 +-
 .../distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in    | 2 +-
 systemvm/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in | 2 +-
 systemvm/distro/ubuntu/SYSCONFDIR/init.d/cloud-console-proxy.in    | 2 +-
 17 files changed, 17 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a4d3ec47/agent/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-agent.in
----------------------------------------------------------------------
diff --git a/agent/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-agent.in b/agent/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-agent.in
index 704ef6b..d1769cc 100755
--- a/agent/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-agent.in
+++ b/agent/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-agent.in
@@ -26,7 +26,7 @@
 
 # set environment variables
 
-SHORTNAME="basename $0"
+SHORTNAME=`basename $0`
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a4d3ec47/agent/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-agent.in
----------------------------------------------------------------------
diff --git a/agent/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-agent.in b/agent/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-agent.in
index 704ef6b..d1769cc 100755
--- a/agent/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-agent.in
+++ b/agent/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-agent.in
@@ -26,7 +26,7 @@
 
 # set environment variables
 
-SHORTNAME="basename $0"
+SHORTNAME=`basename $0`
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a4d3ec47/agent/distro/opensuse/sles/SYSCONFDIR/init.d/cloud-agent.in
----------------------------------------------------------------------
diff --git a/agent/distro/opensuse/sles/SYSCONFDIR/init.d/cloud-agent.in b/agent/distro/opensuse/sles/SYSCONFDIR/init.d/cloud-agent.in
index e684888..741317b 100644
--- a/agent/distro/opensuse/sles/SYSCONFDIR/init.d/cloud-agent.in
+++ b/agent/distro/opensuse/sles/SYSCONFDIR/init.d/cloud-agent.in
@@ -33,7 +33,7 @@
 
 # set environment variables
 
-SHORTNAME="basename $0"
+SHORTNAME=`basename $0`
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a4d3ec47/agent/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-agent.in
----------------------------------------------------------------------
diff --git a/agent/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-agent.in b/agent/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-agent.in
index 704ef6b..d1769cc 100644
--- a/agent/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-agent.in
+++ b/agent/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-agent.in
@@ -26,7 +26,7 @@
 
 # set environment variables
 
-SHORTNAME="basename $0"
+SHORTNAME=`basename $0`
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a4d3ec47/agent/distro/sles/SYSCONFDIR/init.d/cloud-agent.in
----------------------------------------------------------------------
diff --git a/agent/distro/sles/SYSCONFDIR/init.d/cloud-agent.in b/agent/distro/sles/SYSCONFDIR/init.d/cloud-agent.in
index e684888..741317b 100644
--- a/agent/distro/sles/SYSCONFDIR/init.d/cloud-agent.in
+++ b/agent/distro/sles/SYSCONFDIR/init.d/cloud-agent.in
@@ -33,7 +33,7 @@
 
 # set environment variables
 
-SHORTNAME="basename $0"
+SHORTNAME=`basename $0`
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a4d3ec47/packaging/centos63/cloud-agent.rc
----------------------------------------------------------------------
diff --git a/packaging/centos63/cloud-agent.rc b/packaging/centos63/cloud-agent.rc
index af1c624..ece4c27 100755
--- a/packaging/centos63/cloud-agent.rc
+++ b/packaging/centos63/cloud-agent.rc
@@ -26,7 +26,7 @@
 
 # set environment variables
 
-SHORTNAME="basename $0"
+SHORTNAME=`basename $0`
 PIDFILE=/var/run/"$SHORTNAME".pid
 LOCKFILE=/var/lock/subsys/"$SHORTNAME"
 LOGDIR=/var/log/cloudstack/agent

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a4d3ec47/packaging/centos63/cloud-ipallocator.rc
----------------------------------------------------------------------
diff --git a/packaging/centos63/cloud-ipallocator.rc b/packaging/centos63/cloud-ipallocator.rc
index 9d1adb4..d26287d 100755
--- a/packaging/centos63/cloud-ipallocator.rc
+++ b/packaging/centos63/cloud-ipallocator.rc
@@ -25,7 +25,7 @@
 
 # set environment variables
 
-SHORTNAME="basename $0"
+SHORTNAME=`basename $0`
 PIDFILE=/var/run/"$SHORTNAME".pid
 LOCKFILE=/var/lock/subsys/"$SHORTNAME"
 LOGFILE=/var/log/cloudstack/ipallocator/ipallocator.log

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a4d3ec47/python/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
----------------------------------------------------------------------
diff --git a/python/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in b/python/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
index ae8d215..3921484 100755
--- a/python/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
+++ b/python/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
@@ -25,7 +25,7 @@
 
 # set environment variables
 
-SHORTNAME="basename $0"
+SHORTNAME=`basename $0`
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@IPALOCATORLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a4d3ec47/python/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
----------------------------------------------------------------------
diff --git a/python/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in b/python/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
index 49fd9b6..23ec8f3 100755
--- a/python/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
+++ b/python/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
@@ -25,7 +25,7 @@
 
 # set environment variables
 
-SHORTNAME="basename $0"
+SHORTNAME=`basename $0`
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a4d3ec47/python/distro/opensuse/SYSCONFDIR/init.d/cloud-ipallocator.in
----------------------------------------------------------------------
diff --git a/python/distro/opensuse/SYSCONFDIR/init.d/cloud-ipallocator.in b/python/distro/opensuse/SYSCONFDIR/init.d/cloud-ipallocator.in
index 901d5845..558f5a2 100755
--- a/python/distro/opensuse/SYSCONFDIR/init.d/cloud-ipallocator.in
+++ b/python/distro/opensuse/SYSCONFDIR/init.d/cloud-ipallocator.in
@@ -32,7 +32,7 @@
 
 # set environment variables
 
-SHORTNAME="basename $0"
+SHORTNAME=`basename $0`
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a4d3ec47/python/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
----------------------------------------------------------------------
diff --git a/python/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in b/python/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
index 49fd9b6..23ec8f3 100644
--- a/python/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
+++ b/python/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in
@@ -25,7 +25,7 @@
 
 # set environment variables
 
-SHORTNAME="basename $0"
+SHORTNAME=`basename $0`
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a4d3ec47/python/distro/sles/SYSCONFDIR/init.d/cloud-ipallocator.in
----------------------------------------------------------------------
diff --git a/python/distro/sles/SYSCONFDIR/init.d/cloud-ipallocator.in b/python/distro/sles/SYSCONFDIR/init.d/cloud-ipallocator.in
index 901d5845..558f5a2 100755
--- a/python/distro/sles/SYSCONFDIR/init.d/cloud-ipallocator.in
+++ b/python/distro/sles/SYSCONFDIR/init.d/cloud-ipallocator.in
@@ -32,7 +32,7 @@
 
 # set environment variables
 
-SHORTNAME="basename $0"
+SHORTNAME=`basename $0`
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a4d3ec47/python/distro/ubuntu/SYSCONFDIR/init.d/cloud-ipallocator.in
----------------------------------------------------------------------
diff --git a/python/distro/ubuntu/SYSCONFDIR/init.d/cloud-ipallocator.in b/python/distro/ubuntu/SYSCONFDIR/init.d/cloud-ipallocator.in
index 5ec6da0..e2cb361 100755
--- a/python/distro/ubuntu/SYSCONFDIR/init.d/cloud-ipallocator.in
+++ b/python/distro/ubuntu/SYSCONFDIR/init.d/cloud-ipallocator.in
@@ -26,7 +26,7 @@
 
 # set environment variables
 
-SHORTNAME="basename $0"
+SHORTNAME=`basename $0`
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@AGENTLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a4d3ec47/systemvm/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
----------------------------------------------------------------------
diff --git a/systemvm/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in b/systemvm/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
index e43f641..3ec4d06 100644
--- a/systemvm/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
+++ b/systemvm/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
@@ -26,7 +26,7 @@
 
 # set environment variables
 
-SHORTNAME="basename $0"
+SHORTNAME=`basename $0`
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@CPLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a4d3ec47/systemvm/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
----------------------------------------------------------------------
diff --git a/systemvm/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in b/systemvm/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
index e43f641..3ec4d06 100644
--- a/systemvm/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
+++ b/systemvm/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
@@ -26,7 +26,7 @@
 
 # set environment variables
 
-SHORTNAME="basename $0"
+SHORTNAME=`basename $0`
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@CPLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a4d3ec47/systemvm/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
----------------------------------------------------------------------
diff --git a/systemvm/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in b/systemvm/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
index e43f641..3ec4d06 100644
--- a/systemvm/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
+++ b/systemvm/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in
@@ -26,7 +26,7 @@
 
 # set environment variables
 
-SHORTNAME="basename $0"
+SHORTNAME=`basename $0`
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@CPLOG@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a4d3ec47/systemvm/distro/ubuntu/SYSCONFDIR/init.d/cloud-console-proxy.in
----------------------------------------------------------------------
diff --git a/systemvm/distro/ubuntu/SYSCONFDIR/init.d/cloud-console-proxy.in b/systemvm/distro/ubuntu/SYSCONFDIR/init.d/cloud-console-proxy.in
index 87a653e..0c7be73 100755
--- a/systemvm/distro/ubuntu/SYSCONFDIR/init.d/cloud-console-proxy.in
+++ b/systemvm/distro/ubuntu/SYSCONFDIR/init.d/cloud-console-proxy.in
@@ -27,7 +27,7 @@
 
 # set environment variables
 
-SHORTNAME="basename $0"
+SHORTNAME=`basename $0`
 PIDFILE=@PIDDIR@/"$SHORTNAME".pid
 LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@CPLOG@


[49/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
adding distributed routing support for KVM OVS

some check style error fixes


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/a29b5c6e
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/a29b5c6e
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/a29b5c6e

Branch: refs/heads/distributedrouter
Commit: a29b5c6e41e5aaf3870a09e4762083b2bb162d22
Parents: 780c8e7
Author: Murali Reddy <mu...@gmail.com>
Authored: Tue Mar 11 13:05:03 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Tue Mar 11 18:41:22 2014 +0530

----------------------------------------------------------------------
 .../kvm/resource/LibvirtComputingResource.java  |  47 ++++
 .../xen/resource/CitrixResourceBase.java        |   3 +-
 .../api/OvsVpcRoutingPolicyConfigCommand.java   |   1 -
 .../cloud/network/ovs/OvsTunnelManagerImpl.java |  21 +-
 scripts/vm/network/vnet/cloudstack_pluginlib.py | 226 +++++++++++++++++++
 scripts/vm/network/vnet/ovstunnel.py            |  86 ++++++-
 6 files changed, 373 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a29b5c6e/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
----------------------------------------------------------------------
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 9aeabea..4ec7a56 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
@@ -78,6 +78,8 @@ import com.cloud.agent.api.OvsDestroyTunnelCommand;
 import com.cloud.agent.api.OvsFetchInterfaceAnswer;
 import com.cloud.agent.api.OvsFetchInterfaceCommand;
 import com.cloud.agent.api.OvsSetupBridgeCommand;
+import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
+import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand;
 import com.cloud.agent.api.PingCommand;
 import com.cloud.agent.api.PingRoutingCommand;
 import com.cloud.agent.api.PingRoutingWithNwGroupsCommand;
@@ -1360,6 +1362,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
                 return execute((OvsCreateTunnelCommand)cmd);
             } else if (cmd instanceof OvsDestroyTunnelCommand) {
                 return execute((OvsDestroyTunnelCommand)cmd);
+            } else if (cmd instanceof OvsVpcPhysicalTopologyConfigCommand) {
+                return execute((OvsVpcPhysicalTopologyConfigCommand) cmd);
+            } else if (cmd instanceof OvsVpcRoutingPolicyConfigCommand) {
+                return execute((OvsVpcRoutingPolicyConfigCommand) cmd);
             } else {
                 s_logger.warn("Unsupported command ");
                 return Answer.createUnsupportedCommandAnswer(cmd);
@@ -1401,6 +1407,47 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
         return new Answer(cmd, true, null);
     }
 
+    public Answer execute(OvsVpcPhysicalTopologyConfigCommand cmd) {
+
+        String bridge = cmd.getBridgeName();
+        try {
+            Script command = new Script(_ovsTunnelPath, _timeout, s_logger);
+            command.add("configure_ovs_bridge_for_network_topology");
+            command.add("--bridge", bridge);
+            command.add("--config", cmd.getVpcConfigInJson());
+
+            String result = command.execute();
+            if (result.equalsIgnoreCase("SUCCESS")) {
+                return new Answer(cmd, true, result);
+            } else {
+                return new Answer(cmd, false, result);
+            }
+        } catch  (Exception e) {
+            s_logger.warn("caught exception while updating host with latest routing polcies", e);
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
+    public Answer execute(OvsVpcRoutingPolicyConfigCommand cmd) {
+
+        try {
+            Script command = new Script(_ovsTunnelPath, _timeout, s_logger);
+            command.add("configure_ovs_bridge_for_routing_policies");
+            command.add("--bridge", cmd.getBridgeName());
+            command.add("--config", cmd.getVpcConfigInJson());
+
+            String result = command.execute();
+            if (result.equalsIgnoreCase("SUCCESS")) {
+                return new Answer(cmd, true, result);
+            } else {
+                return new Answer(cmd, false, result);
+            }
+        } catch  (Exception e) {
+            s_logger.warn("caught exception while updating host with latest VPC topology", e);
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
     private synchronized void destroyTunnelNetwork(String bridge) {
         try {
             findOrCreateTunnelNetwork(bridge);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a29b5c6e/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
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 da92e1e..d637443 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
@@ -16,7 +16,6 @@
 // under the License.
 package com.cloud.hypervisor.xen.resource;
 
-import com.cloud.agent.api.*;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
@@ -89,7 +88,6 @@ import org.apache.cloudstack.storage.to.TemplateObjectTO;
 import org.apache.cloudstack.storage.to.VolumeObjectTO;
 
 import com.cloud.agent.IAgentControl;
-
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.AttachIsoCommand;
 import com.cloud.agent.api.AttachVolumeAnswer;
@@ -150,6 +148,7 @@ import com.cloud.agent.api.OvsSetTagAndFlowAnswer;
 import com.cloud.agent.api.OvsSetTagAndFlowCommand;
 import com.cloud.agent.api.OvsSetupBridgeCommand;
 import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
+import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand;
 import com.cloud.agent.api.PerformanceMonitorAnswer;
 import com.cloud.agent.api.PerformanceMonitorCommand;
 import com.cloud.agent.api.PingCommand;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a29b5c6e/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java
index 8e4d5d1..50f1fdd 100644
--- a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java
@@ -18,7 +18,6 @@ package com.cloud.agent.api;
 
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
-import java.util.UUID;
 
 /**
  * This command represents logical view of VM's connectivity in VPC.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a29b5c6e/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
index 35b0035..eeb22b1 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
@@ -16,11 +16,25 @@
 // under the License.
 package com.cloud.network.ovs;
 
-import com.amazonaws.services.ec2.model.NetworkAcl;
-import com.cloud.agent.api.*;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.OvsCreateTunnelAnswer;
+import com.cloud.agent.api.OvsCreateTunnelCommand;
+import com.cloud.agent.api.OvsDestroyBridgeCommand;
+import com.cloud.agent.api.OvsDestroyTunnelCommand;
+import com.cloud.agent.api.OvsFetchInterfaceAnswer;
+import com.cloud.agent.api.OvsFetchInterfaceCommand;
+import com.cloud.agent.api.OvsSetupBridgeCommand;
+import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
+import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand;
 import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.vpc.*;
+import com.cloud.network.vpc.NetworkACLVO;
+import com.cloud.network.vpc.NetworkACLItemDao;
+import com.cloud.network.vpc.NetworkACLItemVO;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.network.vpc.VpcVO;
 import com.cloud.network.vpc.dao.NetworkACLDao;
 import com.cloud.vm.dao.VMInstanceDao;
 import com.cloud.vm.Nic;
@@ -63,7 +77,6 @@ import com.cloud.network.ovs.dao.OvsTunnelInterfaceVO;
 import com.cloud.network.ovs.dao.OvsTunnelNetworkDao;
 import com.cloud.network.ovs.dao.OvsTunnelNetworkVO;
 import com.cloud.network.ovs.dao.OvsTunnel;
-import com.cloud.network.vpc.dao.VpcDao;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.db.DB;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a29b5c6e/scripts/vm/network/vnet/cloudstack_pluginlib.py
----------------------------------------------------------------------
diff --git a/scripts/vm/network/vnet/cloudstack_pluginlib.py b/scripts/vm/network/vnet/cloudstack_pluginlib.py
index f886aa3..6c24917 100755
--- a/scripts/vm/network/vnet/cloudstack_pluginlib.py
+++ b/scripts/vm/network/vnet/cloudstack_pluginlib.py
@@ -174,6 +174,7 @@ def _build_flow_expr(**kwargs):
     dl_dst = 'dl_dst' in kwargs and ",dl_dst=%s" % kwargs['dl_dst'] or ''
     nw_src = 'nw_src' in kwargs and ",nw_src=%s" % kwargs['nw_src'] or ''
     nw_dst = 'nw_dst' in kwargs and ",nw_dst=%s" % kwargs['nw_dst'] or ''
+    table = 'table' in kwargs and ",table=%s" % kwargs['table'] or ''
     proto = 'proto' in kwargs and ",%s" % kwargs['proto'] or ''
     ip = ('nw_src' in kwargs or 'nw_dst' in kwargs) and ',ip' or ''
     flow = (flow + in_port + dl_type + dl_src + dl_dst +
@@ -217,3 +218,228 @@ def del_all_flows(bridge):
 def del_port(bridge, port):
     delPort = [VSCTL_PATH, "del-port", bridge, port]
     do_cmd(delPort)
+
+
+def get_network_id_for_vif(vif_name):
+    domain_id, device_id = vif_name[3:len(vif_name)].split(".")
+    dom_uuid = do_cmd([XE_PATH, "vm-list", "dom-id=%s" % domain_id, "--minimal"])
+    vif_uuid = do_cmd([XE_PATH, "vif-list", "vm-uuid=%s" % dom_uuid, "device=%s" % device_id, "--minimal"])
+    vnet = do_cmd([XE_PATH, "vif-param-get", "uuid=%s" % vif_uuid,  "param-name=other-config",
+                             "param-key=cloudstack-network-id"])
+    return vnet
+
+def get_network_id_for_tunnel_port(tunnelif_name):
+    vnet = do_cmd([VSCTL_PATH, "get", "interface", tunnelif_name, "options:cloudstack-network-id"])
+    return vnet
+
+def clear_flooding_rules_for_port(bridge, ofport):
+        del_flows(bridge, in_port=ofport, table=2)
+
+def add_flooding_rules_for_port(bridge, in_ofport, out_ofports):
+        action = "".join("output:%s," %ofport for ofport in out_ofports)[:-1]
+        add_flow(bridge, priority=1100, in_port=in_ofport, table=1, actions=action)
+
+def get_ofport_for_vif(vif_name):
+    return do_cmd([VSCTL_PATH, "get", "interface", vif_name, "ofport"])
+
+def get_macaddress_of_vif(vif_name):
+    domain_id, device_id = vif_name[3:len(vif_name)].split(".")
+    dom_uuid = do_cmd([XE_PATH, "vm-list", "dom-id=%s" % domain_id, "--minimal"])
+    vif_uuid = do_cmd([XE_PATH, "vif-list", "vm-uuid=%s" % dom_uuid, "device=%s" % device_id, "--minimal"])
+    mac = do_cmd([XE_PATH, "vif-param-get", "uuid=%s" % vif_uuid,  "param-name=MAC"])
+    return mac
+
+def get_vif_name_from_macaddress(macaddress):
+    vif_uuid = do_cmd([XE_PATH, "vif-list", "MAC=%s" % macaddress, "--minimal"])
+    vif_device_id = do_cmd([XE_PATH, "vif-param-get", "uuid=%s" % vif_uuid,  "param-name=device"])
+    vm_uuid = do_cmd([XE_PATH, "vif-param-get", "uuid=%s" % vif_uuid,  "param-name=vm-uuid"])
+    vm_domain_id = do_cmd([XE_PATH, "vm-param-get", "uuid=%s" % vm_uuid,  "param-name=dom-id"])
+    return "vif"+vm_domain_id+"."+vif_device_id
+
+def add_mac_lookup_table_entry(bridge, mac_address, out_of_port):
+    add_flow(bridge, priority=1100, dl_dst=mac_address, table=1, actions="output:%s" % out_of_port)
+
+def delete_mac_lookup_table_entry(bridge, mac_address):
+    del_flows(bridge, dl_dst=mac_address, table=1)
+
+def add_ip_lookup_table_entry(bridge, ip, dst_tier_gateway_mac, dst_vm_mac):
+    action_str = "mod_dl_sr:%s" % dst_tier_gateway_mac + ",mod_dl_dst:%s" % dst_vm_mac +",resubmit(,5)"
+    addflow = [OFCTL_PATH, "add-flow", bridge, "table=4", "nw_dst=%s" % ip, "actions=%s" %action_str]
+    do_cmd(addflow)
+
+def get_vms_on_host(vpc, host_id):
+    all_vms = vpc.vms
+    vms_on_host = []
+    for vm in all_vms:
+      if vm.hostid == host_id:
+        vms_on_host.append(vm)
+    return vms_on_host
+
+def get_network_details(vpc, network_uuid):
+    tiers = vpc.tiers
+    for tier in tiers:
+      if tier.networkuuid == network_uuid:
+        return tier
+    return None
+
+class jsonLoader(object):
+  def __init__(self, obj):
+        for k in obj:
+            v = obj[k]
+            if isinstance(v, dict):
+                setattr(self, k, jsonLoader(v))
+            elif isinstance(v, (list, tuple)):
+                if len(v) > 0 and isinstance(v[0], dict):
+                    setattr(self, k, [jsonLoader(elem) for elem in v])
+                else:
+                    setattr(self, k, v)
+            else:
+                setattr(self, k, v)
+
+  def __getattr__(self, val):
+        if val in self.__dict__:
+            return self.__dict__[val]
+        else:
+            return None
+
+  def __repr__(self):
+        return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v)
+                                      in self.__dict__.iteritems()))
+
+  def __str__(self):
+        return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v)
+                                      in self.__dict__.iteritems()))
+
+def configure_bridge_for_network_topology(bridge, this_host_id, json_config):
+    vpconfig = jsonLoader(json.loads(json_config)).vpc
+
+    if vpconfig is None:
+        logging.debug("WARNING:Can't find VPC info in json config file")
+        return "FAILURE:IMPROPER_JSON_CONFG_FILE"
+
+    # get the list of Vm's in the VPC from the JSON config
+    this_host_vms = get_vms_on_host(vpconfig, this_host_id)
+
+    for vm in this_host_vms:
+        for nic in vm.nics:
+            mac_addr = nic.macaddress
+            ip = nic.ipaddress
+            vif_name = get_vif_name_from_macaddress(mac_addr)
+            of_port = get_ofport_for_vif(vif_name)
+            network = get_network_details(vpconfig, nic.networkuuid)
+
+            # Add flow rule in L2 look up table, if the destination mac = MAC of the nic send packet on the found OFPORT
+            add_mac_lookup_table_entry(bridge, mac_addr, of_port)
+
+            # Add flow rule in L3 look up table: if the destination IP = VM's IP then modify the packet
+            # to set DST MAC = VM's MAC, SRC MAC=tier gateway MAC and send to egress table
+            add_ip_lookup_table_entry(bridge, ip, network.gatewaymac, mac_addr)
+
+            # Add flow entry to send with intra tier traffic from the NIC to L2 lookup path)
+            addflow = [OFCTL_PATH, "add-flow", bridge, "table=0", "in_port=%s" % of_port,
+                       "nw_dst=%s" %network.cidr, "actions=resubmit(,1)"]
+            do_cmd(addflow)
+
+            #add flow entry to send inter-tier traffic from the NIC to egress ACL table(to L3 lookup path)
+            addflow = [OFCTL_PATH, "add-flow", bridge, "table=0", "in_port=%s" % of_port,
+                       "dl_dst=%s" %network.gatewaymac, "nw_dst=%s" %vpconfig.cidr, "actions=resubmit(,3)"]
+            do_cmd(addflow)
+
+    # get the list of hosts on which VPC spans from the JSON config
+    vpc_spanning_hosts = vpconfig.hosts
+
+    for host in vpc_spanning_hosts:
+        if this_host_id == host.hostid:
+            continue
+        other_host_vms = get_vms_on_host(vpconfig, host.hostid)
+        for vm in other_host_vms:
+            for nic in vm.nics:
+                mac_addr = nic.macaddress
+                ip = nic.ipaddress
+                network = get_network_details(vpconfig, nic.networkuuid)
+                gre_key = network.grekey
+
+                # generate tunnel name from tunnel naming convention
+                tunnel_name = "t%s-%s-%s" % (gre_key, this_host_id, host.hostid)
+                of_port = get_ofport_for_vif(tunnel_name)
+
+                # Add flow rule in L2 look up table, if the destination mac = MAC of the nic send packet tunnel port
+                add_mac_lookup_table_entry(bridge, mac_addr, of_port)
+
+                # Add flow tule in L3 look up table: if the destination IP = VM's IP then modify the packet
+                # set DST MAC = VM's MAC, SRC MAC=tier gateway MAC and send to egress table
+                add_ip_lookup_table_entry(bridge, ip, network.gatewaymac, mac_addr)
+
+    return "SUCCESS: successfully configured bridge as per the VPC topology"
+
+def get_acl(vpcconfig, required_acl_id):
+    acls = vpcconfig.acls
+    for acl in acls:
+        if acl.id == required_acl_id:
+            return acl
+    return None
+
+def configure_ovs_bridge_for_routing_policies(bridge, json_config):
+    vpconfig = jsonLoader(json.loads(json_config)).vpc
+
+    if vpconfig is None:
+        logging.debug("WARNING:Can't find VPC info in json config file")
+        return "FAILURE:IMPROPER_JSON_CONFG_FILE"
+
+    # First flush current egress ACL's before re-applying the ACL's
+    del_flows(bridge, table=3)
+
+    egress_rules_added = False
+    ingress_rules_added = False
+
+    tiers = vpconfig.tiers
+    for tier in tiers:
+        tier_cidr = tier.cidr
+        acl = get_acl(vpconfig, tier.aclid)
+        acl_items = acl.aclitems
+
+        for acl_item in acl_items:
+            number = acl_item.number
+            action = acl_item.action
+            direction = acl_item.direction
+            source_port_start = acl_item.sourceportstart
+            source_port_end = acl_item.sourceportend
+            protocol = acl_item.protocol
+            source_cidrs = acl_item.sourcecidrs
+            acl_priority = 1000 + number
+            for source_cidr in source_cidrs:
+                if direction is "ingress":
+                    ingress_rules_added = True
+                    # add flow rule to do action (allow/deny) for flows where source IP of the packet is in
+                    # source_cidr and destination ip is in tier_cidr
+                    port = source_port_start
+                    while (port < source_port_end):
+                        if action is "deny":
+                            add_flow(bridge, priority= acl_priority, table=5, nw_src=source_cidr, nw_dst=tier_cidr, tp_dst=port,
+                                     nw_proto=protocol, actions='drop')
+                        if action is "allow":
+                            add_flow(bridge, priority= acl_priority,table=5, nw_src=source_cidr, nw_dst=tier_cidr, tp_dst=port,
+                                     nw_proto=protocol, actions='resubmit(,1)')
+                        port = port + 1
+
+                elif direction in "egress":
+                    egress_rules_added = True
+                    # add flow rule to do action (allow/deny) for flows where destination IP of the packet is in
+                    # source_cidr and source ip is in tier_cidr
+                    port = source_port_start
+                    while (port < source_port_end):
+                        if action is "deny":
+                            add_flow(bridge, priority= acl_priority, table=5, nw_src=tier_cidr, nw_dst=source_cidr, tp_dst=port,
+                                     nw_proto=protocol, actions='drop')
+                        if action is "allow":
+                            add_flow(bridge, priority= acl_priority, table=5, nw_src=tier_cidr, nw_dst=source_cidr, tp_dst=port,
+                                     nw_proto=protocol, actions='resubmit(,1)')
+                        port = port + 1
+
+    if egress_rules_added is False:
+        # add a default rule in egress table to forward packet to L3 lookup table
+        add_flow(bridge, priority=0, table=3, actions='resubmit(,4)')
+
+    if ingress_rules_added is False:
+        # add a default rule in egress table drop packets
+        add_flow(bridge, priority=0, table=5, actions='drop')

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a29b5c6e/scripts/vm/network/vnet/ovstunnel.py
----------------------------------------------------------------------
diff --git a/scripts/vm/network/vnet/ovstunnel.py b/scripts/vm/network/vnet/ovstunnel.py
index 9e05413..57085d8 100755
--- a/scripts/vm/network/vnet/ovstunnel.py
+++ b/scripts/vm/network/vnet/ovstunnel.py
@@ -27,6 +27,7 @@ import os
 import sys
 import subprocess
 import time
+import simplejson as json
 from optparse import OptionParser, OptionGroup, OptParseError, BadOptionError, OptionError, OptionConflictError, OptionValueError
 
 from time import localtime as _localtime, asctime as _asctime
@@ -72,6 +73,58 @@ def setup_ovs_bridge(bridge, key, cs_host_id):
     logging.debug("Setup_ovs_bridge completed with result:%s" % result)
     return result
 
+@echo
+def setup_ovs_bridge_for_distributed_routing(bridge, cs_host_id):
+
+    res = lib.check_switch()
+    if res != "SUCCESS":
+        return "FAILURE:%s" % res
+
+    logging.debug("About to manually create the bridge:%s" % bridge)
+    res = lib.do_cmd([lib.VSCTL_PATH, "--", "--may-exist", "add-br", bridge])
+    logging.debug("Bridge has been manually created:%s" % res)
+
+    # Non empty result means something went wrong
+    if res:
+        result = "FAILURE:%s" % res
+    else:
+        # Verify the bridge actually exists
+        res = lib.do_cmd([lib.VSCTL_PATH, "list", "bridge", bridge])
+
+        res = lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge, "other_config:is-ovs_vpc_distributed_vr_network=True"])
+        conf_hosts = lib.do_cmd([lib.VSCTL_PATH, "get","bridge", bridge,"other:ovs-host-setup"])
+        conf_hosts = cs_host_id + (conf_hosts and ',%s' % conf_hosts or '')
+        lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge,
+                   "other_config:ovs-host-setup=%s" % conf_hosts])
+
+        # add a default flow rule to send broadcast and multi-cast packets to L2 flooding table
+        lib.add_flow(bridge, priority=1000, dl_dst='ff:ff:ff:ff:ff:ff', table=0, actions='resubmit(,2)')
+        lib.add_flow(bridge, priority=1000, nw_dst='224.0.0.0/24', table=0, actions='resubmit(,2)')
+
+        # add a default flow rule to send uni-cast traffic to L2 lookup table
+        lib.add_flow(bridge, priority=0, table=0, actions='resubmit(,1)')
+
+        # add a default rule to send unknown mac address to L2 flooding table
+        lib.add_flow(bridge, priority=0, table=1, actions='resubmit(,2)')
+
+        # add a default rule in L2 flood table to drop packet
+        lib.add_flow(bridge, priority=0, table=2, actions='drop')
+
+        # add a default rule in egress table to forward packet to L3 lookup table
+        lib.add_flow(bridge, priority=0, table=3, actions='resubmit(,4)')
+
+        # add a default rule in L3 lookup table to forward packet to L2 lookup table
+        lib.add_flow(bridge, priority=0, table=4, actions='resubmit(,1)')
+
+        # add a default rule in ingress table to drop in bound packets
+        lib.add_flow(bridge, priority=0, table=5, actions='drop')
+
+        result = "SUCCESS: successfully setup bridge with flow rules"
+
+        logging.debug("Setup_ovs_bridge completed with result:%s" % result)
+
+    return result
+
 def destroy_ovs_bridge(bridge):
 
     res = lib.check_switch()
@@ -163,12 +216,30 @@ def create_tunnel(bridge, remote_ip, key, src_host, dst_host):
         # Ensure no trailing LF
         if tun_ofport.endswith('\n'):
             tun_ofport = tun_ofport[:-1]
-        # add flow entryies for dropping broadcast coming in from gre tunnel
-        lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
+
+        ovs_tunnel_network = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge", bridge, "other_config:is-ovs-tun-network"])
+        ovs_vpc_distributed_vr_network = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge", bridge,
+                                                     "other_config:is-ovs_vpc_distributed_vr_network"])
+
+        if ovs_tunnel_network == 'True':
+            # add flow entryies for dropping broadcast coming in from gre tunnel
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
+                         dl_dst='ff:ff:ff:ff:ff:ff', actions='drop')
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
+                     nw_dst='224.0.0.0/24', actions='drop')
+            drop_flow_setup = True
+
+        if ovs_vpc_distributed_vr_network == 'True':
+            # add flow rules for dropping broadcast coming in from tunnel ports
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0,
                          dl_dst='ff:ff:ff:ff:ff:ff', actions='drop')
-        lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0,
                      nw_dst='224.0.0.0/24', actions='drop')
-        drop_flow_setup = True
+
+            # add flow rule to send the traffic from tunnel ports to L2 switching table only
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0, actions='resubmit(,1)')
+            lib.do_cmd([lib.VSCTL_PATH, "set", "interface", name, "options:cloudstack-network-id=%s" % network_uuid])
+
         logging.debug("Broadcast drop rules added")
 #        return "SUCCESS:%s" % name
         return 'true'
@@ -210,6 +281,7 @@ if __name__ == '__main__':
     parser.add_option("--src_host", dest="src_host")
     parser.add_option("--dst_host", dest="dst_host")
     parser.add_option("--iface_name", dest="iface_name")
+    parser.ad_option("--config", dest="config")
     (option, args) = parser.parse_args()
     if len(args) == 0:
         logging.debug("No command to execute")
@@ -223,6 +295,12 @@ if __name__ == '__main__':
         create_tunnel(option.bridge, option.remote_ip, option.key, option.src_host, option.dst_host)
     elif cmd == "destroy_tunnel":
         destroy_tunnel(option.bridge, option.iface_name)
+    elif cmd == "setup_ovs_bridge_for_distributed_routing":
+        setup_ovs_bridge_for_distributed_routing(bridge, cs_host_id)
+    elif cmd == "configure_ovs_bridge_for_network_topology":
+        configure_bridge_for_network_topology(brdige, cs_host_id, config)
+    elif cmd == "configure_ovs_bridge_for_routing_policies":
+        configure_ovs_bridge_for_routing_policies(bridge, config)
     else:
         logging.debug("Unknown command: " + cmd)
         sys.exit(1)


[43/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
make Ovs as VPC provider


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/21500252
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/21500252
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/21500252

Branch: refs/heads/distributedrouter
Commit: 21500252754f10e886a967330ea2fffa0f9f7cf6
Parents: beafb0e
Author: Murali Reddy <mu...@gmail.com>
Authored: Wed Mar 5 01:26:53 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Tue Mar 11 18:38:44 2014 +0530

----------------------------------------------------------------------
 server/src/com/cloud/network/vpc/VpcManagerImpl.java | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/21500252/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index f4f8772..3ffd4c7 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -205,7 +205,9 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
     private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("VpcChecker"));
     private List<VpcProvider> vpcElements = null;
     private final List<Service> nonSupportedServices = Arrays.asList(Service.SecurityGroup, Service.Firewall);
-    private final List<Provider> supportedProviders = Arrays.asList(Provider.VPCVirtualRouter, Provider.NiciraNvp, Provider.InternalLbVm, Provider.Netscaler, Provider.JuniperContrailVpcRouter);
+    private final List<Provider> supportedProviders = Arrays.asList(Provider.VPCVirtualRouter,
+            Provider.NiciraNvp, Provider.InternalLbVm, Provider.Netscaler, Provider.JuniperContrailVpcRouter,
+            Provider.Ovs);
 
     int _cleanupInterval;
     int _maxNetworks;


[06/50] [abbrv] Dispatcher corrections, refactoring and tests

Posted by mu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/test/com/cloud/api/ApiDispatcherTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/api/ApiDispatcherTest.java b/server/test/com/cloud/api/ApiDispatcherTest.java
deleted file mode 100644
index 7314a57..0000000
--- a/server/test/com/cloud/api/ApiDispatcherTest.java
+++ /dev/null
@@ -1,106 +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 com.cloud.api;
-
-import java.util.HashMap;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.runners.MockitoJUnitRunner;
-
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.context.CallContext;
-
-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.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.User;
-
-@RunWith(MockitoJUnitRunner.class)
-public class ApiDispatcherTest {
-
-    @Mock
-    AccountManager accountManager;
-
-    public static class TestCmd extends BaseCmd {
-
-        @Parameter(name = "strparam1")
-        String strparam1;
-
-        @Parameter(name = "intparam1", type = CommandType.INTEGER)
-        int intparam1;
-
-        @Parameter(name = "boolparam1", type = CommandType.BOOLEAN)
-        boolean boolparam1;
-
-        @Override
-        public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
-            ResourceAllocationException, NetworkRuleConflictException {
-            // well documented nothing
-        }
-
-        @Override
-        public String getCommandName() {
-            return "test";
-        }
-
-        @Override
-        public long getEntityOwnerId() {
-            return 0;
-        }
-
-    }
-
-    @Before
-    public void setup() {
-        CallContext.register(Mockito.mock(User.class), Mockito.mock(Account.class));
-        new ApiDispatcher().init();
-        ApiDispatcher.getInstance()._accountMgr = accountManager;
-    }
-
-    @After
-    public void cleanup() {
-        CallContext.unregister();
-    }
-
-    @Test
-    public void processParameters() {
-        HashMap<String, String> params = new HashMap<String, String>();
-        params.put("strparam1", "foo");
-        params.put("intparam1", "100");
-        params.put("boolparam1", "true");
-        TestCmd cmd = new TestCmd();
-        //how lucky that field is not protected, this test would be impossible
-        ApiDispatcher.processParameters(cmd, params);
-        Assert.assertEquals("foo", cmd.strparam1);
-        Assert.assertEquals(100, cmd.intparam1);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/test/com/cloud/api/dispatch/CommandCreationWorkerTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/api/dispatch/CommandCreationWorkerTest.java b/server/test/com/cloud/api/dispatch/CommandCreationWorkerTest.java
new file mode 100644
index 0000000..34d64fc
--- /dev/null
+++ b/server/test/com/cloud/api/dispatch/CommandCreationWorkerTest.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.api.dispatch;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+
+import com.cloud.exception.ResourceAllocationException;
+
+public class CommandCreationWorkerTest {
+
+    @Test
+    public void testHandle() throws ResourceAllocationException {
+        // Prepare
+        final BaseAsyncCreateCmd asyncCreateCmd = mock(BaseAsyncCreateCmd.class);
+        final Map<String, String> params = new HashMap<String, String>();
+
+        // Execute
+        final CommandCreationWorker creationWorker = new CommandCreationWorker();
+
+        creationWorker.handle(new DispatchTask(asyncCreateCmd, params));
+
+        // Assert
+        verify(asyncCreateCmd, times(1)).create();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/test/com/cloud/api/dispatch/DispatchChainFactoryTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/api/dispatch/DispatchChainFactoryTest.java b/server/test/com/cloud/api/dispatch/DispatchChainFactoryTest.java
new file mode 100644
index 0000000..f54caae
--- /dev/null
+++ b/server/test/com/cloud/api/dispatch/DispatchChainFactoryTest.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 com.cloud.api.dispatch;
+
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
+public class DispatchChainFactoryTest {
+
+    protected static final String STANDARD_CHAIN_ERROR = "Expecting worker of class %s at index %s of StandardChain";
+    protected static final String ASYNC_CHAIN_ERROR = "Expecting worker of class %s at index %s of StandardChain";
+
+    @Test
+    public void testAllChainCreation() {
+        // Prepare
+        final DispatchChainFactory dispatchChainFactory = new DispatchChainFactory();
+        dispatchChainFactory.paramGenericValidationWorker = new ParamGenericValidationWorker();
+        dispatchChainFactory.specificCmdValidationWorker = new SpecificCmdValidationWorker();
+        dispatchChainFactory.paramProcessWorker = new ParamProcessWorker();
+        dispatchChainFactory.commandCreationWorker = new CommandCreationWorker();
+        dispatchChainFactory.paramUnpackWorker = new ParamUnpackWorker();
+
+        final Class<?>[] standardClasses = {ParamUnpackWorker.class, ParamProcessWorker.class,
+                ParamGenericValidationWorker.class, SpecificCmdValidationWorker.class};
+        final Class<?>[] asyncClasses = {ParamUnpackWorker.class, ParamProcessWorker.class,
+                ParamGenericValidationWorker.class, SpecificCmdValidationWorker.class, CommandCreationWorker.class};
+
+        // Execute
+        dispatchChainFactory.setup();
+        final DispatchChain standardChain = dispatchChainFactory.getStandardDispatchChain();
+        final DispatchChain asyncChain = dispatchChainFactory.getAsyncCreationDispatchChain();
+        for (int i = 0; i < standardClasses.length; i++) {
+            assertEquals(String.format(STANDARD_CHAIN_ERROR, standardClasses[i], i),
+                    standardClasses[i], standardChain.workers.get(i).getClass());
+        }
+        for (int i = 0; i < asyncClasses.length; i++) {
+            assertEquals(String.format(ASYNC_CHAIN_ERROR, asyncClasses[i], i),
+                    asyncClasses[i], asyncChain.workers.get(i).getClass());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/test/com/cloud/api/dispatch/ParamGenericValidationWorkerTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/api/dispatch/ParamGenericValidationWorkerTest.java b/server/test/com/cloud/api/dispatch/ParamGenericValidationWorkerTest.java
new file mode 100644
index 0000000..867625d
--- /dev/null
+++ b/server/test/com/cloud/api/dispatch/ParamGenericValidationWorkerTest.java
@@ -0,0 +1,173 @@
+// 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.api.dispatch;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+
+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.Account;
+
+import org.apache.log4j.Logger;
+
+public class ParamGenericValidationWorkerTest {
+
+    protected static final String FAKE_CMD_NAME = "fakecmdname";
+
+    protected static final String FAKE_CMD_ROLE_NAME = "fakecmdrolename";
+
+    protected String loggerOutput;
+
+    protected void driveTest(final BaseCmd cmd, final Map<String, String> params) {
+        final ParamGenericValidationWorker genValidationWorker = new ParamGenericValidationWorker();
+
+        // We create a mock logger to verify the result
+        ParamGenericValidationWorker.s_logger = new Logger(""){
+            @Override
+            public void warn(final Object msg){
+                loggerOutput = msg.toString();
+            }
+        };
+
+        // Execute
+        genValidationWorker.handle(new DispatchTask(cmd, params));
+    }
+
+    @Test
+    public void testHandle() throws ResourceAllocationException {
+        // Prepare
+        final BaseCmd cmd = new FakeCmd();
+        final Map<String, String> params = new HashMap<String, String>();
+        params.put(ApiConstants.COMMAND, "");
+        params.put("addedParam", "");
+
+        // Execute
+        driveTest(cmd, params);
+
+        // Assert
+        assertEquals("There should be no errors since there are no unknown parameters for this command class", null, loggerOutput);
+    }
+
+    @Test
+    public void testHandleWithUnknownParams() throws ResourceAllocationException {
+        // Prepare
+        final String unknownParamKey = "unknownParam";
+        final BaseCmd cmd = new FakeCmd();
+        final Map<String, String> params = new HashMap<String, String>();
+        params.put(ApiConstants.COMMAND, "");
+        params.put("addedParam", "");
+        params.put(unknownParamKey, "");
+
+        // Execute
+        driveTest(cmd, params);
+
+        // Assert
+        assertTrue("There should be error msg, since there is one unknown parameter", loggerOutput.contains(unknownParamKey));
+        assertTrue("There should be error msg containing the correct command name", loggerOutput.contains(FAKE_CMD_NAME));
+    }
+
+    @Test
+    public void testHandleWithoutAuthorization() throws ResourceAllocationException {
+        final short type = Account.ACCOUNT_TYPE_NORMAL;
+        driveAuthTest(type);
+
+        // Assert
+        assertTrue("There should be error msg, since there is one unauthorized parameter", loggerOutput.contains("paramWithRole"));
+        assertTrue("There should be error msg containing the correct command name", loggerOutput.contains(FAKE_CMD_ROLE_NAME));
+    }
+
+    @Test
+    public void testHandleWithAuthorization() throws ResourceAllocationException {
+        final short type = Account.ACCOUNT_TYPE_ADMIN;
+        driveAuthTest(type);
+
+        // Assert
+        assertEquals("There should be no errors since parameters have authorization", null, loggerOutput);
+    }
+
+    protected void driveAuthTest(final short type) {
+        // Prepare
+        final BaseCmd cmd = new FakeCmdWithRoleAdmin();
+        final Account account = mock(Account.class);
+        ((FakeCmdWithRoleAdmin)cmd).account = account;
+        when(account.getType()).thenReturn(type);
+        final Map<String, String> params = new HashMap<String, String>();
+        params.put(ApiConstants.COMMAND, "");
+        params.put("addedParam", "");
+        params.put("paramWithRole", "");
+
+        // Execute
+        driveTest(cmd, params);
+    }
+}
+
+
+@APICommand(name=ParamGenericValidationWorkerTest.FAKE_CMD_NAME, responseObject=BaseResponse.class)
+class FakeCmd extends BaseCmd {
+
+    @Parameter(name = "addedParam")
+    private String addedParam;
+
+    public Account account;
+
+    @Override
+    protected Account getCurrentContextAccount() {
+        return account;
+    }
+
+    //
+    // Dummy methods for mere correct compilation
+    //
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException,
+            NetworkRuleConflictException {
+    }
+    @Override
+    public String getCommandName() {
+        return null;
+    }
+    @Override
+    public long getEntityOwnerId() {
+        return 0;
+    }
+}
+
+@APICommand(name=ParamGenericValidationWorkerTest.FAKE_CMD_ROLE_NAME, responseObject=BaseResponse.class)
+class FakeCmdWithRoleAdmin extends FakeCmd {
+
+    @Parameter(name = "paramWithRole", authorized = {RoleType.Admin})
+    private String paramWithRole;
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/test/com/cloud/api/dispatch/ParamProcessWorkerTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/api/dispatch/ParamProcessWorkerTest.java b/server/test/com/cloud/api/dispatch/ParamProcessWorkerTest.java
new file mode 100644
index 0000000..12051a6
--- /dev/null
+++ b/server/test/com/cloud/api/dispatch/ParamProcessWorkerTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.api.dispatch;
+
+import java.util.HashMap;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.context.CallContext;
+
+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.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.User;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ParamProcessWorkerTest {
+
+    @Mock
+    protected AccountManager accountManager;
+
+    protected ParamProcessWorker paramProcessWorker;
+
+    public static class TestCmd extends BaseCmd {
+
+        @Parameter(name = "strparam1")
+        String strparam1;
+
+        @Parameter(name = "intparam1", type = CommandType.INTEGER)
+        int intparam1;
+
+        @Parameter(name = "boolparam1", type = CommandType.BOOLEAN)
+        boolean boolparam1;
+
+        @Override
+        public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
+            ResourceAllocationException, NetworkRuleConflictException {
+            // well documented nothing
+        }
+
+        @Override
+        public String getCommandName() {
+            return "test";
+        }
+
+        @Override
+        public long getEntityOwnerId() {
+            return 0;
+        }
+
+    }
+
+    @Before
+    public void setup() {
+        CallContext.register(Mockito.mock(User.class), Mockito.mock(Account.class));
+        paramProcessWorker = new ParamProcessWorker();
+        paramProcessWorker._accountMgr = accountManager;
+    }
+
+    @After
+    public void cleanup() {
+        CallContext.unregister();
+    }
+
+    @Test
+    public void processParameters() {
+        final HashMap<String, String> params = new HashMap<String, String>();
+        params.put("strparam1", "foo");
+        params.put("intparam1", "100");
+        params.put("boolparam1", "true");
+        final TestCmd cmd = new TestCmd();
+        paramProcessWorker.processParameters(cmd, params);
+        Assert.assertEquals("foo", cmd.strparam1);
+        Assert.assertEquals(100, cmd.intparam1);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/test/com/cloud/api/dispatch/SpecificCmdValidationWorkerTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/api/dispatch/SpecificCmdValidationWorkerTest.java b/server/test/com/cloud/api/dispatch/SpecificCmdValidationWorkerTest.java
new file mode 100644
index 0000000..4ae7200
--- /dev/null
+++ b/server/test/com/cloud/api/dispatch/SpecificCmdValidationWorkerTest.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.api.dispatch;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import org.apache.cloudstack.api.BaseCmd;
+
+import com.cloud.exception.ResourceAllocationException;
+
+public class SpecificCmdValidationWorkerTest {
+
+    @Test
+    public void testHandle() throws ResourceAllocationException {
+        // Prepare
+        final BaseCmd cmd = mock(BaseCmd.class);
+        final Map<String, String> params = new HashMap<String, String>();
+
+        // Execute
+        final SpecificCmdValidationWorker worker = new SpecificCmdValidationWorker();
+
+        worker.handle(new DispatchTask(cmd, params));
+
+        // Assert
+        verify(cmd, times(1)).validateSpecificParameters(params);
+    }
+}


[09/50] [abbrv] Dispatcher corrections, refactoring and tests

Posted by mu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/src/com/cloud/api/ApiServer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java
index 7e29324..c94bc97 100755
--- a/server/src/com/cloud/api/ApiServer.java
+++ b/server/src/com/cloud/api/ApiServer.java
@@ -86,6 +86,7 @@ import org.springframework.stereotype.Component;
 
 import org.apache.cloudstack.acl.APIChecker;
 import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
 import org.apache.cloudstack.api.BaseAsyncCmd;
 import org.apache.cloudstack.api.BaseAsyncCreateCmd;
@@ -122,6 +123,8 @@ import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
 import org.apache.cloudstack.managed.context.ManagedContextRunnable;
 
+import com.cloud.api.dispatch.DispatchChainFactory;
+import com.cloud.api.dispatch.DispatchTask;
 import com.cloud.api.response.ApiResponseSerializer;
 import com.cloud.configuration.Config;
 import com.cloud.domain.Domain;
@@ -156,14 +159,22 @@ import com.cloud.utils.exception.ExceptionProxyObject;
 
 @Component
 public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiServerService {
+    private static final String UTF_8 = "UTF-8";
     private static final Logger s_logger = Logger.getLogger(ApiServer.class.getName());
     private static final Logger s_accessLogger = Logger.getLogger("apiserver." + ApiServer.class.getName());
 
-    private static boolean encodeApiResponse = false;
-    private static String jsonContentType = "text/javascript";
-    private static String controlCharacters = "[\000-\011\013-\014\016-\037\177]"; // Non-printable ASCII characters - numbers 0 to 31 and 127 decimal
-    @Inject ApiDispatcher _dispatcher;
+    public static boolean encodeApiResponse = false;
+    public static String jsonContentType = "text/javascript";
 
+    /**
+     * Non-printable ASCII characters - numbers 0 to 31 and 127 decimal
+     */
+    public static final String CONTROL_CHARACTERS = "[\000-\011\013-\014\016-\037\177]";
+
+    @Inject
+    protected ApiDispatcher _dispatcher;
+    @Inject
+    protected DispatchChainFactory dispatchChainFactory;
     @Inject
     private AccountManager _accountMgr;
     @Inject
@@ -191,27 +202,27 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
     }
 
     @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
         return true;
     }
 
     @Override
     public boolean start() {
         Integer apiPort = null; // api port, null by default
-        SearchCriteria<ConfigurationVO> sc = _configDao.createSearchCriteria();
+        final SearchCriteria<ConfigurationVO> sc = _configDao.createSearchCriteria();
         sc.addAnd("name", SearchCriteria.Op.EQ, Config.IntegrationAPIPort.key());
-        List<ConfigurationVO> values = _configDao.search(sc, null);
+        final List<ConfigurationVO> values = _configDao.search(sc, null);
         if ((values != null) && (values.size() > 0)) {
-            ConfigurationVO apiPortConfig = values.get(0);
+            final ConfigurationVO apiPortConfig = values.get(0);
             if (apiPortConfig.getValue() != null) {
                 apiPort = Integer.parseInt(apiPortConfig.getValue());
             }
         }
 
-        Map<String, String> configs = _configDao.getConfiguration();
-        String strSnapshotLimit = configs.get(Config.ConcurrentSnapshotsThresholdPerHost.key());
+        final Map<String, String> configs = _configDao.getConfiguration();
+        final String strSnapshotLimit = configs.get(Config.ConcurrentSnapshotsThresholdPerHost.key());
         if (strSnapshotLimit != null) {
-            Long snapshotLimit = NumbersUtil.parseLong(strSnapshotLimit, 1L);
+            final Long snapshotLimit = NumbersUtil.parseLong(strSnapshotLimit, 1L);
             if (snapshotLimit.longValue() <= 0) {
                 s_logger.debug("Global config parameter " + Config.ConcurrentSnapshotsThresholdPerHost.toString() + " is less or equal 0; defaulting to unlimited");
             } else {
@@ -219,20 +230,20 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
             }
         }
 
-        Set<Class<?>> cmdClasses = new HashSet<Class<?>>();
-        for (PluggableService pluggableService : _pluggableServices) {
+        final Set<Class<?>> cmdClasses = new HashSet<Class<?>>();
+        for (final PluggableService pluggableService : _pluggableServices) {
             cmdClasses.addAll(pluggableService.getCommands());
             if (s_logger.isDebugEnabled()) {
                 s_logger.debug("Discovered plugin " + pluggableService.getClass().getSimpleName());
             }
         }
 
-        for (Class<?> cmdClass : cmdClasses) {
-            APICommand at = cmdClass.getAnnotation(APICommand.class);
+        for (final Class<?> cmdClass : cmdClasses) {
+            final APICommand at = cmdClass.getAnnotation(APICommand.class);
             if (at == null) {
                 throw new CloudRuntimeException(String.format("%s is claimed as a API command, but it doesn't have @APICommand annotation", cmdClass.getName()));
             }
-            String apiName = at.name();
+            final String apiName = at.name();
             if (s_apiNameCmdClassMap.containsKey(apiName)) {
                 s_logger.error("API Cmd class " + cmdClass.getName() + " has non-unique apiname" + apiName);
                 continue;
@@ -241,13 +252,13 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
         }
 
         setEncodeApiResponse(Boolean.valueOf(_configDao.getValue(Config.EncodeApiResponse.key())));
-        String jsonType = _configDao.getValue(Config.JavaScriptDefaultContentType.key());
+        final String jsonType = _configDao.getValue(Config.JavaScriptDefaultContentType.key());
         if (jsonType != null) {
             jsonContentType = jsonType;
         }
 
         if (apiPort != null) {
-            ListenerThread listenerThread = new ListenerThread(this, apiPort);
+            final ListenerThread listenerThread = new ListenerThread(this, apiPort);
             listenerThread.start();
         }
 
@@ -258,13 +269,13 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
     // If integration api port is not configured, actual OTW requests will be received by ApiServlet
     @SuppressWarnings({"unchecked", "rawtypes"})
     @Override
-    public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException {
+    public void handle(final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException {
 
         // Create StringBuffer to log information in access log
-        StringBuffer sb = new StringBuffer();
-        HttpServerConnection connObj = (HttpServerConnection)context.getAttribute("http.connection");
+        final StringBuffer sb = new StringBuffer();
+        final HttpServerConnection connObj = (HttpServerConnection)context.getAttribute("http.connection");
         if (connObj instanceof SocketHttpServerConnection) {
-            InetAddress remoteAddr = ((SocketHttpServerConnection)connObj).getRemoteAddress();
+            final InetAddress remoteAddr = ((SocketHttpServerConnection)connObj).getRemoteAddress();
             sb.append(remoteAddr.toString() + " -- ");
         }
         sb.append(StringUtils.cleanString(request.getRequestLine().toString()));
@@ -272,8 +283,8 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
         try {
             List<NameValuePair> paramList = null;
             try {
-                paramList = URLEncodedUtils.parse(new URI(request.getRequestLine().getUri()), "UTF-8");
-            } catch (URISyntaxException e) {
+                paramList = URLEncodedUtils.parse(new URI(request.getRequestLine().getUri()), UTF_8);
+            } catch (final URISyntaxException e) {
                 s_logger.error("Error parsing url request", e);
             }
 
@@ -282,9 +293,9 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
             // APITODO: Use Guava's (import com.google.common.collect.Multimap;)
             // (Immutable)Multimap<String, String> paramMultiMap = HashMultimap.create();
             // Map<String, Collection<String>> parameterMap = paramMultiMap.asMap();
-            Map parameterMap = new HashMap<String, String[]>();
+            final Map parameterMap = new HashMap<String, String[]>();
             String responseType = BaseCmd.RESPONSE_TYPE_XML;
-            for (NameValuePair param : paramList) {
+            for (final NameValuePair param : paramList) {
                 if (param.getName().equalsIgnoreCase("response")) {
                     responseType = param.getValue();
                     continue;
@@ -304,15 +315,15 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
                 // always trust commands from API port, user context will always be UID_SYSTEM/ACCOUNT_ID_SYSTEM
                 CallContext.register(_accountMgr.getSystemUser(), _accountMgr.getSystemAccount());
                 sb.insert(0, "(userId=" + User.UID_SYSTEM + " accountId=" + Account.ACCOUNT_ID_SYSTEM + " sessionId=" + null + ") ");
-                String responseText = handleRequest(parameterMap, responseType, sb);
+                final String responseText = handleRequest(parameterMap, responseType, sb);
                 sb.append(" 200 " + ((responseText == null) ? 0 : responseText.length()));
 
                 writeResponse(response, responseText, HttpStatus.SC_OK, responseType, null);
-            } catch (ServerApiException se) {
-                String responseText = getSerializedApiError(se, parameterMap, responseType);
+            } catch (final ServerApiException se) {
+                final String responseText = getSerializedApiError(se, parameterMap, responseType);
                 writeResponse(response, responseText, se.getErrorCode().getHttpCode(), responseType, se.getDescription());
                 sb.append(" " + se.getErrorCode() + " " + se.getDescription());
-            } catch (RuntimeException e) {
+            } catch (final RuntimeException e) {
                 // log runtime exception like NullPointerException to help identify the source easier
                 s_logger.error("Unhandled exception, ", e);
                 throw e;
@@ -323,9 +334,32 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
         }
     }
 
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public void checkCharacterInkParams(final Map params) {
+        final Map<String, String> stringMap = new HashMap<String, String>();
+        final Set keys = params.keySet();
+        final Iterator keysIter = keys.iterator();
+        while (keysIter.hasNext()) {
+            final String key = (String)keysIter.next();
+            final String[] value = (String[])params.get(key);
+            // fail if parameter value contains ASCII control (non-printable) characters
+            if (value[0] != null) {
+                final Pattern pattern = Pattern.compile(CONTROL_CHARACTERS);
+                final Matcher matcher = pattern.matcher(value[0]);
+                if (matcher.find()) {
+                    throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Received value " + value[0] + " for parameter " + key +
+                        " is invalid, contains illegal ASCII non-printable characters");
+                }
+            }
+            stringMap.put(key, value[0]);
+        }
+    }
+
     @Override
     @SuppressWarnings("rawtypes")
-    public String handleRequest(Map params, String responseType, StringBuffer auditTrailSb) throws ServerApiException {
+    public String handleRequest(final Map params, final String responseType, final StringBuffer auditTrailSb) throws ServerApiException {
+        checkCharacterInkParams(params);
+
         String response = null;
         String[] command = null;
 
@@ -335,37 +369,27 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
                 s_logger.error("invalid request, no command sent");
                 if (s_logger.isTraceEnabled()) {
                     s_logger.trace("dumping request parameters");
-                    for (Object key : params.keySet()) {
-                        String keyStr = (String)key;
-                        String[] value = (String[])params.get(key);
+                    for (final Object key : params.keySet()) {
+                        final String keyStr = (String)key;
+                        final String[] value = (String[])params.get(key);
                         s_logger.trace("   key: " + keyStr + ", value: " + ((value == null) ? "'null'" : value[0]));
                     }
                 }
                 throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "Invalid request, no command sent");
             } else {
-                Map<String, String> paramMap = new HashMap<String, String>();
-                Set keys = params.keySet();
-                Iterator keysIter = keys.iterator();
+                final Map<String, String> paramMap = new HashMap<String, String>();
+                final Set keys = params.keySet();
+                final Iterator keysIter = keys.iterator();
                 while (keysIter.hasNext()) {
-                    String key = (String)keysIter.next();
+                    final String key = (String)keysIter.next();
                     if ("command".equalsIgnoreCase(key)) {
                         continue;
                     }
-                    String[] value = (String[])params.get(key);
-                    // fail if parameter value contains ASCII control (non-printable) characters
-                    if (value[0] != null) {
-                        Pattern pattern = Pattern.compile(controlCharacters);
-                        Matcher matcher = pattern.matcher(value[0]);
-                        if (matcher.find()) {
-                            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Received value " + value[0] + " for parameter " + key +
-                                " is invalid, contains illegal ASCII non-printable characters");
-                        }
-                    }
+                    final String[] value = (String[])params.get(key);
                     paramMap.put(key, value[0]);
                 }
 
                 Class<?> cmdClass = getCmdClass(command[0]);
-
                 if (cmdClass != null) {
                     APICommand annotation = cmdClass.getAnnotation(APICommand.class);
                     if (annotation == null) {
@@ -378,7 +402,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
                     cmdObj.configure();
                     cmdObj.setFullUrlParams(paramMap);
                     cmdObj.setResponseType(responseType);
-                    cmdObj.setHttpMethod(paramMap.get("httpmethod").toString());
+                    cmdObj.setHttpMethod(paramMap.get(ApiConstants.HTTPMETHOD).toString());
 
                     // This is where the command is either serialized, or directly dispatched
                     response = queueCommand(cmdObj, paramMap);
@@ -391,24 +415,24 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
                         buildAuditTrail(auditTrailSb, command[0], response);
                 } else {
                     if (!command[0].equalsIgnoreCase("login") && !command[0].equalsIgnoreCase("logout")) {
-                        String errorString = "Unknown API command: " + command[0];
+                        final String errorString = "Unknown API command: " + command[0];
                         s_logger.warn(errorString);
                         auditTrailSb.append(" " + errorString);
                         throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, errorString);
                     }
                 }
             }
-        } catch (InvalidParameterValueException ex) {
+        } catch (final InvalidParameterValueException ex) {
             s_logger.info(ex.getMessage());
             throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage(), ex);
-        } catch (IllegalArgumentException ex) {
+        } catch (final IllegalArgumentException ex) {
             s_logger.info(ex.getMessage());
             throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage(), ex);
-        } catch (PermissionDeniedException ex) {
-            ArrayList<ExceptionProxyObject> idList = ex.getIdProxyList();
+        } catch (final PermissionDeniedException ex) {
+            final ArrayList<ExceptionProxyObject> idList = ex.getIdProxyList();
             if (idList != null) {
-                StringBuffer buf = new StringBuffer();
-                for (ExceptionProxyObject obj : idList) {
+                final StringBuffer buf = new StringBuffer();
+                for (final ExceptionProxyObject obj : idList) {
                     buf.append(obj.getDescription());
                     buf.append(":");
                     buf.append(obj.getUuid());
@@ -419,10 +443,10 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
                 s_logger.info("PermissionDenied: " + ex.getMessage());
             }
             throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, ex.getMessage(), ex);
-        } catch (AccountLimitException ex) {
+        } catch (final AccountLimitException ex) {
             s_logger.info(ex.getMessage());
             throw new ServerApiException(ApiErrorCode.ACCOUNT_RESOURCE_LIMIT_ERROR, ex.getMessage(), ex);
-        } catch (InsufficientCapacityException ex) {
+        } catch (final InsufficientCapacityException ex) {
             s_logger.info(ex.getMessage());
             String errorMsg = ex.getMessage();
             if (CallContext.current().getCallingAccount().getType() != Account.ACCOUNT_TYPE_ADMIN) {
@@ -430,10 +454,10 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
                 errorMsg = BaseCmd.USER_ERROR_MESSAGE;
             }
             throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, errorMsg, ex);
-        } catch (ResourceAllocationException ex) {
+        } catch (final ResourceAllocationException ex) {
             s_logger.info(ex.getMessage());
             throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage(), ex);
-        } catch (ResourceUnavailableException ex) {
+        } catch (final ResourceUnavailableException ex) {
             s_logger.info(ex.getMessage());
             String errorMsg = ex.getMessage();
             if (CallContext.current().getCallingAccount().getType() != Account.ACCOUNT_TYPE_ADMIN) {
@@ -441,11 +465,11 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
                 errorMsg = BaseCmd.USER_ERROR_MESSAGE;
             }
             throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, errorMsg, ex);
-        } catch (ServerApiException ex) {
+        } catch (final ServerApiException ex) {
             s_logger.info(ex.getDescription());
             throw ex;
-        } catch (Exception ex) {
-            s_logger.error("unhandled exception executing api command: " + ((command == null) ? "null" : command[0]), ex);
+        } catch (final Exception ex) {
+            s_logger.error("unhandled exception executing api command: " + ((command == null) ? "null" : command), ex);
             String errorMsg = ex.getMessage();
             if (CallContext.current().getCallingAccount().getType() != Account.ACCOUNT_TYPE_ADMIN) {
                 // hide internal details to non-admin user for security reason
@@ -457,28 +481,28 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
         return response;
     }
 
-    private String getBaseAsyncResponse(long jobId, BaseAsyncCmd cmd) {
-        AsyncJobResponse response = new AsyncJobResponse();
+    private String getBaseAsyncResponse(final long jobId, final BaseAsyncCmd cmd) {
+        final AsyncJobResponse response = new AsyncJobResponse();
 
-        AsyncJob job = _entityMgr.findById(AsyncJob.class, jobId);
+        final AsyncJob job = _entityMgr.findById(AsyncJob.class, jobId);
         response.setJobId(job.getUuid());
         response.setResponseName(cmd.getCommandName());
         return ApiResponseSerializer.toSerializedString(response, cmd.getResponseType());
     }
 
-    private String getBaseAsyncCreateResponse(long jobId, BaseAsyncCreateCmd cmd, String objectUuid) {
-        CreateCmdResponse response = new CreateCmdResponse();
-        AsyncJob job = _entityMgr.findById(AsyncJob.class, jobId);
+    private String getBaseAsyncCreateResponse(final long jobId, final BaseAsyncCreateCmd cmd, final String objectUuid) {
+        final CreateCmdResponse response = new CreateCmdResponse();
+        final AsyncJob job = _entityMgr.findById(AsyncJob.class, jobId);
         response.setJobId(job.getUuid());
         response.setId(objectUuid);
         response.setResponseName(cmd.getCommandName());
         return ApiResponseSerializer.toSerializedString(response, cmd.getResponseType());
     }
 
-    private String queueCommand(BaseCmd cmdObj, Map<String, String> params) throws Exception {
-        CallContext ctx = CallContext.current();
-        Long callerUserId = ctx.getCallingUserId();
-        Account caller = ctx.getCallingAccount();
+    private String queueCommand(final BaseCmd cmdObj, final Map<String, String> params) throws Exception {
+        final CallContext ctx = CallContext.current();
+        final Long callerUserId = ctx.getCallingUserId();
+        final Account caller = ctx.getCallingAccount();
 
         // Queue command based on Cmd super class:
         // BaseCmd: cmd is dispatched to ApiDispatcher, executed, serialized and returned.
@@ -488,16 +512,16 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
             Long objectId = null;
             String objectUuid = null;
             if (cmdObj instanceof BaseAsyncCreateCmd) {
-                BaseAsyncCreateCmd createCmd = (BaseAsyncCreateCmd)cmdObj;
+                final BaseAsyncCreateCmd createCmd = (BaseAsyncCreateCmd)cmdObj;
                 _dispatcher.dispatchCreateCmd(createCmd, params);
                 objectId = createCmd.getEntityId();
                 objectUuid = createCmd.getEntityUuid();
                 params.put("id", objectId.toString());
             } else {
-                ApiDispatcher.processParameters(cmdObj, params);
+                dispatchChainFactory.getStandardDispatchChain().dispatch(new DispatchTask(cmdObj, params));
             }
 
-            BaseAsyncCmd asyncCmd = (BaseAsyncCmd)cmdObj;
+            final BaseAsyncCmd asyncCmd = (BaseAsyncCmd)cmdObj;
 
             if (callerUserId != null) {
                 params.put("ctxUserId", callerUserId.toString());
@@ -510,7 +534,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
             asyncCmd.setStartEventId(startEventId);
 
             // save the scheduled event
-            Long eventId =
+            final Long eventId =
                 ActionEventUtils.onScheduledActionEvent((callerUserId == null) ? User.UID_SYSTEM : callerUserId, asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(),
                     asyncCmd.getEventDescription(), asyncCmd.isDisplayResourceEnabled(), startEventId);
             if (startEventId == 0) {
@@ -527,16 +551,16 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
                     asyncCmd.getInstanceType() != null ? asyncCmd.getInstanceType().toString() : null);
             job.setDispatcher(_asyncDispatcher.getName());
 
-            long jobId = _asyncMgr.submitAsyncJob(job);
+            final long jobId = _asyncMgr.submitAsyncJob(job);
 
             if (jobId == 0L) {
-                String errorMsg = "Unable to schedule async job for command " + job.getCmd();
+                final String errorMsg = "Unable to schedule async job for command " + job.getCmd();
                 s_logger.warn(errorMsg);
                 throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMsg);
             }
 
             if (objectId != null) {
-                String objUuid = (objectUuid == null) ? objectId.toString() : objectUuid;
+                final String objUuid = (objectUuid == null) ? objectId.toString() : objectUuid;
                 return getBaseAsyncCreateResponse(jobId, (BaseAsyncCreateCmd)asyncCmd, objUuid);
             } else {
                 SerializationContext.current().setUuidTranslation(true);
@@ -563,8 +587,8 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
     }
 
     @SuppressWarnings("unchecked")
-    private void buildAsyncListResponse(BaseListCmd command, Account account) {
-        List<ResponseObject> responses = ((ListResponse)command.getResponseObject()).getResponses();
+    private void buildAsyncListResponse(final BaseListCmd command, final Account account) {
+        final List<ResponseObject> responses = ((ListResponse)command.getResponseObject()).getResponses();
         if (responses != null && responses.size() > 0) {
             List<? extends AsyncJob> jobs = null;
 
@@ -579,18 +603,18 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
                 return;
             }
 
-            Map<String, AsyncJob> objectJobMap = new HashMap<String, AsyncJob>();
-            for (AsyncJob job : jobs) {
+            final Map<String, AsyncJob> objectJobMap = new HashMap<String, AsyncJob>();
+            for (final AsyncJob job : jobs) {
                 if (job.getInstanceId() == null) {
                     continue;
                 }
-                String instanceUuid = ApiDBUtils.findJobInstanceUuid(job);
+                final String instanceUuid = ApiDBUtils.findJobInstanceUuid(job);
                 objectJobMap.put(instanceUuid, job);
             }
 
-            for (ResponseObject response : responses) {
+            for (final ResponseObject response : responses) {
                 if (response.getObjectId() != null && objectJobMap.containsKey(response.getObjectId())) {
-                    AsyncJob job = objectJobMap.get(response.getObjectId());
+                    final AsyncJob job = objectJobMap.get(response.getObjectId());
                     response.setJobId(job.getUuid());
                     response.setJobStatus(job.getStatus().ordinal());
                 }
@@ -598,7 +622,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
         }
     }
 
-    private void buildAuditTrail(StringBuffer auditTrailSb, String command, String result) {
+    private void buildAuditTrail(final StringBuffer auditTrailSb, final String command, final String result) {
         if (result == null) {
             return;
         }
@@ -611,31 +635,31 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
     }
 
     @Override
-    public boolean verifyRequest(Map<String, Object[]> requestParameters, Long userId) throws ServerApiException {
+    public boolean verifyRequest(final Map<String, Object[]> requestParameters, final Long userId) throws ServerApiException {
         try {
             String apiKey = null;
             String secretKey = null;
             String signature = null;
             String unsignedRequest = null;
 
-            String[] command = (String[])requestParameters.get("command");
+            final String[] command = (String[])requestParameters.get(ApiConstants.COMMAND);
             if (command == null) {
                 s_logger.info("missing command, ignoring request...");
                 return false;
             }
 
-            String commandName = command[0];
+            final String commandName = command[0];
 
             // if userId not null, that mean that user is logged in
             if (userId != null) {
-                User user = ApiDBUtils.findUserById(userId);
+                final User user = ApiDBUtils.findUserById(userId);
 
                 try {
                     checkCommandAvailable(user, commandName);
-                } catch (RequestLimitException ex) {
+                } catch (final RequestLimitException ex) {
                     s_logger.debug(ex.getMessage());
                     throw new ServerApiException(ApiErrorCode.API_LIMIT_EXCEED, ex.getMessage());
-                } catch (PermissionDeniedException ex) {
+                } catch (final PermissionDeniedException ex) {
                     s_logger.debug("The given command:" + commandName + " does not exist or it is not available for user with id:" + userId);
                     throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "The given command does not exist or it is not available for user");
                 }
@@ -650,9 +674,9 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
 
             // - build a request string with sorted params, make sure it's all lowercase
             // - sign the request, verify the signature is the same
-            List<String> parameterNames = new ArrayList<String>();
+            final List<String> parameterNames = new ArrayList<String>();
 
-            for (Object paramNameObj : requestParameters.keySet()) {
+            for (final Object paramNameObj : requestParameters.keySet()) {
                 parameterNames.add((String)paramNameObj); // put the name in a list that we'll sort later
             }
 
@@ -661,25 +685,25 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
             String signatureVersion = null;
             String expires = null;
 
-            for (String paramName : parameterNames) {
+            for (final String paramName : parameterNames) {
                 // parameters come as name/value pairs in the form String/String[]
-                String paramValue = ((String[])requestParameters.get(paramName))[0];
+                final String paramValue = ((String[])requestParameters.get(paramName))[0];
 
-                if ("signature".equalsIgnoreCase(paramName)) {
+                if (ApiConstants.SIGNATURE.equalsIgnoreCase(paramName)) {
                     signature = paramValue;
                 } else {
-                    if ("apikey".equalsIgnoreCase(paramName)) {
+                    if (ApiConstants.API_KEY.equalsIgnoreCase(paramName)) {
                         apiKey = paramValue;
-                    } else if ("signatureversion".equalsIgnoreCase(paramName)) {
+                    } else if (ApiConstants.SIGNATURE_VERSION.equalsIgnoreCase(paramName)) {
                         signatureVersion = paramValue;
-                    } else if ("expires".equalsIgnoreCase(paramName)) {
+                    } else if (ApiConstants.EXPIRES.equalsIgnoreCase(paramName)) {
                         expires = paramValue;
                     }
 
                     if (unsignedRequest == null) {
-                        unsignedRequest = paramName + "=" + URLEncoder.encode(paramValue, "UTF-8").replaceAll("\\+", "%20");
+                        unsignedRequest = paramName + "=" + URLEncoder.encode(paramValue, UTF_8).replaceAll("\\+", "%20");
                     } else {
-                        unsignedRequest = unsignedRequest + "&" + paramName + "=" + URLEncoder.encode(paramValue, "UTF-8").replaceAll("\\+", "%20");
+                        unsignedRequest = unsignedRequest + "&" + paramName + "=" + URLEncoder.encode(paramValue, UTF_8).replaceAll("\\+", "%20");
                     }
                 }
             }
@@ -701,30 +725,30 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
                 synchronized (DateFormatToUse) {
                     try {
                         expiresTS = DateFormatToUse.parse(expires);
-                    } catch (ParseException pe) {
+                    } catch (final ParseException pe) {
                         s_logger.debug("Incorrect date format for Expires parameter", pe);
                         return false;
                     }
                 }
-                Date now = new Date(System.currentTimeMillis());
+                final Date now = new Date(System.currentTimeMillis());
                 if (expiresTS.before(now)) {
                     s_logger.debug("Request expired -- ignoring ...sig: " + signature + ", apiKey: " + apiKey);
                     return false;
                 }
             }
 
-            TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
+            final TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
             txn.close();
             User user = null;
             // verify there is a user with this api key
-            Pair<User, Account> userAcctPair = _accountMgr.findUserByApiKey(apiKey);
+            final Pair<User, Account> userAcctPair = _accountMgr.findUserByApiKey(apiKey);
             if (userAcctPair == null) {
                 s_logger.debug("apiKey does not map to a valid user -- ignoring request, apiKey: " + apiKey);
                 return false;
             }
 
             user = userAcctPair.first();
-            Account account = userAcctPair.second();
+            final Account account = userAcctPair.second();
 
             if (user.getState() != Account.State.enabled || !account.getState().equals(Account.State.enabled)) {
                 s_logger.info("disabled or locked user accessing the api, userid = " + user.getId() + "; name = " + user.getUsername() + "; state: " + user.getState() +
@@ -734,10 +758,10 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
 
             try {
                 checkCommandAvailable(user, commandName);
-            } catch (RequestLimitException ex) {
+            } catch (final RequestLimitException ex) {
                 s_logger.debug(ex.getMessage());
                 throw new ServerApiException(ApiErrorCode.API_LIMIT_EXCEED, ex.getMessage());
-            } catch (PermissionDeniedException ex) {
+            } catch (final PermissionDeniedException ex) {
                 s_logger.debug("The given command:" + commandName + " does not exist or it is not available for user");
                 throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "The given command:" + commandName + " does not exist or it is not available for user with id:"
                         + userId);
@@ -752,30 +776,30 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
 
             unsignedRequest = unsignedRequest.toLowerCase();
 
-            Mac mac = Mac.getInstance("HmacSHA1");
-            SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1");
+            final Mac mac = Mac.getInstance("HmacSHA1");
+            final SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1");
             mac.init(keySpec);
             mac.update(unsignedRequest.getBytes());
-            byte[] encryptedBytes = mac.doFinal();
-            String computedSignature = Base64.encodeBase64String(encryptedBytes);
-            boolean equalSig = signature.equals(computedSignature);
+            final byte[] encryptedBytes = mac.doFinal();
+            final String computedSignature = Base64.encodeBase64String(encryptedBytes);
+            final boolean equalSig = signature.equals(computedSignature);
             if (!equalSig) {
                 s_logger.info("User signature: " + signature + " is not equaled to computed signature: " + computedSignature);
             } else {
                 CallContext.register(user, account);
             }
             return equalSig;
-        } catch (ServerApiException ex) {
+        } catch (final ServerApiException ex) {
             throw ex;
-        } catch (Exception ex) {
+        } catch (final Exception ex) {
             s_logger.error("unable to verify request signature");
         }
         return false;
     }
 
     @Override
-    public Long fetchDomainId(String domainUUID) {
-        Domain domain = _domainMgr.getDomain(domainUUID);
+    public Long fetchDomainId(final String domainUUID) {
+        final Domain domain = _domainMgr.getDomain(domainUUID);
         if (domain != null)
             return domain.getId();
         else
@@ -783,15 +807,15 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
     }
 
     @Override
-    public void loginUser(HttpSession session, String username, String password, Long domainId, String domainPath, String loginIpAddress,
-        Map<String, Object[]> requestParameters) throws CloudAuthenticationException {
+    public void loginUser(final HttpSession session, final String username, final String password, Long domainId, final String domainPath, final String loginIpAddress,
+        final Map<String, Object[]> requestParameters) throws CloudAuthenticationException {
         // We will always use domainId first. If that does not exist, we will use domain name. If THAT doesn't exist
         // we will default to ROOT
         if (domainId == null) {
             if (domainPath == null || domainPath.trim().length() == 0) {
                 domainId = Domain.ROOT_DOMAIN;
             } else {
-                Domain domainObj = _domainMgr.findDomainByPath(domainPath);
+                final Domain domainObj = _domainMgr.findDomainByPath(domainPath);
                 if (domainObj != null) {
                     domainId = domainObj.getId();
                 } else { // if an unknown path is passed in, fail the login call
@@ -800,26 +824,26 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
             }
         }
 
-        UserAccount userAcct = _accountMgr.authenticateUser(username, password, domainId, loginIpAddress, requestParameters);
+        final UserAccount userAcct = _accountMgr.authenticateUser(username, password, domainId, loginIpAddress, requestParameters);
         if (userAcct != null) {
-            String timezone = userAcct.getTimezone();
+            final String timezone = userAcct.getTimezone();
             float offsetInHrs = 0f;
             if (timezone != null) {
-                TimeZone t = TimeZone.getTimeZone(timezone);
+                final TimeZone t = TimeZone.getTimeZone(timezone);
                 s_logger.info("Current user logged in under " + timezone + " timezone");
 
-                java.util.Date date = new java.util.Date();
-                long longDate = date.getTime();
-                float offsetInMs = (t.getOffset(longDate));
+                final java.util.Date date = new java.util.Date();
+                final long longDate = date.getTime();
+                final float offsetInMs = (t.getOffset(longDate));
                 offsetInHrs = offsetInMs / (1000 * 60 * 60);
                 s_logger.info("Timezone offset from UTC is: " + offsetInHrs);
             }
 
-            Account account = _accountMgr.getAccount(userAcct.getAccountId());
+            final Account account = _accountMgr.getAccount(userAcct.getAccountId());
 
             // set the userId and account object for everyone
             session.setAttribute("userid", userAcct.getId());
-            UserVO user = (UserVO)_accountMgr.getActiveUser(userAcct.getId());
+            final UserVO user = (UserVO)_accountMgr.getActiveUser(userAcct.getId());
             if (user.getUuid() != null) {
                 session.setAttribute("user_UUID", user.getUuid());
             }
@@ -831,7 +855,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
             session.setAttribute("account", account.getAccountName());
 
             session.setAttribute("domainid", account.getDomainId());
-            DomainVO domain = (DomainVO)_domainMgr.getDomain(account.getDomainId());
+            final DomainVO domain = (DomainVO)_domainMgr.getDomain(account.getDomainId());
             if (domain.getUuid() != null) {
                 session.setAttribute("domain_UUID", domain.getUuid());
             }
@@ -847,10 +871,10 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
 
             // (bug 5483) generate a session key that the user must submit on every request to prevent CSRF, add that
             // to the login response so that session-based authenticators know to send the key back
-            SecureRandom sesssionKeyRandom = new SecureRandom();
-            byte sessionKeyBytes[] = new byte[20];
+            final SecureRandom sesssionKeyRandom = new SecureRandom();
+            final byte sessionKeyBytes[] = new byte[20];
             sesssionKeyRandom.nextBytes(sessionKeyBytes);
-            String sessionKey = Base64.encodeBase64String(sessionKeyBytes);
+            final String sessionKey = Base64.encodeBase64String(sessionKeyBytes);
             session.setAttribute("sessionkey", sessionKey);
 
             return;
@@ -859,14 +883,14 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
     }
 
     @Override
-    public void logoutUser(long userId) {
+    public void logoutUser(final long userId) {
         _accountMgr.logoutUser(userId);
         return;
     }
 
     @Override
-    public boolean verifyUser(Long userId) {
-        User user = _accountMgr.getUserIncludingRemoved(userId);
+    public boolean verifyUser(final Long userId) {
+        final User user = _accountMgr.getUserIncludingRemoved(userId);
         Account account = null;
         if (user != null) {
             account = _accountMgr.getAccount(user.getAccountId());
@@ -880,46 +904,46 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
         return true;
     }
 
-    private void checkCommandAvailable(User user, String commandName) throws PermissionDeniedException {
+    private void checkCommandAvailable(final User user, final String commandName) throws PermissionDeniedException {
         if (user == null) {
             throw new PermissionDeniedException("User is null for role based API access check for command" + commandName);
         }
 
-        for (APIChecker apiChecker : _apiAccessCheckers) {
+        for (final APIChecker apiChecker : _apiAccessCheckers) {
             apiChecker.checkAccess(user, commandName);
         }
     }
 
     @Override
-    public Class<?> getCmdClass(String cmdName) {
+    public Class<?> getCmdClass(final String cmdName) {
         return s_apiNameCmdClassMap.get(cmdName);
     }
 
     // FIXME: rather than isError, we might was to pass in the status code to give more flexibility
-    private void writeResponse(HttpResponse resp, final String responseText, final int statusCode, String responseType, String reasonPhrase) {
+    private void writeResponse(final HttpResponse resp, final String responseText, final int statusCode, final String responseType, final String reasonPhrase) {
         try {
             resp.setStatusCode(statusCode);
             resp.setReasonPhrase(reasonPhrase);
 
-            BasicHttpEntity body = new BasicHttpEntity();
+            final BasicHttpEntity body = new BasicHttpEntity();
             if (BaseCmd.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
                 // JSON response
                 body.setContentType(jsonContentType);
                 if (responseText == null) {
-                    body.setContent(new ByteArrayInputStream("{ \"error\" : { \"description\" : \"Internal Server Error\" } }".getBytes("UTF-8")));
+                    body.setContent(new ByteArrayInputStream("{ \"error\" : { \"description\" : \"Internal Server Error\" } }".getBytes(UTF_8)));
                 }
             } else {
                 body.setContentType("text/xml");
                 if (responseText == null) {
-                    body.setContent(new ByteArrayInputStream("<error>Internal Server Error</error>".getBytes("UTF-8")));
+                    body.setContent(new ByteArrayInputStream("<error>Internal Server Error</error>".getBytes(UTF_8)));
                 }
             }
 
             if (responseText != null) {
-                body.setContent(new ByteArrayInputStream(responseText.getBytes("UTF-8")));
+                body.setContent(new ByteArrayInputStream(responseText.getBytes(UTF_8)));
             }
             resp.setEntity(body);
-        } catch (Exception ex) {
+        } catch (final Exception ex) {
             s_logger.error("error!", ex);
         }
     }
@@ -934,10 +958,10 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
         private ServerSocket _serverSocket = null;
         private HttpParams _params = null;
 
-        public ListenerThread(ApiServer requestHandler, int port) {
+        public ListenerThread(final ApiServer requestHandler, final int port) {
             try {
                 _serverSocket = new ServerSocket(port);
-            } catch (IOException ioex) {
+            } catch (final IOException ioex) {
                 s_logger.error("error initializing api server", ioex);
                 return;
             }
@@ -950,14 +974,14 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
                 .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpComponents/1.1");
 
             // Set up the HTTP protocol processor
-            BasicHttpProcessor httpproc = new BasicHttpProcessor();
+            final BasicHttpProcessor httpproc = new BasicHttpProcessor();
             httpproc.addInterceptor(new ResponseDate());
             httpproc.addInterceptor(new ResponseServer());
             httpproc.addInterceptor(new ResponseContent());
             httpproc.addInterceptor(new ResponseConnControl());
 
             // Set up request handlers
-            HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry();
+            final HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry();
             reqistry.register("*", requestHandler);
 
             // Set up the HTTP service
@@ -972,15 +996,15 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
             while (!Thread.interrupted()) {
                 try {
                     // Set up HTTP connection
-                    Socket socket = _serverSocket.accept();
-                    DefaultHttpServerConnection conn = new DefaultHttpServerConnection();
+                    final Socket socket = _serverSocket.accept();
+                    final DefaultHttpServerConnection conn = new DefaultHttpServerConnection();
                     conn.bind(socket, _params);
 
                     // Execute a new worker task to handle the request
                     s_executor.execute(new WorkerTask(_httpService, conn, s_workerCount++));
-                } catch (InterruptedIOException ex) {
+                } catch (final InterruptedIOException ex) {
                     break;
-                } catch (IOException e) {
+                } catch (final IOException e) {
                     s_logger.error("I/O error initializing connection thread", e);
                     break;
                 }
@@ -999,33 +1023,33 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
 
         @Override
         protected void runInContext() {
-            HttpContext context = new BasicHttpContext(null);
+            final HttpContext context = new BasicHttpContext(null);
             try {
                 while (!Thread.interrupted() && _conn.isOpen()) {
                     _httpService.handleRequest(_conn, context);
                     _conn.close();
                 }
-            } catch (ConnectionClosedException ex) {
+            } catch (final ConnectionClosedException ex) {
                 if (s_logger.isTraceEnabled()) {
                     s_logger.trace("ApiServer:  Client closed connection");
                 }
-            } catch (IOException ex) {
+            } catch (final IOException ex) {
                 if (s_logger.isTraceEnabled()) {
                     s_logger.trace("ApiServer:  IOException - " + ex);
                 }
-            } catch (HttpException ex) {
+            } catch (final HttpException ex) {
                 s_logger.warn("ApiServer:  Unrecoverable HTTP protocol violation" + ex);
             } finally {
                 try {
                     _conn.shutdown();
-                } catch (IOException ignore) {
+                } catch (final IOException ignore) {
                 }
             }
         }
     }
 
     @Override
-    public String getSerializedApiError(int errorCode, String errorText, Map<String, Object[]> apiCommandParams, String responseType) {
+    public String getSerializedApiError(final int errorCode, final String errorText, final Map<String, Object[]> apiCommandParams, final String responseType) {
         String responseName = null;
         Class<?> cmdClass = null;
         String responseText = null;
@@ -1034,10 +1058,10 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
             if (apiCommandParams == null || apiCommandParams.isEmpty()) {
                 responseName = "errorresponse";
             } else {
-                Object cmdObj = apiCommandParams.get("command");
+                final Object cmdObj = apiCommandParams.get(ApiConstants.COMMAND);
                 // cmd name can be null when "command" parameter is missing in the request
                 if (cmdObj != null) {
-                    String cmdName = ((String[])cmdObj)[0];
+                    final String cmdName = ((String[])cmdObj)[0];
                     cmdClass = getCmdClass(cmdName);
                     if (cmdClass != null) {
                         responseName = ((BaseCmd)cmdClass.newInstance()).getCommandName();
@@ -1046,21 +1070,21 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
                     }
                 }
             }
-            ExceptionResponse apiResponse = new ExceptionResponse();
+            final ExceptionResponse apiResponse = new ExceptionResponse();
             apiResponse.setErrorCode(errorCode);
             apiResponse.setErrorText(errorText);
             apiResponse.setResponseName(responseName);
             SerializationContext.current().setUuidTranslation(true);
             responseText = ApiResponseSerializer.toSerializedString(apiResponse, responseType);
 
-        } catch (Exception e) {
+        } catch (final Exception e) {
             s_logger.error("Exception responding to http request", e);
         }
         return responseText;
     }
 
     @Override
-    public String getSerializedApiError(ServerApiException ex, Map<String, Object[]> apiCommandParams, String responseType) {
+    public String getSerializedApiError(final ServerApiException ex, final Map<String, Object[]> apiCommandParams, final String responseType) {
         String responseName = null;
         Class<?> cmdClass = null;
         String responseText = null;
@@ -1073,11 +1097,11 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
             if (ex.getErrorCode() == ApiErrorCode.UNSUPPORTED_ACTION_ERROR || apiCommandParams == null || apiCommandParams.isEmpty()) {
                 responseName = "errorresponse";
             } else {
-                Object cmdObj = apiCommandParams.get("command");
+                final Object cmdObj = apiCommandParams.get(ApiConstants.COMMAND);
                 // cmd name can be null when "command" parameter is missing in
                 // the request
                 if (cmdObj != null) {
-                    String cmdName = ((String[])cmdObj)[0];
+                    final String cmdName = ((String[])cmdObj)[0];
                     cmdClass = getCmdClass(cmdName);
                     if (cmdClass != null) {
                         responseName = ((BaseCmd)cmdClass.newInstance()).getCommandName();
@@ -1086,11 +1110,11 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
                     }
                 }
             }
-            ExceptionResponse apiResponse = new ExceptionResponse();
+            final ExceptionResponse apiResponse = new ExceptionResponse();
             apiResponse.setErrorCode(ex.getErrorCode().getHttpCode());
             apiResponse.setErrorText(ex.getDescription());
             apiResponse.setResponseName(responseName);
-            ArrayList<ExceptionProxyObject> idList = ex.getIdProxyList();
+            final ArrayList<ExceptionProxyObject> idList = ex.getIdProxyList();
             if (idList != null) {
                 for (int i = 0; i < idList.size(); i++) {
                     apiResponse.addProxyObject(idList.get(i));
@@ -1103,7 +1127,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
             SerializationContext.current().setUuidTranslation(true);
             responseText = ApiResponseSerializer.toSerializedString(apiResponse, responseType);
 
-        } catch (Exception e) {
+        } catch (final Exception e) {
             s_logger.error("Exception responding to http request", e);
         }
         return responseText;
@@ -1114,7 +1138,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
     }
 
     @Inject
-    public void setPluggableServices(List<PluggableService> pluggableServices) {
+    public void setPluggableServices(final List<PluggableService> pluggableServices) {
         _pluggableServices = pluggableServices;
     }
 
@@ -1123,7 +1147,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
     }
 
     @Inject
-    public void setApiAccessCheckers(List<APIChecker> apiAccessCheckers) {
+    public void setApiAccessCheckers(final List<APIChecker> apiAccessCheckers) {
         _apiAccessCheckers = apiAccessCheckers;
     }
 
@@ -1131,7 +1155,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
         return encodeApiResponse;
     }
 
-    private static void setEncodeApiResponse(boolean encodeApiResponse) {
+    private static void setEncodeApiResponse(final boolean encodeApiResponse) {
         ApiServer.encodeApiResponse = encodeApiResponse;
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/src/com/cloud/api/ApiServlet.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java
index 46f7eba..37a2549 100755
--- a/server/src/com/cloud/api/ApiServlet.java
+++ b/server/src/com/cloud/api/ApiServlet.java
@@ -35,6 +35,7 @@ import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 import org.springframework.web.context.support.SpringBeanAutowiringSupport;
 
+import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
 import org.apache.cloudstack.api.BaseCmd;
 import org.apache.cloudstack.api.ServerApiException;
@@ -67,40 +68,40 @@ public class ApiServlet extends HttpServlet {
     }
 
     @Override
-    public void init(ServletConfig config) throws ServletException {
+    public void init(final ServletConfig config) throws ServletException {
         SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, config.getServletContext());
     }
 
     @Override
-    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
+    protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) {
         processRequest(req, resp);
     }
 
     @Override
-    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
+    protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) {
         processRequest(req, resp);
     }
 
-    private void utf8Fixup(HttpServletRequest req, Map<String, Object[]> params) {
+    private void utf8Fixup(final HttpServletRequest req, final Map<String, Object[]> params) {
         if (req.getQueryString() == null) {
             return;
         }
 
-        String[] paramsInQueryString = req.getQueryString().split("&");
+        final String[] paramsInQueryString = req.getQueryString().split("&");
         if (paramsInQueryString != null) {
-            for (String param : paramsInQueryString) {
-                String[] paramTokens = param.split("=", 2);
+            for (final String param : paramsInQueryString) {
+                final String[] paramTokens = param.split("=", 2);
                 if (paramTokens != null && paramTokens.length == 2) {
                     String name = paramTokens[0];
                     String value = paramTokens[1];
 
                     try {
                         name = URLDecoder.decode(name, "UTF-8");
-                    } catch (UnsupportedEncodingException e) {
+                    } catch (final UnsupportedEncodingException e) {
                     }
                     try {
                         value = URLDecoder.decode(value, "UTF-8");
-                    } catch (UnsupportedEncodingException e) {
+                    } catch (final UnsupportedEncodingException e) {
                     }
                     params.put(name, new String[] {value});
                 } else {
@@ -119,13 +120,13 @@ public class ApiServlet extends HttpServlet {
         });
     }
 
-    private void processRequestInContext(HttpServletRequest req, HttpServletResponse resp) {
-        StringBuffer auditTrailSb = new StringBuffer();
+    private void processRequestInContext(final HttpServletRequest req, final HttpServletResponse resp) {
+        final StringBuffer auditTrailSb = new StringBuffer();
         auditTrailSb.append(" " + req.getRemoteAddr());
         auditTrailSb.append(" -- " + req.getMethod() + " ");
         // get the response format since we'll need it in a couple of places
         String responseType = BaseCmd.RESPONSE_TYPE_XML;
-        Map<String, Object[]> params = new HashMap<String, Object[]>();
+        final Map<String, Object[]> params = new HashMap<String, Object[]>();
         params.putAll(req.getParameterMap());
 
         // For HTTP GET requests, it seems that HttpServletRequest.getParameterMap() actually tries
@@ -143,19 +144,19 @@ public class ApiServlet extends HttpServlet {
 
         try {
             HttpSession session = req.getSession(false);
-            Object[] responseTypeParam = params.get("response");
+            final Object[] responseTypeParam = params.get(ApiConstants.RESPONSE);
             if (responseTypeParam != null) {
                 responseType = (String)responseTypeParam[0];
             }
 
-            Object[] commandObj = params.get("command");
+            final Object[] commandObj = params.get(ApiConstants.COMMAND);
             if (commandObj != null) {
-                String command = (String)commandObj[0];
+                final String command = (String)commandObj[0];
                 if ("logout".equalsIgnoreCase(command)) {
                     // if this is just a logout, invalidate the session and return
                     if (session != null) {
-                        Long userId = (Long)session.getAttribute("userid");
-                        Account account = (Account)session.getAttribute("accountobj");
+                        final Long userId = (Long)session.getAttribute("userid");
+                        final Account account = (Account)session.getAttribute("accountobj");
                         Long accountId = null;
                         if (account != null) {
                             accountId = account.getId();
@@ -166,7 +167,7 @@ public class ApiServlet extends HttpServlet {
                         }
                         try {
                             session.invalidate();
-                        } catch (IllegalStateException ise) {
+                        } catch (final IllegalStateException ise) {
                         }
                     }
                     auditTrailSb.append("command=logout");
@@ -179,18 +180,18 @@ public class ApiServlet extends HttpServlet {
                     if (session != null) {
                         try {
                             session.invalidate();
-                        } catch (IllegalStateException ise) {
+                        } catch (final IllegalStateException ise) {
                         }
                     }
                     session = req.getSession(true);
-                    String[] username = (String[])params.get("username");
-                    String[] password = (String[])params.get("password");
-                    String[] domainIdArr = (String[])params.get("domainid");
+                    final String[] username = (String[])params.get(ApiConstants.USERNAME);
+                    final String[] password = (String[])params.get(ApiConstants.PASSWORD);
+                    String[] domainIdArr = (String[])params.get(ApiConstants.DOMAIN_ID);
 
                     if (domainIdArr == null) {
-                        domainIdArr = (String[])params.get("domainId");
+                        domainIdArr = (String[])params.get(ApiConstants.DOMAIN__ID);
                     }
-                    String[] domainName = (String[])params.get("domain");
+                    final String[] domainName = (String[])params.get(ApiConstants.DOMAIN);
                     Long domainId = null;
                     if ((domainIdArr != null) && (domainIdArr.length > 0)) {
                         try {
@@ -200,10 +201,10 @@ public class ApiServlet extends HttpServlet {
                                 domainId = new Long(Long.parseLong(domainIdArr[0]));
                             }
                             auditTrailSb.append(" domainid=" + domainId);// building the params for POST call
-                        } catch (NumberFormatException e) {
+                        } catch (final NumberFormatException e) {
                             s_logger.warn("Invalid domain id entered by user");
                             auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "Invalid domain id entered, please enter a valid one");
-                            String serializedResponse =
+                            final String serializedResponse =
                                 _apiServer.getSerializedApiError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid domain id entered, please enter a valid one", params,
                                     responseType);
                             writeResponse(resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType);
@@ -225,24 +226,24 @@ public class ApiServlet extends HttpServlet {
                     }
 
                     if (username != null) {
-                        String pwd = ((password == null) ? null : password[0]);
+                        final String pwd = ((password == null) ? null : password[0]);
                         try {
                             _apiServer.loginUser(session, username[0], pwd, domainId, domain, req.getRemoteAddr(), params);
                             auditTrailSb.insert(0, "(userId=" + session.getAttribute("userid") + " accountId=" + ((Account)session.getAttribute("accountobj")).getId() +
                                 " sessionId=" + session.getId() + ")");
-                            String loginResponse = getLoginSuccessResponse(session, responseType);
+                            final String loginResponse = getLoginSuccessResponse(session, responseType);
                             writeResponse(resp, loginResponse, HttpServletResponse.SC_OK, responseType);
                             return;
-                        } catch (CloudAuthenticationException ex) {
+                        } catch (final CloudAuthenticationException ex) {
                             // TODO: fall through to API key, or just fail here w/ auth error? (HTTP 401)
                             try {
                                 session.invalidate();
-                            } catch (IllegalStateException ise) {
+                            } catch (final IllegalStateException ise) {
                             }
 
                             auditTrailSb.append(" " + ApiErrorCode.ACCOUNT_ERROR + " " + ex.getMessage() != null ? ex.getMessage()
                                 : "failed to authenticate user, check if username/password are correct");
-                            String serializedResponse =
+                            final String serializedResponse =
                                 _apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), ex.getMessage() != null ? ex.getMessage()
                                     : "failed to authenticate user, check if username/password are correct", params, responseType);
                             writeResponse(resp, serializedResponse, ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), responseType);
@@ -252,7 +253,7 @@ public class ApiServlet extends HttpServlet {
                 }
             }
             auditTrailSb.append(req.getQueryString());
-            boolean isNew = ((session == null) ? true : session.isNew());
+            final boolean isNew = ((session == null) ? true : session.isNew());
 
             // Initialize an empty context and we will update it after we have verified the request below,
             // we no longer rely on web-session here, verifyRequest will populate user/account information
@@ -261,17 +262,17 @@ public class ApiServlet extends HttpServlet {
 
             if (!isNew) {
                 userId = (Long)session.getAttribute("userid");
-                String account = (String)session.getAttribute("account");
-                Object accountObj = session.getAttribute("accountobj");
-                String sessionKey = (String)session.getAttribute("sessionkey");
-                String[] sessionKeyParam = (String[])params.get("sessionkey");
+                final String account = (String)session.getAttribute("account");
+                final Object accountObj = session.getAttribute("accountobj");
+                final String sessionKey = (String)session.getAttribute("sessionkey");
+                final String[] sessionKeyParam = (String[])params.get(ApiConstants.SESSIONKEY);
                 if ((sessionKeyParam == null) || (sessionKey == null) || !sessionKey.equals(sessionKeyParam[0])) {
                     try {
                         session.invalidate();
-                    } catch (IllegalStateException ise) {
+                    } catch (final IllegalStateException ise) {
                     }
                     auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "unable to verify user credentials");
-                    String serializedResponse =
+                    final String serializedResponse =
                         _apiServer.getSerializedApiError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials", params, responseType);
                     writeResponse(resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType);
                     return;
@@ -279,26 +280,26 @@ public class ApiServlet extends HttpServlet {
 
                 // Do a sanity check here to make sure the user hasn't already been deleted
                 if ((userId != null) && (account != null) && (accountObj != null) && _apiServer.verifyUser(userId)) {
-                    String[] command = (String[])params.get("command");
+                    final String[] command = (String[])params.get(ApiConstants.COMMAND);
                     if (command == null) {
                         s_logger.info("missing command, ignoring request...");
                         auditTrailSb.append(" " + HttpServletResponse.SC_BAD_REQUEST + " " + "no command specified");
-                        String serializedResponse = _apiServer.getSerializedApiError(HttpServletResponse.SC_BAD_REQUEST, "no command specified", params, responseType);
+                        final String serializedResponse = _apiServer.getSerializedApiError(HttpServletResponse.SC_BAD_REQUEST, "no command specified", params, responseType);
                         writeResponse(resp, serializedResponse, HttpServletResponse.SC_BAD_REQUEST, responseType);
                         return;
                     }
-                    User user = _entityMgr.findById(User.class, userId);
+                    final User user = _entityMgr.findById(User.class, userId);
                     CallContext.register(user, (Account)accountObj);
                 } else {
                     // Invalidate the session to ensure we won't allow a request across management server
                     // restarts if the userId was serialized to the stored session
                     try {
                         session.invalidate();
-                    } catch (IllegalStateException ise) {
+                    } catch (final IllegalStateException ise) {
                     }
 
                     auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "unable to verify user credentials");
-                    String serializedResponse =
+                    final String serializedResponse =
                         _apiServer.getSerializedApiError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials", params, responseType);
                     writeResponse(resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType);
                     return;
@@ -326,29 +327,29 @@ public class ApiServlet extends HttpServlet {
 
                 // Add the HTTP method (GET/POST/PUT/DELETE) as well into the params map.
                 params.put("httpmethod", new String[] {req.getMethod()});
-                String response = _apiServer.handleRequest(params, responseType, auditTrailSb);
+                final String response = _apiServer.handleRequest(params, responseType, auditTrailSb);
                 writeResponse(resp, response != null ? response : "", HttpServletResponse.SC_OK, responseType);
             } else {
                 if (session != null) {
                     try {
                         session.invalidate();
-                    } catch (IllegalStateException ise) {
+                    } catch (final IllegalStateException ise) {
                     }
                 }
 
                 auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "unable to verify user credentials and/or request signature");
-                String serializedResponse =
+                final String serializedResponse =
                     _apiServer.getSerializedApiError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials and/or request signature", params,
                         responseType);
                 writeResponse(resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType);
 
             }
-        } catch (ServerApiException se) {
-            String serializedResponseText = _apiServer.getSerializedApiError(se, params, responseType);
+        } catch (final ServerApiException se) {
+            final String serializedResponseText = _apiServer.getSerializedApiError(se, params, responseType);
             resp.setHeader("X-Description", se.getDescription());
             writeResponse(resp, serializedResponseText, se.getErrorCode().getHttpCode(), responseType);
             auditTrailSb.append(" " + se.getErrorCode() + " " + se.getDescription());
-        } catch (Exception ex) {
+        } catch (final Exception ex) {
             s_logger.error("unknown exception writing api response", ex);
             auditTrailSb.append(" unknown exception writing api response");
         } finally {
@@ -372,7 +373,7 @@ public class ApiServlet extends HttpServlet {
      */
 
     // FIXME: rather than isError, we might was to pass in the status code to give more flexibility
-    private void writeResponse(HttpServletResponse resp, String response, int responseCode, String responseType) {
+    private void writeResponse(final HttpServletResponse resp, final String response, final int responseCode, final String responseType) {
         try {
             if (BaseCmd.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
                 resp.setContentType(ApiServer.getJsonContentType() + "; charset=UTF-8");
@@ -382,11 +383,11 @@ public class ApiServlet extends HttpServlet {
 
             resp.setStatus(responseCode);
             resp.getWriter().print(response);
-        } catch (IOException ioex) {
+        } catch (final IOException ioex) {
             if (s_logger.isTraceEnabled()) {
                 s_logger.trace("exception writing response: " + ioex);
             }
-        } catch (Exception ex) {
+        } catch (final Exception ex) {
             if (!(ex instanceof IllegalStateException)) {
                 s_logger.error("unknown exception writing api response", ex);
             }
@@ -394,29 +395,29 @@ public class ApiServlet extends HttpServlet {
     }
 
     @SuppressWarnings("rawtypes")
-    private String getLoginSuccessResponse(HttpSession session, String responseType) {
-        StringBuffer sb = new StringBuffer();
-        int inactiveInterval = session.getMaxInactiveInterval();
+    private String getLoginSuccessResponse(final HttpSession session, final String responseType) {
+        final StringBuffer sb = new StringBuffer();
+        final int inactiveInterval = session.getMaxInactiveInterval();
 
-        String user_UUID = (String)session.getAttribute("user_UUID");
+        final String user_UUID = (String)session.getAttribute("user_UUID");
         session.removeAttribute("user_UUID");
 
-        String domain_UUID = (String)session.getAttribute("domain_UUID");
+        final String domain_UUID = (String)session.getAttribute("domain_UUID");
         session.removeAttribute("domain_UUID");
 
         if (BaseCmd.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
             sb.append("{ \"loginresponse\" : { ");
-            Enumeration attrNames = session.getAttributeNames();
+            final Enumeration attrNames = session.getAttributeNames();
             if (attrNames != null) {
                 sb.append("\"timeout\" : \"" + inactiveInterval + "\"");
                 while (attrNames.hasMoreElements()) {
-                    String attrName = (String)attrNames.nextElement();
+                    final String attrName = (String)attrNames.nextElement();
                     if ("userid".equalsIgnoreCase(attrName)) {
                         sb.append(", \"" + attrName + "\" : \"" + user_UUID + "\"");
                     } else if ("domainid".equalsIgnoreCase(attrName)) {
                         sb.append(", \"" + attrName + "\" : \"" + domain_UUID + "\"");
                     } else {
-                        Object attrObj = session.getAttribute(attrName);
+                        final Object attrObj = session.getAttribute(attrName);
                         if ((attrObj instanceof String) || (attrObj instanceof Long)) {
                             sb.append(", \"" + attrName + "\" : \"" + attrObj.toString() + "\"");
                         }
@@ -428,16 +429,16 @@ public class ApiServlet extends HttpServlet {
             sb.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
             sb.append("<loginresponse cloud-stack-version=\"" + ApiDBUtils.getVersion() + "\">");
             sb.append("<timeout>" + inactiveInterval + "</timeout>");
-            Enumeration attrNames = session.getAttributeNames();
+            final Enumeration attrNames = session.getAttributeNames();
             if (attrNames != null) {
                 while (attrNames.hasMoreElements()) {
-                    String attrName = (String)attrNames.nextElement();
-                    if ("userid".equalsIgnoreCase(attrName)) {
+                    final String attrName = (String)attrNames.nextElement();
+                    if (ApiConstants.USER_ID.equalsIgnoreCase(attrName)) {
                         sb.append("<" + attrName + ">" + user_UUID + "</" + attrName + ">");
                     } else if ("domainid".equalsIgnoreCase(attrName)) {
                         sb.append("<" + attrName + ">" + domain_UUID + "</" + attrName + ">");
                     } else {
-                        Object attrObj = session.getAttribute(attrName);
+                        final Object attrObj = session.getAttribute(attrName);
                         if (attrObj instanceof String || attrObj instanceof Long || attrObj instanceof Short) {
                             sb.append("<" + attrName + ">" + attrObj.toString() + "</" + attrName + ">");
                         }
@@ -450,8 +451,8 @@ public class ApiServlet extends HttpServlet {
         return sb.toString();
     }
 
-    private String getLogoutSuccessResponse(String responseType) {
-        StringBuffer sb = new StringBuffer();
+    private String getLogoutSuccessResponse(final String responseType) {
+        final StringBuffer sb = new StringBuffer();
         if (BaseCmd.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
             sb.append("{ \"logoutresponse\" : { \"description\" : \"success\" } }");
         } else {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/src/com/cloud/api/dispatch/CommandCreationWorker.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/dispatch/CommandCreationWorker.java b/server/src/com/cloud/api/dispatch/CommandCreationWorker.java
new file mode 100644
index 0000000..30d4637
--- /dev/null
+++ b/server/src/com/cloud/api/dispatch/CommandCreationWorker.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 com.cloud.api.dispatch;
+
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.ServerApiException;
+
+import com.cloud.exception.ResourceAllocationException;
+
+
+/**
+ * This worker invokes create on the {@link BaseCmd} itself
+ *
+ * @author afornie
+ */
+public class CommandCreationWorker implements DispatchWorker {
+
+    private static final String ATTEMP_TO_CREATE_NON_CREATION_CMD =
+            "Trying to invoke creation on a Command that is not " +
+            BaseAsyncCreateCmd.class.getName();
+
+    @Override
+    public void handle(final DispatchTask task) {
+        final BaseCmd cmd = task.getCmd();
+
+        if (cmd instanceof BaseAsyncCreateCmd) {
+            try {
+                ((BaseAsyncCreateCmd)cmd).create();
+            } catch (final ResourceAllocationException e) {
+                throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR,
+                        e.getMessage(), e);
+            }
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR,
+                    ATTEMP_TO_CREATE_NON_CREATION_CMD);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/src/com/cloud/api/dispatch/DispatchChain.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/dispatch/DispatchChain.java b/server/src/com/cloud/api/dispatch/DispatchChain.java
new file mode 100644
index 0000000..0ce0ce0
--- /dev/null
+++ b/server/src/com/cloud/api/dispatch/DispatchChain.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 com.cloud.api.dispatch;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.cloudstack.api.ServerApiException;
+
+public class DispatchChain {
+
+    protected List<DispatchWorker> workers = new ArrayList<DispatchWorker>();
+
+    public DispatchChain add(final DispatchWorker worker) {
+        workers.add(worker);
+        return this;
+    }
+
+    public void dispatch(final DispatchTask task)
+            throws ServerApiException {
+
+        for (final DispatchWorker worker : workers) {
+            worker.handle(task);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/src/com/cloud/api/dispatch/DispatchChainFactory.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/dispatch/DispatchChainFactory.java b/server/src/com/cloud/api/dispatch/DispatchChainFactory.java
new file mode 100644
index 0000000..135829e
--- /dev/null
+++ b/server/src/com/cloud/api/dispatch/DispatchChainFactory.java
@@ -0,0 +1,72 @@
+// 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.api.dispatch;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+import com.cloud.user.AccountManager;
+
+public class DispatchChainFactory {
+
+    @Inject
+    protected AccountManager _accountMgr;
+
+    @Inject
+    protected ParamGenericValidationWorker paramGenericValidationWorker;
+
+    @Inject
+    protected ParamUnpackWorker paramUnpackWorker;
+
+    @Inject
+    protected ParamProcessWorker paramProcessWorker;
+
+    @Inject
+    protected SpecificCmdValidationWorker specificCmdValidationWorker;
+
+    @Inject
+    protected CommandCreationWorker commandCreationWorker;
+
+    protected DispatchChain standardDispatchChain;
+
+    protected DispatchChain asyncCreationDispatchChain;
+
+    @PostConstruct
+    public void setup() {
+        standardDispatchChain = new DispatchChain().
+                add(paramUnpackWorker).
+                add(paramProcessWorker).
+                add(paramGenericValidationWorker).
+                add(specificCmdValidationWorker);
+
+        asyncCreationDispatchChain = new DispatchChain().
+                add(paramUnpackWorker).
+                add(paramProcessWorker).
+                add(paramGenericValidationWorker).
+                add(specificCmdValidationWorker).
+                add(commandCreationWorker);
+    }
+
+    public DispatchChain getStandardDispatchChain() {
+        return standardDispatchChain;
+    }
+
+    public DispatchChain getAsyncCreationDispatchChain() {
+        return asyncCreationDispatchChain;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/src/com/cloud/api/dispatch/DispatchTask.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/dispatch/DispatchTask.java b/server/src/com/cloud/api/dispatch/DispatchTask.java
new file mode 100644
index 0000000..2a8a4bd
--- /dev/null
+++ b/server/src/com/cloud/api/dispatch/DispatchTask.java
@@ -0,0 +1,41 @@
+package com.cloud.api.dispatch;
+
+import java.util.Map;
+
+import org.apache.cloudstack.api.BaseCmd;
+
+/**
+ * This class wraps all the data that any worker could need. If we don't wrap it this
+ * way and we pass the parameters one by one, in the end we could end up having all the
+ * N workers receiving plenty of parameters and changing the signature, each time one
+ * of them changes. This way, if a certain worker needs something else, you just need
+ * to change it in this wrapper class and the worker itself.
+ */
+@SuppressWarnings("rawtypes")
+public class DispatchTask {
+
+    protected BaseCmd cmd;
+
+    protected Map params;
+
+    public DispatchTask(final BaseCmd cmd, final Map params) {
+        this.cmd = cmd;
+        this.params = params;
+    }
+
+    public BaseCmd getCmd() {
+        return cmd;
+    }
+
+    public void setCmd(final BaseCmd cmd) {
+        this.cmd = cmd;
+    }
+
+    public Map getParams() {
+        return params;
+    }
+
+    public void setParams(final Map params) {
+        this.params = params;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/src/com/cloud/api/dispatch/DispatchWorker.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/dispatch/DispatchWorker.java b/server/src/com/cloud/api/dispatch/DispatchWorker.java
new file mode 100644
index 0000000..a0dbc6a
--- /dev/null
+++ b/server/src/com/cloud/api/dispatch/DispatchWorker.java
@@ -0,0 +1,30 @@
+// 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.api.dispatch;
+
+import org.apache.cloudstack.api.ServerApiException;
+
+/**
+ * Describes the behavior of the workers in the Chain of Responsibility, that receive and
+ * work on a {@link DispatchTask} which will then be passed to next workers.
+ */
+public interface DispatchWorker {
+
+    public void handle(DispatchTask task)
+            throws ServerApiException;
+}


[44/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
Scripts that use ovs-vsctl and ovs-ofctl to setup a bridge for VPC in
distributed routing mode, and setup flows appropriatley

script to handle the VPC topology sent from management server in JSOn
format. From the JSON file, reqired configuration (tunnel setup and flow
rules setup) is setup on the bridge


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/a9abf38a
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/a9abf38a
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/a9abf38a

Branch: refs/heads/distributedrouter
Commit: a9abf38a145dd1a11a419fa994aa3661b395877b
Parents: 2150025
Author: Murali Reddy <mu...@gmail.com>
Authored: Mon Mar 10 11:58:37 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Tue Mar 11 18:38:44 2014 +0530

----------------------------------------------------------------------
 .../xenserver/cloudstack_pluginlib.py           | 154 +++++++++++++++++++
 .../vm/hypervisor/xenserver/ovs-vif-flows.py    | 128 +++++++++++----
 scripts/vm/hypervisor/xenserver/ovstunnel       | 114 +++++++++++++-
 3 files changed, 362 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a9abf38a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
index 422111f..d2b95dc 100644
--- a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
+++ b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
@@ -21,6 +21,7 @@ import ConfigParser
 import logging
 import os
 import subprocess
+import json
 
 from time import localtime, asctime
 
@@ -176,6 +177,7 @@ def _build_flow_expr(**kwargs):
     dl_dst = 'dl_dst' in kwargs and ",dl_dst=%s" % kwargs['dl_dst'] or ''
     nw_src = 'nw_src' in kwargs and ",nw_src=%s" % kwargs['nw_src'] or ''
     nw_dst = 'nw_dst' in kwargs and ",nw_dst=%s" % kwargs['nw_dst'] or ''
+    table = 'table' in kwargs and ",table=%s" % kwargs['table'] or ''
     proto = 'proto' in kwargs and ",%s" % kwargs['proto'] or ''
     ip = ('nw_src' in kwargs or 'nw_dst' in kwargs) and ',ip' or ''
     flow = (flow + in_port + dl_type + dl_src + dl_dst +
@@ -219,3 +221,155 @@ def del_all_flows(bridge):
 def del_port(bridge, port):
     delPort = [VSCTL_PATH, "del-port", bridge, port]
     do_cmd(delPort)
+
+def get_network_id_for_vif(vif_name):
+    domain_id, device_id = vif_name[3:len(vif_name)].split(".")
+    dom_uuid = do_cmd([XE_PATH, "vm-list", "dom-id=%s" % domain_id, "--minimal"])
+    vif_uuid = do_cmd([XE_PATH, "vif-list", "vm-uuid=%s" % dom_uuid, "device=%s" % device_id, "--minimal"])
+    vnet = do_cmd([XE_PATH, "vif-param-get", "uuid=%s" % vif_uuid,  "param-name=other-config",
+                             "param-key=cloudstack-network-id"])
+    return vnet
+
+def get_network_id_for_tunnel_port(tunnelif_name):
+    vnet = do_cmd([VSCTL_PATH, "get", "interface", tunnelif_name, "options:cloudstack-network-id"])
+    return vnet
+
+def clear_flooding_rules_for_port(bridge, ofport):
+        del_flows(bridge, in_port=ofport, table=2)
+
+def add_flooding_rules_for_port(bridge, in_ofport, out_ofports):
+        action = "".join("output:%s," %ofport for ofport in out_ofports)[:-1]
+        add_flow(bridge, priority=1100, in_port=in_ofport, table=1, actions=action)
+
+def get_ofport_for_vif(vif_name):
+    return do_cmd([VSCTL_PATH, "get", "interface", vif_name, "ofport"])
+
+def get_macaddress_of_vif(vif_name):
+    domain_id, device_id = vif_name[3:len(vif_name)].split(".")
+    dom_uuid = do_cmd([XE_PATH, "vm-list", "dom-id=%s" % domain_id, "--minimal"])
+    vif_uuid = do_cmd([XE_PATH, "vif-list", "vm-uuid=%s" % dom_uuid, "device=%s" % device_id, "--minimal"])
+    mac = do_cmd([XE_PATH, "vif-param-get", "uuid=%s" % vif_uuid,  "param-name=MAC"])
+    return mac
+
+def get_vif_name_from_macaddress(macaddress):
+    vif_uuid = do_cmd([XE_PATH, "vif-list", "MAC=%s" % macaddress, "--minimal"])
+    vif_device_id = do_cmd([XE_PATH, "vif-param-get", "uuid=%s" % vif_uuid,  "param-name=device"])
+    vm_uuid = do_cmd([XE_PATH, "vif-param-get", "uuid=%s" % vif_uuid,  "param-name=vm-uuid"])
+    vm_domain_id = do_cmd([XE_PATH, "vm-param-get", "uuid=%s" % vm_uuid,  "param-name=dom-id"])
+    return "vif"+vm_domain_id+"."+vif_device_id
+
+def add_mac_lookup_table_entry(bridge, mac_address, out_of_port):
+    add_flow(bridge, priority=1100, dl_dst=mac_address, table=1, actions="output:%s" % out_of_port)
+
+def delete_mac_lookup_table_entry(bridge, mac_address):
+    del_flows(bridge, dl_dst=mac_address, table=1)
+
+def add_ip_lookup_table_entry(bridge, ip, dst_tier_gateway_mac, dst_vm_mac):
+    action_str = "mod_dl_sr:%s" % dst_tier_gateway_mac + ",mod_dl_dst:%s" % dst_vm_mac +",resubmit(,5)"
+    addflow = [OFCTL_PATH, "add-flow", bridge, "table=4", "nw_dst=%s" % ip, "actions=%s" %action_str]
+    do_cmd(addflow)
+
+def get_vms_on_host(vpc, host_id):
+    all_vms = vpc.vms
+    vms_on_host = []
+    for vm in all_vms:
+      if vm.hostid == host_id:
+        vms_on_host.append(vm)
+    return vms_on_host
+
+def get_network_details(vpc, network_uuid):
+    tiers = vpc.tiers
+    for tier in tiers:
+      if tier.networkuuid == network_uuid:
+        return tier
+    return None
+
+class jsonLoader(object):
+  def __init__(self, obj):
+        for k in obj:
+            v = obj[k]
+            if isinstance(v, dict):
+                setattr(self, k, jsonLoader(v))
+            elif isinstance(v, (list, tuple)):
+                if len(v) > 0 and isinstance(v[0], dict):
+                    setattr(self, k, [jsonLoader(elem) for elem in v])
+                else:
+                    setattr(self, k, v)
+            else:
+                setattr(self, k, v)
+
+  def __getattr__(self, val):
+        if val in self.__dict__:
+            return self.__dict__[val]
+        else:
+            return None
+
+  def __repr__(self):
+        return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v)
+                                      in self.__dict__.iteritems()))
+
+  def __str__(self):
+        return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v)
+                                      in self.__dict__.iteritems()))
+
+def configure_bridge_for_topology(bridge, this_host_id, json_config):
+    vpconfig = jsonLoader(json.loads(json_config)).vpc
+
+    if vpconfig is None:
+        logging.debug("WARNING:Can't find VPC info in json config file")
+        return "FAILURE:IMPROPER_JSON_CONFG_FILE"
+
+    # get the list of Vm's in the VPC from the JSON config
+    this_host_vms = get_vms_on_host(vpconfig, this_host_id)
+
+    for vm in this_host_vms:
+        for nic in vm.nics:
+            mac_addr = nic.macaddress
+            ip = nic.ipaddress
+            vif_name = get_vif_name_from_macaddress(mac_addr)
+            of_port = get_ofport_for_vif(vif_name)
+            network = get_network_details(vpconfig, nic.networkuuid)
+
+            # Add flow rule in L2 look up table, if the destination mac = MAC of the nic send packet on the found OFPORT
+            add_mac_lookup_table_entry(bridge, mac_addr, of_port)
+
+            # Add flow rule in L3 look up table: if the destination IP = VM's IP then modify the packet
+            # to set DST MAC = VM's MAC, SRC MAC=tier gateway MAC and send to egress table
+            add_ip_lookup_table_entry(bridge, ip, network.gatewaymac, mac_addr)
+
+            # Add flow entry to send with intra tier traffic from the NIC to L2 lookup path)
+            addflow = [OFCTL_PATH, "add-flow", bridge, "table=0", "in_port=%s" % of_port,
+                       "nw_dst=%s" %network.cidr, "actions=resubmit(,1)"]
+            do_cmd(addflow)
+
+            #add flow entry to send inter-tier traffic from the NIC to egress ACL table(to L3 lookup path)
+            addflow = [OFCTL_PATH, "add-flow", bridge, "table=0", "in_port=%s" % of_port,
+                       "dl_dst=%s" %network.gatewaymac, "nw_dst=%s" %vpconfig.cidr, "actions=resubmit(,3)"]
+            do_cmd(addflow)
+
+    # get the list of hosts on which VPC spans from the JSON config
+    vpc_spanning_hosts = vpconfig.hosts
+
+    for host in vpc_spanning_hosts:
+        if this_host_id == host.hostid:
+            continue
+        other_host_vms = get_vms_on_host(vpconfig, host.hostid)
+        for vm in other_host_vms:
+            for nic in vm.nics:
+                mac_addr = nic.macaddress
+                ip = nic.ipaddress
+                network = get_network_details(vpconfig, nic.networkuuid)
+                gre_key = network.grekey
+
+                # generate tunnel name from tunnel naming convention
+                tunnel_name = "t%s-%s-%s" % (gre_key, this_host_id, host.hostid)
+                of_port = get_ofport_for_vif(tunnel_name)
+
+                # Add flow rule in L2 look up table, if the destination mac = MAC of the nic send packet tunnel port
+                add_mac_lookup_table_entry(bridge, mac_addr, of_port)
+
+                # Add flow tule in L3 look up table: if the destination IP = VM's IP then modify the packet
+                # set DST MAC = VM's MAC, SRC MAC=tier gateway MAC and send to egress table
+                add_ip_lookup_table_entry(bridge, ip, network.gatewaymac, mac_addr)
+
+    return "SUCCESS: successfully configured bridge as per the VPC toplogy"
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a9abf38a/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py b/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py
index 8452dae..ae37525 100644
--- a/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py
+++ b/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py
@@ -18,6 +18,7 @@
 # A simple script for enabling and disabling per-vif rules for explicitly
 # allowing broadcast/multicast traffic on the port where the VIF is attached
 
+import copy
 import os
 import sys
 
@@ -65,7 +66,6 @@ def clear_rules(vif):
     except:
         pass
 
-
 def main(command, vif_raw):
     if command not in ('online', 'offline'):
         return
@@ -86,38 +86,110 @@ def main(command, vif_raw):
 	# find xs network for this bridge, verify is used for ovs tunnel network
     xs_nw_uuid = pluginlib.do_cmd([pluginlib.XE_PATH, "network-list",
 								   "bridge=%s" % bridge, "--minimal"])
-    result = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get",
+    ovs_tunnel_network = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get",
 						       "uuid=%s" % xs_nw_uuid,
 						       "param-name=other-config",
 						       "param-key=is-ovs-tun-network", "--minimal"])
 
-    if result != 'True':
-		return
-    
-    vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge])
-    if vlan != '0':
-            # We need the REAL bridge name
-            bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
-                                       'br-to-parent', bridge])
-
-    vsctl_output = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
-                                     'list-ports', bridge])
-    vifs = vsctl_output.split('\n')
-    vif_ofports = []
-    for vif in vifs:
-    	vif_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get',
-                                       'Interface', vif, 'ofport'])
-    	if this_vif == vif:
-    		this_vif_ofport = vif_ofport
-        if vif.startswith('vif'): 
-            vif_ofports.append(vif_ofport)
-
-    if command == 'offline':
-        clear_flows(bridge,  this_vif_ofport, vif_ofports)
-
-    if command == 'online':
-        apply_flows(bridge,  this_vif_ofport, vif_ofports)
+    ovs_vpc_distributed_vr_network = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get",
+						       "uuid=%s" % xs_nw_uuid,
+						       "param-name=other-config",
+						       "param-key=is-ovs_vpc_distributed_vr_network", "--minimal"])
+
+    if ovs_tunnel_network == 'True':
+        vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge])
+        if vlan != '0':
+                # We need the REAL bridge name
+                bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
+                                           'br-to-parent', bridge])
+        vsctl_output = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
+                                         'list-ports', bridge])
+        vifs = vsctl_output.split('\n')
+        vif_ofports = []
+        for vif in vifs:
+            vif_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get',
+                                           'Interface', vif, 'ofport'])
+            if this_vif == vif:
+                this_vif_ofport = vif_ofport
+            if vif.startswith('vif'):
+                vif_ofports.append(vif_ofport)
 
+        if command == 'offline':
+            clear_flows(bridge,  this_vif_ofport, vif_ofports)
+
+        if command == 'online':
+            apply_flows(bridge,  this_vif_ofport, vif_ofports)
+
+
+    if ovs_vpc_distributed_vr_network == 'True':
+        vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge])
+        if vlan != '0':
+                # We need the REAL bridge name
+                bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
+                                           'br-to-parent', bridge])
+        vsctl_output = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
+                                         'list-ports', bridge])
+        vif_network_id = pluginlib.get_network_id_for_vif(this_vif)
+        vnet_vif_ofports = []
+        vnet_tunnelif_ofports = []
+        vnet_all_ofports = []
+
+        ports = vsctl_output.split('\n')
+        for port in ports:
+            if_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get', 'Interface', vif, 'ofport'])
+            if vif.startswith('vif'):
+                # check VIF is in same network as that of plugged vif
+                if vif_network_id != pluginlib.get_network_id_for_vif(port):
+                    continue
+                vnet_vif_ofports.append(if_ofport)
+                vnet_all_ofports.append(if_ofport)
+
+            if vif.startswith('t'):
+                # check tunnel port is in same network as that of plugged vif
+                if vif_network_id != pluginlib.get_network_id_for_tunnel_port(port):
+                    continue
+                vnet_tunnelif_ofports.append(if_ofport)
+                vnet_all_ofports.append(if_ofport)
+
+        if command == 'online':
+            for port in vnet_all_ofports:
+                pluginlib.clear_flooding_rules_for_port(bridge, port)
+
+            # for a packet arrived from tunnel port, flood only on VIF ports
+            for port in vnet_tunnelif_ofports:
+                pluginlib.add_flooding_rules_for_port(bridge, port, vnet_vif_ofports)
+
+            # send on all VIF and tunnel port excluding the port on which packet arrived
+            for port in vnet_vif_ofports:
+                vnet_all_ofports_copy = copy.copy(vnet_all_ofports)
+                vnet_all_ofports_copy.remove(port)
+                pluginlib.add_flooding_rules_for_port(bridge, port, vnet_all_ofports_copy)
+
+            #learn that MAC is reachable through the VIF port
+            mac = pluginlib.get_macaddress_of_vif(this_vif)
+            pluginlib.add_mac_lookup_table_entry(bridge, mac, this_vif_ofport)
+
+        if command == 'offline':
+            for port in vnet_all_ofports:
+                pluginlib.clear_flooding_rules_for_port(bridge, port)
+            vnet_all_ofports.remove(this_vif_ofport)
+            vnet_vif_ofports.remove(this_vif_ofport)
+
+            # for a packet arrived from tunnel port, flood only on VIF ports
+            for port in vnet_tunnelif_ofports:
+                pluginlib.add_flooding_rules_for_port(bridge, port, vnet_vif_ofports)
+
+            # for a packet from VIF port send on all VIF's and tunnel ports excluding the port on which packet arrived
+            for port in vnet_vif_ofports:
+                vnet_all_ofports_copy = copy.copy(vnet_all_ofports)
+                vnet_all_ofports_copy.remove(port)
+                pluginlib.add_flooding_rules_for_port(bridge, port, vnet_all_ofports_copy)
+
+            #un-learn that MAC is reachable through the VIF port
+            mac = pluginlib.get_macaddress_of_vif(this_vif)
+            pluginlib.delete_mac_lookup_table_entry(bridge, mac)
+
+    return
 
 if __name__ == "__main__":
     if len(sys.argv) != 3:

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a9abf38a/scripts/vm/hypervisor/xenserver/ovstunnel
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/ovstunnel b/scripts/vm/hypervisor/xenserver/ovstunnel
index 106be04..d558e97 100755
--- a/scripts/vm/hypervisor/xenserver/ovstunnel
+++ b/scripts/vm/hypervisor/xenserver/ovstunnel
@@ -124,6 +124,75 @@ def setup_ovs_bridge(session, args):
     logging.debug("Setup_ovs_bridge completed with result:%s" % result)
     return result
 
+@echo
+def setup_ovs_bridge_for_distributed_routing(session, args):
+    bridge = args.pop("bridge")
+    key = args.pop("key")
+    xs_nw_uuid = args.pop("xs_nw_uuid")
+    cs_host_id = args.pop("cs_host_id")
+
+    res = lib.check_switch()
+    if res != "SUCCESS":
+        return "FAILURE:%s" % res
+
+    logging.debug("About to manually create the bridge:%s" % bridge)
+    # create a bridge with the same name as the xapi network
+    res = lib.do_cmd([lib.VSCTL_PATH, "--", "--may-exist", "add-br", bridge,
+                                     "--", "set", "bridge", bridge])
+    logging.debug("Bridge has been manually created:%s" % res)
+    # TODO: Make sure xs-network-uuid is set into external_ids
+    lib.do_cmd([lib.VSCTL_PATH, "set", "Bridge", bridge,
+                            "external_ids:xs-network-uuid=%s" % xs_nw_uuid])
+
+    # Non empty result means something went wrong
+    if res:
+        result = "FAILURE:%s" % res
+    else:
+        # Verify the bridge actually exists, with the gre_key properly set
+        res = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge",
+                                          bridge, "other_config:gre_key"])
+        if key in res:
+            result = "SUCCESS:%s" % bridge
+        else:
+            result = "FAILURE:%s" % res
+        # Finally note in the xenapi network object that the network has
+        # been configured
+        xs_nw_uuid = lib.do_cmd([lib.XE_PATH, "network-list",
+                                "bridge=%s" % bridge, "--minimal"])
+        lib.do_cmd([lib.XE_PATH, "network-param-set", "uuid=%s" % xs_nw_uuid,
+                   "other-config:is-ovs_vpc_distributed_vr_network=True"])
+        conf_hosts = lib.do_cmd([lib.XE_PATH, "network-param-get",
+                                "uuid=%s" % xs_nw_uuid,
+                                "param-name=other-config",
+                                "param-key=ovs-host-setup", "--minimal"])
+        conf_hosts = cs_host_id + (conf_hosts and ',%s' % conf_hosts or '')
+        lib.do_cmd([lib.XE_PATH, "network-param-set", "uuid=%s" % xs_nw_uuid,
+                   "other-config:ovs-host-setup=%s" % conf_hosts])
+
+        # add a default flow rule to send broadcast and multi-cast packets to L2 flooding table
+        lib.add_flow(bridge, priority=1000, dl_dst='ff:ff:ff:ff:ff:ff', table=0, actions='resubmit(,2)')
+        lib.add_flow(bridge, priority=1000, nw_dst='224.0.0.0/24', table=0, actions='resubmit(,2)')
+
+        # add a default flow rule to send uni-cast traffic to L2 lookup table
+        lib.add_flow(bridge, priority=0, table=0, actions='resubmit(,1)')
+
+        # add a default rule to send unknown mac address to L2 flooding table
+        lib.add_flow(bridge, priority=0, table=1, actions='resubmit(,2)')
+
+        # add a default rule in L2 flood table to drop packet
+        lib.add_flow(bridge, priority=0, table=2, actions='drop')
+
+        # add a default rule in egress table to forward packet to L3 lookup table
+        lib.add_flow(bridge, priority=0, table=3, actions='resubmit(,4)')
+
+        # add a default rule in L3 lookup table to forward packet to L2 lookup table
+        lib.add_flow(bridge, priority=0, table=4, actions='resubmit(,1)')
+
+        # add a default rule in egress table to forward packet to L3 lookup table
+        lib.add_flow(bridge, priority=0, table=5, actions='drop')
+
+    logging.debug("Setup_ovs_bridge completed with result:%s" % result)
+    return result
 
 @echo
 def destroy_ovs_bridge(session, args):
@@ -220,13 +289,36 @@ def create_tunnel(session, args):
         # Ensure no trailing LF
         if tun_ofport.endswith('\n'):
             tun_ofport = tun_ofport[:-1]
-        # add flow entryies for dropping broadcast coming in from gre tunnel
-        lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
+        # find xs network for this bridge, verify is used for ovs tunnel network
+        xs_nw_uuid = lib.do_cmd([lib.XE_PATH, "network-list",
+								   "bridge=%s" % bridge, "--minimal"])
+        ovs_tunnel_network = lib.do_cmd([lib.XE_PATH,"network-param-get",
+						       "uuid=%s" % xs_nw_uuid,
+						       "param-name=other-config",
+						       "param-key=is-ovs-tun-network", "--minimal"])
+        ovs_vpc_distributed_vr_network = lib.do_cmd([lib.XE_PATH,"network-param-get",
+                           "uuid=%s" % xs_nw_uuid,
+                           "param-name=other-config",
+                           "param-key=is-ovs_vpc_distributed_vr_network", "--minimal"])
+        if ovs_tunnel_network == 'True':
+            # add flow entryies for dropping broadcast coming in from gre tunnel
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
                          dl_dst='ff:ff:ff:ff:ff:ff', actions='drop')
-        lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
                      nw_dst='224.0.0.0/24', actions='drop')
-        drop_flow_setup = True
-        logging.debug("Broadcast drop rules added")
+            drop_flow_setup = True
+            logging.debug("Broadcast drop rules added")
+
+        if ovs_vpc_distributed_vr_network == 'True':
+            # add flow rules for dropping broadcast coming in from tunnel ports
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0,
+                         dl_dst='ff:ff:ff:ff:ff:ff', actions='drop')
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0,
+                     nw_dst='224.0.0.0/24', actions='drop')
+
+            # add flow rule to send the traffic from tunnel ports to L2 switching table only
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0, actions='resubmit(,1)')
+
         return "SUCCESS:%s" % name
     except:
         logging.debug("An unexpected error occured. Rolling back")
@@ -293,10 +385,20 @@ def getLabel(session, args):
     	return label
     return False
 
+@echo
+def configure_ovs_bridge_for_network_topology(session, args):
+    bridge = args.pop("bridge")
+    json_config = args.pop("config")
+    this_host_id = args.pop("host-id")
+
+    return lib.configure_bridge_for_topology(bridge, this_host_id, json_config)
+
 if __name__ == "__main__":
     XenAPIPlugin.dispatch({"create_tunnel": create_tunnel,
                            "destroy_tunnel": destroy_tunnel,
                            "setup_ovs_bridge": setup_ovs_bridge,
                            "destroy_ovs_bridge": destroy_ovs_bridge,
                            "is_xcp": is_xcp,
-                           "getLabel": getLabel})
+                           "getLabel": getLabel,
+                           "setup_ovs_bridge_for_distributed_routing": setup_ovs_bridge_for_distributed_routing,
+                           "configure_ovs_bridge_for_network_topology": configure_ovs_bridge_for_network_topology})


[31/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
CLOUDSTACK-6170


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/1d74daf6
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/1d74daf6
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/1d74daf6

Branch: refs/heads/distributedrouter
Commit: 1d74daf6fe7c87931b6308d4e2e0e39f109a85ac
Parents: a1b778f
Author: Mike Tutkowski <mi...@solidfire.com>
Authored: Mon Mar 10 11:42:56 2014 -0600
Committer: Mike Tutkowski <mi...@solidfire.com>
Committed: Mon Mar 10 11:43:54 2014 -0600

----------------------------------------------------------------------
 .../apache/cloudstack/engine/orchestration/CloudOrchestrator.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1d74daf6/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java
index 7969e43..fc1b85c 100755
--- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java
@@ -188,7 +188,7 @@ public class CloudOrchestrator implements OrchestrationService {
         rootDiskOfferingInfo.setDiskOffering(offering);
         rootDiskOfferingInfo.setSize(rootDiskSize);
 
-        if (offering.isCustomizedIops()) {
+        if (offering.isCustomizedIops() != null && offering.isCustomizedIops()) {
             Map<String, String> userVmDetails = _userVmDetailsDao.listDetailsKeyPairs(vm.getId());
 
             if (userVmDetails != null) {


[18/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
CLOUDSTACK-6170


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/cb26b4c3
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/cb26b4c3
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/cb26b4c3

Branch: refs/heads/distributedrouter
Commit: cb26b4c3375cdf4f8ecedf618f98e6b24a2cba6e
Parents: ded7e68
Author: Mike Tutkowski <mi...@solidfire.com>
Authored: Fri Mar 7 22:20:38 2014 -0700
Committer: Mike Tutkowski <mi...@solidfire.com>
Committed: Fri Mar 7 23:52:01 2014 -0700

----------------------------------------------------------------------
 .../src/com/cloud/hypervisor/XenServerGuru.java | 33 ++++++++++----------
 1 file changed, 16 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cb26b4c3/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java
index 529e261..059e6e4 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java
@@ -34,7 +34,6 @@ import com.cloud.host.HostVO;
 import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.storage.GuestOSVO;
-import com.cloud.storage.Volume;
 import com.cloud.storage.VolumeVO;
 import com.cloud.storage.dao.GuestOSDao;
 import com.cloud.storage.dao.VolumeDao;
@@ -103,30 +102,30 @@ public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru
 
         List<VolumeVO> volumes = _volumeDao.findByInstance(vm.getId());
 
+        // it's OK in this case to send a detach command to the host for a root volume as this
+        // will simply lead to the SR that supports the root volume being removed
         if (volumes != null) {
             for (VolumeVO volume : volumes) {
-                if (volume.getVolumeType() == Volume.Type.DATADISK) {
-                    StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
+                StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
 
-                    // storagePool should be null if we are expunging a volume that was never
-                    // attached to a VM that was started (the "trick" for storagePool to be null
-                    // is that none of the VMs this volume may have been attached to were ever started,
-                    // so the volume was never assigned to a storage pool)
-                    if (storagePool != null && storagePool.isManaged()) {
-                        DataTO volTO = _volFactory.getVolume(volume.getId()).getTO();
-                        DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getPath(), volume.getVolumeType());
+                // storagePool should be null if we are expunging a volume that was never
+                // attached to a VM that was started (the "trick" for storagePool to be null
+                // is that none of the VMs this volume may have been attached to were ever started,
+                // so the volume was never assigned to a storage pool)
+                if (storagePool != null && storagePool.isManaged()) {
+                    DataTO volTO = _volFactory.getVolume(volume.getId()).getTO();
+                    DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getPath(), volume.getVolumeType());
 
-                        DettachCommand cmd = new DettachCommand(disk, vm.getInstanceName());
+                    DettachCommand cmd = new DettachCommand(disk, vm.getInstanceName());
 
-                        cmd.setManaged(true);
+                    cmd.setManaged(true);
 
-                        cmd.setStorageHost(storagePool.getHostAddress());
-                        cmd.setStoragePort(storagePool.getPort());
+                    cmd.setStorageHost(storagePool.getHostAddress());
+                    cmd.setStoragePort(storagePool.getPort());
 
-                        cmd.set_iScsiName(volume.get_iScsiName());
+                    cmd.set_iScsiName(volume.get_iScsiName());
 
-                        commands.add(cmd);
-                    }
+                    commands.add(cmd);
                 }
             }
         }


[40/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
CLOUDSTACK-6222: Fix the marvin config generator scripts to include
new syntax changes in marvin code and fix the logFolderPath


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/991e1eb6
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/991e1eb6
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/991e1eb6

Branch: refs/heads/distributedrouter
Commit: 991e1eb6b119a62dedbc0e39a612941af9999103
Parents: c7d31fe
Author: SrikanteswaraRao Talluri <ta...@apache.org>
Authored: Tue Mar 11 16:07:28 2014 +0530
Committer: SrikanteswaraRao Talluri <ta...@apache.org>
Committed: Tue Mar 11 16:09:01 2014 +0530

----------------------------------------------------------------------
 tools/marvin/marvin/configGenerator.py          |  5 ++---
 .../marvin/sandbox/advanced/advanced_env.py     | 23 ++++++++------------
 .../marvin/sandbox/advancedsg/advancedsg_env.py | 18 +++++----------
 tools/marvin/marvin/sandbox/basic/basic_env.py  | 16 +++++---------
 .../sandbox/demo/simulator/simulator_setup.py   | 16 +++++---------
 5 files changed, 27 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/991e1eb6/tools/marvin/marvin/configGenerator.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/configGenerator.py b/tools/marvin/marvin/configGenerator.py
index 0d79e8e..0b4a0a1 100644
--- a/tools/marvin/marvin/configGenerator.py
+++ b/tools/marvin/marvin/configGenerator.py
@@ -51,8 +51,7 @@ class configuration(object):
 class logger(object):
     def __init__(self):
         '''TestCase/TestClient'''
-        self.name = None
-        self.file = None
+        self.logFolderPath = None
 
 
 class cloudstackConfiguration(object):
@@ -61,7 +60,7 @@ class cloudstackConfiguration(object):
         self.mgtSvr = []
         self.dbSvr = None
         self.globalConfig = []
-        self.logger = []
+        self.logger = None
 
 
 class zone(object):

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/991e1eb6/tools/marvin/marvin/sandbox/advanced/advanced_env.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/sandbox/advanced/advanced_env.py b/tools/marvin/marvin/sandbox/advanced/advanced_env.py
index 1728e61..f3d3064 100644
--- a/tools/marvin/marvin/sandbox/advanced/advanced_env.py
+++ b/tools/marvin/marvin/sandbox/advanced/advanced_env.py
@@ -54,22 +54,22 @@ def describeResources(config):
     lbprovider = provider()
     lbprovider.name = 'InternalLbVm'
     
-    pn = physical_network()
+    pn = physicalNetwork()
     pn.name = "Sandbox-pnet"
     pn.vlan = config.get('cloudstack', 'pnet.vlan')
     pn.tags = ["cloud-simulator-public"]
-    pn.traffictypes = [traffictype("Guest"),
-            traffictype("Management", {"simulator" : "cloud-simulator-mgmt"}),
-            traffictype("Public", {"simulator":"cloud-simulator-public"})]
+    pn.traffictypes = [trafficType("Guest"),
+            trafficType("Management", {"simulator" : "cloud-simulator-mgmt"}),
+            trafficType("Public", {"simulator":"cloud-simulator-public"})]
     pn.isolationmethods = ["VLAN"]
     pn.providers.append(vpcprovider)
     pn.providers.append(lbprovider)
 
-    pn2 = physical_network()
+    pn2 = physicalNetwork()
     pn2.name = "Sandbox-pnet2"
     pn2.vlan = config.get('cloudstack', 'pnet2.vlan')
     pn2.tags = ["cloud-simulator-guest"]
-    pn2.traffictypes = [traffictype('Guest', {'simulator': 'cloud-simulator-guest'})]
+    pn2.traffictypes = [trafficType('Guest', {'simulator': 'cloud-simulator-guest'})]
     pn2.isolationmethods = ["VLAN"]
     pn2.providers.append(vpcprovider)
     pn2.providers.append(lbprovider)
@@ -137,16 +137,11 @@ def describeResources(config):
     [zs.globalConfig.append(cfg) for cfg in getGlobalSettings(config)]
 
     ''''add loggers'''
-    testClientLogger = logger()
-    testClientLogger.name = 'TestClient'
-    testClientLogger.file = 'testclient.log'
+    testLogger = logger()
+    testLogger.logFolderPath = '/tmp/'
+    zs.logger = testLogger
 
-    testCaseLogger = logger()
-    testCaseLogger.name = 'TestCase'
-    testCaseLogger.file = 'testcase.log'
 
-    zs.logger.append(testClientLogger)
-    zs.logger.append(testCaseLogger)
     return zs
 
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/991e1eb6/tools/marvin/marvin/sandbox/advancedsg/advancedsg_env.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/sandbox/advancedsg/advancedsg_env.py b/tools/marvin/marvin/sandbox/advancedsg/advancedsg_env.py
index 9cf4a0a..284ea2e 100644
--- a/tools/marvin/marvin/sandbox/advancedsg/advancedsg_env.py
+++ b/tools/marvin/marvin/sandbox/advancedsg/advancedsg_env.py
@@ -51,11 +51,11 @@ def describeResources(config):
     sgprovider.broadcastdomainrange = 'ZONE'
     sgprovider.name = 'SecurityGroupProvider'
     
-    pn = physical_network()
+    pn = physicalNetwork()
     pn.name = "Sandbox-pnet"
     pn.tags = ["cloud-simulator-pnet"]
-    pn.traffictypes = [traffictype("Guest"),
-                       traffictype("Management", {"simulator" : "cloud-simulator-mgmt"})]
+    pn.traffictypes = [trafficType("Guest"),
+                       trafficType("Management", {"simulator" : "cloud-simulator-mgmt"})]
     pn.isolationmethods = ["VLAN"]
     pn.providers.append(sgprovider)
 
@@ -121,16 +121,10 @@ def describeResources(config):
     [zs.globalConfig.append(cfg) for cfg in getGlobalSettings(config)]
 
     ''''add loggers'''
-    testClientLogger = logger()
-    testClientLogger.name = 'TestClient'
-    testClientLogger.file = 'testclient.log'
+    testLogger = logger()
+    testLogger.logFolderPath = '/tmp/'
+    zs.logger = testLogger
 
-    testCaseLogger = logger()
-    testCaseLogger.name = 'TestCase'
-    testCaseLogger.file = 'testcase.log'
-
-    zs.logger.append(testClientLogger)
-    zs.logger.append(testCaseLogger)
     return zs
 
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/991e1eb6/tools/marvin/marvin/sandbox/basic/basic_env.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/sandbox/basic/basic_env.py b/tools/marvin/marvin/sandbox/basic/basic_env.py
index bf106fc..6198163 100644
--- a/tools/marvin/marvin/sandbox/basic/basic_env.py
+++ b/tools/marvin/marvin/sandbox/basic/basic_env.py
@@ -52,9 +52,9 @@ def describeResources(config):
     sgprovider.broadcastdomainrange = 'Pod'
     sgprovider.name = 'SecurityGroupProvider'
     
-    pn = physical_network()
+    pn = physicalNetwork()
     pn.name = "Sandbox-pnet"
-    pn.traffictypes = [traffictype("Guest"), traffictype("Management")]
+    pn.traffictypes = [trafficType("Guest"), trafficType("Management")]
     pn.isolationmethods = ["L3"]
     pn.providers.append(sgprovider)
     
@@ -119,16 +119,10 @@ def describeResources(config):
     [zs.globalConfig.append(cfg) for cfg in getGlobalSettings(config)]
 
     ''''add loggers'''
-    testClientLogger = logger()
-    testClientLogger.name = 'TestClient'
-    testClientLogger.file = '/var/log/testclient.log'
+    testLogger = logger()
+    testLogger.logFolderPath = '/tmp/'
+    zs.logger = testLogger
 
-    testCaseLogger = logger()
-    testCaseLogger.name = 'TestCase'
-    testCaseLogger.file = '/var/log/testcase.log'
-
-    zs.logger.append(testClientLogger)
-    zs.logger.append(testCaseLogger)
     return zs
 
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/991e1eb6/tools/marvin/marvin/sandbox/demo/simulator/simulator_setup.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/sandbox/demo/simulator/simulator_setup.py b/tools/marvin/marvin/sandbox/demo/simulator/simulator_setup.py
index d45d482..08b20cc 100644
--- a/tools/marvin/marvin/sandbox/demo/simulator/simulator_setup.py
+++ b/tools/marvin/marvin/sandbox/demo/simulator/simulator_setup.py
@@ -46,9 +46,9 @@ def describeResources(config):
     vpcprovider = provider()
     vpcprovider.name = 'VpcVirtualRouter'
     
-    pn = physical_network()
+    pn = physicalNetwork()
     pn.name = "Sandbox-pnet"
-    pn.traffictypes = [traffictype("Guest"), traffictype("Management"), traffictype("Public")]
+    pn.traffictypes = [trafficType("Guest"), trafficType("Management"), trafficType("Public")]
     pn.isolationmethods = ["VLAN"]
     pn.providers.append(vpcprovider)
     pn.vlan = config.get('cloudstack', 'zone.vlan')
@@ -120,16 +120,10 @@ def describeResources(config):
     [zs.globalConfig.append(cfg) for cfg in getGlobalSettings(config)]
 
     ''''add loggers'''
-    testClientLogger = logger()
-    testClientLogger.name = 'TestClient'
-    testClientLogger.file = '/var/log/testclient.log'
+    testLogger = logger()
+    testLogger.logFolderPath = '/tmp/'
+    zs.logger = testLogger
 
-    testCaseLogger = logger()
-    testCaseLogger.name = 'TestCase'
-    testCaseLogger.file = '/var/log/testcase.log'
-
-    zs.logger.append(testClientLogger)
-    zs.logger.append(testCaseLogger)
     return zs
 
 


[22/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
findbugs: scope and final to mitgate possible abuse of fields

Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/07102b40
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/07102b40
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/07102b40

Branch: refs/heads/distributedrouter
Commit: 07102b400f11284009f283aa23faf2d24d543b21
Parents: 4eece72
Author: Daan Hoogland <da...@onecht.net>
Authored: Mon Mar 10 09:39:35 2014 +0100
Committer: Daan Hoogland <da...@onecht.net>
Committed: Mon Mar 10 09:39:35 2014 +0100

----------------------------------------------------------------------
 .../src/com/cloud/api/dispatch/ParamGenericValidationWorker.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/07102b40/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java b/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java
index 0c829e8..f456468 100644
--- a/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java
+++ b/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java
@@ -37,9 +37,9 @@ import org.apache.log4j.Logger;
  */
 public class ParamGenericValidationWorker implements DispatchWorker {
 
-    protected static Logger s_logger = Logger.getLogger(ParamGenericValidationWorker.class.getName());
+    static Logger s_logger = Logger.getLogger(ParamGenericValidationWorker.class.getName());
 
-    protected static List<String> defaultParamNames = new ArrayList<String>();
+    protected static final List<String> defaultParamNames = new ArrayList<String>();
 
     static {
         defaultParamNames.add(ApiConstants.CTX_START_EVENT_ID);


[19/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
CLOUDSTACK-6204: removing realhostip dependency

Moving default transport for console proxy, SSVM to http.

See
https://cwiki.apache.org/confluence/display/CLOUDSTACK/Realhost+IP+changes
for more info.

jlk ported Amogh's patch for 4.3 to master - code base is different
enough that patch has multiple issues.

Author: Amogh Vasekar <Amogh Vasekar <am...@citrix.com>
Signed-off-by: John Kinsella <jl...@stratosec.co> 1394398017 -0700


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/09c37537
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/09c37537
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/09c37537

Branch: refs/heads/distributedrouter
Commit: 09c375379ddae2d85ce9549bb6a58860c53bfecd
Parents: cb26b4c
Author: John Kinsella <jl...@stratosec.co>
Authored: Sun Mar 9 13:46:57 2014 -0700
Committer: John Kinsella <jl...@stratosec.co>
Committed: Sun Mar 9 13:46:57 2014 -0700

----------------------------------------------------------------------
 core/src/com/cloud/info/ConsoleProxyInfo.java    | 19 ++++++++++---------
 .../storage/image/TemplateServiceImpl.java       | 13 +++++++++++--
 .../driver/CloudStackImageStoreDriverImpl.java   | 12 ++++++++----
 server/src/com/cloud/configuration/Config.java   |  4 ++--
 .../consoleproxy/ConsoleProxyManagerImpl.java    | 11 +++++++++--
 .../SecondaryStorageManagerImpl.java             |  7 +++++++
 setup/db/db/schema-421to430.sql                  |  4 ++++
 systemvm/conf/consoleproxy.properties            |  2 +-
 8 files changed, 52 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/09c37537/core/src/com/cloud/info/ConsoleProxyInfo.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/info/ConsoleProxyInfo.java b/core/src/com/cloud/info/ConsoleProxyInfo.java
index 9a94474..0e57b75 100644
--- a/core/src/com/cloud/info/ConsoleProxyInfo.java
+++ b/core/src/com/cloud/info/ConsoleProxyInfo.java
@@ -32,16 +32,17 @@ public class ConsoleProxyInfo {
         this.sslEnabled = sslEnabled;
 
         if (sslEnabled) {
-            StringBuffer sb = new StringBuffer(proxyIpAddress);
-            for (int i = 0; i < sb.length(); i++)
-                if (sb.charAt(i) == '.')
-                    sb.setCharAt(i, '-');
-            if (consoleProxyUrlDomain != null && consoleProxyUrlDomain.length() > 0) {
-                sb.append(".");
+            StringBuffer sb = new StringBuffer();
+            if (consoleProxyUrlDomain.startsWith("*")) {
+                sb.append(proxyIpAddress);
+                for (int i = 0; i < proxyIpAddress.length(); i++)
+                    if (sb.charAt(i) == '.')
+                        sb.setCharAt(i, '-');
+                sb.append(consoleProxyUrlDomain.substring(1));//skip the *
+            } else {
+                //LB address
                 sb.append(consoleProxyUrlDomain);
-            } else
-                sb.append(".realhostip.com");
-
+            }
             proxyAddress = sb.toString();
             proxyPort = port;
             this.proxyUrlPort = proxyUrlPort;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/09c37537/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
index 166b523..4e6ab6b 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
@@ -777,12 +777,21 @@ public class TemplateServiceImpl implements TemplateService {
         String scheme = "http";
         boolean _sslCopy = false;
         String sslCfg = _configDao.getValue(Config.SecStorageEncryptCopy.toString());
+        String _ssvmUrlDomain = _configDao.getValue("secstorage.ssl.cert.domain");
         if (sslCfg != null) {
             _sslCopy = Boolean.parseBoolean(sslCfg);
         }
+        if(_sslCopy && (_ssvmUrlDomain == null || _ssvmUrlDomain.isEmpty())){
+            s_logger.warn("Empty secondary storage url domain, ignoring SSL");
+            _sslCopy = false;
+        }
         if (_sslCopy) {
-            hostname = ipAddress.replace(".", "-");
-            hostname = hostname + ".realhostip.com";
+            if(_ssvmUrlDomain.startsWith("*")) {
+                hostname = ipAddress.replace(".", "-");
+                hostname = hostname + _ssvmUrlDomain.substring(1);
+            } else {
+                hostname = _ssvmUrlDomain;
+            }
             scheme = "https";
         }
         return scheme + "://" + hostname + "/copy/SecStorage/" + dir + "/" + path;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/09c37537/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java
----------------------------------------------------------------------
diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java
index d6e1a01..c2e26d5 100644
--- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java
+++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java
@@ -93,12 +93,16 @@ public class CloudStackImageStoreDriverImpl extends BaseImageStoreDriverImpl {
         if (sslCfg != null) {
             _sslCopy = Boolean.parseBoolean(sslCfg);
         }
+        if(_sslCopy && (_ssvmUrlDomain == null || _ssvmUrlDomain.isEmpty())){
+            s_logger.warn("Empty secondary storage url domain, ignoring SSL");
+            _sslCopy = false;
+        }
         if (_sslCopy) {
-            hostname = ipAddress.replace(".", "-");
-            if (_ssvmUrlDomain != null && _ssvmUrlDomain.length() > 0) {
-                hostname = hostname + "." + _ssvmUrlDomain;
+            if(_ssvmUrlDomain.startsWith("*")) {
+                hostname = ipAddress.replace(".", "-");
+                hostname = hostname + _ssvmUrlDomain.substring(1);
             } else {
-                hostname = hostname + ".realhostip.com";
+                hostname = _ssvmUrlDomain;
             }
             scheme = "https";
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/09c37537/server/src/com/cloud/configuration/Config.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
index 98e5d34..f2fe68a 100755
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -439,7 +439,7 @@ public enum Config {
             "Console proxy command port that is used to communicate with management server",
             null),
     ConsoleProxyRestart("Console Proxy", AgentManager.class, Boolean.class, "consoleproxy.restart", "true", "Console proxy restart flag, defaulted to true", null),
-    ConsoleProxyUrlDomain("Console Proxy", AgentManager.class, String.class, "consoleproxy.url.domain", "realhostip.com", "Console proxy url domain", null),
+    ConsoleProxyUrlDomain("Console Proxy", AgentManager.class, String.class, "consoleproxy.url.domain", "", "Console proxy url domain", null),
     ConsoleProxyLoadscanInterval(
             "Console Proxy",
             AgentManager.class,
@@ -782,7 +782,7 @@ public enum Config {
             ManagementServer.class,
             String.class,
             "secstorage.ssl.cert.domain",
-            "realhostip.com",
+            "",
             "SSL certificate used to encrypt copy traffic between zones",
             null),
     SecStorageCapacityStandby(

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/09c37537/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
index 3e4c57e..0512096 100755
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
@@ -233,6 +233,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
 
     private int _proxySessionTimeoutValue = DEFAULT_PROXY_SESSION_TIMEOUT;
     private boolean _sslEnabled = true;
+    private String _consoleProxyUrlDomain;
 
     // global load picture at zone basis
     private SystemVmLoadScanner<Long> _loadScanner;
@@ -384,9 +385,9 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
         assert (ksVo != null);
 
         if (_staticPublicIp == null) {
-            return new ConsoleProxyInfo(proxy.isSslEnabled(), proxy.getPublicIpAddress(), _consoleProxyPort, proxy.getPort(), ksVo.getDomainSuffix());
+            return new ConsoleProxyInfo(proxy.isSslEnabled(), proxy.getPublicIpAddress(), _consoleProxyPort, proxy.getPort(), _consoleProxyUrlDomain);
         } else {
-            return new ConsoleProxyInfo(proxy.isSslEnabled(), _staticPublicIp, _consoleProxyPort, _staticPort, ksVo.getDomainSuffix());
+            return new ConsoleProxyInfo(proxy.isSslEnabled(), _staticPublicIp, _consoleProxyPort, _staticPort, _consoleProxyUrlDomain);
         }
     }
 
@@ -1191,6 +1192,12 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
             _sslEnabled = true;
         }
 
+        _consoleProxyUrlDomain = configs.get(Config.ConsoleProxyUrlDomain.key());
+        if( _sslEnabled && (_consoleProxyUrlDomain == null || _consoleProxyUrlDomain.isEmpty())) {
+            s_logger.warn("Empty console proxy domain, explicitly disabling SSL");
+            _sslEnabled = false;
+        }
+
         value = configs.get(Config.ConsoleProxyCapacityScanInterval.key());
         _capacityScanInterval = NumbersUtil.parseLong(value, DEFAULT_CAPACITY_SCAN_INTERVAL);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/09c37537/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
index dd0c267..f8edefa 100755
--- a/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
+++ b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
@@ -807,6 +807,13 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
             _useSSlCopy = true;
         }
 
+        //default to HTTP in case of missing domain
+        String ssvmUrlDomain = _configDao.getValue("secstorage.ssl.cert.domain");
+        if(_useSSlCopy && (ssvmUrlDomain == null || ssvmUrlDomain.isEmpty())){
+            s_logger.warn("Empty secondary storage url domain, explicitly disabling SSL");
+            _useSSlCopy = false;
+        }
+
         _allowedInternalSites = _configDao.getValue("secstorage.allowed.internal.sites");
 
         String value = configs.get("secstorage.capacityscan.interval");

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/09c37537/setup/db/db/schema-421to430.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql
index b49fd96..3f2ad02 100644
--- a/setup/db/db/schema-421to430.sql
+++ b/setup/db/db/schema-421to430.sql
@@ -110,6 +110,10 @@ CREATE TABLE `cloud`.`async_job_join_map` (
   INDEX `i_async_job_join_map__expiration`(`expiration`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
+#realhostip changes, before changing table and adding default value
+UPDATE `cloud`.`configuration` SET value = CONCAT("*.",(SELECT `temptable`.`value` FROM (SELECT * FROM `cloud`.`configuration` WHERE `name`="consoleproxy.url.domain") AS `temptable` WHERE `temptable`.`name`="consoleproxy.url.domain")) WHERE `name`="consoleproxy.url.domain";
+UPDATE `cloud`.`configuration` SET `value` = CONCAT("*.",(SELECT `temptable`.`value` FROM (SELECT * FROM `cloud`.`configuration` WHERE `name`="secstorage.ssl.cert.domain") AS `temptable` WHERE `temptable`.`name`="secstorage.ssl.cert.domain")) WHERE `name`="secstorage.ssl.cert.domain";
+
 ALTER TABLE `cloud`.`configuration` ADD COLUMN `default_value` VARCHAR(4095) COMMENT 'Default value for a configuration parameter';
 ALTER TABLE `cloud`.`configuration` ADD COLUMN `updated` datetime COMMENT 'Time this was updated by the server. null means this row is obsolete.';
 ALTER TABLE `cloud`.`configuration` ADD COLUMN `scope` VARCHAR(255) DEFAULT NULL COMMENT 'Can this parameter be scoped';

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/09c37537/systemvm/conf/consoleproxy.properties
----------------------------------------------------------------------
diff --git a/systemvm/conf/consoleproxy.properties b/systemvm/conf/consoleproxy.properties
index bb452f5..a3cddbc 100644
--- a/systemvm/conf/consoleproxy.properties
+++ b/systemvm/conf/consoleproxy.properties
@@ -16,7 +16,7 @@
 # under the License.
 
 consoleproxy.tcpListenPort=0
-consoleproxy.httpListenPort=8088
+consoleproxy.httpListenPort=80
 consoleproxy.httpCmdListenPort=8001
 consoleproxy.jarDir=./applet/
 consoleproxy.viewerLinger=180


[36/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
CLOUDSTACK-6221:
Publish first class objects involved in an operation (for now vm uuid) on the event bus . Example -  during attach/detachIso along with iso id, vm id should be available as well.


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/33a0dec9
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/33a0dec9
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/33a0dec9

Branch: refs/heads/distributedrouter
Commit: 33a0dec965c96483c8cd55e309250662fca5e2da
Parents: 466825a
Author: Nitin Mehta <ni...@citrix.com>
Authored: Mon Mar 10 16:22:34 2014 -0700
Committer: Nitin Mehta <ni...@citrix.com>
Committed: Mon Mar 10 16:22:34 2014 -0700

----------------------------------------------------------------------
 api/src/com/cloud/event/EventTypes.java          |  1 +
 server/src/com/cloud/api/ApiDispatcher.java      |  9 ++++++++-
 server/src/com/cloud/api/ApiServer.java          | 11 ++++++++++-
 server/src/com/cloud/event/ActionEventUtils.java |  8 +++++++-
 utils/src/com/cloud/utils/ReflectUtil.java       | 13 +++++++++++++
 5 files changed, 39 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/33a0dec9/api/src/com/cloud/event/EventTypes.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java
index 7994ada..a5fc0f0 100755
--- a/api/src/com/cloud/event/EventTypes.java
+++ b/api/src/com/cloud/event/EventTypes.java
@@ -483,6 +483,7 @@ public class EventTypes {
 
         // TODO: need a way to force author adding event types to declare the entity details as well, with out braking
         // current ActionEvent annotation semantics
+        // TODO #2 - The map should be from event type to class.
 
         entityEventDetails = new HashMap<String, String>();
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/33a0dec9/server/src/com/cloud/api/ApiDispatcher.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java
index 8f980d9..27ff952 100755
--- a/server/src/com/cloud/api/ApiDispatcher.java
+++ b/server/src/com/cloud/api/ApiDispatcher.java
@@ -22,6 +22,8 @@ import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 
 import com.cloud.event.EventTypes;
+import com.cloud.utils.ReflectUtil;
+import com.cloud.vm.VirtualMachine;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.BaseAsyncCmd;
 import org.apache.cloudstack.api.BaseAsyncCreateCmd;
@@ -83,13 +85,18 @@ public class ApiDispatcher {
 
             final BaseAsyncCmd asyncCmd = (BaseAsyncCmd)cmd;
             final String startEventId = params.get(ApiConstants.CTX_START_EVENT_ID);
-            String uuid = params.get("uuid");
+            String uuid = params.get(ApiConstants.UUID);
             ctx.setStartEventId(Long.valueOf(startEventId));
 
             // Fow now use the key from EventTypes.java rather than getInstanceType bcz the later doesn't refer to the interfaces
+            // Add the resource id in the call context, also add some other first class object ids (for now vm) if available.
+            // TODO - this should be done for all the uuids passed in the cmd - so should be moved where uuid to id conversion happens.
             if(EventTypes.getEntityForEvent(asyncCmd.getEventType()) != null){
                 ctx.putContextParameter(EventTypes.getEntityForEvent(asyncCmd.getEventType()), uuid);
             }
+            if(params.get(ApiConstants.VIRTUAL_MACHINE_ID) != null){
+                ctx.putContextParameter(ReflectUtil.getEntityName(VirtualMachine.class), params.get(ApiConstants.VIRTUAL_MACHINE_ID));
+            }
 
             // Synchronise job on the object if needed
             if (asyncCmd.getJob() != null && asyncCmd.getSyncObjId() != null && asyncCmd.getSyncObjType() != null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/33a0dec9/server/src/com/cloud/api/ApiServer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java
index 7ad7c10..3502689 100755
--- a/server/src/com/cloud/api/ApiServer.java
+++ b/server/src/com/cloud/api/ApiServer.java
@@ -54,6 +54,8 @@ import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 
 import com.cloud.event.EventTypes;
+import com.cloud.utils.ReflectUtil;
+import com.cloud.vm.VirtualMachine;
 import org.apache.cloudstack.acl.APIChecker;
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
@@ -503,6 +505,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
         final CallContext ctx = CallContext.current();
         final Long callerUserId = ctx.getCallingUserId();
         final Account caller = ctx.getCallingAccount();
+        String vmUUID = params.get(ApiConstants.VIRTUAL_MACHINE_ID);
 
         // Queue command based on Cmd super class:
         // BaseCmd: cmd is dispatched to ApiDispatcher, executed, serialized and returned.
@@ -519,7 +522,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
                 params.put("id", objectId.toString());
             } else {
                 // Extract the uuid before params are processed and id reflects internal db id
-                objectUuid = params.get("id");
+                objectUuid = params.get(ApiConstants.ID);
                 dispatchChainFactory.getStandardDispatchChain().dispatch(new DispatchTask(cmdObj, params));
             }
 
@@ -538,9 +541,15 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
             long startEventId = ctx.getStartEventId();
             asyncCmd.setStartEventId(startEventId);
 
+            // Add the resource id in the call context, also add some other first class object ids (for now vm) if available.
+            // TODO - this should be done for all the uuids passed in the cmd - so should be moved where uuid to id conversion happens.
             if(EventTypes.getEntityForEvent(asyncCmd.getEventType()) != null){
                 ctx.putContextParameter(EventTypes.getEntityForEvent(asyncCmd.getEventType()), objectUuid);
             }
+            if(vmUUID != null){
+                ctx.putContextParameter(ReflectUtil.getEntityName(VirtualMachine.class), vmUUID);
+            }
+
             // save the scheduled event
             final Long eventId =
                 ActionEventUtils.onScheduledActionEvent((callerUserId == null) ? User.UID_SYSTEM : callerUserId, asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(),

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/33a0dec9/server/src/com/cloud/event/ActionEventUtils.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/event/ActionEventUtils.java b/server/src/com/cloud/event/ActionEventUtils.java
index 5954670..28e5680 100755
--- a/server/src/com/cloud/event/ActionEventUtils.java
+++ b/server/src/com/cloud/event/ActionEventUtils.java
@@ -25,6 +25,8 @@ import java.util.Map;
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 
+import com.cloud.utils.ReflectUtil;
+import com.cloud.vm.VirtualMachine;
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 
@@ -186,10 +188,12 @@ public class ActionEventUtils {
         String entityType = null;
         String entityUuid = null;
         CallContext context = CallContext.current();
+        String vmEntityName = ReflectUtil.getEntityName(VirtualMachine.class);
+        String vmuuid = (String) context.getContextParameter(vmEntityName);
         Class entityKey = getEntityKey(eventType);
         if (entityKey != null)
         {
-            //FIXME - Remove this
+            //FIXME - Remove this since it should be covered by the else if condition below.
             entityUuid = (String)context.getContextParameter(entityKey);
             if (entityUuid != null)
                 entityType = entityKey.getName();
@@ -220,6 +224,8 @@ public class ActionEventUtils {
         eventDescription.put("status", state.toString());
         eventDescription.put("entity", entityType);
         eventDescription.put("entityuuid", entityUuid);
+        //Put all the first class entities that are touched during the action. For now atleast put in the vmid.
+        eventDescription.put(vmEntityName, vmuuid);
         eventDescription.put("description", description);
 
         String eventDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z").format(new Date());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/33a0dec9/utils/src/com/cloud/utils/ReflectUtil.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/ReflectUtil.java b/utils/src/com/cloud/utils/ReflectUtil.java
index 379f1c0..9c09980 100755
--- a/utils/src/com/cloud/utils/ReflectUtil.java
+++ b/utils/src/com/cloud/utils/ReflectUtil.java
@@ -189,4 +189,17 @@ public class ReflectUtil {
 
     }
 
+    public static String getEntityName(Class clz){
+        if(clz == null)
+            return null;
+
+        String entityName = clz.getName();
+        int index = entityName.lastIndexOf(".");
+        if (index != -1) {
+            return entityName.substring(index + 1);
+        }else{
+            return entityName;
+        }
+    }
+
 }


[30/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
Fix truncation issue with refresh, add button icons


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/a1b778fc
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/a1b778fc
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/a1b778fc

Branch: refs/heads/distributedrouter
Commit: a1b778fc2c7f0ec84014f9e7329944032fb3c2a7
Parents: d182a51
Author: Brian Federle <br...@citrix.com>
Authored: Mon Mar 10 07:43:28 2014 -0700
Committer: Brian Federle <br...@citrix.com>
Committed: Mon Mar 10 07:43:28 2014 -0700

----------------------------------------------------------------------
 ui/css/cloudstack3.css | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a1b778fc/ui/css/cloudstack3.css
----------------------------------------------------------------------
diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css
index 11c1c7e..2b88e03 100644
--- a/ui/css/cloudstack3.css
+++ b/ui/css/cloudstack3.css
@@ -3080,7 +3080,7 @@ div.toolbar div.button.refresh span {
 
 div.toolbar div.button.add span,
 .detail-group .button.add span.icon {
-  padding: 0px 0 0px 18px;
+  padding: 0px 0 3px 18px;
   background: url(../images/icons.png) no-repeat -626px -209px;
   /*+placement:shift 0px 0px;*/
   position: relative;


[03/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
CLOUDSTACK-6047: Fix checkstyle build issue


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/2de67dff
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/2de67dff
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/2de67dff

Branch: refs/heads/distributedrouter
Commit: 2de67dff423be1fd81992302ae9ec38f6d619c09
Parents: ccea570
Author: Sheng Yang <sh...@citrix.com>
Authored: Thu Mar 6 16:49:07 2014 -0800
Committer: Sheng Yang <sh...@citrix.com>
Committed: Thu Mar 6 16:49:07 2014 -0800

----------------------------------------------------------------------
 .../VirtualRoutingResourceTest.java             | 66 ++++++++++----------
 1 file changed, 33 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2de67dff/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java
----------------------------------------------------------------------
diff --git a/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java b/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java
index 9b116dd..4737019 100644
--- a/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java
+++ b/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java
@@ -86,27 +86,27 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
     String _file;
     boolean _aggregated = false;
 
-    String ROUTER_IP = "169.254.3.4";
-    String ROUTER_GUEST_IP = "10.200.1.1";
-    String ROUTER_NAME = "r-4-VM";
+    String ROUTERIP = "169.254.3.4";
+    String ROUTERGUESTIP = "10.200.1.1";
+    String ROUTERNAME = "r-4-VM";
 
     @Override
     public ExecutionResult executeInVR(String routerIp, String script, String args) {
-        assertEquals(routerIp, ROUTER_IP);
+        assertEquals(routerIp, ROUTERIP);
         verifyCommand(_currentCmd, script, args);
         return new ExecutionResult(true, null);
     }
 
     @Override
     public ExecutionResult createFileInVR(String routerIp, String path, String filename, String content) {
-        assertEquals(routerIp, ROUTER_IP);
+        assertEquals(routerIp, ROUTERIP);
         verifyFile(_currentCmd, path, filename, content);
         return new ExecutionResult(true, null);
     }
 
     @Override
     public ExecutionResult prepareCommand(NetworkElementCommand cmd) {
-        cmd.setRouterAccessIp(ROUTER_IP);
+        cmd.setRouterAccessIp(ROUTERIP);
         _currentCmd = cmd;
         if (cmd instanceof IpAssocVpcCommand) {
             return prepareNetworkElementCommand((IpAssocVpcCommand)cmd);
@@ -239,7 +239,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         pfRules.add(new PortForwardingRuleTO(1, "64.1.1.10", 22, 80, "10.10.1.10", 22, 80, "TCP", false, false));
         pfRules.add(new PortForwardingRuleTO(2, "64.1.1.11", 8080, 8080, "10.10.1.11", 8080, 8080, "UDP", true, false));
         SetPortForwardingRulesVpcCommand cmd = new SetPortForwardingRulesVpcCommand(pfRules);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         assertEquals(cmd.getAnswersCount(), 2);
         return cmd;
     }
@@ -276,7 +276,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         pfRules.add(new PortForwardingRuleTO(1, "64.1.1.10", 22, 80, "10.10.1.10", 22, 80, "TCP", false, false));
         pfRules.add(new PortForwardingRuleTO(2, "64.1.1.11", 8080, 8080, "10.10.1.11", 8080, 8080, "UDP", true, false));
         SetPortForwardingRulesCommand cmd = new SetPortForwardingRulesCommand(pfRules);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         assertEquals(cmd.getAnswersCount(), 2);
         return cmd;
     }
@@ -323,7 +323,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         ips.add(new IpAddressTO(3, "65.1.1.11", true, false, false, "vlan://65", "65.1.1.1", "255.255.255.0", "11:23:45:67:89:AB", 1000, false));
         IpAddressTO[] ipArray = ips.toArray(new IpAddressTO[ips.size()]);
         IpAssocCommand cmd = new IpAssocCommand(ipArray);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         assertEquals(cmd.getAnswersCount(), 3);
 
         return cmd;
@@ -356,7 +356,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         ips.add(new IpAddressTO(3, "65.1.1.11", true, false, false, "vlan://65", "65.1.1.1", "255.255.255.0", "11:23:45:67:89:AB", 1000, false));
         IpAddressTO[] ipArray = ips.toArray(new IpAddressTO[ips.size()]);
         IpAssocVpcCommand cmd = new IpAssocVpcCommand(ipArray);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         assertEquals(cmd.getAnswersCount(), 6);
 
         return cmd;
@@ -424,7 +424,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
     protected SetSourceNatCommand generateSetSourceNatCommand() {
         IpAddressTO ip = new IpAddressTO(1, "64.1.1.10", true, true, true, "vlan://64", "64.1.1.1", "255.255.255.0", "01:23:45:67:89:AB", 1000, false);
         SetSourceNatCommand cmd = new SetSourceNatCommand(ip, true);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         return cmd;
     }
 
@@ -459,7 +459,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         nic.setIp("192.168.1.1");
         nic.setNetmask("255.255.255.0");
         SetNetworkACLCommand cmd = new SetNetworkACLCommand(acls, nic);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
 
         return cmd;
     }
@@ -510,7 +510,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         SetupGuestNetworkCommand cmd = new SetupGuestNetworkCommand("10.1.1.10-10.1.1.20", "cloud.test", false, 0, "8.8.8.8", "8.8.4.4", true, nic);
         cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, "10.1.1.2");
         cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY, "10.1.1.1");
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
 
         return cmd;
     }
@@ -533,7 +533,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         services.add(new MonitorServiceTO("service_2", "process_2", "name_2", "path_2", "file_2", false));
 
         SetMonitorServiceCommand cmd = new SetMonitorServiceCommand(services);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
 
         return cmd;
     }
@@ -548,17 +548,17 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         _count = 0;
 
         Site2SiteVpnCfgCommand cmd = new Site2SiteVpnCfgCommand(true, "64.10.1.10", "64.10.1.1", "192.168.1.1/16", "124.10.1.10", "192.168.100.1/24", "3des-sha1,aes128-sha1;modp1536", "3des-sha1,aes128-md5", "psk", Long.valueOf(1800), Long.valueOf(1800), true, false);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         Answer answer = _resource.executeRequest(cmd);
         assertTrue(answer.getResult());
 
         cmd = new Site2SiteVpnCfgCommand(true, "64.10.1.10", "64.10.1.1", "192.168.1.1/16", "124.10.1.10", "192.168.100.1/24", "3des-sha1,aes128-sha1;modp1536", "3des-sha1,aes128-md5", "psk", Long.valueOf(1800), Long.valueOf(1800), false, true);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         answer = _resource.executeRequest(cmd);
         assertTrue(answer.getResult());
 
         cmd = new Site2SiteVpnCfgCommand(false, "64.10.1.10", "64.10.1.1", "192.168.1.1/16", "124.10.1.10", "192.168.100.1/24", "3des-sha1,aes128-sha1;modp1536", "3des-sha1,aes128-md5", "psk", Long.valueOf(1800), Long.valueOf(1800), false, true);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         answer = _resource.executeRequest(cmd);
         assertTrue(answer.getResult());
     }
@@ -598,21 +598,21 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
 
     protected RemoteAccessVpnCfgCommand generateRemoteAccessVpnCfgCommand1() {
         RemoteAccessVpnCfgCommand cmd = new RemoteAccessVpnCfgCommand(true, "124.10.10.10", "10.10.1.1", "10.10.1.10-10.10.1.20", "sharedkey", false);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         cmd.setLocalCidr("10.1.1.1/24");
         return cmd;
     }
 
     protected RemoteAccessVpnCfgCommand generateRemoteAccessVpnCfgCommand2() {
         RemoteAccessVpnCfgCommand cmd = new RemoteAccessVpnCfgCommand(false, "124.10.10.10", "10.10.1.1", "10.10.1.10-10.10.1.20", "sharedkey", false);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         cmd.setLocalCidr("10.1.1.1/24");
         return cmd;
     }
 
     protected RemoteAccessVpnCfgCommand generateRemoteAccessVpnCfgCommand3() {
         RemoteAccessVpnCfgCommand cmd = new RemoteAccessVpnCfgCommand(true, "124.10.10.10", "10.10.1.1", "10.10.1.10-10.10.1.20", "sharedkey", true);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         cmd.setLocalCidr("10.1.1.1/24");
         return cmd;
     }
@@ -658,7 +658,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         rules.add(new FirewallRuleTO(2, "64.10.10.10", "ICMP", 0, 0, false, false, Purpose.Firewall, sourceCidrs, -1, -1));
         rules.add(new FirewallRuleTO(3, "64.10.10.10", "ICMP", 0, 0, true, true, Purpose.Firewall, sourceCidrs, -1, -1));
         SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(rules);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
 
         return cmd;
     }
@@ -688,7 +688,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         cmd.addVmData("metadata", "public-keys", "publickey");
         cmd.addVmData("metadata", "cloud-identifier", "CloudStack-{test}");
 
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
 
         return cmd;
     }
@@ -711,7 +711,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
 
     protected SavePasswordCommand generateSavePasswordCommand() {
         SavePasswordCommand cmd = new SavePasswordCommand("123pass", "10.1.10.4", "i-4-VM", true);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         return cmd;
     }
 
@@ -736,20 +736,20 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
 
     protected DhcpEntryCommand generateDhcpEntryCommand1() {
         DhcpEntryCommand cmd = new DhcpEntryCommand("12:34:56:78:90:AB", "10.1.10.2", "vm1", null, true);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         return cmd;
     }
 
     protected DhcpEntryCommand generateDhcpEntryCommand2() {
         DhcpEntryCommand cmd = new DhcpEntryCommand("12:34:56:78:90:AB", null, "vm1", "2001:db8:0:0:0:ff00:42:8329", true);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         cmd.setDuid(NetUtils.getDuidLL(cmd.getVmMac()));
         return cmd;
     }
 
     protected DhcpEntryCommand generateDhcpEntryCommand3() {
         DhcpEntryCommand cmd = new DhcpEntryCommand("12:34:56:78:90:AB", "10.1.10.2", "vm1", "2001:db8:0:0:0:ff00:42:8329", true);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         cmd.setDuid(NetUtils.getDuidLL(cmd.getVmMac()));
         return cmd;
     }
@@ -784,7 +784,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         aliases.add(new IpAliasTO("169.254.3.11", "255.255.255.0", "2"));
         aliases.add(new IpAliasTO("169.254.3.12", "255.255.255.0", "3"));
         CreateIpAliasCommand cmd = new CreateIpAliasCommand("169.254.3.10", aliases);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
 
         return cmd;
     }
@@ -806,7 +806,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         aliases.add(new IpAliasTO("169.254.3.11", "255.255.255.0", "2"));
         aliases.add(new IpAliasTO("169.254.3.12", "255.255.255.0", "3"));
         DeleteIpAliasCommand cmd = new DeleteIpAliasCommand("169.254.10.1", aliases, aliases);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         return cmd;
     }
 
@@ -826,7 +826,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         dhcps.add(new DhcpTO("10.1.20.2", "10.1.20.1", "255.255.255.0", "10.1.20.5"));
         dhcps.add(new DhcpTO("10.1.21.2", "10.1.21.1", "255.255.255.0", "10.1.21.5"));
         DnsMasqConfigCommand cmd = new DnsMasqConfigCommand(dhcps);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         return cmd;
     }
 
@@ -858,7 +858,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         NicTO nic = new NicTO();
         LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(arrayLbs, "64.10.2.10", "10.1.10.2", "192.168.1.2", nic, null, "1000", false);
         cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, "10.1.10.2");
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         return cmd;
     }
 
@@ -874,7 +874,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         nic.setIp("10.1.10.2");
         LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(arrayLbs, "64.10.2.10", "10.1.10.2", "192.168.1.2", nic, Long.valueOf(1), "1000", false);
         cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, "10.1.10.2");
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTER_NAME);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
         return cmd;
     }
 
@@ -948,7 +948,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
     @Test
     public void testAggregationCommands() {
         List<NetworkElementCommand> cmds = new LinkedList<>();
-        StartAggregationCommand startCmd = new StartAggregationCommand(ROUTER_NAME, ROUTER_IP, ROUTER_GUEST_IP);
+        StartAggregationCommand startCmd = new StartAggregationCommand(ROUTERNAME, ROUTERIP, ROUTERGUESTIP);
         cmds.add(startCmd);
         cmds.add(generateIpAssocCommand());
         cmds.add(generateIpAssocVpcCommand());
@@ -979,7 +979,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         cmds.add(generateSavePasswordCommand());
         cmds.add(generateVmDataCommand());
 
-        FinishAggregationCommand finishCmd = new FinishAggregationCommand(ROUTER_NAME, ROUTER_IP, ROUTER_GUEST_IP);
+        FinishAggregationCommand finishCmd = new FinishAggregationCommand(ROUTERNAME, ROUTERIP, ROUTERGUESTIP);
         cmds.add(finishCmd);
 
         for (NetworkElementCommand cmd : cmds) {


[37/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
CLOUDSTACK-6179 Execute VR commands on Virtual Resource when commands received to Hyper-V


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/540d020a
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/540d020a
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/540d020a

Branch: refs/heads/distributedrouter
Commit: 540d020aa5c0cd5d3b4657973b1c8a852bdf6d58
Parents: 33a0dec
Author: Rajesh Battala <ra...@citrix.com>
Authored: Tue Mar 11 13:09:18 2014 +0530
Committer: Rajesh Battala <ra...@citrix.com>
Committed: Tue Mar 11 13:10:13 2014 +0530

----------------------------------------------------------------------
 .../hypervisor/hyperv/guru/HypervGuru.java      |   9 +-
 .../resource/HypervDirectConnectResource.java   | 216 ++++++++++++++++++-
 .../debian/config/etc/init.d/cloud-early-config |   8 +-
 3 files changed, 222 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/540d020a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java
index 1d9e7f6..bf0795d 100644
--- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java
+++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java
@@ -53,7 +53,7 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru {
     @Inject HypervManager _hypervMgr;
     @Inject NetworkDao _networkDao;
     @Inject NetworkModel _networkMgr;
-
+    int MaxNicSupported = 8;
     @Override
     public final HypervisorType getHypervisorType() {
         return HypervisorType.Hyperv;
@@ -85,7 +85,7 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru {
                 NicTO[] nics = to.getNics();
 
                 // reserve extra NICs
-                NicTO[] expandedNics = new NicTO[nics.length +  _hypervMgr.getRouterExtraPublicNics()];
+                NicTO[] expandedNics = new NicTO[MaxNicSupported];
                 int i = 0;
                 int deviceId = -1;
                 for(i = 0; i < nics.length; i++) {
@@ -97,8 +97,9 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru {
 
                 long networkId = publicNicProfile.getNetworkId();
                 NetworkVO network = _networkDao.findById(networkId);
-
-                for(; i < nics.length + _hypervMgr.getRouterExtraPublicNics(); i++) {
+                // for Hyperv Hot Nic plug is not supported and it will support upto 8 nics.
+                // creating the VR with extra nics (actual nics(3) + extra nics) will be 8
+                for(; i < MaxNicSupported; i++) {
                     NicTO nicTo = new NicTO();
                     nicTo.setDeviceId(deviceId++);
                     nicTo.setBroadcastType(publicNicProfile.getBroadcastType());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/540d020a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
index 549f06d..a3ffa75 100644
--- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
+++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
@@ -83,6 +83,7 @@ import com.cloud.agent.api.NetworkUsageCommand;
 import com.cloud.agent.api.PingCommand;
 import com.cloud.agent.api.PingRoutingCommand;
 import com.cloud.agent.api.PingTestCommand;
+import com.cloud.agent.api.SetupGuestNetworkCommand;
 import com.cloud.agent.api.StartCommand;
 import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.StartupRoutingCommand;
@@ -98,6 +99,7 @@ import com.cloud.agent.api.routing.DnsMasqConfigCommand;
 import com.cloud.agent.api.routing.IpAliasTO;
 import com.cloud.agent.api.routing.IpAssocAnswer;
 import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.IpAssocVpcCommand;
 import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
 import com.cloud.agent.api.routing.NetworkElementCommand;
 import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
@@ -105,6 +107,7 @@ import com.cloud.agent.api.routing.SavePasswordCommand;
 import com.cloud.agent.api.routing.SetFirewallRulesAnswer;
 import com.cloud.agent.api.routing.SetFirewallRulesCommand;
 import com.cloud.agent.api.routing.SetMonitorServiceCommand;
+import com.cloud.agent.api.routing.SetNetworkACLCommand;
 import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer;
 import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
 import com.cloud.agent.api.routing.SetSourceNatAnswer;
@@ -119,9 +122,12 @@ import com.cloud.agent.api.routing.VpnUsersCfgCommand;
 import com.cloud.agent.api.to.DhcpTO;
 import com.cloud.agent.api.to.FirewallRuleTO;
 import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.agent.api.to.NicTO;
 import com.cloud.agent.api.to.PortForwardingRuleTO;
 import com.cloud.agent.api.to.StaticNatRuleTO;
 import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer;
+import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
 import com.cloud.dc.DataCenter.NetworkType;
 import com.cloud.exception.InternalErrorException;
 import com.cloud.host.Host.Type;
@@ -135,6 +141,7 @@ import com.cloud.network.rules.FirewallRule;
 import com.cloud.resource.ServerResource;
 import com.cloud.resource.ServerResourceBase;
 import com.cloud.serializer.GsonHelper;
+import com.cloud.utils.ExecutionResult;
 import com.cloud.utils.Pair;
 import com.cloud.utils.StringUtils;
 import com.cloud.utils.net.NetUtils;
@@ -148,7 +155,7 @@ import com.cloud.vm.VirtualMachineName;
  * Implementation of dummy resource to be returned from discoverer.
  **/
 @Local(value = ServerResource.class)
-public class HypervDirectConnectResource extends ServerResourceBase implements ServerResource {
+public class HypervDirectConnectResource extends ServerResourceBase implements ServerResource, VirtualRouterDeployer {
     public static final int DEFAULT_AGENT_PORT = 8250;
     public static final String HOST_VM_STATE_REPORT_COMMAND = "org.apache.cloudstack.HostVmStateReportCommand";
     private static final Logger s_logger = Logger.getLogger(HypervDirectConnectResource.class.getName());
@@ -178,6 +185,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
     private static HypervManager s_hypervMgr;
     @Inject
     HypervManager _hypervMgr;
+    protected VirtualRoutingResource _vrResource;
 
     @PostConstruct
     void init() {
@@ -421,8 +429,9 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
             s_logger.error(errMsg, e);
             return null;
         }
-
-        if (clazz == CheckSshCommand.class) {
+        if (cmd instanceof NetworkElementCommand) {
+        return _vrResource.executeRequest((NetworkElementCommand)cmd);
+        }if (clazz == CheckSshCommand.class) {
             answer = execute((CheckSshCommand)cmd);
         } else if (clazz == GetDomRVersionCmd.class) {
             answer = execute((GetDomRVersionCmd)cmd);
@@ -499,6 +508,203 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
         }
         return answer;
     }
+
+    @Override
+    public ExecutionResult executeInVR(String routerIP, String script, String args) {
+        Pair<Boolean, String> result;
+
+        //TODO: Password should be masked, cannot output to log directly
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Run command on VR: " + routerIP + ", script: " + script + " with args: " + args);
+        }
+
+        try {
+            result = SshHelper.sshExecute(routerIP, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/" + script + " " + args);
+        } catch (Exception e) {
+            String msg = "Command failed due to " + e ;
+            s_logger.error(msg);
+            result = new Pair<Boolean, String>(false, msg);
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug(script + " execution result: " + result.first().toString());
+        }
+        return new ExecutionResult(result.first(), result.second());
+    }
+
+    @Override
+    public ExecutionResult createFileInVR(String routerIp, String filePath, String fileName, String content) {
+        File keyFile = getSystemVMKeyFile();
+        try {
+            SshHelper.scpTo(routerIp, 3922, "root", keyFile, null, filePath, content.getBytes(), fileName, null);
+        } catch (Exception e) {
+            s_logger.warn("Fail to create file " + filePath + fileName + " in VR " + routerIp, e);
+            return new ExecutionResult(false, e.getMessage());
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    @Override
+    public ExecutionResult prepareCommand(NetworkElementCommand cmd) {
+        //Update IP used to access router
+        cmd.setRouterAccessIp(getRouterSshControlIp(cmd));
+        assert cmd.getRouterAccessIp() != null;
+
+        if (cmd instanceof IpAssocVpcCommand) {
+            return prepareNetworkElementCommand((IpAssocVpcCommand)cmd);
+        } else if (cmd instanceof IpAssocCommand) {
+            return prepareNetworkElementCommand((IpAssocCommand)cmd);
+        } else if (cmd instanceof SetSourceNatCommand) {
+            return prepareNetworkElementCommand((SetSourceNatCommand)cmd);
+        } else if (cmd instanceof SetupGuestNetworkCommand) {
+            return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd);
+        } else if (cmd instanceof SetNetworkACLCommand) {
+            return prepareNetworkElementCommand((SetNetworkACLCommand)cmd);
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    private ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) {
+        try {
+
+            IpAddressTO[] ips = cmd.getIpAddresses();
+            String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+            String controlIp = getRouterSshControlIp(cmd);
+
+            for (IpAddressTO ip : ips) {
+                /**
+                 * TODO support other networks
+                 */
+                URI broadcastUri = BroadcastDomainType.fromString(ip.getBroadcastUri());
+                if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) {
+                    throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + ip.getBroadcastUri());
+                }
+                int vlanId = Integer.parseInt(BroadcastDomainType.getValue(broadcastUri));
+                int publicNicInfo = -1;
+                publicNicInfo = getVmNics(routerName, vlanId);
+
+                boolean addVif = false;
+                if (ip.isAdd() && publicNicInfo == -1) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Plug new NIC to associate" + controlIp + " to " + ip.getPublicIp());
+                    }
+                    addVif = true;
+                }
+
+                if (addVif) {
+                    Pair<Integer, String> nicdevice = findRouterFreeEthDeviceIndex(controlIp);
+                    publicNicInfo = nicdevice.first();
+                    if (publicNicInfo > 0) {
+                        modifyNicVlan(routerName, vlanId, nicdevice.second());
+                        // After modifying the vnic on VR, check the VR VNics config in the host and get the device position
+                        publicNicInfo = getVmNics(routerName, vlanId);
+                        // As a new nic got activated in the VR. add the entry in the NIC's table.
+                        networkUsage(controlIp, "addVif", "eth" + publicNicInfo);
+                    }
+                    else {
+                        // we didn't find any eth device available in VR to configure the ip range with new VLAN
+                        String msg = "No Nic is available on DomR VIF to associate/disassociate IP with.";
+                        s_logger.error(msg);
+                        throw new InternalErrorException(msg);
+                    }
+                    ip.setNicDevId(publicNicInfo);
+                    ip.setNewNic(addVif);
+                } else {
+                    ip.setNicDevId(publicNicInfo);
+                }
+            }
+        } catch (Throwable e) {
+            s_logger.error("Unexpected exception: " + e.toString() + " will shortcut rest of IPAssoc commands", e);
+            return new ExecutionResult(false, e.toString());
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    protected ExecutionResult prepareNetworkElementCommand(SetupGuestNetworkCommand cmd) {
+        NicTO nic = cmd.getNic();
+        String routerIp = getRouterSshControlIp(cmd);
+        String domrName =
+                cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+
+        try {
+            int ethDeviceNum = findRouterEthDeviceIndex(domrName, routerIp,
+                    nic.getMac());
+            nic.setDeviceId(ethDeviceNum);
+        } catch (Exception e) {
+            String msg = "Prepare SetupGuestNetwork failed due to " + e.toString();
+            s_logger.warn(msg, e);
+            return new ExecutionResult(false, msg);
+        }
+        return new ExecutionResult(true, null);
+    }
+
+
+    private ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand cmd) {
+        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        String routerIp = getRouterSshControlIp(cmd);
+
+        try {
+            IpAddressTO[] ips = cmd.getIpAddresses();
+            for (IpAddressTO ip : ips) {
+
+                int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, ip.getVifMacAddress());
+                if (ethDeviceNum < 0) {
+                    if (ip.isAdd()) {
+                        throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with.");
+                    } else {
+                        s_logger.debug("VIF to deassociate IP with does not exist, return success");
+                        continue;
+                    }
+                }
+
+                ip.setNicDevId(ethDeviceNum);
+            }
+        } catch (Exception e) {
+            s_logger.error("Prepare Ip Assoc failure on applying one ip due to exception:  ", e);
+            return new ExecutionResult(false, e.toString());
+        }
+
+        return new ExecutionResult(true, null);
+    }
+
+    protected ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) {
+        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        String routerIp = getRouterSshControlIp(cmd);
+        IpAddressTO pubIp = cmd.getIpAddress();
+
+        try {
+            int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, pubIp.getVifMacAddress());
+            pubIp.setNicDevId(ethDeviceNum);
+        } catch (Exception e) {
+            String msg = "Prepare Ip SNAT failure due to " + e.toString();
+            s_logger.error(msg, e);
+            return new ExecutionResult(false, e.toString());
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    private ExecutionResult prepareNetworkElementCommand(SetNetworkACLCommand cmd) {
+        NicTO nic = cmd.getNic();
+        String routerName =
+                cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        String routerIp = getRouterSshControlIp(cmd);
+
+        try {
+            int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp,
+                    nic.getMac());
+            nic.setDeviceId(ethDeviceNum);
+        } catch (Exception e) {
+            String msg = "Prepare SetNetworkACL failed due to " + e.toString();
+            s_logger.error(msg, e);
+            return new ExecutionResult(false, msg);
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    @Override
+    public ExecutionResult cleanupCommand(NetworkElementCommand cmd) {
+        return new ExecutionResult(true, null);
+    }
+
     protected Answer execute(final RemoteAccessVpnCfgCommand cmd) {
         String controlIp = getRouterSshControlIp(cmd);
         StringBuffer argsBuf = new StringBuffer();
@@ -1926,6 +2132,10 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
             _configureCalled = true;
         }
 
+        _vrResource = new VirtualRoutingResource(this);
+        if (!_vrResource.configure(name, new HashMap<String, Object>())) {
+            throw new ConfigurationException("Unable to configure VirtualRoutingResource");
+        }
         return true;
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/540d020a/systemvm/patches/debian/config/etc/init.d/cloud-early-config
----------------------------------------------------------------------
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 fa95fda..c287d43 100755
--- a/systemvm/patches/debian/config/etc/init.d/cloud-early-config
+++ b/systemvm/patches/debian/config/etc/init.d/cloud-early-config
@@ -1221,10 +1221,6 @@ start() {
   patch_log4j
   parse_cmd_line
   change_password
-  if [ "$hyp" == "hyperv" ]; then
-    # eject the systemvm.iso
-      eject
-  fi
   case $TYPE in 
      router)
          [ "$NAME" == "" ] && NAME=router
@@ -1259,6 +1255,10 @@ start() {
          setup_default;
           ;;
   esac
+    if [ "$hyp" == "hyperv" ]; then
+    # eject the systemvm.iso
+     eject
+  fi
   return 0
 }
 


[08/50] [abbrv] Dispatcher corrections, refactoring and tests

Posted by mu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java b/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java
new file mode 100644
index 0000000..0c829e8
--- /dev/null
+++ b/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java
@@ -0,0 +1,103 @@
+// 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.api.dispatch;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.log4j.Logger;
+
+/**
+ * This worker validates parameters in a generic way, by using annotated
+ * restrictions without involving the {@Link BaseCmd}. This worker doesn't
+ * know or care about the meaning of the parameters and that's why we can
+ * have it out of the {@Link BaseCmd}
+ *
+ * @author afornie
+ */
+public class ParamGenericValidationWorker implements DispatchWorker {
+
+    protected static Logger s_logger = Logger.getLogger(ParamGenericValidationWorker.class.getName());
+
+    protected static List<String> defaultParamNames = new ArrayList<String>();
+
+    static {
+        defaultParamNames.add(ApiConstants.CTX_START_EVENT_ID);
+        defaultParamNames.add(ApiConstants.COMMAND);
+        defaultParamNames.add(ApiConstants.CMD_EVENT_TYPE);
+        defaultParamNames.add(ApiConstants.USERNAME);
+        defaultParamNames.add(ApiConstants.USER_ID);
+        defaultParamNames.add(ApiConstants.PASSWORD);
+        defaultParamNames.add(ApiConstants.DOMAIN);
+        defaultParamNames.add(ApiConstants.DOMAIN_ID);
+        defaultParamNames.add(ApiConstants.DOMAIN__ID);
+        defaultParamNames.add(ApiConstants.SESSIONKEY);
+        defaultParamNames.add(ApiConstants.RESPONSE);
+        defaultParamNames.add(ApiConstants.PAGE);
+        defaultParamNames.add(ApiConstants.USER_API_KEY);
+        defaultParamNames.add(ApiConstants.API_KEY);
+        defaultParamNames.add(ApiConstants.PAGE_SIZE);
+        defaultParamNames.add(ApiConstants.HTTPMETHOD);
+        defaultParamNames.add(ApiConstants.SIGNATURE);
+        defaultParamNames.add(ApiConstants.CTX_ACCOUNT_ID);
+        defaultParamNames.add(ApiConstants.CTX_START_EVENT_ID);
+        defaultParamNames.add(ApiConstants.CTX_USER_ID);
+        defaultParamNames.add("_");
+    }
+
+    protected static final String ERROR_MSG_PREFIX = "Unknown parameters :";
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    public void handle(final DispatchTask task) {
+        final BaseCmd cmd = task.getCmd();
+        final Map params = task.getParams();
+
+        final List<String> expectedParamNames = getParamNamesForCommand(cmd);
+
+        final StringBuilder errorMsg = new StringBuilder(ERROR_MSG_PREFIX);
+        boolean foundUnknownParam = false;
+        for (final Object paramName : params.keySet()) {
+            if (!expectedParamNames.contains(paramName)) {
+                errorMsg.append(" ").append(paramName);
+                foundUnknownParam= true;
+            }
+        }
+
+        if (foundUnknownParam) {
+            s_logger.warn(String.format("Received unknown parameters for command %s. %s", cmd.getActualCommandName(), errorMsg));
+        }
+    }
+
+    protected List<String> getParamNamesForCommand(final BaseCmd cmd) {
+        final List<String> paramNames = new ArrayList<String>();
+        // The expected param names are all the specific for the current command class ...
+        for (final Field field : cmd.getParamFields()) {
+            final Parameter parameterAnnotation = field.getAnnotation(Parameter.class);
+            paramNames.add(parameterAnnotation.name());
+        }
+        // ... plus the default ones
+        paramNames.addAll(defaultParamNames);
+        return paramNames;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/src/com/cloud/api/dispatch/ParamProcessWorker.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/dispatch/ParamProcessWorker.java b/server/src/com/cloud/api/dispatch/ParamProcessWorker.java
new file mode 100644
index 0000000..e9bdd8b
--- /dev/null
+++ b/server/src/com/cloud/api/dispatch/ParamProcessWorker.java
@@ -0,0 +1,428 @@
+// 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.api.dispatch;
+
+import static org.apache.commons.lang.StringUtils.isNotBlank;
+
+import java.lang.reflect.Field;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.InfrastructureEntity;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.EntityReference;
+import org.apache.cloudstack.api.InternalIdentity;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.BaseCmd.CommandType;
+import org.apache.cloudstack.api.command.admin.resource.ArchiveAlertsCmd;
+import org.apache.cloudstack.api.command.admin.resource.DeleteAlertsCmd;
+import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd;
+import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd;
+import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class ParamProcessWorker implements DispatchWorker {
+
+    private static final Logger s_logger = Logger.getLogger(ParamProcessWorker.class.getName());
+
+    @Inject
+    protected AccountManager _accountMgr;
+
+    @Inject
+    protected EntityManager _entityMgr;
+
+    @Override
+    public void handle(final DispatchTask task) {
+        processParameters(task.getCmd(), task.getParams());
+    }
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public void processParameters(final BaseCmd cmd, final Map params) {
+        final Map<Object, AccessType> entitiesToAccess = new HashMap<Object, AccessType>();
+
+        final List<Field> cmdFields = cmd.getParamFields();
+
+        for (final Field field : cmdFields) {
+            final Parameter parameterAnnotation = field.getAnnotation(Parameter.class);
+            final Object paramObj = params.get(parameterAnnotation.name());
+            if (paramObj == null) {
+                if (parameterAnnotation.required()) {
+                    throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to execute API command " +
+                        cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) +
+                        " due to missing parameter " + parameterAnnotation.name());
+                }
+                continue;
+            }
+
+            // marshall the parameter into the correct type and set the field value
+            try {
+                setFieldValue(field, cmd, paramObj, parameterAnnotation);
+            } catch (final IllegalArgumentException argEx) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Unable to execute API command " + cmd.getCommandName() + " due to invalid value " + paramObj + " for parameter " +
+                            parameterAnnotation.name());
+                }
+                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to execute API command " +
+                    cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) + " due to invalid value " + paramObj + " for parameter " +
+                    parameterAnnotation.name());
+            } catch (final ParseException parseEx) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Invalid date parameter " + paramObj + " passed to command " + cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8));
+                }
+                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to parse date " + paramObj + " for command " +
+                    cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) + ", please pass dates in the format mentioned in the api documentation");
+            } catch (final InvalidParameterValueException invEx) {
+                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to execute API command " +
+                    cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) + " due to invalid value. " + invEx.getMessage());
+            } catch (final CloudRuntimeException cloudEx) {
+                s_logger.error("CloudRuntimeException", cloudEx);
+                // FIXME: Better error message? This only happens if the API command is not executable, which typically
+                //means
+                // there was
+                // and IllegalAccessException setting one of the parameters.
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Internal error executing API command " +
+                    cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8));
+            }
+
+            //check access on the resource this field points to
+            try {
+                final ACL checkAccess = field.getAnnotation(ACL.class);
+                final CommandType fieldType = parameterAnnotation.type();
+
+                if (checkAccess != null) {
+                    // Verify that caller can perform actions in behalf of vm owner
+                    //acumulate all Controlled Entities together.
+
+                    //parse the array of resource types and in case of map check access on key or value or both as specified in @acl
+                    //implement external dao for classes that need findByName
+                    //for maps, specify access to be checkd on key or value.
+
+                    // find the controlled entity DBid by uuid
+                    if (parameterAnnotation.entityType() != null) {
+                        final Class<?>[] entityList = parameterAnnotation.entityType()[0].getAnnotation(EntityReference.class).value();
+
+                        for (final Class entity : entityList) {
+                            // Check if the parameter type is a single
+                            // Id or list of id's/name's
+                            switch (fieldType) {
+                                case LIST:
+                                    final CommandType listType = parameterAnnotation.collectionType();
+                                    switch (listType) {
+                                        case LONG:
+                                        case UUID:
+                                            final List<Long> listParam = (List<Long>)field.get(cmd);
+                                            for (final Long entityId : listParam) {
+                                                final Object entityObj = _entityMgr.findById(entity, entityId);
+                                                entitiesToAccess.put(entityObj, checkAccess.accessType());
+                                            }
+                                            break;
+                                        /*
+                                         * case STRING: List<String> listParam =
+                                         * new ArrayList<String>(); listParam =
+                                         * (List)field.get(cmd); for(String
+                                         * entityName: listParam){
+                                         * ControlledEntity entityObj =
+                                         * (ControlledEntity
+                                         * )daoClassInstance(entityId);
+                                         * entitiesToAccess.add(entityObj); }
+                                         * break;
+                                         */
+                                        default:
+                                            break;
+                                    }
+                                    break;
+                                case LONG:
+                                case UUID:
+                                    final Object entityObj = _entityMgr.findById(entity, (Long)field.get(cmd));
+                                    entitiesToAccess.put(entityObj, checkAccess.accessType());
+                                    break;
+                                default:
+                                    break;
+                            }
+
+                            if (ControlledEntity.class.isAssignableFrom(entity)) {
+                                if (s_logger.isDebugEnabled()) {
+                                    s_logger.debug("ControlledEntity name is:" + entity.getName());
+                                }
+                            }
+
+                            if (InfrastructureEntity.class.isAssignableFrom(entity)) {
+                                if (s_logger.isDebugEnabled()) {
+                                    s_logger.debug("InfrastructureEntity name is:" + entity.getName());
+                                }
+                            }
+                        }
+
+                    }
+
+                }
+
+            } catch (final IllegalArgumentException e) {
+                s_logger.error("Error initializing command " + cmd.getCommandName() + ", field " + field.getName() + " is not accessible.");
+                throw new CloudRuntimeException("Internal error initializing parameters for command " + cmd.getCommandName() + " [field " + field.getName() +
+                    " is not accessible]");
+            } catch (final IllegalAccessException e) {
+                s_logger.error("Error initializing command " + cmd.getCommandName() + ", field " + field.getName() + " is not accessible.");
+                throw new CloudRuntimeException("Internal error initializing parameters for command " + cmd.getCommandName() + " [field " + field.getName() +
+                    " is not accessible]");
+            }
+
+        }
+
+        doAccessChecks(cmd, entitiesToAccess);
+    }
+
+
+    private void doAccessChecks(final BaseCmd cmd, final Map<Object, AccessType> entitiesToAccess) {
+        final Account caller = CallContext.current().getCallingAccount();
+        final Account owner = _accountMgr.getActiveAccountById(cmd.getEntityOwnerId());
+
+        if (cmd instanceof BaseAsyncCreateCmd) {
+            //check that caller can access the owner account.
+            _accountMgr.checkAccess(caller, null, true, owner);
+        }
+
+        if (!entitiesToAccess.isEmpty()) {
+            //check that caller can access the owner account.
+            _accountMgr.checkAccess(caller, null, true, owner);
+            for (final Object entity : entitiesToAccess.keySet()) {
+                if (entity instanceof ControlledEntity) {
+                    _accountMgr.checkAccess(caller, entitiesToAccess.get(entity), true, (ControlledEntity)entity);
+                } else if (entity instanceof InfrastructureEntity) {
+                    //FIXME: Move this code in adapter, remove code from Account manager
+                }
+            }
+        }
+    }
+
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    private void setFieldValue(final Field field, final BaseCmd cmdObj, final Object paramObj, final Parameter annotation) throws IllegalArgumentException, ParseException {
+        try {
+            field.setAccessible(true);
+            final CommandType fieldType = annotation.type();
+            switch (fieldType) {
+                case BOOLEAN:
+                    field.set(cmdObj, Boolean.valueOf(paramObj.toString()));
+                    break;
+                case DATE:
+                    // This piece of code is for maintaining backward compatibility
+                    // and support both the date formats(Bug 9724)
+                    // Do the date messaging for ListEventsCmd only
+                    if (cmdObj instanceof ListEventsCmd || cmdObj instanceof DeleteEventsCmd || cmdObj instanceof ArchiveEventsCmd ||
+                        cmdObj instanceof ArchiveAlertsCmd || cmdObj instanceof DeleteAlertsCmd) {
+                        final boolean isObjInNewDateFormat = isObjInNewDateFormat(paramObj.toString());
+                        if (isObjInNewDateFormat) {
+                            final DateFormat newFormat = BaseCmd.NEW_INPUT_FORMAT;
+                            synchronized (newFormat) {
+                                field.set(cmdObj, newFormat.parse(paramObj.toString()));
+                            }
+                        } else {
+                            final DateFormat format = BaseCmd.INPUT_FORMAT;
+                            synchronized (format) {
+                                Date date = format.parse(paramObj.toString());
+                                if (field.getName().equals("startDate")) {
+                                    date = messageDate(date, 0, 0, 0);
+                                } else if (field.getName().equals("endDate")) {
+                                    date = messageDate(date, 23, 59, 59);
+                                }
+                                field.set(cmdObj, date);
+                            }
+                        }
+                    } else {
+                        final DateFormat format = BaseCmd.INPUT_FORMAT;
+                        synchronized (format) {
+                            format.setLenient(false);
+                            field.set(cmdObj, format.parse(paramObj.toString()));
+                        }
+                    }
+                    break;
+                case FLOAT:
+                    // Assuming that the parameters have been checked for required before now,
+                    // we ignore blank or null values and defer to the command to set a default
+                    // value for optional parameters ...
+                    if (paramObj != null && isNotBlank(paramObj.toString())) {
+                        field.set(cmdObj, Float.valueOf(paramObj.toString()));
+                    }
+                    break;
+                case INTEGER:
+                    // Assuming that the parameters have been checked for required before now,
+                    // we ignore blank or null values and defer to the command to set a default
+                    // value for optional parameters ...
+                    if (paramObj != null && isNotBlank(paramObj.toString())) {
+                        field.set(cmdObj, Integer.valueOf(paramObj.toString()));
+                    }
+                    break;
+                case LIST:
+                    final List listParam = new ArrayList();
+                    final StringTokenizer st = new StringTokenizer(paramObj.toString(), ",");
+                    while (st.hasMoreTokens()) {
+                        final String token = st.nextToken();
+                        final CommandType listType = annotation.collectionType();
+                        switch (listType) {
+                            case INTEGER:
+                                listParam.add(Integer.valueOf(token));
+                                break;
+                            case UUID:
+                                if (token.isEmpty())
+                                    break;
+                                final Long internalId = translateUuidToInternalId(token, annotation);
+                                listParam.add(internalId);
+                                break;
+                            case LONG: {
+                                listParam.add(Long.valueOf(token));
+                            }
+                                break;
+                            case SHORT:
+                                listParam.add(Short.valueOf(token));
+                            case STRING:
+                                listParam.add(token);
+                                break;
+                        }
+                    }
+                    field.set(cmdObj, listParam);
+                    break;
+                case UUID:
+                    if (paramObj.toString().isEmpty())
+                        break;
+                    final Long internalId = translateUuidToInternalId(paramObj.toString(), annotation);
+                    field.set(cmdObj, internalId);
+                    break;
+                case LONG:
+                    field.set(cmdObj, Long.valueOf(paramObj.toString()));
+                    break;
+                case SHORT:
+                    field.set(cmdObj, Short.valueOf(paramObj.toString()));
+                    break;
+                case STRING:
+                    if ((paramObj != null) && paramObj.toString().length() > annotation.length()) {
+                        s_logger.error("Value greater than max allowed length " + annotation.length() + " for param: " + field.getName());
+                        throw new InvalidParameterValueException("Value greater than max allowed length " + annotation.length() + " for param: " + field.getName());
+                    }
+                    field.set(cmdObj, paramObj.toString());
+                    break;
+                case TZDATE:
+                    field.set(cmdObj, DateUtil.parseTZDateString(paramObj.toString()));
+                    break;
+                case MAP:
+                default:
+                    field.set(cmdObj, paramObj);
+                    break;
+            }
+        } catch (final IllegalAccessException ex) {
+            s_logger.error("Error initializing command " + cmdObj.getCommandName() + ", field " + field.getName() + " is not accessible.");
+            throw new CloudRuntimeException("Internal error initializing parameters for command " + cmdObj.getCommandName() + " [field " + field.getName() +
+                " is not accessible]");
+        }
+    }
+
+    private boolean isObjInNewDateFormat(final String string) {
+        final Matcher matcher = BaseCmd.newInputDateFormat.matcher(string);
+        return matcher.matches();
+    }
+
+    private Date messageDate(final Date date, final int hourOfDay, final int minute, final int second) {
+        final Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        cal.set(Calendar.HOUR_OF_DAY, hourOfDay);
+        cal.set(Calendar.MINUTE, minute);
+        cal.set(Calendar.SECOND, second);
+        return cal.getTime();
+    }
+
+    private Long translateUuidToInternalId(final String uuid, final Parameter annotation) {
+        if (uuid.equals("-1")) {
+            // FIXME: This is to handle a lot of hardcoded special cases where -1 is sent
+            // APITODO: Find and get rid of all hardcoded params in API Cmds and service layer
+            return -1L;
+        }
+        Long internalId = null;
+        // If annotation's empty, the cmd existed before 3.x try conversion to long
+        final boolean isPre3x = annotation.since().isEmpty();
+        // Match against Java's UUID regex to check if input is uuid string
+        final boolean isUuid = uuid.matches("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$");
+        // Enforce that it's uuid for newly added apis from version 3.x
+        if (!isPre3x && !isUuid)
+            return null;
+        // Allow both uuid and internal id for pre3x apis
+        if (isPre3x && !isUuid) {
+            try {
+                internalId = Long.parseLong(uuid);
+            } catch (final NumberFormatException e) {
+                internalId = null;
+            }
+            if (internalId != null)
+                return internalId;
+        }
+        // There may be multiple entities defined on the @EntityReference of a Response.class
+        // UUID CommandType would expect only one entityType, so use the first entityType
+        final Class<?>[] entities = annotation.entityType()[0].getAnnotation(EntityReference.class).value();
+        // Go through each entity which is an interface to a VO class and get a VO object
+        // Try to getId() for the object using reflection, break on first non-null value
+        for (final Class<?> entity : entities) {
+            // For backward compatibility, we search within removed entities and let service layer deal
+            // with removed ones, return empty response or error
+            final Object objVO = _entityMgr.findByUuidIncludingRemoved(entity, uuid);
+            if (objVO == null) {
+                continue;
+            }
+            // Invoke the getId method, get the internal long ID
+            // If that fails hide exceptions as the uuid may not exist
+            try {
+                internalId = ((InternalIdentity)objVO).getId();
+            } catch (final IllegalArgumentException e) {
+            } catch (final NullPointerException e) {
+            }
+            // Return on first non-null Id for the uuid entity
+            if (internalId != null)
+                break;
+        }
+        if (internalId == null) {
+            if (s_logger.isDebugEnabled())
+                s_logger.debug("Object entity uuid = " + uuid + " does not exist in the database.");
+            throw new InvalidParameterValueException("Invalid parameter " + annotation.name() + " value=" + uuid +
+                " due to incorrect long value format, or entity does not exist or due to incorrect parameter annotation for the field in api cmd class.");
+        }
+        return internalId;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/src/com/cloud/api/dispatch/ParamUnpackWorker.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/dispatch/ParamUnpackWorker.java b/server/src/com/cloud/api/dispatch/ParamUnpackWorker.java
new file mode 100644
index 0000000..12e1226
--- /dev/null
+++ b/server/src/com/cloud/api/dispatch/ParamUnpackWorker.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 com.cloud.api.dispatch;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ServerApiException;
+
+public class ParamUnpackWorker implements DispatchWorker {
+
+    private static final Logger s_logger = Logger.getLogger(ParamUnpackWorker.class);
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    @Override
+    public void handle(final DispatchTask task) throws ServerApiException {
+        final Map<String, Object> lowercaseParams = new HashMap<String, Object>();
+        final Map<String, String> params = task.getParams();
+        for (final String key : params.keySet()) {
+            final int arrayStartIndex = key.indexOf('[');
+            final int arrayStartLastIndex = key.lastIndexOf('[');
+            if (arrayStartIndex != arrayStartLastIndex) {
+                throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key +
+                    "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
+            }
+
+            if (arrayStartIndex > 0) {
+                final int arrayEndIndex = key.indexOf(']');
+                final int arrayEndLastIndex = key.lastIndexOf(']');
+                if ((arrayEndIndex < arrayStartIndex) || (arrayEndIndex != arrayEndLastIndex)) {
+                    // malformed parameter
+                    throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key +
+                        "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
+                }
+
+                // Now that we have an array object, check for a field name in the case of a complex object
+                final int fieldIndex = key.indexOf('.');
+                String fieldName = null;
+                if (fieldIndex < arrayEndIndex) {
+                    throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key +
+                        "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
+                } else {
+                    fieldName = key.substring(fieldIndex + 1);
+                }
+
+                // parse the parameter name as the text before the first '[' character
+                String paramName = key.substring(0, arrayStartIndex);
+                paramName = paramName.toLowerCase();
+
+                Map<Integer, Map> mapArray = null;
+                Map<String, Object> mapValue = null;
+                final String indexStr = key.substring(arrayStartIndex + 1, arrayEndIndex);
+                int index = 0;
+                boolean parsedIndex = false;
+                try {
+                    if (indexStr != null) {
+                        index = Integer.parseInt(indexStr);
+                        parsedIndex = true;
+                    }
+                } catch (final NumberFormatException nfe) {
+                    s_logger.warn("Invalid parameter " + key + " received, unable to parse object array, returning an error.");
+                }
+
+                if (!parsedIndex) {
+                    throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key +
+                        "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
+                }
+
+                final Object value = lowercaseParams.get(paramName);
+                if (value == null) {
+                    // for now, assume object array with sub fields
+                    mapArray = new HashMap<Integer, Map>();
+                    mapValue = new HashMap<String, Object>();
+                    mapArray.put(Integer.valueOf(index), mapValue);
+                } else if (value instanceof Map) {
+                    mapArray = (HashMap)value;
+                    mapValue = mapArray.get(Integer.valueOf(index));
+                    if (mapValue == null) {
+                        mapValue = new HashMap<String, Object>();
+                        mapArray.put(Integer.valueOf(index), mapValue);
+                    }
+                }
+
+                // we are ready to store the value for a particular field into the map for this object
+                mapValue.put(fieldName, params.get(key));
+
+                lowercaseParams.put(paramName, mapArray);
+            } else {
+                lowercaseParams.put(key.toLowerCase(), params.get(key));
+            }
+        }
+
+        // The chain continues processing the unpacked parameters
+        task.setParams(lowercaseParams);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c211f0bb/server/src/com/cloud/api/dispatch/SpecificCmdValidationWorker.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/dispatch/SpecificCmdValidationWorker.java b/server/src/com/cloud/api/dispatch/SpecificCmdValidationWorker.java
new file mode 100644
index 0000000..3566a1a
--- /dev/null
+++ b/server/src/com/cloud/api/dispatch/SpecificCmdValidationWorker.java
@@ -0,0 +1,34 @@
+// 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.api.dispatch;
+
+/**
+ * This worker validates parameters in a semantic way, that is of
+ * course specific for each {@link BaseCmd}, so actually it delegates
+ * the validation on the {@link BaseCmd} itself
+ *
+ */
+public class SpecificCmdValidationWorker implements DispatchWorker {
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void handle(final DispatchTask task) {
+        task.getCmd().validateSpecificParameters(task.getParams());
+    }
+
+}


[27/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
findbugs: null check before use of pointer

Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/e0d20fb6
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/e0d20fb6
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/e0d20fb6

Branch: refs/heads/distributedrouter
Commit: e0d20fb6eb7b9550ad8b543e2df0ad00d8c9965e
Parents: 579cb9c
Author: Daan Hoogland <da...@onecht.net>
Authored: Mon Mar 10 13:08:15 2014 +0100
Committer: Daan Hoogland <da...@onecht.net>
Committed: Mon Mar 10 13:08:15 2014 +0100

----------------------------------------------------------------------
 server/src/com/cloud/network/NetworkModelImpl.java | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e0d20fb6/server/src/com/cloud/network/NetworkModelImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java
index 9212a89..7b4b2be 100755
--- a/server/src/com/cloud/network/NetworkModelImpl.java
+++ b/server/src/com/cloud/network/NetworkModelImpl.java
@@ -1533,28 +1533,34 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
 
     @Override
     public void checkNetworkPermissions(Account owner, Network network) {
+        // dahn 20140310: I was thinking of making this an assert but
+        //                as we hardly ever test with asserts I think
+        //                we better make sure at runtime.
+        if (network == null) {
+            throw new CloudRuntimeException("cannot check permissions on (Network) <null>");
+        }
         // Perform account permission check
         if (network.getGuestType() != Network.GuestType.Shared || (network.getGuestType() == Network.GuestType.Shared && network.getAclType() == ACLType.Account)) {
             AccountVO networkOwner = _accountDao.findById(network.getAccountId());
             if (networkOwner == null)
-                throw new PermissionDeniedException("Unable to use network with id= " + ((network != null) ? ((NetworkVO)network).getUuid() : "") +
+                throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
                     ", network does not have an owner");
             if (owner.getType() != Account.ACCOUNT_TYPE_PROJECT && networkOwner.getType() == Account.ACCOUNT_TYPE_PROJECT) {
                 if (!_projectAccountDao.canAccessProjectAccount(owner.getAccountId(), network.getAccountId())) {
-                    throw new PermissionDeniedException("Unable to use network with id= " + ((network != null) ? ((NetworkVO)network).getUuid() : "") +
+                    throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
                         ", permission denied");
                 }
             } else {
                 List<NetworkVO> networkMap = _networksDao.listBy(owner.getId(), network.getId());
                 if (networkMap == null || networkMap.isEmpty()) {
-                    throw new PermissionDeniedException("Unable to use network with id= " + ((network != null) ? ((NetworkVO)network).getUuid() : "") +
+                    throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
                         ", permission denied");
                 }
             }
 
         } else {
             if (!isNetworkAvailableInDomain(network.getId(), owner.getDomainId())) {
-                throw new PermissionDeniedException("Shared network id=" + ((network != null) ? ((NetworkVO)network).getUuid() : "") + " is not available in domain id=" +
+                throw new PermissionDeniedException("Shared network id=" + ((NetworkVO)network).getUuid() + " is not available in domain id=" +
                     owner.getDomainId());
             }
         }


[24/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
rat

Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/2386ad73
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/2386ad73
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/2386ad73

Branch: refs/heads/distributedrouter
Commit: 2386ad73da43c42ecb019973786a73f0b12d474d
Parents: 1075bed
Author: Daan Hoogland <da...@onecht.net>
Authored: Mon Mar 10 10:54:31 2014 +0100
Committer: Daan Hoogland <da...@onecht.net>
Committed: Mon Mar 10 10:54:31 2014 +0100

----------------------------------------------------------------------
 .../com/cloud/network/vpc/VpcManagerImplTest.java | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2386ad73/server/test/com/cloud/network/vpc/VpcManagerImplTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/network/vpc/VpcManagerImplTest.java b/server/test/com/cloud/network/vpc/VpcManagerImplTest.java
index a0237b4..189b793 100644
--- a/server/test/com/cloud/network/vpc/VpcManagerImplTest.java
+++ b/server/test/com/cloud/network/vpc/VpcManagerImplTest.java
@@ -1,3 +1,21 @@
+/*
+ * 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.vpc;
 
 import static org.junit.Assert.assertEquals;


[46/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
introduce OvsNetworkTopologyGuru that has convinenace functions to
   - get the hosts on which VPC spans given vpc id
   - get the VM's in the VPC
   - get the hosts on which a network spans
   - get the VPC's to which a hosts is part of
   - get VM's of a VPC on a hosts

introduces capability to build a physical toplogy representation of a
VPC. This json file is encapsulated in
OvsVpcPhysicalTopologyConfigCommand, and is used to send full topology
to hypervisor hosts. On hypervisor this json config can be used to setup
tunnels, configure bridge, add flow rules etc

Ovs GURU, to use different broasdcast scheme VS://vpcid.gerkey for the
networks in VPC that use distributed routing

each VIF and tunnel interface to carry the network UUID in other/options
config


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/92c9d3b8
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/92c9d3b8
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/92c9d3b8

Branch: refs/heads/distributedrouter
Commit: 92c9d3b83f36dcf1cef50d6d7d248253e61f2cd8
Parents: a9abf38
Author: Murali Reddy <mu...@gmail.com>
Authored: Mon Mar 10 12:52:30 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Tue Mar 11 18:38:45 2014 +0530

----------------------------------------------------------------------
 api/src/com/cloud/agent/api/to/NicTO.java       |   8 +
 .../kvm/resource/LibvirtComputingResource.java  |  34 +-
 .../xen/resource/CitrixResourceBase.java        |  95 +++--
 .../cloudstack/ovs/spring-ovs-context.xml       |   2 +-
 .../cloud/agent/api/OvsCreateTunnelCommand.java |  19 +-
 .../agent/api/OvsDestroyBridgeCommand.java      |  10 +-
 .../agent/api/OvsDestroyTunnelCommand.java      |  10 +-
 .../cloud/agent/api/OvsSetupBridgeCommand.java  |  10 +-
 .../OvsVpcPhysicalTopologyConfigCommand.java    | 127 +++++++
 .../com/cloud/network/element/OvsElement.java   |  35 +-
 .../cloud/network/guru/OvsGuestNetworkGuru.java |  17 +-
 .../network/ovs/OvsNetworkTopologyGuru.java     |  49 +++
 .../network/ovs/OvsNetworkTopologyGuruImpl.java |  74 ++++
 .../com/cloud/network/ovs/OvsTunnelManager.java |  16 +-
 .../cloud/network/ovs/OvsTunnelManagerImpl.java | 356 ++++++++++++++-----
 .../com/cloud/network/ovs/dao/OvsTunnel.java    |  24 ++
 .../network/ovs/dao/OvsTunnelNetworkVO.java     |   2 +-
 scripts/vm/hypervisor/xenserver/ovstunnel       |   2 +
 .../cloud/hypervisor/HypervisorGuruBase.java    |   7 +
 19 files changed, 737 insertions(+), 160 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/api/src/com/cloud/agent/api/to/NicTO.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/to/NicTO.java b/api/src/com/cloud/agent/api/to/NicTO.java
index bd8f24e..67660c8 100644
--- a/api/src/com/cloud/agent/api/to/NicTO.java
+++ b/api/src/com/cloud/agent/api/to/NicTO.java
@@ -80,4 +80,12 @@ public class NicTO extends NetworkTO {
     public List<String> getNicSecIps() {
         return nicSecIps;
     }
+
+    public String getNetworkUuid() {
+        return super.getUuid();
+    }
+
+    public void setNetworkUuid(String uuid) {
+        super.setUuid(uuid);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
----------------------------------------------------------------------
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 5912dd3..9aeabea 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
@@ -1388,23 +1388,22 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
     }
 
     private Answer execute(OvsSetupBridgeCommand cmd) {
-        findOrCreateTunnelNetwork(cmd.getKey());
+        findOrCreateTunnelNetwork(cmd.getBridgeName());
         configureTunnelNetwork(cmd.getNetworkId(), cmd.getHostId(),
-                cmd.getKey());
+                cmd.getBridgeName());
         s_logger.debug("OVS Bridge configured");
         return new Answer(cmd, true, null);
     }
 
     private Answer execute(OvsDestroyBridgeCommand cmd) {
-        destroyTunnelNetwork(cmd.getKey());
+        destroyTunnelNetwork(cmd.getBridgeName());
         s_logger.debug("OVS Bridge destroyed");
         return new Answer(cmd, true, null);
     }
 
-    private synchronized void destroyTunnelNetwork(int key) {
+    private synchronized void destroyTunnelNetwork(String bridge) {
         try {
-            findOrCreateTunnelNetwork(key);
-            String bridge = "OVSTunnel" + key;
+            findOrCreateTunnelNetwork(bridge);
             Script cmd = new Script(_ovsTunnelPath, _timeout, s_logger);
             cmd.add("destroy_ovs_bridge");
             cmd.add("--bridge", bridge);
@@ -1423,9 +1422,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
         }
     }
 
-    private synchronized boolean findOrCreateTunnelNetwork(long key) {
+    private synchronized boolean findOrCreateTunnelNetwork(String nwName) {
         try {
-            String nwName = "OVSTunnel" + key;
             if (checkNetwork(nwName)) {
                 return true;
             }
@@ -1443,10 +1441,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
     }
 
     private synchronized boolean configureTunnelNetwork(long networkId,
-            long hostId, int key) {
+            long hostId, String nwName) {
         try {
-            findOrCreateTunnelNetwork(key);
-            String nwName = "OVSTunnel" + key;
+            findOrCreateTunnelNetwork(nwName);
             String configuredHosts = Script
                     .runSimpleBashScript("ovs-vsctl get bridge " + nwName
                             + " other_config:ovs_host_setup");
@@ -1463,7 +1460,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
             if (!configured) {
                 Script cmd = new Script(_ovsTunnelPath, _timeout, s_logger);
                 cmd.add("setup_ovs_bridge");
-                cmd.add("--key", String.valueOf(key));
+                cmd.add("--key", nwName);
                 cmd.add("--cs_host_id", ((Long)hostId).toString());
                 cmd.add("--bridge", nwName);
                 String result = cmd.execute();
@@ -1481,16 +1478,16 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
     }
 
     private OvsCreateTunnelAnswer execute(OvsCreateTunnelCommand cmd) {
-        String bridge = "OVSTunnel" + cmd.getKey();
+        String bridge = cmd.getNetworkName();
         try {
-            if (!findOrCreateTunnelNetwork(cmd.getKey())) {
+            if (!findOrCreateTunnelNetwork(bridge)) {
                 s_logger.debug("Error during bridge setup");
                 return new OvsCreateTunnelAnswer(cmd, false,
                         "Cannot create network", bridge);
             }
 
             configureTunnelNetwork(cmd.getNetworkId(), cmd.getFrom(),
-                    cmd.getKey());
+                    cmd.getNetworkName());
             Script command = new Script(_ovsTunnelPath, _timeout, s_logger);
             command.add("create_tunnel");
             command.add("--bridge", bridge);
@@ -1515,16 +1512,15 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
 
     private Answer execute(OvsDestroyTunnelCommand cmd) {
         try {
-            if (!findOrCreateTunnelNetwork(cmd.getKey())) {
+            if (!findOrCreateTunnelNetwork(cmd.getBridgeName())) {
                 s_logger.warn("Unable to find tunnel network for GRE key:"
-                        + cmd.getKey());
+                        + cmd.getBridgeName());
                 return new Answer(cmd, false, "No network found");
             }
 
-            String bridge = "OVSTunnel" + cmd.getKey();
             Script command = new Script(_ovsTunnelPath, _timeout, s_logger);
             command.add("destroy_tunnel");
-            command.add("--bridge", bridge);
+            command.add("--bridge", cmd.getBridgeName());
             command.add("--iface_name", cmd.getInPortName());
             String result = command.execute();
             if (result == null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
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 d80bddc..8585996 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
@@ -147,6 +147,7 @@ import com.cloud.agent.api.OvsFetchInterfaceCommand;
 import com.cloud.agent.api.OvsSetTagAndFlowAnswer;
 import com.cloud.agent.api.OvsSetTagAndFlowCommand;
 import com.cloud.agent.api.OvsSetupBridgeCommand;
+import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
 import com.cloud.agent.api.PerformanceMonitorAnswer;
 import com.cloud.agent.api.PerformanceMonitorCommand;
 import com.cloud.agent.api.PingCommand;
@@ -506,6 +507,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             return execute((OvsSetTagAndFlowCommand)cmd);
         } else if (clazz == OvsDeleteFlowCommand.class) {
             return execute((OvsDeleteFlowCommand)cmd);
+        } else if (clazz == OvsVpcPhysicalTopologyConfigCommand.class) {
+            return execute((OvsVpcPhysicalTopologyConfigCommand) cmd);
         } else if (clazz == CleanupNetworkRulesCmd.class) {
             return execute((CleanupNetworkRulesCmd)cmd);
         } else if (clazz == NetworkRulesSystemVmCommand.class) {
@@ -963,15 +966,14 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
     /**
      * This method just creates a XenServer network following the tunnel network naming convention
      */
-    private synchronized Network findOrCreateTunnelNetwork(Connection conn, long key) {
+    private synchronized Network findOrCreateTunnelNetwork(Connection conn, String nwName) {
         try {
-            String nwName = "OVSTunnel" + key;
             Network nw = null;
             Network.Record rec = new Network.Record();
             Set<Network> networks = Network.getByNameLabel(conn, nwName);
 
             if (networks.size() == 0) {
-                rec.nameDescription = "tunnel network id# " + key;
+                rec.nameDescription = "tunnel network id# " + nwName;
                 rec.nameLabel = nwName;
                 //Initialize the ovs-host-setup to avoid error when doing get-param in plugin
                 Map<String, String> otherConfig = new HashMap<String, String>();
@@ -980,7 +982,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
                 nw = Network.create(conn, rec);
                 // Plug dom0 vif only when creating network
                 if (!is_xcp())
-                    enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + key);
+                    enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + nwName);
                 s_logger.debug("### Xen Server network for tunnels created:" + nwName);
             } else {
                 nw = networks.iterator().next();
@@ -996,10 +998,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
     /**
      * This method creates a XenServer network and configures it for being used as a L2-in-L3 tunneled network
      */
-    private synchronized Network configureTunnelNetwork(Connection conn, long networkId, long hostId, int key) {
+    private synchronized Network configureTunnelNetwork(Connection conn, long networkId, long hostId, String bridgeName) {
         try {
-            Network nw = findOrCreateTunnelNetwork(conn, key);
-            String nwName = "OVSTunnel" + key;
+            Network nw = findOrCreateTunnelNetwork(conn, bridgeName);
+            String nwName = bridgeName;
             //Invoke plugin to setup the bridge which will be used by this network
             String bridge = nw.getBridge(conn);
             Map<String, String> nwOtherConfig = nw.getOtherConfig(conn);
@@ -1017,11 +1019,20 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             if (!configured) {
                 // Plug dom0 vif only if not done before for network and host
                 if (!is_xcp())
-                    enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + key);
-                String result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge", "bridge", bridge,
-                        "key", String.valueOf(key),
-                        "xs_nw_uuid", nw.getUuid(conn),
-                        "cs_host_id", ((Long)hostId).toString());
+                    enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + bridgeName);
+                String result;
+                if (bridgeName.startsWith("OVS-DR-VPC-Bridge")) {
+                    result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge_for_distributed_routing", "bridge", bridge,
+                            "key", bridgeName,
+                            "xs_nw_uuid", nw.getUuid(conn),
+                            "cs_host_id", ((Long)hostId).toString());
+                } else {
+                    result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge", "bridge", bridge,
+                            "key", bridgeName,
+                            "xs_nw_uuid", nw.getUuid(conn),
+                            "cs_host_id", ((Long)hostId).toString());
+                }
+
                 //Note down the fact that the ovs bridge has been setup
                 String[] res = result.split(":");
                 if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) {
@@ -1036,9 +1047,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         }
     }
 
-    private synchronized void destroyTunnelNetwork(Connection conn, int key) {
+    private synchronized void destroyTunnelNetwork(Connection conn, String bridgeName) {
         try {
-            Network nw = findOrCreateTunnelNetwork(conn, key);
+            Network nw = findOrCreateTunnelNetwork(conn, bridgeName);
             String bridge = nw.getBridge(conn);
             String result = callHostPlugin(conn, "ovstunnel", "destroy_ovs_bridge", "bridge", bridge);
             String[] res = result.split(":");
@@ -1078,8 +1089,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
                 _isOvs = true;
                 return setupvSwitchNetwork(conn);
             } else {
-                long vnetId = Long.parseLong(BroadcastDomainType.getValue(uri));
-                return findOrCreateTunnelNetwork(conn, vnetId);
+                return findOrCreateTunnelNetwork(conn, getOvsTunnelNetworkName(BroadcastDomainType.getValue(uri)));
             }
         } else if (type == BroadcastDomainType.Storage) {
             if (uri == null) {
@@ -1101,6 +1111,19 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         throw new CloudRuntimeException("Unable to support this type of network broadcast domain: " + nic.getBroadcastUri());
     }
 
+    private String getOvsTunnelNetworkName(String broadcastUri) {
+        if (broadcastUri.contains(".")) {
+            String[] parts = broadcastUri.split(".");
+            return "OVS-DR-VPC-Bridge"+parts[0];
+         } else {
+            try {
+                return "OVSTunnel" + broadcastUri;
+            } catch (Exception e) {
+                return null;
+            }
+         }
+    }
+
     protected VIF createVif(Connection conn, String vmName, VM vm, VirtualMachineTO vmSpec, NicTO nic) throws XmlRpcException, XenAPIException {
         assert (nic.getUuid() != null) : "Nic should have a uuid value";
 
@@ -1121,7 +1144,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         if (vmSpec != null) {
             vifr.otherConfig.put("cloudstack-vm-id", vmSpec.getUuid());
         }
-
+        vifr.otherConfig.put("cloudstack-network-id", nic.getNetworkUuid());
         vifr.network = getNetwork(conn, nic);
 
         if (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) {
@@ -5219,15 +5242,15 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
 
     private Answer execute(OvsSetupBridgeCommand cmd) {
         Connection conn = getConnection();
-        findOrCreateTunnelNetwork(conn, cmd.getKey());
-        configureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getHostId(), cmd.getKey());
+        findOrCreateTunnelNetwork(conn, cmd.getBridgeName());
+        configureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getHostId(), cmd.getBridgeName());
         s_logger.debug("OVS Bridge configured");
         return new Answer(cmd, true, null);
     }
 
     private Answer execute(OvsDestroyBridgeCommand cmd) {
         Connection conn = getConnection();
-        destroyTunnelNetwork(conn, cmd.getKey());
+        destroyTunnelNetwork(conn, cmd.getBridgeName());
         s_logger.debug("OVS Bridge destroyed");
         return new Answer(cmd, true, null);
     }
@@ -5235,14 +5258,14 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
     private Answer execute(OvsDestroyTunnelCommand cmd) {
         Connection conn = getConnection();
         try {
-            Network nw = findOrCreateTunnelNetwork(conn, cmd.getNetworkId());
+            Network nw = findOrCreateTunnelNetwork(conn, cmd.getBridgeName());
             if (nw == null) {
-                s_logger.warn("Unable to find tunnel network for GRE key:" + cmd.getKey());
+                s_logger.warn("Unable to find tunnel network for GRE key:" + cmd.getBridgeName());
                 return new Answer(cmd, false, "No network found");
             }
 
             String bridge = nw.getBridge(conn);
-            String result = callHostPlugin(conn, "ovstunnel", "destroy_tunnel", "bridge", bridge, "in_port", cmd.getInPortName());
+            String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge", bridge, "in_port", cmd.getInPortName());
             if (result.equalsIgnoreCase("SUCCESS")) {
                 return new Answer(cmd, true, result);
             } else {
@@ -5254,6 +5277,22 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         }
     }
 
+    public Answer execute(OvsVpcPhysicalTopologyConfigCommand cmd) {
+        Connection conn = getConnection();
+        try {
+            String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge",
+                    cmd.getBridgeName(), "host-id", ((Long)cmd.getHostId()).toString());
+            if (result.equalsIgnoreCase("SUCCESS")) {
+                return new Answer(cmd, true, result);
+            } else {
+                return new Answer(cmd, false, result);
+            }
+        } catch  (Exception e) {
+            s_logger.warn("caught exception while updating host with latest VPC topology", e);
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
     private Answer execute(UpdateHostPasswordCommand cmd) {
         _password.add(cmd.getNewPassword());
         return new Answer(cmd, true, null);
@@ -5263,17 +5302,19 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         Connection conn = getConnection();
         String bridge = "unknown";
         try {
-            Network nw = findOrCreateTunnelNetwork(conn, cmd.getKey());
+            Network nw = findOrCreateTunnelNetwork(conn, cmd.getNetworkName());
             if (nw == null) {
                 s_logger.debug("Error during bridge setup");
                 return new OvsCreateTunnelAnswer(cmd, false, "Cannot create network", bridge);
             }
 
-            configureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getFrom(), cmd.getKey());
+            configureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getFrom(), cmd.getNetworkName());
             bridge = nw.getBridge(conn);
             String result =
-                    callHostPlugin(conn, "ovstunnel", "create_tunnel", "bridge", bridge, "remote_ip", cmd.getRemoteIp(), "key", cmd.getKey().toString(), "from",
-                            cmd.getFrom().toString(), "to", cmd.getTo().toString());
+                    callHostPlugin(conn, "ovstunnel", "create_tunnel", "bridge", bridge, "remote_ip", cmd.getRemoteIp(),
+                            "key", cmd.getKey().toString(), "from",
+                            cmd.getFrom().toString(), "to", cmd.getTo().toString(), "cloudstack-network-id",
+                            cmd.getNetworkUuid());
             String[] res = result.split(":");
             if (res.length == 2 && res[0].equalsIgnoreCase("SUCCESS")) {
                 return new OvsCreateTunnelAnswer(cmd, true, result, res[1], bridge);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml
----------------------------------------------------------------------
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
index e60d93e..fa56d5d 100644
--- 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
@@ -38,5 +38,5 @@
     <bean id="ovsTunnelManagerImpl" class="com.cloud.network.ovs.OvsTunnelManagerImpl" />
     <bean id="ovsTunnelInterfaceDaoImpl" class="com.cloud.network.ovs.dao.OvsTunnelInterfaceDaoImpl" />
     <bean id="ovsTunnelNetworkDaoImpl" class="com.cloud.network.ovs.dao.OvsTunnelNetworkDaoImpl" />
-    
+    <bean id="ovsNetworkTopologyGuruImpl" class="com.cloud.network.ovs.OvsNetworkTopologyGuruImpl"/>
 </beans>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateTunnelCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateTunnelCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateTunnelCommand.java
index 7f151fb..3e08531 100644
--- a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateTunnelCommand.java
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateTunnelCommand.java
@@ -20,10 +20,13 @@ package com.cloud.agent.api;
 public class OvsCreateTunnelCommand extends Command {
     Integer key;
     String remoteIp;
+    String networkName;
     Long from;
     Long to;
     long networkId;
 
+    String networkUuid;
+
     // for debug info
     String fromIp;
 
@@ -33,13 +36,15 @@ public class OvsCreateTunnelCommand extends Command {
     }
 
     public OvsCreateTunnelCommand(String remoteIp, Integer key, Long from,
-            Long to, long networkId, String fromIp) {
+            Long to, long networkId, String fromIp, String networkName, String networkUuid) {
         this.remoteIp = remoteIp;
         this.key = key;
         this.from = from;
         this.to = to;
         this.networkId = networkId;
         this.fromIp = fromIp;
+        this.networkName = networkName;
+        this.networkUuid = networkUuid;
     }
 
     public Integer getKey() {
@@ -66,4 +71,16 @@ public class OvsCreateTunnelCommand extends Command {
         return fromIp;
     }
 
+    public String getNetworkName() {
+        return networkName;
+    }
+
+
+    public String getNetworkUuid() {
+        return networkUuid;
+    }
+
+    public void setNetworkUuid(String networkUuid) {
+        this.networkUuid = networkUuid;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyBridgeCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyBridgeCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyBridgeCommand.java
index 59b50be..f9205c5 100644
--- a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyBridgeCommand.java
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyBridgeCommand.java
@@ -21,19 +21,19 @@ package com.cloud.agent.api;
 public class OvsDestroyBridgeCommand extends Command {
 
     Long networkId;
-    Integer key;
+    String name;
 
-    public OvsDestroyBridgeCommand(Long networkId, Integer key) {
+    public OvsDestroyBridgeCommand(Long networkId, String name) {
         this.networkId = networkId;
-        this.key = key;
+        this.name = name;
     }
 
     public Long getNetworkId() {
         return networkId;
     }
 
-    public Integer getKey() {
-        return key;
+    public String getBridgeName() {
+        return name;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyTunnelCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyTunnelCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyTunnelCommand.java
index 4776a07..9fc6c37 100644
--- a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyTunnelCommand.java
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyTunnelCommand.java
@@ -20,14 +20,14 @@ package com.cloud.agent.api;
 public class OvsDestroyTunnelCommand extends Command {
 
     Long networkId;
-    Integer key;
+    String networkName;
     String inPortName;
 
-    public OvsDestroyTunnelCommand(Long networkId, Integer key,
+    public OvsDestroyTunnelCommand(Long networkId, String networkName,
             String inPortName) {
         this.networkId = networkId;
         this.inPortName = inPortName;
-        this.key = key;
+        this.networkName = networkName;
     }
 
     public Long getNetworkId() {
@@ -38,8 +38,8 @@ public class OvsDestroyTunnelCommand extends Command {
         return inPortName;
     }
 
-    public Integer getKey() {
-        return key;
+    public String getBridgeName() {
+        return networkName;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsSetupBridgeCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsSetupBridgeCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsSetupBridgeCommand.java
index e3390f3..a104598 100644
--- a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsSetupBridgeCommand.java
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsSetupBridgeCommand.java
@@ -19,7 +19,7 @@ package com.cloud.agent.api;
 
 
 public class OvsSetupBridgeCommand extends Command {
-    Integer key;
+    String name;
     Long hostId;
     Long networkId;
 
@@ -28,14 +28,14 @@ public class OvsSetupBridgeCommand extends Command {
         return true;
     }
 
-    public OvsSetupBridgeCommand(Integer key, Long hostId, Long networkId) {
-        this.key = key;
+    public OvsSetupBridgeCommand(String name, Long hostId, Long networkId) {
+        this.name = name;
         this.hostId = hostId;
         this.networkId = networkId;
     }
 
-    public Integer getKey() {
-        return key;
+    public String getBridgeName() {
+        return name;
     }
 
     public Long getHostId() {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
new file mode 100644
index 0000000..35d4c6e
--- /dev/null
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
@@ -0,0 +1,127 @@
+// 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.api;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+/**
+ * This command represents view of how a VPC is laid out (on which hosts, which VM is on which host etc)
+ * on the physical infrastructure.
+ */
+public class OvsVpcPhysicalTopologyConfigCommand extends Command {
+
+    VpcConfig vpcConfig =null;
+    long hostId;
+    String bridgeName;
+
+    public static class Host {
+        long hostId;
+        String ipAddress;
+
+        public Host (long hostId, String ipAddress) {
+            this.hostId = hostId;
+            this.ipAddress = ipAddress;
+        }
+    }
+
+    public static class Nic {
+        String ipAddress;
+        String macAddress;
+        String networkUuid;
+        public Nic (String ipAddress, String macAddress, String networkUuid) {
+            this.ipAddress = ipAddress;
+            this.macAddress = macAddress;
+            this.networkUuid = networkUuid;
+        }
+    }
+
+    public static class Tier {
+        long greKey;
+        String networkUuid;
+        String gatewayIp;
+        String gatewayMac;
+        String cidr;
+        public Tier(long greKey, String networkUuid, String gatewayIp, String gatewayMac, String cidr) {
+            this.greKey = greKey;
+            this.networkUuid = networkUuid;
+            this.gatewayIp = gatewayIp;
+            this.gatewayMac = gatewayMac;
+            this.cidr = cidr;
+        }
+    }
+
+    public static class Vm {
+        long hostId;
+        Nic[] nics;
+        public Vm(long hostId, Nic[] nics) {
+            this.hostId = hostId;
+            this.nics = nics;
+        }
+    }
+
+    public static class Vpc {
+        String cidr;
+        Host[] hosts;
+        Tier[] tiers;
+        Vm[]  vms;
+        public Vpc(Host[] hosts, Tier[] tiers, Vm[] vms, String cidr) {
+            this.hosts = hosts;
+            this.tiers = tiers;
+            this.vms = vms;
+            this.cidr = cidr;
+        }
+    }
+
+    public static class VpcConfig {
+        Vpc vpc;
+        public VpcConfig(Vpc vpc) {
+            this.vpc = vpc;
+        }
+    }
+
+    public OvsVpcPhysicalTopologyConfigCommand(Host[] hosts, Tier[] tiers, Vm[] vms, String cidr) {
+        Vpc vpc = new Vpc(hosts, tiers, vms, cidr);
+        vpcConfig = new VpcConfig(vpc);
+    }
+
+    public String getjsonVpcConfig() {
+        Gson gson = new GsonBuilder().create();
+        return gson.toJson(vpcConfig).toLowerCase();
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        return false;
+    }
+
+    public void setHostId(long hostId) {
+        this.hostId = hostId;
+    }
+
+    public long getHostId() {
+        return hostId;
+    }
+
+    public String getBridgeName() {
+        return bridgeName;
+    }
+
+    public void setBridgeName(String bridgeName) {
+        this.bridgeName = bridgeName;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
index 05e81a1..c28d908 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
@@ -16,6 +16,8 @@
 // under the License.
 package com.cloud.network.element;
 
+import com.cloud.host.dao.HostDao;
+import com.cloud.vm.dao.UserVmDao;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -73,6 +75,8 @@ import com.cloud.vm.NicProfile;
 import com.cloud.vm.ReservationContext;
 import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachine;
 
 @Local(value = {NetworkElement.class, ConnectivityProvider.class,
         SourceNatServiceProvider.class, StaticNatServiceProvider.class,
@@ -93,6 +97,10 @@ StaticNatServiceProvider, IpDeployer {
     DomainRouterDao _routerDao;
     @Inject
     VpcVirtualNetworkApplianceManager _routerMgr;
+    @Inject
+    UserVmDao _userVmDao;
+    @Inject
+    HostDao _hostDao;
 
     private static final Logger s_logger = Logger.getLogger(OvsElement.class);
     private static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
@@ -171,7 +179,12 @@ StaticNatServiceProvider, IpDeployer {
             return false;
         }
 
-        _ovsTunnelMgr.vmCheckAndCreateTunnel(vm, network, dest);
+        if (vm.getType() != VirtualMachine.Type.User && vm.getType() != VirtualMachine.Type.DomainRouter) {
+            return false;
+        }
+
+        // prepare the tunnel network on the host, in order for VM to get launched
+        _ovsTunnelMgr.checkAndPrepareHostForTunnelNetwork(network, dest.getHost());
 
         return true;
     }
@@ -192,7 +205,25 @@ StaticNatServiceProvider, IpDeployer {
             return false;
         }
 
-        _ovsTunnelMgr.checkAndDestroyTunnel(vm.getVirtualMachine(), network);
+        List<UserVmVO> userVms = _userVmDao.listByAccountIdAndHostId(vm.getVirtualMachine().getAccountId(),
+                vm.getVirtualMachine().getHostId());
+        if (vm.getType() == VirtualMachine.Type.User) {
+            if (userVms.size() > 1) {
+                return true;
+            }
+
+            List<DomainRouterVO> routers = _routerDao.findByNetwork(network.getId());
+            for (DomainRouterVO router : routers) {
+                if (router.getHostId().equals(vm.getVirtualMachine().getHostId())) {
+                    return true;
+                }
+            }
+        } else if (vm.getType() == VirtualMachine.Type.DomainRouter && userVms.size() != 0) {
+            return true;
+        }
+
+        HostVO host = _hostDao.findById(vm.getVirtualMachine().getHostId());
+        _ovsTunnelMgr.checkAndRemoveHostFromTunnelNetwork(network, host);
         return true;
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
index 8fa636d..2814c2a 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
@@ -16,6 +16,8 @@
 // under the License.
 package com.cloud.network.guru;
 
+import com.cloud.network.vpc.VpcVO;
+import com.cloud.network.vpc.dao.VpcDao;
 import javax.ejb.Local;
 import javax.inject.Inject;
 
@@ -61,6 +63,8 @@ public class OvsGuestNetworkGuru extends GuestNetworkGuru {
     OvsTunnelManager _ovsTunnelMgr;
     @Inject
     NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
+    @Inject
+    VpcDao _vpcDao;
 
     OvsGuestNetworkGuru() {
         super();
@@ -145,10 +149,14 @@ public class OvsGuestNetworkGuru extends GuestNetworkGuru {
             implemented.setCidr(network.getCidr());
         }
 
-        // do we need to create switch right now?
-
         implemented.setBroadcastDomainType(BroadcastDomainType.Vswitch);
 
+        if (network.getVpcId() != null && isVpcEnabledForDistributedRouter(network.getVpcId())) {
+            String keyStr = BroadcastDomainType.getValue(implemented.getBroadcastUri());
+            Long vpcid= network.getVpcId();
+            implemented.setBroadcastUri(BroadcastDomainType.Vswitch.toUri(vpcid.toString()+keyStr));
+        }
+
         return implemented;
     }
 
@@ -215,4 +223,9 @@ public class OvsGuestNetworkGuru extends GuestNetworkGuru {
             implemented.setBroadcastUri(network.getBroadcastUri());
         }
     }
+
+    boolean isVpcEnabledForDistributedRouter(long vpcId) {
+        VpcVO vpc = _vpcDao.findById(vpcId);
+        return vpc.usesDistributedRouter();
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
new file mode 100644
index 0000000..c410d10
--- /dev/null
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.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 com.cloud.network.ovs;
+
+import com.cloud.utils.component.Manager;
+
+import java.util.List;
+
+public interface OvsNetworkTopologyGuru extends Manager {
+
+    /**
+     * get the list of hypervisor hosts id's on which VM's belonging to the network currently spans
+     */
+    public  List<Long> getNetworkSpanedHosts(long networkId);
+
+    /**
+     * get the list of hypervisor hosts id's on which VM's belonging to a VPC spans
+     */
+    public  List<Long> getVpcSpannedHosts(long vpId);
+
+    /**
+     * get the list of VPC id's of the vpc's for which one or more VM's from the VPC are running on the host
+     */
+    public  List<Long> getVpcOnHost(long hostId);
+
+    /**
+     * get the list of all active Vm id's in the VPC for all ther tiers
+     */
+    public List<Long> getAllActiveVmsInVpc(long vpcId);
+
+    /**
+     * get the list of all Vm id's in the VPC for all the tiers that are running on the host
+     */
+    public List<Long> getActiveVmsInVpcOnHost(long vpcId, long hostId);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
new file mode 100644
index 0000000..7560e35
--- /dev/null
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
@@ -0,0 +1,74 @@
+package com.cloud.network.ovs;
+
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.UserVmDao;
+import java.util.ArrayList;
+import java.util.List;
+import javax.ejb.Local;
+import javax.inject.Inject;
+import org.springframework.stereotype.Component;
+
+@Component
+@Local(value = {OvsNetworkTopologyGuru.class})
+public class OvsNetworkTopologyGuruImpl extends ManagerBase implements OvsNetworkTopologyGuru {
+
+    @Inject
+    UserVmDao _userVmDao;
+    @Inject
+    DomainRouterDao _routerDao;
+
+    /**
+     * get the list of hypervisor hosts on which VM's belonging to a network currently spans
+     */
+    public  List<Long> getNetworkSpanedHosts(long networkId) {
+        List<Long> hostIds = new ArrayList<Long>();
+        // Find active VMs with a NIC on the target network
+        List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(networkId,
+                VirtualMachine.State.Running, VirtualMachine.State.Starting, VirtualMachine.State.Stopping, VirtualMachine.State.Unknown,
+                VirtualMachine.State.Migrating);
+        // Find routers for the network
+        List<DomainRouterVO> routers = _routerDao.findByNetwork(networkId);
+        List<VMInstanceVO> ins = new ArrayList<VMInstanceVO>();
+        if (vms != null) {
+            ins.addAll(vms);
+        }
+        if (routers.size() != 0) {
+            ins.addAll(routers);
+        }
+        for (VMInstanceVO v : ins) {
+            Long rh = v.getHostId();
+            if (rh == null) {
+                continue;
+            }
+            if (!hostIds.contains(rh)) {
+                hostIds.add(rh);
+            }
+        }
+        return  hostIds;
+    }
+
+    @Override
+    public List<Long> getVpcSpannedHosts(long vpId) {
+        return null;
+    }
+
+    @Override
+    public List<Long> getVpcOnHost(long hostId) {
+        return null;
+    }
+
+    @Override
+    public List<Long> getAllActiveVmsInVpc(long vpcId) {
+        return null;
+    }
+
+    @Override
+    public List<Long> getActiveVmsInVpcOnHost(long vpcId, long hostId) {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManager.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManager.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManager.java
index 118beeb..cd88136 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManager.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManager.java
@@ -16,18 +16,24 @@
 // under the License.
 package com.cloud.network.ovs;
 
-import com.cloud.deploy.DeployDestination;
+import com.cloud.host.Host;
 import com.cloud.network.Network;
 import com.cloud.utils.component.Manager;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineProfile;
 
 public interface OvsTunnelManager extends Manager {
 
     boolean isOvsTunnelEnabled();
 
-    public void vmCheckAndCreateTunnel(VirtualMachineProfile vm, Network nw, DeployDestination dest);
+    /**
+     *  create a bridge on the host if not already created for the network and establish full tunnel mesh with
+     *  the rest of the hosts on which network spans
+     */
+    public void checkAndPrepareHostForTunnelNetwork(Network nw, Host host);
 
-    public void checkAndDestroyTunnel(VirtualMachine vm, Network nw);
+    /**
+     * remove the bridge and tunnels to the hosts on which network spans if there are no other VM's
+     * belonging to the network are running on the host
+     */
+    public void checkAndRemoveHostFromTunnelNetwork(Network nw, Host host);
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
index 320568b..ae37095 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
@@ -16,6 +16,12 @@
 // under the License.
 package com.cloud.network.ovs;
 
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.VMInstanceDao;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -42,9 +48,9 @@ import com.cloud.agent.api.OvsDestroyTunnelCommand;
 import com.cloud.agent.api.OvsFetchInterfaceAnswer;
 import com.cloud.agent.api.OvsFetchInterfaceCommand;
 import com.cloud.agent.api.OvsSetupBridgeCommand;
+import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
 import com.cloud.agent.manager.Commands;
 import com.cloud.configuration.Config;
-import com.cloud.deploy.DeployDestination;
 import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.OperationTimedoutException;
 import com.cloud.host.Host;
@@ -60,19 +66,15 @@ import com.cloud.network.ovs.dao.OvsTunnelInterfaceDao;
 import com.cloud.network.ovs.dao.OvsTunnelInterfaceVO;
 import com.cloud.network.ovs.dao.OvsTunnelNetworkDao;
 import com.cloud.network.ovs.dao.OvsTunnelNetworkVO;
+import com.cloud.network.ovs.dao.OvsTunnel;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.network.vpc.VpcVO;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.dao.DomainRouterDao;
 import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.UserVmDao;
 
 @Component
 @Local(value = {OvsTunnelManager.class})
@@ -91,8 +93,7 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
     HostDao _hostDao;
     @Inject
     PhysicalNetworkTrafficTypeDao _physNetTTDao;
-    @Inject
-    UserVmDao _userVmDao;
+
     @Inject
     DomainRouterDao _routerDao;
     @Inject
@@ -101,6 +102,16 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
     OvsTunnelInterfaceDao _tunnelInterfaceDao;
     @Inject
     AgentManager _agentMgr;
+    @Inject
+    OvsNetworkTopologyGuru _ovsNetworkToplogyGuru;
+    @Inject
+    VpcDao _vpcDao;
+    @Inject
+    VpcManager _vpcMgr;
+    @Inject
+    protected VMInstanceDao _vmInstanceDao;
+    @Inject
+    NetworkDao _networkDao;
 
     @Override
     public boolean configure(String name, Map<String, Object> params)
@@ -182,13 +193,13 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
                             from, to, networkId));
         }
         if (!r.getResult()) {
-            tunnel.setState("FAILED");
-            s_logger.warn("Create GRE tunnel failed due to " + r.getDetails()
+            tunnel.setState(OvsTunnel.State.Failed.name());
+            s_logger.warn("Create GRE tunnel from " + from + " to " + to + " failed due to " + r.getDetails()
                     + s);
         } else {
-            tunnel.setState("SUCCESS");
+            tunnel.setState(OvsTunnel.State.Established.name());
             tunnel.setPortName(r.getInPortName());
-            s_logger.warn("Create GRE tunnel " + r.getDetails() + s);
+            s_logger.info("Create GRE tunnel from " + from + " to " + to + " succeeded." + r.getDetails() + s);
         }
         _tunnelNetworkDao.update(tunnel.getId(), tunnel);
     }
@@ -249,13 +260,14 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         int key = 0;
         try {
             //The GRE key is actually in the host part of the URI
-            // this is not true for lswitch/NiciraNvp!
             String keyStr = BroadcastDomainType.getValue(network.getBroadcastUri());
-            // The key is most certainly and int if network is a vlan.
-            // !! not in the case of lswitch/pvlan/(possibly)vswitch
-            // So we now feel quite safe in converting it into a string
-            // by calling the appropriate BroadcastDomainType method
-            key = Integer.parseInt(keyStr);
+            if (keyStr.contains(".")) {
+                String[] parts = keyStr.split(".");
+                key = Integer.parseInt(parts[1]);
+            } else {
+                key = Integer.parseInt(keyStr);
+            }
+
             return key;
         } catch (NumberFormatException e) {
             s_logger.debug("Well well, how did '" + key
@@ -268,41 +280,23 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
     }
 
     @DB
-    protected void checkAndCreateTunnel(VirtualMachine instance, Network nw, DeployDestination dest) {
+    protected void checkAndCreateTunnel(Network nw, Host host) {
 
         s_logger.debug("Creating tunnels with OVS tunnel manager");
-        if (instance.getType() != VirtualMachine.Type.User
-                && instance.getType() != VirtualMachine.Type.DomainRouter) {
-            s_logger.debug("Will not work if you're not"
-                    + "an instance or a virtual router");
-            return;
-        }
 
-        long hostId = dest.getHost().getId();
+        long hostId = host.getId();
         int key = getGreKey(nw);
-        // Find active VMs with a NIC on the target network
-        List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(nw.getId(),
-                State.Running, State.Starting, State.Stopping, State.Unknown,
-                State.Migrating);
-        // Find routers for the network
-        List<DomainRouterVO> routers = _routerDao.findByNetwork(nw.getId());
-        List<VMInstanceVO> ins = new ArrayList<VMInstanceVO>();
-        if (vms != null) {
-            ins.addAll(vms);
-        }
-        if (routers.size() != 0) {
-            ins.addAll(routers);
-        }
+        String bridgeName = generateBridgeName(nw, key);
         List<Long> toHostIds = new ArrayList<Long>();
         List<Long> fromHostIds = new ArrayList<Long>();
-        for (VMInstanceVO v : ins) {
-            Long rh = v.getHostId();
-            if (rh == null || rh.longValue() == hostId) {
+        List<Long> networkSpannedHosts = _ovsNetworkToplogyGuru.getNetworkSpanedHosts(nw.getId());
+        for (Long rh : networkSpannedHosts) {
+            if (rh == hostId) {
                 continue;
             }
             OvsTunnelNetworkVO ta = _tunnelNetworkDao.getByFromToNetwork(hostId, rh.longValue(), nw.getId());
             // Try and create the tunnel even if a previous attempt failed
-            if (ta == null || ta.getState().equals("FAILED")) {
+            if (ta == null || ta.getState().equals(OvsTunnel.State.Failed.name())) {
                 s_logger.debug("Attempting to create tunnel from:" + hostId + " to:" + rh.longValue());
                 if (ta == null) {
                     createTunnelRecord(hostId, rh.longValue(), nw.getId(), key);
@@ -315,7 +309,7 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
             ta = _tunnelNetworkDao.getByFromToNetwork(rh.longValue(),
                     hostId, nw.getId());
             // Try and create the tunnel even if a previous attempt failed
-            if (ta == null || ta.getState().equals("FAILED")) {
+            if (ta == null || ta.getState().equals(OvsTunnel.State.Failed.name())) {
                 s_logger.debug("Attempting to create tunnel from:" +
                         rh.longValue() + " to:" + hostId);
                 if (ta == null) {
@@ -329,9 +323,9 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         }
         //TODO: Should we propagate the exception here?
         try {
-            String myIp = getGreEndpointIP(dest.getHost(), nw);
+            String myIp = getGreEndpointIP(host, nw);
             if (myIp == null)
-                throw new GreTunnelException("Unable to retrieve the source " + "endpoint for the GRE tunnel." + "Failure is on host:" + dest.getHost().getId());
+                throw new GreTunnelException("Unable to retrieve the source " + "endpoint for the GRE tunnel." + "Failure is on host:" + host.getId());
             boolean noHost = true;
             for (Long i : toHostIds) {
                 HostVO rHost = _hostDao.findById(i);
@@ -343,7 +337,8 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
                                     + "Failure is on host:" + rHost.getId());
                 Commands cmds = new Commands(
                         new OvsCreateTunnelCommand(otherIp, key,
-                                Long.valueOf(hostId), i, nw.getId(), myIp));
+                                Long.valueOf(hostId), i, nw.getId(), myIp, bridgeName, nw.getUuid()));
+                s_logger.debug("Attempting to create tunnel from:" + hostId + " to:" + i + " for the network " + nw.getId());
                 s_logger.debug("Ask host " + hostId
                         + " to create gre tunnel to " + i);
                 Answer[] answers = _agentMgr.send(hostId, cmds);
@@ -355,21 +350,19 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
                 HostVO rHost = _hostDao.findById(i);
                 String otherIp = getGreEndpointIP(rHost, nw);
                 Commands cmds = new Commands(new OvsCreateTunnelCommand(myIp,
-                        key, i, Long.valueOf(hostId), nw.getId(), otherIp));
+                        key, i, Long.valueOf(hostId), nw.getId(), otherIp, bridgeName, nw.getUuid()));
                 s_logger.debug("Ask host " + i + " to create gre tunnel to "
                         + hostId);
                 Answer[] answers = _agentMgr.send(i, cmds);
                 handleCreateTunnelAnswer(answers);
                 noHost = false;
             }
+
             // If no tunnels have been configured, perform the bridge setup
-            // anyway
-            // This will ensure VIF rules will be triggered
+            // anyway. This will ensure VIF rules will be triggered
             if (noHost) {
-                Commands cmds = new Commands(new OvsSetupBridgeCommand(key,
-                        hostId, nw.getId()));
-                s_logger.debug("Ask host " + hostId
-                        + " to configure bridge for network:" + nw.getId());
+                Commands cmds = new Commands(new OvsSetupBridgeCommand(bridgeName, hostId, nw.getId()));
+                s_logger.debug("Ask host " + hostId + " to configure bridge for network:" + nw.getId());
                 Answer[] answers = _agentMgr.send(hostId, cmds);
                 handleSetupBridgeAnswer(answers);
             }
@@ -384,10 +377,20 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         return true;
     }
 
+    boolean isVpcEnabledForDistributedRouter(long vpcId) {
+        VpcVO vpc = _vpcDao.findById(vpcId);
+        return vpc.usesDistributedRouter();
+    }
+
     @Override
-    public void vmCheckAndCreateTunnel(VirtualMachineProfile vm,
-            Network nw, DeployDestination dest) {
-        checkAndCreateTunnel(vm.getVirtualMachine(), nw, dest);
+    public void checkAndPrepareHostForTunnelNetwork(Network nw, Host host) {
+        if (nw.getVpcId() != null && isVpcEnabledForDistributedRouter(nw.getVpcId())) {
+            // check and setup host to be in full tunnel mesh with each of the network in the VPC
+            checkAndCreateVpcTunnelNetworks(host, nw.getVpcId());
+        } else {
+            // check and setup host to be in full tunnel mesh with the network
+            checkAndCreateTunnel(nw, host);
+        }
     }
 
     @DB
@@ -440,45 +443,28 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
     }
 
     @Override
-    public void checkAndDestroyTunnel(VirtualMachine vm, Network nw) {
-        // if (!_isEnabled) {
-        // return;
-        // }
-
-        List<UserVmVO> userVms = _userVmDao.listByAccountIdAndHostId(vm.getAccountId(), vm.getHostId());
-        if (vm.getType() == VirtualMachine.Type.User) {
-            if (userVms.size() > 1) {
-                return;
-            }
+    public void checkAndRemoveHostFromTunnelNetwork(Network nw, Host host) {
 
-            List<DomainRouterVO> routers = _routerDao.findByNetwork(nw.getId());
-            for (DomainRouterVO router : routers) {
-                if (router.getHostId().equals(vm.getHostId())) {
-                    return;
-                }
-            }
-        } else if (vm.getType() == VirtualMachine.Type.DomainRouter && userVms.size() != 0) {
-            return;
-        }
         try {
             /* Now we are last one on host, destroy the bridge with all
              * the tunnels for this network  */
             int key = getGreKey(nw);
-            Command cmd = new OvsDestroyBridgeCommand(nw.getId(), key);
-            s_logger.debug("Destroying bridge for network " + nw.getId() + " on host:" + vm.getHostId());
-            Answer ans = _agentMgr.send(vm.getHostId(), cmd);
-            handleDestroyBridgeAnswer(ans, vm.getHostId(), nw.getId());
+            String bridgeName = generateBridgeName(nw, key);
+            Command cmd = new OvsDestroyBridgeCommand(nw.getId(), bridgeName);
+            s_logger.debug("Destroying bridge for network " + nw.getId() + " on host:" + host.getId());
+            Answer ans = _agentMgr.send(host.getId(), cmd);
+            handleDestroyBridgeAnswer(ans, host.getId(), nw.getId());
 
             /* Then ask hosts have peer tunnel with me to destroy them */
             List<OvsTunnelNetworkVO> peers =
-                    _tunnelNetworkDao.listByToNetwork(vm.getHostId(),
+                    _tunnelNetworkDao.listByToNetwork(host.getId(),
                             nw.getId());
             for (OvsTunnelNetworkVO p : peers) {
                 // If the tunnel was not successfully created don't bother to remove it
-                if (p.getState().equals("SUCCESS")) {
-                    cmd = new OvsDestroyTunnelCommand(p.getNetworkId(), key,
+                if (p.getState().equals(OvsTunnel.State.Established.name())) {
+                    cmd = new OvsDestroyTunnelCommand(p.getNetworkId(), bridgeName,
                             p.getPortName());
-                    s_logger.debug("Destroying tunnel to " + vm.getHostId() +
+                    s_logger.debug("Destroying tunnel to " + host.getId() +
                             " from " + p.getFrom());
                     ans = _agentMgr.send(p.getFrom(), cmd);
                     handleDestroyTunnelAnswer(ans, p.getFrom(),
@@ -486,8 +472,204 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
                 }
             }
         } catch (Exception e) {
-            s_logger.warn(String.format("Destroy tunnel(account:%1$s," + "hostId:%2$s) failed", vm.getAccountId(), vm.getHostId()), e);
+            s_logger.warn(String.format("Destroy tunnel failed", e));
+        }
+    }
+
+    private String generateBridgeName(Network nw, int key) {
+        if (nw.getVpcId() != null && isVpcEnabledForDistributedRouter(nw.getVpcId())) {
+            return "OVS-DR-VPC-Bridge" + nw.getVpcId();
+        } else {
+            return "OVSTunnel"+key;
+        }
+    }
+    private String generateBridgeNameForVpc(long vpcId) {
+        return "OVS-DR-VPC-Bridge" + vpcId;
+    }
+
+    public boolean sendVpcTopologyChangeUpdate(OvsVpcPhysicalTopologyConfigCommand updateCmd, long hostId, String bridgeName) {
+        try {
+            s_logger.debug("Sending VPC topology update to the host " + hostId);
+            updateCmd.setHostId(hostId);
+            updateCmd.setBridgeName(bridgeName);
+            Answer ans = _agentMgr.send(hostId, updateCmd);
+            if (ans.getResult()) {
+                s_logger.debug("Successfully updated the host " + hostId + " with latest VPC topology." );
+                return true;
+            }  else {
+                s_logger.debug("Failed to update the host " + hostId + " with latest VPC topology." );
+                return false;
+            }
+        } catch (Exception e) {
+            s_logger.debug("Failed to updated the host " + hostId + " with latest VPC topology." );
+            return false;
         }
     }
 
+    OvsVpcPhysicalTopologyConfigCommand prepareVpcTopologyUpdate(long vpcId) {
+        VpcVO vpc = _vpcDao.findById(vpcId);
+        assert (vpc != null): "invalid vpc id";
+
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        List<Long> hostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
+        List<Long> vmIds = _ovsNetworkToplogyGuru.getAllActiveVmsInVpc(vpcId);
+
+        List<OvsVpcPhysicalTopologyConfigCommand.Host> hosts = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Host>();
+        List<OvsVpcPhysicalTopologyConfigCommand.Tier> tiers = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Tier>();
+        List<OvsVpcPhysicalTopologyConfigCommand.Vm> vms = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Vm>();
+
+        for (Long hostId : hostIds) {
+            HostVO hostDetails = _hostDao.findById(hostId);
+            String remoteIp = null;
+            for (Network network: vpcNetworks) {
+                try {
+                    remoteIp = getGreEndpointIP(hostDetails, network);
+                } catch (Exception e) {
+
+                }
+            }
+            OvsVpcPhysicalTopologyConfigCommand.Host host = new OvsVpcPhysicalTopologyConfigCommand.Host(hostId, remoteIp);
+            hosts.add(host);
+        }
+
+        for (Network network: vpcNetworks) {
+            String key = BroadcastDomainType.getValue(network.getBroadcastUri());
+            long gre_key;
+            if (key.contains(".")) {
+                String[] parts = key.split(".");
+                gre_key = Long.parseLong(parts[1]);
+            } else {
+                try {
+                    gre_key = Long.parseLong(BroadcastDomainType.getValue(key));
+                } catch (Exception e) {
+                    return null;
+                }
+            }
+            NicVO nic = _nicDao.findByIp4AddressAndNetworkId(network.getGateway(), network.getId());
+            OvsVpcPhysicalTopologyConfigCommand.Tier tier = new OvsVpcPhysicalTopologyConfigCommand.Tier(gre_key,
+                    network.getUuid(), network.getGateway(), nic.getMacAddress(), network.getCidr());
+            tiers.add(tier);
+        }
+
+        for (long vmId: vmIds) {
+            VirtualMachine vmInstance = _vmInstanceDao.findById(vmId);
+            List<OvsVpcPhysicalTopologyConfigCommand.Nic>  vmNics = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Nic>();
+            for (Nic vmNic :_nicDao.listByVmId(vmId)) {
+                Network network = _networkDao.findById(vmNic.getNetworkId());
+                if (network.getTrafficType() == TrafficType.Guest) {
+                    OvsVpcPhysicalTopologyConfigCommand.Nic nic =  new OvsVpcPhysicalTopologyConfigCommand.Nic(
+                            vmNic.getIp4Address(), vmNic.getMacAddress(), ((Long)vmNic.getNetworkId()).toString());
+                    vmNics.add(nic);
+                }
+            }
+            OvsVpcPhysicalTopologyConfigCommand.Vm vm = new OvsVpcPhysicalTopologyConfigCommand.Vm(
+                    vmInstance.getHostId(), vmNics.toArray(new OvsVpcPhysicalTopologyConfigCommand.Nic[vmNics.size()]));
+            vms.add(vm);
+        }
+        return new OvsVpcPhysicalTopologyConfigCommand(
+                hosts.toArray(new OvsVpcPhysicalTopologyConfigCommand.Host[hosts.size()]),
+                tiers.toArray(new OvsVpcPhysicalTopologyConfigCommand.Tier[tiers.size()]),
+                vms.toArray(new OvsVpcPhysicalTopologyConfigCommand.Vm[vms.size()]),
+                vpc.getCidr());
+    }
+
+    @DB
+    protected void checkAndCreateVpcTunnelNetworks(Host host, long vpcId) {
+
+        long hostId = host.getId();
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        List<Long> vpcSpannedHostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
+        String bridgeName=generateBridgeNameForVpc(vpcId);
+
+        for (Network vpcNetwork: vpcNetworks) {
+            int key = getGreKey(vpcNetwork);
+            List<Long> toHostIds = new ArrayList<Long>();
+            List<Long> fromHostIds = new ArrayList<Long>();
+
+            for (Long rh : vpcSpannedHostIds) {
+                if (rh == hostId) {
+                    continue;
+                }
+                OvsTunnelNetworkVO ta = _tunnelNetworkDao.getByFromToNetwork(hostId, rh.longValue(), vpcNetwork.getId());
+                // Try and create the tunnel even if a previous attempt failed
+                if (ta == null || ta.getState().equals(OvsTunnel.State.Failed.name())) {
+                    s_logger.debug("Attempting to create tunnel from:" + hostId + " to:" + rh.longValue());
+                    if (ta == null) {
+                        createTunnelRecord(hostId, rh.longValue(), vpcNetwork.getId(), key);
+                    }
+                    if (!toHostIds.contains(rh)) {
+                        toHostIds.add(rh);
+                    }
+                }
+
+                ta = _tunnelNetworkDao.getByFromToNetwork(rh.longValue(),
+                        hostId, vpcNetwork.getId());
+                // Try and create the tunnel even if a previous attempt failed
+                if (ta == null || ta.getState().equals(OvsTunnel.State.Failed.name())) {
+                    s_logger.debug("Attempting to create tunnel from:" +
+                            rh.longValue() + " to:" + hostId);
+                    if (ta == null) {
+                        createTunnelRecord(rh.longValue(), hostId,
+                                vpcNetwork.getId(), key);
+                    }
+                    if (!fromHostIds.contains(rh)) {
+                        fromHostIds.add(rh);
+                    }
+                }
+            }
+
+            try {
+                String myIp = getGreEndpointIP(host, vpcNetwork);
+                if (myIp == null)
+                    throw new GreTunnelException("Unable to retrieve the source " + "endpoint for the GRE tunnel."
+                            + "Failure is on host:" + host.getId());
+                boolean noHost = true;
+
+                for (Long i : toHostIds) {
+                    HostVO rHost = _hostDao.findById(i);
+                    String otherIp = getGreEndpointIP(rHost, vpcNetwork);
+                    if (otherIp == null)
+                        throw new GreTunnelException(
+                                "Unable to retrieve the remote "
+                                        + "endpoint for the GRE tunnel."
+                                        + "Failure is on host:" + rHost.getId());
+                    Commands cmds = new Commands(
+                            new OvsCreateTunnelCommand(otherIp, key,
+                                    Long.valueOf(hostId), i, vpcNetwork.getId(), myIp, bridgeName,
+                                    vpcNetwork.getUuid()));
+                    s_logger.debug("Attempting to create tunnel from:" + hostId + " to:" + i + " for the network "
+                            + vpcNetwork.getId());
+                    s_logger.debug("Ask host " + hostId
+                            + " to create gre tunnel to " + i);
+                    Answer[] answers = _agentMgr.send(hostId, cmds);
+                    handleCreateTunnelAnswer(answers);
+                    noHost = false;
+                }
+
+                for (Long i : fromHostIds) {
+                    HostVO rHost = _hostDao.findById(i);
+                    String otherIp = getGreEndpointIP(rHost, vpcNetwork);
+                    Commands cmds = new Commands(new OvsCreateTunnelCommand(myIp,
+                            key, i, Long.valueOf(hostId), vpcNetwork.getId(), otherIp, bridgeName,
+                            vpcNetwork.getUuid()));
+                    s_logger.debug("Ask host " + i + " to create gre tunnel to "
+                            + hostId);
+                    Answer[] answers = _agentMgr.send(i, cmds);
+                    handleCreateTunnelAnswer(answers);
+                    noHost = false;
+                }
+            } catch (GreTunnelException | OperationTimedoutException | AgentUnavailableException e) {
+                // I really thing we should do a better handling of these exceptions
+                s_logger.warn("Ovs Tunnel network created tunnel failed", e);
+            }
+        }
+
+        OvsVpcPhysicalTopologyConfigCommand topologyConfigCommand = prepareVpcTopologyUpdate(vpcId);
+        for (Long id: vpcSpannedHostIds) {
+            if (!sendVpcTopologyChangeUpdate(topologyConfigCommand, id, bridgeName)) {
+                s_logger.debug("Failed to send VPC topology change update to host : " + id + ". Moving on with rest of" +
+                        "the host update.");
+            }
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnel.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnel.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnel.java
new file mode 100644
index 0000000..3216ac7
--- /dev/null
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnel.java
@@ -0,0 +1,24 @@
+// 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.ovs.dao;
+
+public interface OvsTunnel {
+    public enum State {
+        Created, Established, Failed
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelNetworkVO.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelNetworkVO.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelNetworkVO.java
index 2826912..88a7591 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelNetworkVO.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelNetworkVO.java
@@ -62,7 +62,7 @@ public class OvsTunnelNetworkVO implements InternalIdentity {
         this.key = key;
         this.networkId = networkId;
         this.portName = "[]";
-        this.state = "FAILED";
+        this.state = OvsTunnel.State.Created.name();
     }
 
     public void setKey(int key) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/scripts/vm/hypervisor/xenserver/ovstunnel
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/ovstunnel b/scripts/vm/hypervisor/xenserver/ovstunnel
index d558e97..64a2d36 100755
--- a/scripts/vm/hypervisor/xenserver/ovstunnel
+++ b/scripts/vm/hypervisor/xenserver/ovstunnel
@@ -224,6 +224,7 @@ def create_tunnel(session, args):
     gre_key = args.pop("key")
     src_host = args.pop("from")
     dst_host = args.pop("to")
+    network_uuid = args.pop("cloudstack-network-id")
 
     logging.debug("Entering create_tunnel")
 
@@ -318,6 +319,7 @@ def create_tunnel(session, args):
 
             # add flow rule to send the traffic from tunnel ports to L2 switching table only
             lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0, actions='resubmit(,1)')
+            lib.do_cmd([lib.VSCTL_PATH, "set", "interface", name, "options:cloudstack-network-id=%s" % network_uuid])
 
         return "SUCCESS:%s" % name
     except:

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/92c9d3b8/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
index 4af20c6..b643ec4 100644
--- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
+++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
@@ -16,6 +16,7 @@
 // under the License.
 package com.cloud.hypervisor;
 
+import com.cloud.network.dao.NetworkVO;
 import java.util.List;
 import java.util.Map;
 
@@ -41,6 +42,7 @@ import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.dao.NicDao;
+import com.cloud.network.dao.NetworkDao;
 import com.cloud.vm.dao.NicSecondaryIpDao;
 import com.cloud.vm.dao.UserVmDetailsDao;
 import com.cloud.vm.dao.VMInstanceDao;
@@ -52,6 +54,8 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
     @Inject
     NicDao _nicDao;
     @Inject
+    NetworkDao  _networkDao;
+    @Inject
     VMInstanceDao _virtualMachineDao;
     @Inject
     UserVmDetailsDao _userVmDetailsDao;
@@ -87,6 +91,9 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
         to.setName(profile.getName());
         to.setSecurityGroupEnabled(profile.isSecurityGroupEnabled());
 
+        NetworkVO network = _networkDao.findById(profile.getNetworkId());
+        to.setNetworkUuid(network.getUuid());
+
         // Workaround to make sure the TO has the UUID we need for Niciri integration
         NicVO nicVO = _nicDao.findById(profile.getId());
         to.setUuid(nicVO.getUuid());


[05/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
Fixed CLOUDSTACK-6210 LDAP:listLdapUsers api throws exception when we click on "Add LDAP Account" This occurs when ldap basedn is not configured. Throwing an IAE and a proper message is returned from the api call

Signed-off-by: Ian Duffy <ia...@ianduffy.ie>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/4552ec63
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/4552ec63
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/4552ec63

Branch: refs/heads/distributedrouter
Commit: 4552ec632201e7432afae7770f5854aaa244267c
Parents: 78b148d
Author: Rajani Karuturi <ra...@gmail.com>
Authored: Fri Mar 7 11:13:35 2014 +0530
Committer: Ian Duffy <ia...@ianduffy.ie>
Committed: Fri Mar 7 16:57:13 2014 +0000

----------------------------------------------------------------------
 .../apache/cloudstack/ldap/LdapUserManager.java |   8 +-
 .../cloudstack/ldap/LdapUserManagerSpec.groovy  | 263 ++++++++++---------
 2 files changed, 145 insertions(+), 126 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4552ec63/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManager.java
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManager.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManager.java
index 2dacafe..afdf975 100644
--- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManager.java
+++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManager.java
@@ -29,6 +29,8 @@ import javax.naming.directory.DirContext;
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 
+import org.apache.commons.lang.StringUtils;
+
 public class LdapUserManager {
 
     @Inject
@@ -185,6 +187,10 @@ public class LdapUserManager {
         controls.setSearchScope(_ldapConfiguration.getScope());
         controls.setReturningAttributes(_ldapConfiguration.getReturnAttributes());
 
-        return context.search(_ldapConfiguration.getBaseDn(), generateSearchFilter(username), controls);
+        String basedn = _ldapConfiguration.getBaseDn();
+        if (StringUtils.isBlank(basedn)) {
+            throw new IllegalArgumentException("ldap basedn is not configured");
+        }
+        return context.search(basedn, generateSearchFilter(username), controls);
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4552ec63/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerSpec.groovy
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerSpec.groovy
index fa735d3..9fbc81f 100644
--- a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerSpec.groovy
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerSpec.groovy
@@ -21,10 +21,9 @@ import org.apache.cloudstack.ldap.LdapUserManager
 import spock.lang.Shared
 
 import javax.naming.NamingException
-import javax.naming.NamingEnumeration
 import javax.naming.directory.Attribute
 import javax.naming.directory.Attributes
-import javax.naming.directory.DirContext
+import javax.naming.directory.InitialDirContext
 import javax.naming.directory.SearchControls
 import javax.naming.directory.SearchResult
 import javax.naming.ldap.LdapContext
@@ -51,83 +50,83 @@ class LdapUserManagerSpec extends spock.lang.Specification {
 
     private def createGroupSearchContext() {
 
-	def umSearchResult = Mock(SearchResult)
-	umSearchResult.getName() >> principal;
-	umSearchResult.getAttributes() >> principal
+        def umSearchResult = Mock(SearchResult)
+        umSearchResult.getName() >> principal;
+        umSearchResult.getAttributes() >> principal
 
-	def uniqueMembers = new BasicNamingEnumerationImpl()
-	uniqueMembers.add(umSearchResult);
-	def attributes = Mock(Attributes)
-	def uniqueMemberAttribute = Mock(Attribute)
-	uniqueMemberAttribute.getId() >> "uniquemember"
-	uniqueMemberAttribute.getAll() >> uniqueMembers
-	attributes.get("uniquemember") >> uniqueMemberAttribute
+        def uniqueMembers = new BasicNamingEnumerationImpl()
+        uniqueMembers.add(umSearchResult);
+        def attributes = Mock(Attributes)
+        def uniqueMemberAttribute = Mock(Attribute)
+        uniqueMemberAttribute.getId() >> "uniquemember"
+        uniqueMemberAttribute.getAll() >> uniqueMembers
+        attributes.get("uniquemember") >> uniqueMemberAttribute
 
-	def groupSearchResult = Mock(SearchResult)
-	groupSearchResult.getName() >> principal;
-	groupSearchResult.getAttributes() >> attributes
+        def groupSearchResult = Mock(SearchResult)
+        groupSearchResult.getName() >> principal;
+        groupSearchResult.getAttributes() >> attributes
 
-	def searchGroupResults = new BasicNamingEnumerationImpl()
-	searchGroupResults.add(groupSearchResult);
+        def searchGroupResults = new BasicNamingEnumerationImpl()
+        searchGroupResults.add(groupSearchResult);
 
-	attributes = createUserAttributes(username, email, firstname, lastname)
-	SearchResult userSearchResult = createSearchResult(attributes)
-	def searchUsersResults = new BasicNamingEnumerationImpl()
-	searchUsersResults.add(userSearchResult);
+        attributes = createUserAttributes(username, email, firstname, lastname)
+        SearchResult userSearchResult = createSearchResult(attributes)
+        def searchUsersResults = new BasicNamingEnumerationImpl()
+        searchUsersResults.add(userSearchResult);
 
-	def context = Mock(LdapContext)
-	context.search(_, _, _) >>> [searchGroupResults, searchUsersResults];
+        def context = Mock(LdapContext)
+        context.search(_, _, _) >>> [searchGroupResults, searchUsersResults];
 
-	return context
+        return context
     }
 
     private def createContext() {
-		Attributes attributes = createUserAttributes(username, email, firstname, lastname)
-		SearchResult searchResults = createSearchResult(attributes)
-		def searchUsersResults = new BasicNamingEnumerationImpl()
-		searchUsersResults.add(searchResults);
+        Attributes attributes = createUserAttributes(username, email, firstname, lastname)
+        SearchResult searchResults = createSearchResult(attributes)
+        def searchUsersResults = new BasicNamingEnumerationImpl()
+        searchUsersResults.add(searchResults);
 
-		def context = Mock(LdapContext)
-		context.search(_, _, _) >> searchUsersResults;
+        def context = Mock(LdapContext)
+        context.search(_, _, _) >> searchUsersResults;
 
-		return context
+        return context
     }
 
     private SearchResult createSearchResult(attributes) {
-		def search = Mock(SearchResult)
+        def search = Mock(SearchResult)
 
-		search.getName() >> "cn=" + attributes.getAt("uid").get();
+        search.getName() >> "cn=" + attributes.getAt("uid").get();
 
-		search.getAttributes() >> attributes
-	search.getNameInNamespace() >> principal
+        search.getAttributes() >> attributes
+        search.getNameInNamespace() >> principal
 
-		return search
+        return search
     }
 
     private Attributes createUserAttributes(String username, String email, String firstname, String lastname) {
-		def attributes = Mock(Attributes)
+        def attributes = Mock(Attributes)
 
-		def nameAttribute = Mock(Attribute)
-		nameAttribute.getId() >> "uid"
-		nameAttribute.get() >> username
-		attributes.get("uid") >> nameAttribute
+        def nameAttribute = Mock(Attribute)
+        nameAttribute.getId() >> "uid"
+        nameAttribute.get() >> username
+        attributes.get("uid") >> nameAttribute
 
-		def mailAttribute = Mock(Attribute)
-		mailAttribute.getId() >> "mail"
-		mailAttribute.get() >> email
-		attributes.get("mail") >> mailAttribute
+        def mailAttribute = Mock(Attribute)
+        mailAttribute.getId() >> "mail"
+        mailAttribute.get() >> email
+        attributes.get("mail") >> mailAttribute
 
-		def givennameAttribute = Mock(Attribute)
-		givennameAttribute.getId() >> "givenname"
-		givennameAttribute.get() >> firstname
-		attributes.get("givenname") >> givennameAttribute
+        def givennameAttribute = Mock(Attribute)
+        givennameAttribute.getId() >> "givenname"
+        givennameAttribute.get() >> firstname
+        attributes.get("givenname") >> givennameAttribute
 
-		def snAttribute = Mock(Attribute)
-		snAttribute.getId() >> "sn"
-		snAttribute.get() >> lastname
-		attributes.get("sn") >> snAttribute
+        def snAttribute = Mock(Attribute)
+        snAttribute.getId() >> "sn"
+        snAttribute.get() >> lastname
+        attributes.get("sn") >> snAttribute
 
-		return attributes
+        return attributes
     }
 
     def setupSpec() {
@@ -140,144 +139,158 @@ class LdapUserManagerSpec extends spock.lang.Specification {
         ldapConfiguration.getFirstnameAttribute() >> "givenname"
         ldapConfiguration.getLastnameAttribute() >> "sn"
         ldapConfiguration.getBaseDn() >> "dc=cloudstack,dc=org"
-	ldapConfiguration.getCommonNameAttribute() >> "cn"
-	ldapConfiguration.getGroupObject() >> "groupOfUniqueNames"
-	ldapConfiguration.getGroupUniqueMemeberAttribute() >> "uniquemember"
+        ldapConfiguration.getCommonNameAttribute() >> "cn"
+        ldapConfiguration.getGroupObject() >> "groupOfUniqueNames"
+        ldapConfiguration.getGroupUniqueMemeberAttribute() >> "uniquemember"
 
         username = "rmurphy"
         email = "rmurphy@test.com"
         firstname = "Ryan"
         lastname = "Murphy"
-		principal = "cn=" + username + "," + ldapConfiguration.getBaseDn()
+        principal = "cn=" + username + "," + ldapConfiguration.getBaseDn()
     }
 
     def "Test successfully creating an Ldap User from Search result"() {
-		given: "We have attributes, a search and a user manager"
-		def attributes = createUserAttributes(username, email, firstname, lastname)
+        given: "We have attributes, a search and a user manager"
+        def attributes = createUserAttributes(username, email, firstname, lastname)
         def search = createSearchResult(attributes)
         def userManager = new LdapUserManager(ldapConfiguration)
         def result = userManager.createUser(search)
 
-		expect: "The crated user the data supplied from LDAP"
+        expect: "The crated user the data supplied from LDAP"
 
         result.username == username
         result.email == email
         result.firstname == firstname
         result.lastname == lastname
-		result.principal == principal
+        result.principal == principal
     }
 
     def "Test successfully returning a list from get users"() {
-		given: "We have a LdapUserManager"
+        given: "We have a LdapUserManager"
 
         def userManager = new LdapUserManager(ldapConfiguration)
 
-		when: "A request for users is made"
+        when: "A request for users is made"
         def result = userManager.getUsers(username, createContext())
 
-		then: "A list of users is returned"
+        then: "A list of users is returned"
         result.size() == 1
     }
 
     def "Test successfully returning a list from get users when no username is given"() {
-		given: "We have a LdapUserManager"
+        given: "We have a LdapUserManager"
 
         def userManager = new LdapUserManager(ldapConfiguration)
 
-		when: "Get users is called without a username"
+        when: "Get users is called without a username"
         def result = userManager.getUsers(createContext())
 
-		then: "All users are returned"
-		result.size() == 1
+        then: "All users are returned"
+        result.size() == 1
     }
 
     def "Test successfully returning a NamingEnumeration from searchUsers"() {
-		given: "We have a LdapUserManager"
-		def userManager = new LdapUserManager(ldapConfiguration)
+        given: "We have a LdapUserManager"
+        def userManager = new LdapUserManager(ldapConfiguration)
 
-		when: "We search for users"
+        when: "We search for users"
         def result = userManager.searchUsers(createContext())
 
-		then: "A list of users are returned."
+        then: "A list of users are returned."
         result.next().getName() + "," + ldapConfiguration.getBaseDn() == principal
     }
 
     def "Test successfully returning an Ldap user from a get user request"() {
-		given: "We have a LdapUserMaanger"
+        given: "We have a LdapUserMaanger"
 
-		def userManager = new LdapUserManager(ldapConfiguration)
+        def userManager = new LdapUserManager(ldapConfiguration)
 
-		when: "A request for a user is made"
-		def result = userManager.getUser(username, createContext())
+        when: "A request for a user is made"
+        def result = userManager.getUser(username, createContext())
 
-		then: "The user is returned"
-		result.username == username
-		result.email == email
-		result.firstname == firstname
-		result.lastname == lastname
-		result.principal == principal
+        then: "The user is returned"
+        result.username == username
+        result.email == email
+        result.firstname == firstname
+        result.lastname == lastname
+        result.principal == principal
     }
 
     def "Test successfully throwing an exception when no users are found with getUser"() {
-		given: "We have a seachResult of users and a User Manager"
+        given: "We have a seachResult of users and a User Manager"
 
-		def searchUsersResults = new BasicNamingEnumerationImpl()
+        def searchUsersResults = new BasicNamingEnumerationImpl()
 
-		def context = Mock(LdapContext)
-		context.search(_, _, _) >> searchUsersResults;
+        def context = Mock(LdapContext)
+        context.search(_, _, _) >> searchUsersResults;
 
-		def userManager = new LdapUserManager(ldapConfiguration)
+        def userManager = new LdapUserManager(ldapConfiguration)
 
-		when: "a get user request is made and no user is found"
-		def result = userManager.getUser(username, context)
+        when: "a get user request is made and no user is found"
+        def result = userManager.getUser(username, context)
 
-		then: "An exception is thrown."
-		thrown NamingException
+        then: "An exception is thrown."
+        thrown NamingException
     }
 
     def "Test that a newly created Ldap User Manager is not null"() {
-		given: "You have created a new Ldap user manager object"
-		def result = new LdapUserManager();
-		expect: "The result is not null"
-		result != null
+        given: "You have created a new Ldap user manager object"
+        def result = new LdapUserManager();
+        expect: "The result is not null"
+        result != null
     }
 
     def "test successful generateGroupSearchFilter"() {
-	given: "ldap user manager and ldap config"
-	def ldapUserManager = new LdapUserManager(ldapConfiguration)
-	def groupName = varGroupName == null ? "*" : varGroupName
-	def expectedResult = "(&(objectClass=groupOfUniqueNames)(cn="+groupName+"))";
-
-	def result = ldapUserManager.generateGroupSearchFilter(varGroupName)
-	expect:
-	result == expectedResult
-	where: "The group name passed is set to "
-	varGroupName << ["", null, "Murphy"]
+        given: "ldap user manager and ldap config"
+        def ldapUserManager = new LdapUserManager(ldapConfiguration)
+        def groupName = varGroupName == null ? "*" : varGroupName
+        def expectedResult = "(&(objectClass=groupOfUniqueNames)(cn=" + groupName + "))";
+
+        def result = ldapUserManager.generateGroupSearchFilter(varGroupName)
+        expect:
+        result == expectedResult
+        where: "The group name passed is set to "
+        varGroupName << ["", null, "Murphy"]
     }
 
-    def "test successful getUsersInGroup"(){
-	given: "ldap user manager and ldap config"
-	def ldapUserManager = new LdapUserManager(ldapConfiguration)
+    def "test successful getUsersInGroup"() {
+        given: "ldap user manager and ldap config"
+        def ldapUserManager = new LdapUserManager(ldapConfiguration)
+
+        when: "A request for users is made"
+        def result = ldapUserManager.getUsersInGroup("engineering", createGroupSearchContext())
+        then: "one user is returned"
+        result.size() == 1
+    }
+
+    def "test successful getUserForDn"() {
+        given: "ldap user manager and ldap config"
+        def ldapUserManager = new LdapUserManager(ldapConfiguration)
+
+        when: "A request for users is made"
+        def result = ldapUserManager.getUserForDn("cn=Ryan Murphy,ou=engineering,dc=cloudstack,dc=org", createContext())
+        then: "A list of users is returned"
+        result != 1
+        result.username == username
+        result.email == email
+        result.firstname == firstname
+        result.lastname == lastname
+        result.principal == principal
 
-	when: "A request for users is made"
-	def result = ldapUserManager.getUsersInGroup("engineering", createGroupSearchContext())
-	then: "one user is returned"
-	result.size() == 1
     }
 
-    def "test successful getUserForDn"(){
-	given: "ldap user manager and ldap config"
-	def ldapUserManager = new LdapUserManager(ldapConfiguration)
+    def "test searchUsers when ldap basedn in not set"() {
+        given: "ldap configuration where basedn is not set"
+        def ldapconfig = Mock(LdapConfiguration)
+        ldapconfig.getBaseDn() >> null
+        def ldapUserManager = new LdapUserManager(ldapconfig)
 
-	when: "A request for users is made"
-	def result = ldapUserManager.getUserForDn("cn=Ryan Murphy,ou=engineering,dc=cloudstack,dc=org",createContext())
-	then: "A list of users is returned"
-	result != 1
-	result.username == username
-	result.email == email
-	result.firstname == firstname
-	result.lastname == lastname
-	result.principal == principal
+        when: "A request for search users is made"
+        def result = ldapUserManager.searchUsers(new InitialDirContext())
 
+        then: "An exception with no basedn defined is returned"
+        def e = thrown(IllegalArgumentException)
+        e.message == "ldap basedn is not configured"
     }
 }


[12/50] [abbrv] Removed unused methods from BaseCmd class. Moved some helper methods to AccountManagerImpl class

Posted by mu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/server/test/com/cloud/api/dispatch/ParamGenericValidationWorkerTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/api/dispatch/ParamGenericValidationWorkerTest.java b/server/test/com/cloud/api/dispatch/ParamGenericValidationWorkerTest.java
index 867625d..0803a2b 100644
--- a/server/test/com/cloud/api/dispatch/ParamGenericValidationWorkerTest.java
+++ b/server/test/com/cloud/api/dispatch/ParamGenericValidationWorkerTest.java
@@ -16,16 +16,15 @@
 // under the License.
 package com.cloud.api.dispatch;
 
-import java.util.HashMap;
-import java.util.Map;
-
-import org.junit.Test;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
 import org.apache.cloudstack.acl.RoleType;
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
@@ -33,6 +32,9 @@ import org.apache.cloudstack.api.BaseCmd;
 import org.apache.cloudstack.api.BaseResponse;
 import org.apache.cloudstack.api.Parameter;
 import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
+import org.junit.Test;
 
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
@@ -40,8 +42,9 @@ import com.cloud.exception.NetworkRuleConflictException;
 import com.cloud.exception.ResourceAllocationException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.user.Account;
-
-import org.apache.log4j.Logger;
+import com.cloud.user.AccountVO;
+import com.cloud.user.User;
+import com.cloud.user.UserVO;
 
 public class ParamGenericValidationWorkerTest {
 
@@ -55,9 +58,9 @@ public class ParamGenericValidationWorkerTest {
         final ParamGenericValidationWorker genValidationWorker = new ParamGenericValidationWorker();
 
         // We create a mock logger to verify the result
-        ParamGenericValidationWorker.s_logger = new Logger(""){
+        ParamGenericValidationWorker.s_logger = new Logger("") {
             @Override
-            public void warn(final Object msg){
+            public void warn(final Object msg) {
                 loggerOutput = msg.toString();
             }
         };
@@ -74,8 +77,15 @@ public class ParamGenericValidationWorkerTest {
         params.put(ApiConstants.COMMAND, "");
         params.put("addedParam", "");
 
+        Account account = new AccountVO("testaccount", 1L, "networkdomain", (short) 0, "uuid");
+        UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString());
+        CallContext.register(user, account);
         // Execute
-        driveTest(cmd, params);
+        try {
+            driveTest(cmd, params);
+        } finally {
+            CallContext.unregister();
+        }
 
         // Assert
         assertEquals("There should be no errors since there are no unknown parameters for this command class", null, loggerOutput);
@@ -91,8 +101,16 @@ public class ParamGenericValidationWorkerTest {
         params.put("addedParam", "");
         params.put(unknownParamKey, "");
 
+        Account account = new AccountVO("testaccount", 1L, "networkdomain", (short) 0, "uuid");
+        UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString());
+        CallContext.register(user, account);
+
         // Execute
-        driveTest(cmd, params);
+        try {
+            driveTest(cmd, params);
+        } finally {
+            CallContext.unregister();
+        }
 
         // Assert
         assertTrue("There should be error msg, since there is one unknown parameter", loggerOutput.contains(unknownParamKey));
@@ -102,6 +120,7 @@ public class ParamGenericValidationWorkerTest {
     @Test
     public void testHandleWithoutAuthorization() throws ResourceAllocationException {
         final short type = Account.ACCOUNT_TYPE_NORMAL;
+
         driveAuthTest(type);
 
         // Assert
@@ -112,25 +131,33 @@ public class ParamGenericValidationWorkerTest {
     @Test
     public void testHandleWithAuthorization() throws ResourceAllocationException {
         final short type = Account.ACCOUNT_TYPE_ADMIN;
-        driveAuthTest(type);
 
+        driveAuthTest(type);
         // Assert
         assertEquals("There should be no errors since parameters have authorization", null, loggerOutput);
     }
 
     protected void driveAuthTest(final short type) {
+
         // Prepare
         final BaseCmd cmd = new FakeCmdWithRoleAdmin();
         final Account account = mock(Account.class);
         ((FakeCmdWithRoleAdmin)cmd).account = account;
         when(account.getType()).thenReturn(type);
+        User user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString());
+        CallContext.register(user, account);
+
         final Map<String, String> params = new HashMap<String, String>();
         params.put(ApiConstants.COMMAND, "");
         params.put("addedParam", "");
         params.put("paramWithRole", "");
 
         // Execute
-        driveTest(cmd, params);
+        try {
+            driveTest(cmd, params);
+        } finally {
+            CallContext.unregister();
+        }
     }
 }
 
@@ -143,11 +170,6 @@ class FakeCmd extends BaseCmd {
 
     public Account account;
 
-    @Override
-    protected Account getCurrentContextAccount() {
-        return account;
-    }
-
     //
     // Dummy methods for mere correct compilation
     //

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b0c5cfc/server/test/com/cloud/user/MockAccountManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/user/MockAccountManagerImpl.java b/server/test/com/cloud/user/MockAccountManagerImpl.java
index 62e7fc8..5a44800 100644
--- a/server/test/com/cloud/user/MockAccountManagerImpl.java
+++ b/server/test/com/cloud/user/MockAccountManagerImpl.java
@@ -22,8 +22,6 @@ import java.util.Map;
 import javax.ejb.Local;
 import javax.naming.ConfigurationException;
 
-import org.springframework.stereotype.Component;
-
 import org.apache.cloudstack.acl.ControlledEntity;
 import org.apache.cloudstack.acl.RoleType;
 import org.apache.cloudstack.acl.SecurityChecker.AccessType;
@@ -31,6 +29,7 @@ import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
 import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
 import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
 import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
+import org.springframework.stereotype.Component;
 
 import com.cloud.api.query.vo.ControlledViewEntity;
 import com.cloud.domain.Domain;
@@ -322,4 +321,10 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco
         return null;
     }
 
+    @Override
+    public Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
 }


[35/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
Fixed nonoss build


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/466825a1
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/466825a1
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/466825a1

Branch: refs/heads/distributedrouter
Commit: 466825a167b3ee465a92297b96fb517bb35a810f
Parents: a4d3ec4
Author: Alena Prokharchyk <al...@citrix.com>
Authored: Mon Mar 10 15:27:13 2014 -0700
Committer: Alena Prokharchyk <al...@citrix.com>
Committed: Mon Mar 10 15:29:18 2014 -0700

----------------------------------------------------------------------
 .../src/com/cloud/network/element/CiscoNexusVSMElement.java     | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/466825a1/plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElement.java
----------------------------------------------------------------------
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 c33af27..0e2a911 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElement.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElement.java
@@ -79,6 +79,8 @@ public class CiscoNexusVSMElement extends CiscoNexusVSMDeviceManagerImpl impleme
     ClusterDao _clusterDao;
     @Inject
     ClusterVSMMapDao _clusterVSMDao;
+    @Inject
+    ManagementService _mgr;
 
     @Override
     public Map<Service, Map<Capability, String>> getCapabilities() {
@@ -190,7 +192,8 @@ public class CiscoNexusVSMElement extends CiscoNexusVSMDeviceManagerImpl impleme
         // Else if there is only a zoneId defined, get a list of all vmware clusters
         // in the zone, and then for each cluster, pull the VSM and prepare a list.
         if (zoneId != null && zoneId.longValue() != 0) {
-            ManagementService ref = cmd.getMgmtServiceRef();
+            ManagementService ref = _mgr;
+            ;
             List<? extends Cluster> clusterList = ref.searchForClusters(zoneId, cmd.getStartIndex(), cmd.getPageSizeVal(), "VMware");
 
             if (clusterList.size() == 0) {


[48/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
adds hypervisor script to convert JSON routing polcies (ACL) config in
to flow rules and applies them on the bridge

add event subscriber in OvsTunnelManager, that listens to
replaceNetworkAcl events. On event sends the updated policy info to all
the hosts in the VPC


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/780c8e7a
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/780c8e7a
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/780c8e7a

Branch: refs/heads/distributedrouter
Commit: 780c8e7a71c1e09ed5cdbb5d904c6d3e541d5abd
Parents: c00a3b7
Author: Murali Reddy <mu...@gmail.com>
Authored: Tue Mar 11 04:07:13 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Tue Mar 11 18:40:16 2014 +0530

----------------------------------------------------------------------
 .../xen/resource/CitrixResourceBase.java        |  24 +++-
 .../api/OvsVpcLogicalTopologyConfigCommand.java |  33 -----
 .../OvsVpcPhysicalTopologyConfigCommand.java    |   6 +-
 .../api/OvsVpcRoutingPolicyConfigCommand.java   | 124 +++++++++++++++++++
 .../cloud/network/ovs/OvsTunnelManagerImpl.java | 104 ++++++++++++++--
 .../xenserver/cloudstack_pluginlib.py           |  76 +++++++++++-
 scripts/vm/hypervisor/xenserver/ovstunnel       |  14 ++-
 .../network/vpc/NetworkACLManagerImpl.java      |  12 +-
 8 files changed, 337 insertions(+), 56 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/780c8e7a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
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 2315b31..da92e1e 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
@@ -16,6 +16,7 @@
 // under the License.
 package com.cloud.hypervisor.xen.resource;
 
+import com.cloud.agent.api.*;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
@@ -88,6 +89,7 @@ import org.apache.cloudstack.storage.to.TemplateObjectTO;
 import org.apache.cloudstack.storage.to.VolumeObjectTO;
 
 import com.cloud.agent.IAgentControl;
+
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.AttachIsoCommand;
 import com.cloud.agent.api.AttachVolumeAnswer;
@@ -509,6 +511,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             return execute((OvsDeleteFlowCommand)cmd);
         } else if (clazz == OvsVpcPhysicalTopologyConfigCommand.class) {
             return execute((OvsVpcPhysicalTopologyConfigCommand) cmd);
+        } else if (clazz == OvsVpcRoutingPolicyConfigCommand.class) {
+            return execute((OvsVpcRoutingPolicyConfigCommand) cmd);
         } else if (clazz == CleanupNetworkRulesCmd.class) {
             return execute((CleanupNetworkRulesCmd)cmd);
         } else if (clazz == NetworkRulesSystemVmCommand.class) {
@@ -532,7 +536,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         } else if (clazz == PlugNicCommand.class) {
             return execute((PlugNicCommand)cmd);
         } else if (clazz == UnPlugNicCommand.class) {
-            return execute((UnPlugNicCommand)cmd);
+            return execute((UnPlugNicCommand) cmd);
         } else if (cmd instanceof StorageSubSystemCommand) {
             return storageHandler.handleStorageCommands((StorageSubSystemCommand) cmd);
         } else if (clazz == CreateVMSnapshotCommand.class) {
@@ -5282,8 +5286,24 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         Connection conn = getConnection();
         try {
             String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge",
+                    cmd.getBridgeName(), "config", cmd.getVpcConfigInJson());
+            if (result.equalsIgnoreCase("SUCCESS")) {
+                return new Answer(cmd, true, result);
+            } else {
+                return new Answer(cmd, false, result);
+            }
+        } catch  (Exception e) {
+            s_logger.warn("caught exception while updating host with latest routing polcies", e);
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
+    public Answer execute(OvsVpcRoutingPolicyConfigCommand cmd) {
+        Connection conn = getConnection();
+        try {
+            String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_routing_policies", "bridge",
                     cmd.getBridgeName(), "host-id", ((Long)cmd.getHostId()).toString(), "config",
-                    cmd.getjsonVpcConfig());
+                    cmd.getVpcConfigInJson());
             if (result.equalsIgnoreCase("SUCCESS")) {
                 return new Answer(cmd, true, result);
             } else {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/780c8e7a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java
deleted file mode 100644
index 2fafb6e..0000000
--- a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java
+++ /dev/null
@@ -1,33 +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 com.cloud.agent.api;
-
-/**
- * This command represents view of how a VPC is laid out (on which hosts, which VM is on which host etc)
- * on the physical infrastructure.
- */
-public class OvsVpcLogicalTopologyConfigCommand extends Command {
-
-    public OvsVpcLogicalTopologyConfigCommand() {
-
-    }
-
-    @Override
-    public boolean executeInSequence() {
-        return false;
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/780c8e7a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
index e6f4383..17299d3 100644
--- a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
@@ -20,8 +20,8 @@ import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
 /**
- * This command represents physical view of how a VPC is laid out on the physical infrastructure.
- *   - on which hypervisor hosts VPC spans (host is running in at least one VM from the VPC)
+ * This command represents physical view of how a VPC is laid out on the physical infrastructure. Contains information:
+ *   - on which hypervisor hosts VPC spans (host running at least one VM from the VPC)
  *   - information of tiers, so we can figure how one VM can talk to a different VM in same tier or different tier
  *   - information on all the VM's in the VPC.
  *   - information of NIC's of each VM in the VPC
@@ -102,7 +102,7 @@ public class OvsVpcPhysicalTopologyConfigCommand extends Command {
         vpcConfig = new VpcConfig(vpc);
     }
 
-    public String getjsonVpcConfig() {
+    public String getVpcConfigInJson() {
         Gson gson = new GsonBuilder().create();
         return gson.toJson(vpcConfig).toLowerCase();
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/780c8e7a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java
new file mode 100644
index 0000000..8e4d5d1
--- /dev/null
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java
@@ -0,0 +1,124 @@
+// 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.api;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import java.util.UUID;
+
+/**
+ * This command represents logical view of VM's connectivity in VPC.
+ */
+public class OvsVpcRoutingPolicyConfigCommand extends Command {
+
+    VpcConfig vpcConfig =null;
+    long hostId;
+    String bridgeName;
+
+    public static class AclItem {
+        int number;
+        String uuid;
+        String action;
+        String direction;
+        String sourcePortStart;
+        String sourcePortEnd;
+        String protocol;
+        String[] sourceCidrs;
+        public AclItem(int number, String uuid, String action, String direction, String sourcePortStart,
+                       String sourcePortEnd, String protocol, String[] sourceCidrs) {
+            this.number = number;
+            this.uuid =uuid;
+            this.action = action;
+            this.direction = direction;
+            this.sourceCidrs = sourceCidrs;
+            this.sourcePortStart = sourcePortStart;
+            this.sourcePortEnd = sourcePortEnd;
+            this.protocol = protocol;
+        }
+    }
+
+    public static class Acl {
+        String id;
+        AclItem[] aclItems;
+        public Acl(String uuid, AclItem[] aclItems) {
+            this.id = uuid;
+            this.aclItems = aclItems;
+        }
+    }
+
+    public static class Tier {
+        String id;
+        String cidr;
+        String aclId;
+        public Tier(String uuid, String cidr, String aclId) {
+            this.id = uuid;
+            this.cidr = cidr;
+            this.aclId = aclId;
+        }
+    }
+
+    public class Vpc {
+        String cidr;
+        String id;
+        Acl[] acls;
+        Tier[] tiers;
+        public Vpc(String id, String cidr, Acl[] acls, Tier[] tiers) {
+            this.id = id;
+            this.cidr = cidr;
+            this.acls = acls;
+            this.tiers = tiers;
+        }
+    }
+
+    public static class VpcConfig {
+        Vpc vpc;
+        public VpcConfig(Vpc vpc) {
+            this.vpc = vpc;
+        }
+    }
+
+    public OvsVpcRoutingPolicyConfigCommand(String id, String cidr, Acl[] acls, Tier[] tiers) {
+        Vpc vpc = new Vpc(id, cidr, acls, tiers);
+        vpcConfig = new VpcConfig(vpc);
+    }
+
+    public String getVpcConfigInJson() {
+        Gson gson = new GsonBuilder().create();
+        return gson.toJson(vpcConfig).toLowerCase();
+    }
+
+    public void setHostId(long hostId) {
+        this.hostId = hostId;
+    }
+
+    public long getHostId() {
+        return hostId;
+    }
+
+    public String getBridgeName() {
+        return bridgeName;
+    }
+
+    public void setBridgeName(String bridgeName) {
+        this.bridgeName = bridgeName;
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        return false;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/780c8e7a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
index 82dbfed..35b0035 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
@@ -16,8 +16,12 @@
 // under the License.
 package com.cloud.network.ovs;
 
+import com.amazonaws.services.ec2.model.NetworkAcl;
+import com.cloud.agent.api.*;
 import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.vpc.VpcManager;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.vpc.*;
+import com.cloud.network.vpc.dao.NetworkACLDao;
 import com.cloud.vm.dao.VMInstanceDao;
 import com.cloud.vm.Nic;
 import com.cloud.vm.NicVO;
@@ -33,22 +37,14 @@ import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 import javax.persistence.EntityExistsException;
 
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.MessageSubscriber;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 
 import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.OvsCreateTunnelAnswer;
-import com.cloud.agent.api.OvsCreateTunnelCommand;
-import com.cloud.agent.api.OvsDestroyBridgeCommand;
-import com.cloud.agent.api.OvsDestroyTunnelCommand;
-import com.cloud.agent.api.OvsFetchInterfaceAnswer;
-import com.cloud.agent.api.OvsFetchInterfaceCommand;
-import com.cloud.agent.api.OvsSetupBridgeCommand;
-import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
 import com.cloud.agent.manager.Commands;
 import com.cloud.configuration.Config;
 import com.cloud.exception.AgentUnavailableException;
@@ -68,7 +64,6 @@ import com.cloud.network.ovs.dao.OvsTunnelNetworkDao;
 import com.cloud.network.ovs.dao.OvsTunnelNetworkVO;
 import com.cloud.network.ovs.dao.OvsTunnel;
 import com.cloud.network.vpc.dao.VpcDao;
-import com.cloud.network.vpc.VpcVO;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.db.DB;
@@ -112,6 +107,12 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
     protected VMInstanceDao _vmInstanceDao;
     @Inject
     NetworkDao _networkDao;
+    @Inject
+    MessageBus _messageBus;
+    @Inject
+    NetworkACLDao _networkACLDao;
+    @Inject
+    NetworkACLItemDao _networkACLItemDao;
 
     @Override
     public boolean configure(String name, Map<String, Object> params)
@@ -119,6 +120,7 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         _executorPool = Executors.newScheduledThreadPool(10, new NamedThreadFactory("OVS"));
         _cleanupExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("OVS-Cleanup"));
 
+        _messageBus.subscribe("Network_ACL_Replaced", new NetworkAclEventsSubscriber());
         return true;
     }
 
@@ -725,4 +727,82 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
             }
         }
     }
+
+    // Subscriber to ACL replace events. On acl replace event, if the vpc is enabled for distributed routing
+    // send the ACL update to all the hosts on which VPC spans
+    public class NetworkAclEventsSubscriber implements MessageSubscriber {
+        @Override
+        public void onPublishMessage(String senderAddress, String subject, Object args) {
+            NetworkVO network = (NetworkVO) args;
+            String bridgeName=generateBridgeNameForVpc(network.getVpcId());
+            if (network.getVpcId() != null & isVpcEnabledForDistributedRouter(network.getVpcId())) {
+                long vpcId = network.getVpcId();
+                OvsVpcRoutingPolicyConfigCommand cmd = prepareVpcRoutingPolicyUpdate(vpcId);
+                List<Long> vpcSpannedHostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
+                for (Long id: vpcSpannedHostIds) {
+                    if (!sendVpcRoutingPolicyChangeUpdate(cmd, id, bridgeName)) {
+                        s_logger.debug("Failed to send VPC routing policy change update to host : " + id +
+                                ". Moving on with rest of the host updates.");
+                    }
+                }
+            }
+        }
+    }
+
+    OvsVpcRoutingPolicyConfigCommand prepareVpcRoutingPolicyUpdate(long vpcId) {
+        VpcVO vpc = _vpcDao.findById(vpcId);
+        assert (vpc != null): "invalid vpc id";
+        List<OvsVpcRoutingPolicyConfigCommand.Acl> acls = new ArrayList<>();
+        List<OvsVpcRoutingPolicyConfigCommand.Tier> tiers = new ArrayList<>();
+
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        for (Network network : vpcNetworks) {
+            Long networkAclId = network.getNetworkACLId();
+            NetworkACLVO networkAcl = _networkACLDao.findById(networkAclId);
+
+            List<OvsVpcRoutingPolicyConfigCommand.AclItem> aclItems = new ArrayList<>();
+            List<NetworkACLItemVO> aclItemVos = _networkACLItemDao.listByACL(networkAclId);
+            for (NetworkACLItemVO aclItem : aclItemVos) {
+                String[] sourceCidrs = aclItem.getSourceCidrList().toArray(new String[aclItem.getSourceCidrList().size()]);
+                aclItems.add(new OvsVpcRoutingPolicyConfigCommand.AclItem(
+                        aclItem.getNumber(), aclItem.getUuid(), aclItem.getAction().name(),
+                        aclItem.getTrafficType().name(),
+                        aclItem.getSourcePortStart().toString(), aclItem.getSourcePortEnd().toString(),
+                        aclItem.getProtocol(), sourceCidrs));
+            }
+
+            OvsVpcRoutingPolicyConfigCommand.Acl acl = new OvsVpcRoutingPolicyConfigCommand.Acl(networkAcl.getUuid(),
+                    aclItems.toArray(new OvsVpcRoutingPolicyConfigCommand.AclItem[aclItems.size()]));
+            acls.add(acl);
+
+            OvsVpcRoutingPolicyConfigCommand.Tier tier = new OvsVpcRoutingPolicyConfigCommand.Tier(network.getUuid(),
+                    network.getCidr(), networkAcl.getUuid());
+            tiers.add(tier);
+        }
+
+        OvsVpcRoutingPolicyConfigCommand cmd = new OvsVpcRoutingPolicyConfigCommand(vpc.getUuid(), vpc.getCidr(),
+                acls.toArray(new OvsVpcRoutingPolicyConfigCommand.Acl[acls.size()]),
+                tiers.toArray(new OvsVpcRoutingPolicyConfigCommand.Tier[tiers.size()]));
+        return cmd;
+    }
+
+
+    public boolean sendVpcRoutingPolicyChangeUpdate(OvsVpcRoutingPolicyConfigCommand updateCmd, long hostId, String bridgeName) {
+        try {
+            s_logger.debug("Sending VPC routing policy change update to the host " + hostId);
+            updateCmd.setHostId(hostId);
+            updateCmd.setBridgeName(bridgeName);
+            Answer ans = _agentMgr.send(hostId, updateCmd);
+            if (ans.getResult()) {
+                s_logger.debug("Successfully updated the host " + hostId + " with latest VPC routing policies." );
+                return true;
+            }  else {
+                s_logger.debug("Failed to update the host " + hostId + " with latest routing policy." );
+                return false;
+            }
+        } catch (Exception e) {
+            s_logger.debug("Failed to updated the host " + hostId + " with latest routing policy." );
+            return false;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/780c8e7a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
index dbcc288..ac8a11d 100644
--- a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
+++ b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
@@ -312,7 +312,7 @@ class jsonLoader(object):
         return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v)
                                       in self.__dict__.iteritems()))
 
-def configure_bridge_for_topology(bridge, this_host_id, json_config):
+def configure_bridge_for_network_topology(bridge, this_host_id, json_config):
     vpconfig = jsonLoader(json.loads(json_config)).vpc
 
     if vpconfig is None:
@@ -372,4 +372,76 @@ def configure_bridge_for_topology(bridge, this_host_id, json_config):
                 # set DST MAC = VM's MAC, SRC MAC=tier gateway MAC and send to egress table
                 add_ip_lookup_table_entry(bridge, ip, network.gatewaymac, mac_addr)
 
-    return "SUCCESS: successfully configured bridge as per the VPC toplogy"
\ No newline at end of file
+    return "SUCCESS: successfully configured bridge as per the VPC topology"
+
+def get_acl(vpcconfig, required_acl_id):
+    acls = vpcconfig.acls
+    for acl in acls:
+        if acl.id == required_acl_id:
+            return acl
+    return None
+
+def configure_ovs_bridge_for_routing_policies(bridge, json_config):
+    vpconfig = jsonLoader(json.loads(json_config)).vpc
+
+    if vpconfig is None:
+        logging.debug("WARNING:Can't find VPC info in json config file")
+        return "FAILURE:IMPROPER_JSON_CONFG_FILE"
+
+    # First flush current egress ACL's before re-applying the ACL's
+    del_flows(bridge, table=3)
+
+    egress_rules_added = False
+    ingress_rules_added = False
+
+    tiers = vpconfig.tiers
+    for tier in tiers:
+        tier_cidr = tier.cidr
+        acl = get_acl(vpconfig, tier.aclid)
+        acl_items = acl.aclitems
+
+        for acl_item in acl_items:
+            number = acl_item.number
+            action = acl_item.action
+            direction = acl_item.direction
+            source_port_start = acl_item.sourceportstart
+            source_port_end = acl_item.sourceportend
+            protocol = acl_item.protocol
+            source_cidrs = acl_item.sourcecidrs
+            acl_priority = 1000 + number
+            for source_cidr in source_cidrs:
+                if direction is "ingress":
+                    ingress_rules_added = True
+                    # add flow rule to do action (allow/deny) for flows where source IP of the packet is in
+                    # source_cidr and destination ip is in tier_cidr
+                    port = source_port_start
+                    while (port < source_port_end):
+                        if action is "deny":
+                            add_flow(bridge, priority= acl_priority, table=5, nw_src=source_cidr, nw_dst=tier_cidr, tp_dst=port,
+                                     nw_proto=protocol, actions='drop')
+                        if action is "allow":
+                            add_flow(bridge, priority= acl_priority,table=5, nw_src=source_cidr, nw_dst=tier_cidr, tp_dst=port,
+                                     nw_proto=protocol, actions='resubmit(,1)')
+                        port = port + 1
+
+                elif direction in "egress":
+                    egress_rules_added = True
+                    # add flow rule to do action (allow/deny) for flows where destination IP of the packet is in
+                    # source_cidr and source ip is in tier_cidr
+                    port = source_port_start
+                    while (port < source_port_end):
+                        if action is "deny":
+                            add_flow(bridge, priority= acl_priority, table=5, nw_src=tier_cidr, nw_dst=source_cidr, tp_dst=port,
+                                     nw_proto=protocol, actions='drop')
+                        if action is "allow":
+                            add_flow(bridge, priority= acl_priority, table=5, nw_src=tier_cidr, nw_dst=source_cidr, tp_dst=port,
+                                     nw_proto=protocol, actions='resubmit(,1)')
+                        port = port + 1
+
+    if egress_rules_added is False:
+        # add a default rule in egress table to forward packet to L3 lookup table
+        add_flow(bridge, priority=0, table=3, actions='resubmit(,4)')
+
+    if ingress_rules_added is False:
+        # add a default rule in egress table drop packets
+        add_flow(bridge, priority=0, table=5, actions='drop')
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/780c8e7a/scripts/vm/hypervisor/xenserver/ovstunnel
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/ovstunnel b/scripts/vm/hypervisor/xenserver/ovstunnel
index 9ef0f7b..98a9d0b 100755
--- a/scripts/vm/hypervisor/xenserver/ovstunnel
+++ b/scripts/vm/hypervisor/xenserver/ovstunnel
@@ -184,7 +184,7 @@ def setup_ovs_bridge_for_distributed_routing(session, args):
         # add a default rule in L3 lookup table to forward packet to L2 lookup table
         lib.add_flow(bridge, priority=0, table=4, actions='resubmit(,1)')
 
-        # add a default rule in egress table to forward packet to L3 lookup table
+        # add a default rule in ingress table to drop in bound packets
         lib.add_flow(bridge, priority=0, table=5, actions='drop')
 
         result = "SUCCESS: successfully setup bridge with flow rules"
@@ -391,7 +391,14 @@ def configure_ovs_bridge_for_network_topology(session, args):
     json_config = args.pop("config")
     this_host_id = args.pop("host-id")
 
-    return lib.configure_bridge_for_topology(bridge, this_host_id, json_config)
+    return lib.configure_bridge_for_network_topology(bridge, this_host_id, json_config)
+
+@echo
+def configure_ovs_bridge_for_routing_policies(session, args):
+    bridge = args.pop("bridge")
+    json_config = args.pop("config")
+
+    return lib.configure_ovs_bridge_for_router_policies(bridge, json_config)
 
 if __name__ == "__main__":
     XenAPIPlugin.dispatch({"create_tunnel": create_tunnel,
@@ -401,4 +408,5 @@ if __name__ == "__main__":
                            "is_xcp": is_xcp,
                            "getLabel": getLabel,
                            "setup_ovs_bridge_for_distributed_routing": setup_ovs_bridge_for_distributed_routing,
-                           "configure_ovs_bridge_for_network_topology": configure_ovs_bridge_for_network_topology})
+                           "configure_ovs_bridge_for_network_topology": configure_ovs_bridge_for_network_topology,
+                           "configure_ovs_bridge_for_routing_policies": "configure_ovs_bridge_for_routing_policies"})

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/780c8e7a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java
index 82f1216..ad47df1 100644
--- a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java
@@ -23,6 +23,8 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 
 import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.PublishScope;
 import org.apache.log4j.Logger;
 
 import com.cloud.configuration.ConfigurationManager;
@@ -82,6 +84,8 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana
     EntityManager _entityMgr;
     @Inject
     VpcService _vpcSvc;
+    @Inject
+    MessageBus _messageBus;
 
     @Override
     public NetworkACL createNetworkACL(String name, String description, long vpcId, Boolean forDisplay) {
@@ -210,7 +214,13 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana
         if (_networkDao.update(network.getId(), network)) {
             s_logger.debug("Updated network: " + network.getId() + " with Network ACL Id: " + acl.getId() + ", Applying ACL items");
             //Apply ACL to network
-            return applyACLToNetwork(network.getId());
+            Boolean result = applyACLToNetwork(network.getId());
+            if (result) {
+                // public message on message bus, so that network elements implementing distributed routing capability
+                // can act on the event
+                _messageBus.publish(_name, "Network_ACL_Replaced", PublishScope.LOCAL, network);
+            }
+            return result;
         }
         return false;
     }


[23/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
findbugs: String for Service type mismatch (plus test for dummy  data)

Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/1075bed0
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/1075bed0
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/1075bed0

Branch: refs/heads/distributedrouter
Commit: 1075bed06c32f14152a8c5c7e534955392e5f662
Parents: 07102b4
Author: Daan Hoogland <da...@onecht.net>
Authored: Mon Mar 10 10:44:10 2014 +0100
Committer: Daan Hoogland <da...@onecht.net>
Committed: Mon Mar 10 10:44:10 2014 +0100

----------------------------------------------------------------------
 .../com/cloud/network/vpc/VpcManagerImpl.java   |  4 +-
 .../cloud/network/vpc/VpcManagerImplTest.java   | 53 ++++++++++++++++++++
 2 files changed, 55 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1075bed0/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index 403b95e..762cc6f 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -424,14 +424,14 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
         List<VpcOfferingServiceMapVO> map = _vpcOffSvcMapDao.listByVpcOffId(vpcOffId);
 
         for (VpcOfferingServiceMapVO instance : map) {
-            String service = instance.getService();
+            Service service = Service.getService(instance.getService());
             Set<Provider> providers;
             providers = serviceProviderMap.get(service);
             if (providers == null) {
                 providers = new HashSet<Provider>();
             }
             providers.add(Provider.getProvider(instance.getProvider()));
-            serviceProviderMap.put(Service.getService(service), providers);
+            serviceProviderMap.put(service, providers);
         }
 
         return serviceProviderMap;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1075bed0/server/test/com/cloud/network/vpc/VpcManagerImplTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/network/vpc/VpcManagerImplTest.java b/server/test/com/cloud/network/vpc/VpcManagerImplTest.java
new file mode 100644
index 0000000..a0237b4
--- /dev/null
+++ b/server/test/com/cloud/network/vpc/VpcManagerImplTest.java
@@ -0,0 +1,53 @@
+package com.cloud.network.vpc;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.cloudstack.context.CallContext;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import static org.mockito.Mockito.when;
+
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
+import com.cloud.user.Account;
+import com.cloud.user.User;
+
+public class VpcManagerImplTest {
+
+    @Mock
+    VpcOfferingServiceMapDao vpcOffSvcMapDao;
+    VpcManagerImpl manager;
+
+    @Before
+    public void setup()
+    {
+        MockitoAnnotations.initMocks(this);
+        manager = new VpcManagerImpl();
+        manager._vpcOffSvcMapDao = vpcOffSvcMapDao;
+    }
+    @Test
+    public void getVpcOffSvcProvidersMapForEmptyServiceTest() {
+        long vpcOffId = 1L;
+        List<VpcOfferingServiceMapVO> list = new ArrayList<VpcOfferingServiceMapVO>();
+        list.add(Mockito.mock(VpcOfferingServiceMapVO.class));
+        when(manager._vpcOffSvcMapDao.listByVpcOffId(vpcOffId)).thenReturn(list);
+
+        Map<Service, Set<Provider>> map = manager.getVpcOffSvcProvidersMap(vpcOffId);
+
+        assertNotNull(map);
+        assertEquals(map.size(),1);
+    }
+
+}


[45/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
mark VPC to be using distributed router if VPC offerign supports
distributedrouter capability.


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/beafb0ea
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/beafb0ea
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/beafb0ea

Branch: refs/heads/distributedrouter
Commit: beafb0ea2ba08367b70e2a46627cf5841494b812
Parents: c7529d8
Author: Murali Reddy <mu...@gmail.com>
Authored: Tue Mar 4 18:17:02 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Tue Mar 11 18:38:44 2014 +0530

----------------------------------------------------------------------
 api/src/com/cloud/network/vpc/Vpc.java                 |  6 ++++++
 .../apache/cloudstack/api/response/VpcResponse.java    |  9 +++++++++
 engine/schema/src/com/cloud/network/vpc/VpcVO.java     | 13 +++++++++++--
 server/src/com/cloud/api/ApiResponseHelper.java        |  1 +
 server/src/com/cloud/network/vpc/VpcManagerImpl.java   |  9 +++++----
 server/test/com/cloud/vpc/VpcApiUnitTest.java          |  2 +-
 server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java      |  4 ++--
 setup/db/db/schema-430to440.sql                        |  1 +
 8 files changed, 36 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/beafb0ea/api/src/com/cloud/network/vpc/Vpc.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/vpc/Vpc.java b/api/src/com/cloud/network/vpc/Vpc.java
index eb7e391..4bc8c98 100644
--- a/api/src/com/cloud/network/vpc/Vpc.java
+++ b/api/src/com/cloud/network/vpc/Vpc.java
@@ -73,4 +73,10 @@ public interface Vpc extends ControlledEntity, Identity, InternalIdentity {
     boolean isRestartRequired();
 
     boolean isDisplay();
+
+    /**
+     *
+     * @return true if VPC is configured to use distributed router to provides one-hop forwarding and hypervisor based ACL
+     */
+    boolean usesDistributedRouter();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/beafb0ea/api/src/org/apache/cloudstack/api/response/VpcResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/VpcResponse.java b/api/src/org/apache/cloudstack/api/response/VpcResponse.java
index eeafb40..e3b44f2 100644
--- a/api/src/org/apache/cloudstack/api/response/VpcResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/VpcResponse.java
@@ -111,6 +111,11 @@ public class VpcResponse extends BaseResponse implements ControlledEntityRespons
     @Param(description = "is vpc for display to the regular user", since = "4.4", authorized = {RoleType.Admin})
     private Boolean forDisplay;
 
+
+    @SerializedName(ApiConstants.DISTRIBUTED_VPC_ROUTER)
+    @Param(description = "is VPC uses distributed router for one hop forwarding and host based network ACL's")
+    private boolean usesDistributedRouter;
+
     public void setId(String id) {
         this.id = id;
     }
@@ -199,4 +204,8 @@ public class VpcResponse extends BaseResponse implements ControlledEntityRespons
     public void setForDisplay(Boolean forDisplay) {
         this.forDisplay = forDisplay;
     }
+
+    public void setUsesDistributedRouter(Boolean usesDistributedRouter) {
+        this.usesDistributedRouter = usesDistributedRouter;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/beafb0ea/engine/schema/src/com/cloud/network/vpc/VpcVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/vpc/VpcVO.java b/engine/schema/src/com/cloud/network/vpc/VpcVO.java
index d1cfd7c..5cf8aed 100644
--- a/engine/schema/src/com/cloud/network/vpc/VpcVO.java
+++ b/engine/schema/src/com/cloud/network/vpc/VpcVO.java
@@ -81,11 +81,15 @@ public class VpcVO implements Vpc {
     @Column(name = "display", updatable = true, nullable = false)
     protected boolean display = true;
 
+    @Column(name="uses_distributed_router")
+    boolean usesDistributedRouter = false;
+
     public VpcVO() {
         uuid = UUID.randomUUID().toString();
     }
 
-    public VpcVO(long zoneId, String name, String displayText, long accountId, long domainId, long vpcOffId, String cidr, String networkDomain) {
+    public VpcVO(long zoneId, String name, String displayText, long accountId, long domainId, long vpcOffId, String cidr,
+                 String networkDomain, boolean useDistributedRouter) {
         this.zoneId = zoneId;
         this.name = name;
         this.displayText = displayText;
@@ -95,7 +99,8 @@ public class VpcVO implements Vpc {
         uuid = UUID.randomUUID().toString();
         state = State.Enabled;
         this.networkDomain = networkDomain;
-        vpcOfferingId = vpcOffId;
+        this.vpcOfferingId = vpcOffId;
+        this.usesDistributedRouter = useDistributedRouter;
     }
 
     @Override
@@ -200,5 +205,9 @@ public class VpcVO implements Vpc {
     @Override
     public IAMEntityType getEntityType() {
         return IAMEntityType.Vpc;
+
+    @Override
+    public boolean usesDistributedRouter() {
+        return usesDistributedRouter;
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/beafb0ea/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index 73c9c6b..fe7fe55 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -2791,6 +2791,7 @@ public class ApiResponseHelper implements ResponseGenerator {
         response.setRestartRequired(vpc.isRestartRequired());
         response.setNetworkDomain(vpc.getNetworkDomain());
         response.setForDisplay(vpc.isDisplay());
+        response.setUsesDistributedRouter(vpc.usesDistributedRouter());
 
         Map<Service, Set<Provider>> serviceProviderMap = ApiDBUtils.listVpcOffServices(vpc.getVpcOfferingId());
         List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/beafb0ea/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index 5abc5e8..f4f8772 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -728,13 +728,13 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
                 networkDomain = "cs" + Long.toHexString(owner.getId()) + NetworkOrchestrationService.GuestDomainSuffix.valueIn(zoneId);
             }
         }
-
-        return createVpc(zoneId, vpcOffId, owner, vpcName, displayText, cidr, networkDomain, displayVpc);
+        boolean useDistributedRouter = vpcOff.supportsDistributedRouter();
+        return createVpc(zoneId, vpcOffId, owner, vpcName, displayText, cidr, networkDomain, displayVpc, useDistributedRouter);
     }
 
     @DB
     protected Vpc createVpc(final long zoneId, final long vpcOffId, final Account vpcOwner, final String vpcName, final String displayText, final String cidr,
-            final String networkDomain, final Boolean displayVpc) {
+            final String networkDomain, final Boolean displayVpc, final boolean useDistributedRouter) {
 
         //Validate CIDR
         if (!NetUtils.isValidCIDR(cidr)) {
@@ -756,7 +756,8 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
         return Transaction.execute(new TransactionCallback<VpcVO>() {
             @Override
             public VpcVO doInTransaction(TransactionStatus status) {
-                VpcVO vpc = new VpcVO(zoneId, vpcName, displayText, vpcOwner.getId(), vpcOwner.getDomainId(), vpcOffId, cidr, networkDomain);
+                VpcVO vpc = new VpcVO(zoneId, vpcName, displayText, vpcOwner.getId(), vpcOwner.getDomainId(), vpcOffId,
+                        cidr, networkDomain, useDistributedRouter);
                 if (displayVpc != null) {
                     vpc.setDisplay(displayVpc);
                 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/beafb0ea/server/test/com/cloud/vpc/VpcApiUnitTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/VpcApiUnitTest.java b/server/test/com/cloud/vpc/VpcApiUnitTest.java
index bc982a9..5e28374 100644
--- a/server/test/com/cloud/vpc/VpcApiUnitTest.java
+++ b/server/test/com/cloud/vpc/VpcApiUnitTest.java
@@ -85,7 +85,7 @@ public class VpcApiUnitTest extends TestCase {
     public void validateNtwkOffForVpc() {
         //validate network offering
         //1) correct network offering
-        VpcVO vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain");
+        VpcVO vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false);
         boolean result = false;
         try {
             _vpcService.validateNtwkOffForNtwkInVpc(2L, 1, "0.0.0.0", "111-", vo, "10.1.1.1", new AccountVO(), null);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/beafb0ea/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java b/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java
index 7a0c7a0..e1a6ac2 100644
--- a/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java
+++ b/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java
@@ -98,9 +98,9 @@ public class MockVpcDaoImpl extends GenericDaoBase<VpcVO, Long> implements VpcDa
     public VpcVO findById(Long id) {
         VpcVO vo = null;
         if (id.longValue() == 1) {
-            vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain");
+            vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false);
         } else if (id.longValue() == 2) {
-            vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain");
+            vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false);
             vo.setState(State.Inactive);
         }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/beafb0ea/setup/db/db/schema-430to440.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql
index ff9c47f..530ccbc 100644
--- a/setup/db/db/schema-430to440.sql
+++ b/setup/db/db/schema-430to440.sql
@@ -612,3 +612,4 @@ CREATE TABLE `cloud`.`vgpu_types` (
 ) ENGINE=InnoDB CHARSET=utf8;
 
 ALTER TABLE `cloud`.`vpc_offerings` ADD COLUMN supports_distributed_router boolean default false;
+ALTER TABLE `cloud`.`vpc` ADD COLUMN uses_distributed_router  boolean default false;


[39/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
CLOUDSTACK-4760 : Enabling GPU support for XenServer.
CLOUDSTACK-4762 : Enabling VGPU support for XenServer.

This feature is to enable the GPU-passthrough and vGPU functionality,
with the help of this feature, admins/users will be able to leverage
the GPU graphics unit power by deploying a virtul machine with GPU or
vGPU support or by changing the service offering of an existing VM
at any later point of time. There GPU/vGPU enabled VMs are able to run
graphical applications.
For now, this feature is only supported with XenServer hypervisor but
can be extended to add the support of other hypervisors.


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c7d31fe2
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c7d31fe2
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c7d31fe2

Branch: refs/heads/distributedrouter
Commit: c7d31fe288b13ff4f0f046f83f9eb4a9c2bf06c5
Parents: 540d020
Author: Sanjay Tripathi <sa...@citrix.com>
Authored: Thu Feb 6 15:08:53 2014 +0530
Committer: Sanjay Tripathi <sa...@citrix.com>
Committed: Tue Mar 11 15:44:51 2014 +0530

----------------------------------------------------------------------
 api/src/com/cloud/agent/api/to/GPUDeviceTO.java |  56 +++++
 .../cloud/agent/api/to/VirtualMachineTO.java    |   9 +
 api/src/com/cloud/gpu/GPU.java                  |  49 ++++
 .../org/apache/cloudstack/api/ApiConstants.java |   5 +
 .../offering/CreateServiceOfferingCmd.java      |  18 +-
 .../cloudstack/api/response/GpuResponse.java    |  46 ++++
 .../cloudstack/api/response/HostResponse.java   |   8 +
 .../cloudstack/api/response/UserVmResponse.java |  10 +
 .../cloudstack/api/response/VgpuResponse.java   |  52 +++++
 .../com/cloud/agent/api/GetGPUStatsAnswer.java  |  36 +++
 .../com/cloud/agent/api/GetGPUStatsCommand.java |  47 ++++
 .../cloud/agent/api/StartupRoutingCommand.java  |   9 +
 core/src/com/cloud/agent/api/StopCommand.java   |   9 +
 .../src/com/cloud/resource/ResourceManager.java |  41 ++++
 .../com/cloud/vm/VirtualMachineManagerImpl.java |  18 ++
 .../spring-engine-schema-core-daos-context.xml  |   2 +
 .../src/com/cloud/gpu/HostGpuGroupsVO.java      |  70 ++++++
 .../schema/src/com/cloud/gpu/VGPUTypesVO.java   |  82 +++++++
 .../src/com/cloud/gpu/dao/HostGpuGroupsDao.java |  60 +++++
 .../com/cloud/gpu/dao/HostGpuGroupsDaoImpl.java |  94 ++++++++
 .../src/com/cloud/gpu/dao/VGPUTypesDao.java     |  48 ++++
 .../src/com/cloud/gpu/dao/VGPUTypesDaoImpl.java |  95 ++++++++
 engine/schema/src/com/cloud/host/HostVO.java    |  13 ++
 .../src/com/cloud/host/dao/HostDaoImpl.java     |  18 ++
 .../cloud/service/ServiceOfferingDetailsVO.java |   4 +
 .../xen/resource/CitrixResourceBase.java        | 108 +++++++++
 .../allocator/impl/FirstFitAllocator.java       |  17 +-
 server/src/com/cloud/api/ApiDBUtils.java        |  30 +++
 .../cloud/api/query/dao/HostJoinDaoImpl.java    |  25 ++
 .../cloud/api/query/dao/UserVmJoinDaoImpl.java  |   6 +
 .../configuration/ConfigurationManagerImpl.java |  54 ++++-
 .../deploy/DeploymentPlanningManagerImpl.java   |  14 +-
 .../cloud/hypervisor/HypervisorGuruBase.java    |  15 ++
 .../cloud/network/NetworkUsageManagerImpl.java  |   4 +
 .../com/cloud/resource/ResourceManagerImpl.java |  97 +++++++-
 .../com/cloud/server/ManagementServerImpl.java  |  12 +
 server/src/com/cloud/server/StatsCollector.java |  21 ++
 .../com/cloud/storage/VolumeApiServiceImpl.java |   8 +
 server/src/com/cloud/vm/UserVmManagerImpl.java  |  10 +
 .../cloud/resource/MockResourceManagerImpl.java |  31 +++
 .../vm/DeploymentPlanningManagerImplTest.java   |  12 +
 server/test/resources/createNetworkOffering.xml |   4 +-
 setup/db/db/schema-430to440.sql                 |  18 ++
 .../smoke/test_deploy_vgpu_enabled_vm.py        | 227 +++++++++++++++++++
 tools/marvin/marvin/integration/lib/base.py     |   3 +
 ui/scripts/configuration.js                     |  73 ++++++
 ui/scripts/instances.js                         |   4 +-
 47 files changed, 1671 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/api/src/com/cloud/agent/api/to/GPUDeviceTO.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/to/GPUDeviceTO.java b/api/src/com/cloud/agent/api/to/GPUDeviceTO.java
new file mode 100644
index 0000000..8bc9e52
--- /dev/null
+++ b/api/src/com/cloud/agent/api/to/GPUDeviceTO.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 com.cloud.agent.api.to;
+
+import java.util.HashMap;
+
+public class GPUDeviceTO {
+
+    private String gpuGroup;
+    private String vgpuType;
+    private HashMap<String, HashMap<String, Long>> groupDetails = new HashMap<String, HashMap<String, Long>>();
+
+    public GPUDeviceTO( String gpuGroup, String vgpuType, HashMap<String, HashMap<String, Long>> groupDetails) {
+        this.gpuGroup = gpuGroup;
+        this.vgpuType = vgpuType;
+        this.groupDetails = groupDetails;
+    }
+
+    public String getGpuGroup() {
+        return gpuGroup;
+    }
+
+    public String getVgpuType() {
+        return vgpuType;
+    }
+
+    public void setGpuGroup(String gpuGroup) {
+        this.gpuGroup = gpuGroup;
+    }
+
+    public void setVgpuType(String vgpuType) {
+        this.vgpuType = vgpuType;
+    }
+
+    public HashMap<String, HashMap<String, Long>> getGroupDetails() {
+        return groupDetails;
+    }
+
+    public void setGroupDetails(HashMap<String, HashMap<String, Long>> groupDetails) {
+        this.groupDetails = groupDetails;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/api/src/com/cloud/agent/api/to/VirtualMachineTO.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java
index bed3e1d..bbd8385 100644
--- a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java
+++ b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java
@@ -60,6 +60,7 @@ public class VirtualMachineTO {
 
     DiskTO[] disks;
     NicTO[] nics;
+    GPUDeviceTO gpuDevice;
 
     public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer speed, long minRam, long maxRam, BootloaderType bootloader,
             String os, boolean enableHA, boolean limitCpuUse, String vncPassword) {
@@ -266,4 +267,12 @@ public class VirtualMachineTO {
         this.uuid = uuid;
     }
 
+    public GPUDeviceTO getGpuDevice() {
+        return gpuDevice;
+    }
+
+    public void setGpuDevice(GPUDeviceTO gpuDevice) {
+        this.gpuDevice = gpuDevice;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/api/src/com/cloud/gpu/GPU.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/gpu/GPU.java b/api/src/com/cloud/gpu/GPU.java
new file mode 100644
index 0000000..0eb4667
--- /dev/null
+++ b/api/src/com/cloud/gpu/GPU.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 com.cloud.gpu;
+
+
+public class GPU {
+
+    public enum Keys {
+        pciDevice,
+        vgpuType
+    }
+    public enum Type {
+        GPU_Passthrough,
+        VGPU
+    }
+
+    public enum vGPUType {
+        GRID_K100("GRID K100"),
+        GRID_K140Q("GRID K140Q"),
+        GRID_K200("GRID K200"),
+        GRID_K240Q("GRID K240Q"),
+        GRID_K260("GRID K260Q"),
+        passthrough("passthrough");
+
+        private String type;
+
+        vGPUType(String type) {
+            this.type = type;
+        }
+
+        public String getType() {
+            return type;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index f0de48e..0a3fafd 100755
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -581,6 +581,11 @@ public class ApiConstants {
     public static final String PASSIVE = "passive";
     public static final String VERSION = "version";
     public static final String START = "start";
+    public static final String GPUGROUP = "gpugroup";
+    public static final String GPUGROUPNAME = "gpugroupname";
+    public static final String VGPU = "vgpu";
+    public static final String VGPUTYPE = "vgputype";
+    public static final String REMAININGCAPACITY = "remainingcapacity";
 
     public enum HostDetails {
         all, capacity, events, stats, min;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
index 4143c2e..42bd95d 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
@@ -17,6 +17,8 @@
 package org.apache.cloudstack.api.command.admin.offering;
 
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
 
 import org.apache.log4j.Logger;
@@ -206,13 +208,17 @@ public class CreateServiceOfferingCmd extends BaseCmd {
     }
 
     public Map<String, String> getDetails() {
-        if (details == null || details.isEmpty()) {
-            return null;
+        Map<String, String> detailsMap = null;
+        if (details != null && !details.isEmpty()) {
+            detailsMap = new HashMap<String, String>();
+            Collection<?> props = details.values();
+            Iterator<?> iter = props.iterator();
+            while (iter.hasNext()) {
+                HashMap<String, String> detail = (HashMap<String, String>) iter.next();
+                detailsMap.putAll(detail);
+            }
         }
-
-        Collection<String> paramsCollection = details.values();
-        Map<String, String> params = (Map<String, String>)(paramsCollection.toArray())[0];
-        return params;
+        return detailsMap;
     }
 
     public Long getBytesReadRate() {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/api/src/org/apache/cloudstack/api/response/GpuResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/GpuResponse.java b/api/src/org/apache/cloudstack/api/response/GpuResponse.java
new file mode 100644
index 0000000..b655749
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/response/GpuResponse.java
@@ -0,0 +1,46 @@
+// 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 java.util.List;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+
+import com.cloud.serializer.Param;
+
+public class GpuResponse extends BaseResponse {
+
+    @SerializedName(ApiConstants.GPUGROUPNAME)
+    @Param(description = "GPU cards present in the host")
+    private String gpuGroupName;
+
+    @SerializedName(ApiConstants.VGPU)
+    @Param(description = "the list of enabled vGPUs", responseObject = VgpuResponse.class)
+    private List<VgpuResponse> vgpu;
+
+    public void setGpuGroupName(String gpuGroupName) {
+        this.gpuGroupName = gpuGroupName;
+    }
+
+    public void setVgpu(List<VgpuResponse> vgpu) {
+        this.vgpu = vgpu;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/api/src/org/apache/cloudstack/api/response/HostResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/HostResponse.java b/api/src/org/apache/cloudstack/api/response/HostResponse.java
index e2d8eb5..1fbc668 100644
--- a/api/src/org/apache/cloudstack/api/response/HostResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/HostResponse.java
@@ -17,6 +17,7 @@
 package org.apache.cloudstack.api.response;
 
 import java.util.Date;
+import java.util.List;
 
 import com.google.gson.annotations.SerializedName;
 
@@ -135,6 +136,10 @@ public class HostResponse extends BaseResponse {
     @Param(description = "the amount of the host's memory currently used")
     private Long memoryUsed;
 
+    @SerializedName(ApiConstants.GPUGROUP)
+    @Param(description = "GPU cards present in the host", responseObject = GpuResponse.class)
+    private List<GpuResponse> gpuGroup;
+
     @SerializedName("disksizetotal")
     @Param(description = "the total disk size of the host")
     private Long diskSizeTotal;
@@ -320,6 +325,9 @@ public class HostResponse extends BaseResponse {
         this.memoryUsed = memoryUsed;
     }
 
+    public void setGpuGroups(List<GpuResponse> gpuGroup) {
+        this.gpuGroup = gpuGroup;
+    }
     public void setDiskSizeTotal(Long diskSizeTotal) {
         this.diskSizeTotal = diskSizeTotal;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/api/src/org/apache/cloudstack/api/response/UserVmResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java
index 84d532b..d6ce84f 100644
--- a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java
@@ -164,6 +164,10 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp
     @Param(description = "the memory allocated for the virtual machine")
     private Integer memory;
 
+    @SerializedName(ApiConstants.VGPU)
+    @Param(description = "the vgpu type used by the virtual machine")
+    private String vgpu;
+
     @SerializedName("cpuused")
     @Param(description = "the amount of the vm's CPU currently used")
     private String cpuUsed;
@@ -420,6 +424,9 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp
         return memory;
     }
 
+    public String getVgpu() {
+        return vgpu;
+    }
     public String getCpuUsed() {
         return cpuUsed;
     }
@@ -643,6 +650,9 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp
         this.memory = memory;
     }
 
+    public void setVgpu(String vgpu) {
+        this.vgpu = vgpu;
+    }
     public void setCpuUsed(String cpuUsed) {
         this.cpuUsed = cpuUsed;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/api/src/org/apache/cloudstack/api/response/VgpuResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/VgpuResponse.java b/api/src/org/apache/cloudstack/api/response/VgpuResponse.java
new file mode 100644
index 0000000..17e194b
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/response/VgpuResponse.java
@@ -0,0 +1,52 @@
+// 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.google.gson.annotations.SerializedName;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+
+import com.cloud.serializer.Param;
+
+public class VgpuResponse extends BaseResponse {
+
+    @SerializedName(ApiConstants.VGPUTYPE)
+    @Param(description = "Model Name of vGPU")
+    private String name;
+
+    @SerializedName(ApiConstants.REMAININGCAPACITY)
+    @Param(description = "No. of more VMs can be deployped with this vGPU type")
+    private Long capacity;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Long getCapacity() {
+        return capacity;
+    }
+
+    public void setCapacity(Long capacity) {
+        this.capacity = capacity;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/core/src/com/cloud/agent/api/GetGPUStatsAnswer.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/GetGPUStatsAnswer.java b/core/src/com/cloud/agent/api/GetGPUStatsAnswer.java
new file mode 100644
index 0000000..566eed5
--- /dev/null
+++ b/core/src/com/cloud/agent/api/GetGPUStatsAnswer.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 com.cloud.agent.api;
+
+import java.util.HashMap;
+
+import com.cloud.agent.api.LogLevel.Log4jLevel;
+
+@LogLevel(Log4jLevel.Trace)
+public class GetGPUStatsAnswer extends Answer {
+
+    private HashMap<String, HashMap<String, Long>> groupDetails;
+
+    public GetGPUStatsAnswer(GetGPUStatsCommand cmd, HashMap<String, HashMap<String, Long>> groupDetails) {
+        super(cmd);
+        this.groupDetails = groupDetails;
+    }
+
+    public HashMap<String, HashMap<String, Long>> getGroupDetails() {
+        return this.groupDetails;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/core/src/com/cloud/agent/api/GetGPUStatsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/GetGPUStatsCommand.java b/core/src/com/cloud/agent/api/GetGPUStatsCommand.java
new file mode 100644
index 0000000..047f562
--- /dev/null
+++ b/core/src/com/cloud/agent/api/GetGPUStatsCommand.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 com.cloud.agent.api;
+
+import com.cloud.agent.api.LogLevel.Log4jLevel;
+
+@LogLevel(Log4jLevel.Trace)
+public class GetGPUStatsCommand extends Command
+{
+    String hostGuid;
+    String hostName;
+
+    protected GetGPUStatsCommand() {
+    }
+
+    public GetGPUStatsCommand(String hostGuid, String hostName) {
+        this.hostGuid = hostGuid;
+        this.hostName = hostName;
+    }
+
+    public String getHostGuid(){
+        return this.hostGuid;
+    }
+
+    public String getHostName(){
+        return this.hostName;
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/core/src/com/cloud/agent/api/StartupRoutingCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/StartupRoutingCommand.java b/core/src/com/cloud/agent/api/StartupRoutingCommand.java
index 8c0eb8a..dc37113 100755
--- a/core/src/com/cloud/agent/api/StartupRoutingCommand.java
+++ b/core/src/com/cloud/agent/api/StartupRoutingCommand.java
@@ -70,6 +70,7 @@ public class StartupRoutingCommand extends StartupCommand {
     HypervisorType hypervisorType;
     Map<String, String> hostDetails; //stuff like host os, cpu capabilities
     String hypervisorVersion;
+    HashMap<String, HashMap<String, Long>> groupDetails = new HashMap<String, HashMap<String, Long>>();
 
     public StartupRoutingCommand() {
         super(Host.Type.Routing);
@@ -244,4 +245,12 @@ public class StartupRoutingCommand extends StartupCommand {
     public void setHostVmStateReport(Map<String, HostVmStateReportEntry> hostVmStateReport) {
         this._hostVmStateReport = hostVmStateReport;
     }
+
+    public  HashMap<String, HashMap<String, Long>> getGpuGroupDetails() {
+        return groupDetails;
+    }
+
+    public void setGpuGroupDetails(HashMap<String, HashMap<String, Long>> groupDetails) {
+        this.groupDetails = groupDetails;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/core/src/com/cloud/agent/api/StopCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/StopCommand.java b/core/src/com/cloud/agent/api/StopCommand.java
index 6a29aa6..00d7f5f 100755
--- a/core/src/com/cloud/agent/api/StopCommand.java
+++ b/core/src/com/cloud/agent/api/StopCommand.java
@@ -16,6 +16,7 @@
 // under the License.
 package com.cloud.agent.api;
 
+import com.cloud.agent.api.to.GPUDeviceTO;
 import com.cloud.vm.VirtualMachine;
 
 public class StopCommand extends RebootCommand {
@@ -23,6 +24,7 @@ public class StopCommand extends RebootCommand {
     private String urlPort = null;
     private String publicConsoleProxyIpAddress = null;
     boolean executeInSequence = false;
+    private GPUDeviceTO gpuDevice;
 
     protected StopCommand() {
     }
@@ -62,4 +64,11 @@ public class StopCommand extends RebootCommand {
         return this.publicConsoleProxyIpAddress;
     }
 
+    public GPUDeviceTO getGpuDevice() {
+        return this.gpuDevice;
+    }
+
+    public void setGpuDevice(GPUDeviceTO gpuDevice) {
+        this.gpuDevice = gpuDevice;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/engine/components-api/src/com/cloud/resource/ResourceManager.java
----------------------------------------------------------------------
diff --git a/engine/components-api/src/com/cloud/resource/ResourceManager.java b/engine/components-api/src/com/cloud/resource/ResourceManager.java
index 95fb385..5a9bddb 100755
--- a/engine/components-api/src/com/cloud/resource/ResourceManager.java
+++ b/engine/components-api/src/com/cloud/resource/ResourceManager.java
@@ -17,15 +17,18 @@
 // under the License.
 package com.cloud.resource;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.to.GPUDeviceTO;
 import com.cloud.dc.DataCenterVO;
 import com.cloud.dc.HostPodVO;
 import com.cloud.dc.PodCluster;
 import com.cloud.exception.AgentUnavailableException;
+import com.cloud.gpu.HostGpuGroupsVO;
 import com.cloud.host.Host;
 import com.cloud.host.Host.Type;
 import com.cloud.host.HostStats;
@@ -137,4 +140,42 @@ public interface ResourceManager extends ResourceService {
      * @return
      */
     List<HostVO> listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Long podId, long dcId);
+
+    /**
+     * Check if host has GPU devices available
+     * @param hostId the host to be checked
+     * @param vgpuType the VGPU type
+     * @return true when the host has the capacity with given VGPU type
+     */
+    boolean isGPUDeviceAvailable(long hostId, String vgpuType);
+
+    /**
+     * Get available GPU device
+     * @param hostId the host to be checked
+     * @param vgpuType the VGPU type
+     * @return GPUDeviceTO[]
+     */
+    GPUDeviceTO getGPUDevice(long hostId, String vgpuType);
+
+    /**
+     * Return listof available GPU devices
+     * @param hostId, the host to be checked
+     * @param vgpuType the VGPU type
+     * @return List of HostGpuGroupsVO.
+     */
+    List<HostGpuGroupsVO> listAvailableGPUDevice(long hostId, String vgpuType);
+
+    /**
+     * Update GPU device details (post VM deployment)
+     * @param hostId, the dest host Id
+     * @param groupDetails, capacity of GPU group.
+     */
+    void updateGPUDetails(long hostId, HashMap<String, HashMap<String, Long>> groupDetails);
+
+    /**
+     * Get GPU details for a host
+     * @param host, the Host object
+     * @return Details of groupNames and enabled VGPU type with remaining capacity.
+     */
+    HashMap<String, HashMap<String, Long>> getGPUStatistics(HostVO host);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
index 8edbb76..609aefa 100755
--- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -103,6 +103,7 @@ import com.cloud.agent.api.StopCommand;
 import com.cloud.agent.api.UnPlugNicAnswer;
 import com.cloud.agent.api.UnPlugNicCommand;
 import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.GPUDeviceTO;
 import com.cloud.agent.api.to.NicTO;
 import com.cloud.agent.api.to.VirtualMachineTO;
 import com.cloud.agent.manager.Commands;
@@ -139,6 +140,7 @@ import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.OperationTimedoutException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.exception.StorageUnavailableException;
+import com.cloud.gpu.dao.VGPUTypesDao;
 import com.cloud.ha.HighAvailabilityManager;
 import com.cloud.ha.HighAvailabilityManager.WorkType;
 import com.cloud.host.Host;
@@ -276,6 +278,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     @Inject
     protected AffinityGroupVMMapDao _affinityGroupVMMapDao;
     @Inject
+    protected VGPUTypesDao _vgpuTypesDao;
+    @Inject
     protected EntityManager _entityMgr;
 
     @Inject
@@ -1026,6 +1030,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
                                 throw new ConcurrentOperationException("Unable to transition to a new state.");
                             }
 
+                            // Update GPU device capacity
+                            GPUDeviceTO gpuDevice = startAnswer.getVirtualMachine().getGpuDevice();
+                            if (gpuDevice != null) {
+                                _resourceMgr.updateGPUDetails(destHostId, gpuDevice.getGroupDetails());
+                            }
+
                             startedVm = vm;
                             if (s_logger.isDebugEnabled()) {
                                 s_logger.debug("Start completed for VM " + vm);
@@ -1221,6 +1231,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
                     }
                 }
 
+                GPUDeviceTO gpuDevice = stop.getGpuDevice();
+                if (gpuDevice != null) {
+                    _resourceMgr.updateGPUDetails(vm.getHostId(), gpuDevice.getGroupDetails());
+                }
                 if (!answer.getResult()) {
                     s_logger.debug("Unable to stop VM due to " + answer.getDetails());
                     return false;
@@ -1483,6 +1497,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
                     throw new CloudRuntimeException("Unable to stop the virtual machine due to " + answer.getDetails());
                 }
                 vmGuru.finalizeStop(profile, answer);
+                GPUDeviceTO gpuDevice = stop.getGpuDevice();
+                if (gpuDevice != null) {
+                    _resourceMgr.updateGPUDetails(vm.getHostId(), gpuDevice.getGroupDetails());
+                }
             } else {
                 throw new CloudRuntimeException("Invalid answer received in response to a StopCommand on " + vm.instanceName);
             }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
----------------------------------------------------------------------
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
index 08efb83..765d86c 100644
--- 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
@@ -316,6 +316,8 @@
   <bean id="networkOfferingDetailsDaoImpl" class="com.cloud.offerings.dao.NetworkOfferingDetailsDaoImpl" />
   <bean id="serviceOfferingDetailsDaoImpl" class="com.cloud.service.dao.ServiceOfferingDetailsDaoImpl"/>
   <bean id="networkDetailsDaoImpl" class="com.cloud.network.dao.NetworkDetailsDaoImpl" />
+  <bean id="hostGpuGroupsDaoImpl" class="com.cloud.gpu.dao.HostGpuGroupsDaoImpl" />
+  <bean id="vGPUTypesDaoImpl" class="com.cloud.gpu.dao.VGPUTypesDaoImpl" />
   <bean id="AffinityGroupDaoImpl" class="org.apache.cloudstack.affinity.dao.AffinityGroupDaoImpl" />
   <bean id="AffinityGroupVMMapDaoImpl" class="org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDaoImpl" />
   <bean id="AffinityGroupDomainMapDaoImpl" class="org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDaoImpl" />

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/engine/schema/src/com/cloud/gpu/HostGpuGroupsVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/gpu/HostGpuGroupsVO.java b/engine/schema/src/com/cloud/gpu/HostGpuGroupsVO.java
new file mode 100644
index 0000000..1c186a1
--- /dev/null
+++ b/engine/schema/src/com/cloud/gpu/HostGpuGroupsVO.java
@@ -0,0 +1,70 @@
+// 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.gpu;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.apache.cloudstack.api.InternalIdentity;
+
+@Entity
+@Table(name="host_gpu_groups")
+public class HostGpuGroupsVO implements InternalIdentity {
+    @Id
+    @GeneratedValue(strategy=GenerationType.IDENTITY)
+    @Column(name="id")
+    private long id;
+
+    @Column(name="group_name")
+    private String groupName;
+
+    @Column(name="host_id")
+    private long hostId;
+
+    protected HostGpuGroupsVO() {
+    }
+
+    public HostGpuGroupsVO(long hostId, String groupName) {
+        this.hostId = hostId;
+        this.groupName = groupName;
+    }
+
+    public long getHostId() {
+        return hostId;
+    }
+
+    public void setHostId(long hostId) {
+        this.hostId = hostId;
+    }
+
+    public String getGroupName() {
+        return groupName;
+    }
+
+    public void setGroupName(String groupName) {
+        this.groupName = groupName;
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/engine/schema/src/com/cloud/gpu/VGPUTypesVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/gpu/VGPUTypesVO.java b/engine/schema/src/com/cloud/gpu/VGPUTypesVO.java
new file mode 100644
index 0000000..586a0c9
--- /dev/null
+++ b/engine/schema/src/com/cloud/gpu/VGPUTypesVO.java
@@ -0,0 +1,82 @@
+// 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.gpu;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.apache.cloudstack.api.InternalIdentity;
+
+@Entity
+@Table(name="vgpu_types")
+public class VGPUTypesVO implements InternalIdentity {
+    @Id
+    @GeneratedValue(strategy=GenerationType.IDENTITY)
+    @Column(name="id")
+    private long id;
+
+    @Column(name="vgpu_type")
+    private String vgpuType;
+
+    @Column(name="gpu_group_id")
+    private long gpuGroupId;
+
+    @Column(name="remaining_vm_capacity")
+    private long remainingCapacity;
+
+    protected VGPUTypesVO() {
+    }
+
+    public VGPUTypesVO(String vgpuType, long gpuGroupId, long remainingCapacity) {
+        this.vgpuType = vgpuType;
+        this.gpuGroupId = gpuGroupId;
+        this.remainingCapacity = remainingCapacity;
+    }
+
+    public String getVgpuType() {
+        return vgpuType;
+    }
+
+    public void setVgpuType(String vgpuType) {
+        this.vgpuType = vgpuType;
+    }
+
+    public long getGpuGroupId() {
+        return gpuGroupId;
+    }
+
+    public void setGpuGroupId(long gpuGroupId) {
+        this.gpuGroupId = gpuGroupId;
+    }
+
+    public long getRemainingCapacity() {
+        return remainingCapacity;
+    }
+
+    public void setRemainingCapacity(long remainingCapacity) {
+        this.remainingCapacity = remainingCapacity;
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/engine/schema/src/com/cloud/gpu/dao/HostGpuGroupsDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/gpu/dao/HostGpuGroupsDao.java b/engine/schema/src/com/cloud/gpu/dao/HostGpuGroupsDao.java
new file mode 100644
index 0000000..5864144
--- /dev/null
+++ b/engine/schema/src/com/cloud/gpu/dao/HostGpuGroupsDao.java
@@ -0,0 +1,60 @@
+// 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.gpu.dao;
+
+import java.util.List;
+
+import com.cloud.gpu.HostGpuGroupsVO;
+import com.cloud.utils.db.GenericDao;
+
+public interface HostGpuGroupsDao extends GenericDao<HostGpuGroupsVO, Long> {
+
+    /**
+     * Find host device by hostId and PCI ID
+     * @param hostId the host
+     * @param groupName GPU group
+     * @return HostGpuGroupsVO
+     */
+    HostGpuGroupsVO findByHostIdGroupName(long hostId, String groupName);
+
+    /**
+     * List all the host Ids, that are GPU enabled.
+     * @return list of hostIds
+     */
+    List<Long> listHostIds();
+
+    /**
+     * Return a list by hostId.
+     * @param hostId the host
+     * @return HostGpuGroupsVO
+     */
+    List<HostGpuGroupsVO> listByHostId(long hostId);
+
+    /**
+     * Delete entries by hostId.
+     * @param hostId the host
+     */
+    void deleteGpuEntries(long hostId);
+
+    /**
+     * Save the list of GPU groups belonging to a host
+     * @param hostId the host
+     * @param gpuGroups the list of GPU groups to save
+     */
+    void persist(long hostId, List<String> gpuGroups);
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/engine/schema/src/com/cloud/gpu/dao/HostGpuGroupsDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/gpu/dao/HostGpuGroupsDaoImpl.java b/engine/schema/src/com/cloud/gpu/dao/HostGpuGroupsDaoImpl.java
new file mode 100644
index 0000000..6bddea2
--- /dev/null
+++ b/engine/schema/src/com/cloud/gpu/dao/HostGpuGroupsDaoImpl.java
@@ -0,0 +1,94 @@
+// 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.gpu.dao;
+
+import java.util.List;
+
+import javax.ejb.Local;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.gpu.HostGpuGroupsVO;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+@Component
+@Local(value = HostGpuGroupsDao.class)
+public class HostGpuGroupsDaoImpl extends GenericDaoBase<HostGpuGroupsVO, Long> implements HostGpuGroupsDao {
+    private static final Logger s_logger = Logger.getLogger(HostGpuGroupsDaoImpl.class);
+
+    private final SearchBuilder<HostGpuGroupsVO> _hostIdGroupNameSearch;
+    private final SearchBuilder<HostGpuGroupsVO> _searchByHostId;
+    private final GenericSearchBuilder<HostGpuGroupsVO, Long> _searchHostIds;
+
+    public HostGpuGroupsDaoImpl() {
+
+        _hostIdGroupNameSearch = createSearchBuilder();
+        _hostIdGroupNameSearch.and("hostId", _hostIdGroupNameSearch.entity().getHostId(), SearchCriteria.Op.EQ);
+        _hostIdGroupNameSearch.and("groupName", _hostIdGroupNameSearch.entity().getGroupName(), SearchCriteria.Op.EQ);
+        _hostIdGroupNameSearch.done();
+
+        _searchByHostId = createSearchBuilder();
+        _searchByHostId.and("hostId", _searchByHostId.entity().getHostId(), SearchCriteria.Op.EQ);
+        _searchByHostId.done();
+
+        _searchHostIds = createSearchBuilder(Long.class);
+        _searchHostIds.selectFields(_searchHostIds.entity().getHostId());
+        _searchHostIds.done();
+    }
+
+    @Override
+    public HostGpuGroupsVO findByHostIdGroupName(long hostId, String groupName) {
+        SearchCriteria<HostGpuGroupsVO> sc = _hostIdGroupNameSearch.create();
+        sc.setParameters("hostId", hostId);
+        sc.setParameters("groupName", groupName);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public List<Long> listHostIds() {
+        SearchCriteria<Long> sc = _searchHostIds.create();
+        return customSearch(sc, null);
+    }
+
+    @Override
+    public List<HostGpuGroupsVO> listByHostId(long hostId) {
+        SearchCriteria<HostGpuGroupsVO> sc = _searchByHostId.create();
+        sc.setParameters("hostId", hostId);
+        return listBy(sc);
+    }
+
+    @Override
+    public void persist(long hostId, List<String> gpuGroups) {
+        for (String groupName : gpuGroups) {
+            if (findByHostIdGroupName(hostId, groupName) == null) {
+                HostGpuGroupsVO record = new HostGpuGroupsVO(hostId, groupName);
+                persist(record);
+            }
+        }
+    }
+
+    @Override
+    public void deleteGpuEntries(long hostId) {
+        SearchCriteria<HostGpuGroupsVO> sc = _searchByHostId.create();
+        sc.setParameters("hostId", hostId);
+        remove(sc);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/engine/schema/src/com/cloud/gpu/dao/VGPUTypesDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/gpu/dao/VGPUTypesDao.java b/engine/schema/src/com/cloud/gpu/dao/VGPUTypesDao.java
new file mode 100644
index 0000000..2872cfd
--- /dev/null
+++ b/engine/schema/src/com/cloud/gpu/dao/VGPUTypesDao.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.gpu.dao;
+
+import java.util.HashMap;
+import java.util.List;
+
+import com.cloud.gpu.VGPUTypesVO;
+import com.cloud.utils.db.GenericDao;
+
+public interface VGPUTypesDao extends GenericDao<VGPUTypesVO, Long> {
+
+ /**
+  * Find VGPU types by group Id
+  * @param groupId of the GPU group
+  * @return list of VGPUTypesVO
+  */
+ List<VGPUTypesVO> listByGroupId(long groupId);
+
+ /**
+  * Find VGPU type by group Id and VGPU type
+  * @param groupId of the GPU group
+  * @param vgpuType name of VGPU type
+  * @return VGPUTypesVO
+  */
+ VGPUTypesVO findByGroupIdVGPUType(long groupId, String vgpuType);
+
+ /**
+  * Save the list of enabled VGPU types
+  * @param hostId the host
+  * @param groupDetails with enabled VGPU types
+  */
+ void persist(long hostId, HashMap<String, HashMap<String, Long>> groupDetails);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/engine/schema/src/com/cloud/gpu/dao/VGPUTypesDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/gpu/dao/VGPUTypesDaoImpl.java b/engine/schema/src/com/cloud/gpu/dao/VGPUTypesDaoImpl.java
new file mode 100644
index 0000000..7cc83cc
--- /dev/null
+++ b/engine/schema/src/com/cloud/gpu/dao/VGPUTypesDaoImpl.java
@@ -0,0 +1,95 @@
+//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.gpu.dao;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map.Entry;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.gpu.HostGpuGroupsVO;
+import com.cloud.gpu.VGPUTypesVO;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+@Component
+@Local(value = VGPUTypesDao.class)
+public class VGPUTypesDaoImpl extends GenericDaoBase<VGPUTypesVO, Long> implements VGPUTypesDao {
+    private static final Logger s_logger = Logger.getLogger(VGPUTypesDaoImpl.class);
+
+    private final SearchBuilder<VGPUTypesVO> _searchByGroupId;
+    private final SearchBuilder<VGPUTypesVO> _searchByGroupIdVGPUType;
+    // private final SearchBuilder<VGPUTypesVO> _searchByHostId;
+    // private final SearchBuilder<VGPUTypesVO> _searchForStaleEntries;
+
+    @Inject protected HostGpuGroupsDao _hostGpuGroupsDao;
+
+    public VGPUTypesDaoImpl() {
+
+        _searchByGroupId = createSearchBuilder();
+        _searchByGroupId.and("groupId", _searchByGroupId.entity().getGpuGroupId(), SearchCriteria.Op.EQ);
+        _searchByGroupId.done();
+
+        _searchByGroupIdVGPUType = createSearchBuilder();
+        _searchByGroupIdVGPUType.and("groupId", _searchByGroupIdVGPUType.entity().getGpuGroupId(), SearchCriteria.Op.EQ);
+        _searchByGroupIdVGPUType.and("vgpuType", _searchByGroupIdVGPUType.entity().getVgpuType(), SearchCriteria.Op.EQ);
+        _searchByGroupIdVGPUType.done();
+    }
+
+    @Override
+    public List<VGPUTypesVO> listByGroupId(long groupId) {
+        SearchCriteria<VGPUTypesVO> sc = _searchByGroupId.create();
+        sc.setParameters("groupId", groupId);
+        return listBy(sc);
+    }
+
+    @Override
+    public VGPUTypesVO findByGroupIdVGPUType(long groupId, String vgpuType) {
+        SearchCriteria<VGPUTypesVO> sc = _searchByGroupIdVGPUType.create();
+        sc.setParameters("groupId", groupId);
+        sc.setParameters("vgpuType", vgpuType);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public void persist(long hostId, HashMap<String, HashMap<String, Long>> groupDetails) {
+        Iterator<Entry<String, HashMap<String, Long>>> it1 = groupDetails.entrySet().iterator();
+        while (it1.hasNext()) {
+            Entry<String, HashMap<String, Long>> entry = it1.next();
+            HostGpuGroupsVO gpuGroup = _hostGpuGroupsDao.findByHostIdGroupName(hostId, entry.getKey());
+            HashMap<String, Long> values = entry.getValue();
+            Iterator<Entry<String, Long>> it2 = values.entrySet().iterator();
+            while (it2.hasNext()) {
+                Entry<String, Long> record = it2.next();
+                VGPUTypesVO vgpuType = null;
+                if ((vgpuType = findByGroupIdVGPUType(gpuGroup.getId(), record.getKey())) == null) {
+                    persist(new VGPUTypesVO(record.getKey(), gpuGroup.getId(), record.getValue()));
+                } else {
+                    vgpuType.setRemainingCapacity(record.getValue());
+                    update(vgpuType.getId(), vgpuType);
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/engine/schema/src/com/cloud/host/HostVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/host/HostVO.java b/engine/schema/src/com/cloud/host/HostVO.java
index 56c066b..25cc954 100755
--- a/engine/schema/src/com/cloud/host/HostVO.java
+++ b/engine/schema/src/com/cloud/host/HostVO.java
@@ -17,6 +17,7 @@
 package com.cloud.host;
 
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
@@ -153,6 +154,10 @@ public class HostVO implements Host {
     @Transient
     List<String> hostTags;
 
+    // This value is only for saving and current cannot be loaded.
+    @Transient
+    HashMap<String, HashMap<String, Long>> groupDetails = new HashMap<String, HashMap<String, Long>>();
+
     @Override
     public String getStorageIpAddressDeux() {
         return storageIpAddressDeux;
@@ -313,6 +318,14 @@ public class HostVO implements Host {
         this.hostTags = hostTags;
     }
 
+    public  HashMap<String, HashMap<String, Long>> getGpuGroupDetails() {
+        return groupDetails;
+    }
+
+    public void setGpuGroups(HashMap<String, HashMap<String, Long>> groupDetails) {
+        this.groupDetails = groupDetails;
+    }
+
     @Column(name = "data_center_id", nullable = false)
     private long dataCenterId;
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java
index 08a4366..c2a9826 100755
--- a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java
+++ b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java
@@ -38,6 +38,8 @@ import com.cloud.cluster.agentlb.HostTransferMapVO;
 import com.cloud.cluster.agentlb.dao.HostTransferMapDao;
 import com.cloud.dc.ClusterVO;
 import com.cloud.dc.dao.ClusterDao;
+import com.cloud.gpu.dao.HostGpuGroupsDao;
+import com.cloud.gpu.dao.VGPUTypesDao;
 import com.cloud.host.Host;
 import com.cloud.host.Host.Type;
 import com.cloud.host.HostTagVO;
@@ -126,6 +128,10 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
     @Inject
     protected HostDetailsDao _detailsDao;
     @Inject
+    protected HostGpuGroupsDao _hostGpuGroupsDao;
+    @Inject
+    protected VGPUTypesDao _vgpuTypesDao;
+    @Inject
     protected HostTagsDao _hostTagsDao;
     @Inject
     protected HostTransferMapDao _hostTransferDao;
@@ -775,6 +781,16 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
         _hostTagsDao.persist(host.getId(), hostTags);
     }
 
+    protected void saveGpuRecords(HostVO host) {
+        HashMap<String, HashMap<String, Long>> groupDetails = host.getGpuGroupDetails();
+        if (groupDetails != null) {
+            // Create/Update GPU group entries
+            _hostGpuGroupsDao.persist(host.getId(), new ArrayList<String>(groupDetails.keySet()));
+            // Create/Update VGPU types entries
+            _vgpuTypesDao.persist(host.getId(), groupDetails);
+        }
+    }
+
     @Override
     @DB
     public HostVO persist(HostVO host) {
@@ -797,6 +813,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
         loadDetails(dbHost);
         saveHostTags(host);
         loadHostTags(dbHost);
+        saveGpuRecords(host);
 
         txn.commit();
 
@@ -816,6 +833,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
 
         saveDetails(host);
         saveHostTags(host);
+        saveGpuRecords(host);
 
         txn.commit();
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/engine/schema/src/com/cloud/service/ServiceOfferingDetailsVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/service/ServiceOfferingDetailsVO.java b/engine/schema/src/com/cloud/service/ServiceOfferingDetailsVO.java
index ed8090b..8dfe527 100644
--- a/engine/schema/src/com/cloud/service/ServiceOfferingDetailsVO.java
+++ b/engine/schema/src/com/cloud/service/ServiceOfferingDetailsVO.java
@@ -60,6 +60,10 @@ public class ServiceOfferingDetailsVO implements ResourceDetail {
         return resourceId;
     }
 
+    public void setResourceId(long serviceOfferingId) {
+        this.resourceId = serviceOfferingId;
+    }
+
     @Override
     public String getName() {
         return name;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
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 b1ad63a..d80bddc 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
@@ -56,11 +56,13 @@ import com.trilead.ssh2.SCPClient;
 import com.xensource.xenapi.Bond;
 import com.xensource.xenapi.Connection;
 import com.xensource.xenapi.Console;
+import com.xensource.xenapi.GPUGroup;
 import com.xensource.xenapi.Host;
 import com.xensource.xenapi.HostCpu;
 import com.xensource.xenapi.HostMetrics;
 import com.xensource.xenapi.Network;
 import com.xensource.xenapi.PBD;
+import com.xensource.xenapi.PGPU;
 import com.xensource.xenapi.PIF;
 import com.xensource.xenapi.Pool;
 import com.xensource.xenapi.SR;
@@ -73,6 +75,8 @@ import com.xensource.xenapi.Types.XenAPIException;
 import com.xensource.xenapi.VBD;
 import com.xensource.xenapi.VBDMetrics;
 import com.xensource.xenapi.VDI;
+import com.xensource.xenapi.VGPU;
+import com.xensource.xenapi.VGPUType;
 import com.xensource.xenapi.VIF;
 import com.xensource.xenapi.VLAN;
 import com.xensource.xenapi.VM;
@@ -108,6 +112,8 @@ import com.cloud.agent.api.CreateVMSnapshotCommand;
 import com.cloud.agent.api.DeleteStoragePoolCommand;
 import com.cloud.agent.api.DeleteVMSnapshotAnswer;
 import com.cloud.agent.api.DeleteVMSnapshotCommand;
+import com.cloud.agent.api.GetGPUStatsAnswer;
+import com.cloud.agent.api.GetGPUStatsCommand;
 import com.cloud.agent.api.GetHostStatsAnswer;
 import com.cloud.agent.api.GetHostStatsCommand;
 import com.cloud.agent.api.GetStorageStatsAnswer;
@@ -201,6 +207,7 @@ import com.cloud.agent.api.storage.ResizeVolumeCommand;
 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.GPUDeviceTO;
 import com.cloud.agent.api.to.IpAddressTO;
 import com.cloud.agent.api.to.NfsTO;
 import com.cloud.agent.api.to.NicTO;
@@ -433,6 +440,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             return execute((GetHostStatsCommand)cmd);
         } else if (clazz == GetVmStatsCommand.class) {
             return execute((GetVmStatsCommand)cmd);
+        } else if (clazz == GetGPUStatsCommand.class) {
+            return execute((GetGPUStatsCommand) cmd);
         } else if (clazz == GetVmDiskStatsCommand.class) {
             return execute((GetVmDiskStatsCommand)cmd);
         } else if (clazz == CheckHealthCommand.class) {
@@ -1288,6 +1297,65 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         return dynamicMinRam;
     }
 
+    private HashMap<String, HashMap<String, Long>> getGPUGroupDetails(Connection conn) throws XenAPIException, XmlRpcException {
+        HashMap<String, HashMap<String, Long>> groupDetails = new HashMap<String, HashMap<String, Long>>();
+        Host host = Host.getByUuid(conn, _host.uuid);
+        Set<PGPU> pgpus = host.getPGPUs(conn);
+        Iterator<PGPU> iter = pgpus.iterator();
+        while (iter.hasNext()) {
+            PGPU pgpu = iter.next();
+            GPUGroup gpuGroup = pgpu.getGPUGroup(conn);
+            Set<VGPUType> enabledVGPUTypes = gpuGroup.getEnabledVGPUTypes(conn);
+            String groupName = gpuGroup.getNameLabel(conn);
+            HashMap<String, Long> gpuCapacity = new HashMap<String, Long>();
+            if (groupDetails.get(groupName) != null) {
+                gpuCapacity = groupDetails.get(groupName);
+            }
+            // Get remaining capacity of all the enabled VGPU in a PGPU
+            if(enabledVGPUTypes != null) {
+                Iterator<VGPUType> it = enabledVGPUTypes.iterator();
+                while (it.hasNext()) {
+                    VGPUType type = it.next();
+                    String modelName = type.getModelName(conn);
+                    Long remainingCapacity = pgpu.getRemainingCapacity(conn, type);
+                    if (gpuCapacity.get(modelName) != null) {
+                        long newRemainingCapacity = gpuCapacity.get(modelName) + remainingCapacity;
+                        gpuCapacity.put(modelName, newRemainingCapacity);
+                    } else {
+                        gpuCapacity.put(modelName, remainingCapacity);
+                    }
+                }
+            }
+            groupDetails.put(groupName, gpuCapacity);
+        }
+        return groupDetails;
+    }
+
+    protected void createVGPU(Connection conn, StartCommand cmd, VM vm, GPUDeviceTO gpuDevice) throws XenAPIException, XmlRpcException {
+        Set<GPUGroup> groups = GPUGroup.getByNameLabel(conn, gpuDevice.getGpuGroup());
+        assert groups.size() == 1 : "Should only have 1 group but found " + groups.size();
+        GPUGroup gpuGroup = groups.iterator().next();
+
+        Set<VGPUType> vgpuTypes = gpuGroup.getEnabledVGPUTypes(conn);
+        Iterator<VGPUType> iter = vgpuTypes.iterator();
+        VGPUType vgpuType = null;
+        while (iter.hasNext()) {
+            VGPUType entry = iter.next();
+            if (entry.getModelName(conn).equals(gpuDevice.getVgpuType())) {
+                vgpuType = entry;
+            }
+        }
+        String device = "0"; // Only allow device = "0" for now, as XenServer supports just a single vGPU per VM.
+        Map<String, String> other_config = new HashMap<String, String>();
+        VGPU.create(conn, vm, gpuGroup, device, other_config, vgpuType);
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Created VGPU of VGPU type [ " + gpuDevice.getVgpuType() + " ] for VM " + cmd.getVirtualMachine().getName());
+        }
+        // Calculate and set remaining GPU capacity in the host.
+        cmd.getVirtualMachine().getGpuDevice().setGroupDetails(getGPUGroupDetails(conn));
+    }
+
     protected VM createVmFromTemplate(Connection conn, VirtualMachineTO vmSpec, Host host) throws XenAPIException, XmlRpcException {
         String guestOsTypeName = getGuestOsType(vmSpec.getOs(), vmSpec.getBootloader() == BootloaderType.CD);
         Set<VM> templates = VM.getByNameLabel(conn, guestOsTypeName);
@@ -1721,6 +1789,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             Host host = Host.getByUuid(conn, _host.uuid);
             vm = createVmFromTemplate(conn, vmSpec, host);
 
+            GPUDeviceTO gpuDevice = vmSpec.getGpuDevice();
+            if (gpuDevice != null) {
+                s_logger.debug("Creating VGPU for of VGPU type: " + gpuDevice.getVgpuType() + " in GPU group "
+                        + gpuDevice.getGpuGroup() + " for VM " + vmName );
+                createVGPU(conn, cmd, vm, gpuDevice);
+            }
+
             for (DiskTO disk : vmSpec.getDisks()) {
                 VDI newVdi = prepareManagedDisk(conn, disk, vmName);
 
@@ -2245,6 +2320,18 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         return hostStats;
     }
 
+    protected GetGPUStatsAnswer execute(GetGPUStatsCommand cmd) {
+        Connection conn = getConnection();
+        HashMap<String, HashMap<String, Long>> groupDetails = new HashMap<String, HashMap<String, Long>>();
+        try {
+            groupDetails = getGPUGroupDetails(conn);
+        } catch (Exception e) {
+            String msg = "Unable to get GPU stats" + e.toString();
+            s_logger.warn(msg, e);
+        }
+        return new GetGPUStatsAnswer(cmd, groupDetails);
+    }
+
     protected GetVmStatsAnswer execute(GetVmStatsCommand cmd) {
         Connection conn = getConnection();
         List<String> vmNames = cmd.getVmNames();
@@ -3566,6 +3653,18 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
 
                     try {
                         if (vm.getPowerState(conn) == VmPowerState.HALTED) {
+                            Set<VGPU> vGPUs = null;
+                            // Get updated GPU details
+                            try {
+                                vGPUs = vm.getVGPUs(conn);
+                            } catch (XenAPIException e2) {
+                                s_logger.debug("VM " + vmName + " does not have GPU support.");
+                            }
+                            if (vGPUs != null && !vGPUs.isEmpty()) {
+                                HashMap<String, HashMap<String, Long>> groupDetails = getGPUGroupDetails(conn);
+                                cmd.setGpuDevice(new GPUDeviceTO(null, null, groupDetails));
+                            }
+
                             Set<VIF> vifs = vm.getVIFs(conn);
                             List<Network> networks = new ArrayList<Network>();
                             for (VIF vif : vifs) {
@@ -5400,6 +5499,15 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
                 details.put("private.network.device", _privateNetworkName);
             }
 
+            try {
+                HashMap<String, HashMap<String, Long>> groupDetails = getGPUGroupDetails(conn);
+                cmd.setGpuGroupDetails(groupDetails);
+            } catch (Exception e) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("GPU device not found in host " + hr.hostname);
+                }
+            }
+
             cmd.setHostDetails(details);
             cmd.setName(hr.nameLabel);
             cmd.setGuid(_host.uuid);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java b/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java
index b77f8ac..8abb5cd 100755
--- a/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java
+++ b/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java
@@ -26,11 +26,10 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-
 import com.cloud.agent.manager.allocator.HostAllocator;
 import com.cloud.capacity.CapacityManager;
 import com.cloud.dc.ClusterDetailsDao;
@@ -38,6 +37,7 @@ import com.cloud.dc.ClusterDetailsVO;
 import com.cloud.dc.dao.ClusterDao;
 import com.cloud.deploy.DeploymentPlan;
 import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.gpu.GPU;
 import com.cloud.host.DetailVO;
 import com.cloud.host.Host;
 import com.cloud.host.Host.Type;
@@ -47,7 +47,9 @@ import com.cloud.host.dao.HostDetailsDao;
 import com.cloud.offering.ServiceOffering;
 import com.cloud.org.Cluster;
 import com.cloud.resource.ResourceManager;
+import com.cloud.service.ServiceOfferingDetailsVO;
 import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.service.dao.ServiceOfferingDetailsDao;
 import com.cloud.storage.GuestOSCategoryVO;
 import com.cloud.storage.GuestOSVO;
 import com.cloud.storage.VMTemplateVO;
@@ -99,6 +101,8 @@ public class FirstFitAllocator extends AdapterBase implements HostAllocator {
     ClusterDao _clusterDao;
     @Inject
     ClusterDetailsDao _clusterDetailsDao;
+    @Inject
+    ServiceOfferingDetailsDao _serviceOfferingDetailsDao;
     float _factor = 1;
     boolean _checkHvm = true;
     protected String _allocationAlgorithm = "random";
@@ -264,7 +268,9 @@ public class FirstFitAllocator extends AdapterBase implements HostAllocator {
             s_logger.debug("Looking for speed=" + (offering.getCpu() * offering.getSpeed()) + "Mhz, Ram=" + offering.getRamSize());
         }
 
+        long serviceOfferingId = offering.getId();
         List<Host> suitableHosts = new ArrayList<Host>();
+        ServiceOfferingDetailsVO offeringDetails = null;
 
         for (Host host : hosts) {
             if (suitableHosts.size() == returnUpTo) {
@@ -286,6 +292,13 @@ public class FirstFitAllocator extends AdapterBase implements HostAllocator {
                 continue;
             }
 
+            // Check if GPU device is required by offering and host has the availability
+            if ((offeringDetails   = _serviceOfferingDetailsDao.findDetail(serviceOfferingId, GPU.Keys.vgpuType.toString())) != null
+                    && !_resourceMgr.isGPUDeviceAvailable(host.getId(), offeringDetails.getValue())){
+                s_logger.info("Host name: " + host.getName() + ", hostId: "+ host.getId() +" does not have required GPU devices available");
+                continue;
+            }
+
             int cpu_requested = offering.getCpu() * offering.getSpeed();
             long ram_requested = offering.getRamSize() * 1024L * 1024L;
             Cluster cluster = _clusterDao.findById(host.getClusterId());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/server/src/com/cloud/api/ApiDBUtils.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java
index a23244b..539eb70 100755
--- a/server/src/com/cloud/api/ApiDBUtils.java
+++ b/server/src/com/cloud/api/ApiDBUtils.java
@@ -130,6 +130,10 @@ import com.cloud.domain.dao.DomainDao;
 import com.cloud.event.Event;
 import com.cloud.event.dao.EventJoinDao;
 import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.gpu.HostGpuGroupsVO;
+import com.cloud.gpu.VGPUTypesVO;
+import com.cloud.gpu.dao.HostGpuGroupsDao;
+import com.cloud.gpu.dao.VGPUTypesDao;
 import com.cloud.ha.HighAvailabilityManager;
 import com.cloud.host.Host;
 import com.cloud.host.HostStats;
@@ -221,8 +225,10 @@ import com.cloud.server.ResourceTag;
 import com.cloud.server.ResourceTag.ResourceObjectType;
 import com.cloud.server.StatsCollector;
 import com.cloud.server.TaggedResourceService;
+import com.cloud.service.ServiceOfferingDetailsVO;
 import com.cloud.service.ServiceOfferingVO;
 import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.service.dao.ServiceOfferingDetailsDao;
 import com.cloud.storage.DiskOfferingVO;
 import com.cloud.storage.GuestOS;
 import com.cloud.storage.GuestOSCategoryVO;
@@ -325,6 +331,7 @@ public class ApiDBUtils {
     static NetworkRuleConfigDao s_networkRuleConfigDao;
     static HostPodDao s_podDao;
     static ServiceOfferingDao s_serviceOfferingDao;
+    static ServiceOfferingDetailsDao s_serviceOfferingDetailsDao;
     static SnapshotDao s_snapshotDao;
     static PrimaryDataStoreDao s_storagePoolDao;
     static VMTemplateDao s_templateDao;
@@ -400,6 +407,8 @@ public class ApiDBUtils {
     static NetworkACLDao s_networkACLDao;
     static AccountService s_accountService;
     static ResourceMetaDataService s_resourceDetailsService;
+    static HostGpuGroupsDao s_hostGpuGroupsDao;
+    static VGPUTypesDao s_vgpuTypesDao;
 
     @Inject
     private ManagementServer ms;
@@ -467,6 +476,8 @@ public class ApiDBUtils {
     @Inject
     private ServiceOfferingDao serviceOfferingDao;
     @Inject
+    private ServiceOfferingDetailsDao serviceOfferingDetailsDao;
+    @Inject
     private SnapshotDao snapshotDao;
     @Inject
     private PrimaryDataStoreDao storagePoolDao;
@@ -616,6 +627,10 @@ public class ApiDBUtils {
     private ConfigurationManager configMgr;
     @Inject
     private ResourceMetaDataService resourceDetailsService;
+    @Inject
+    private HostGpuGroupsDao hostGpuGroupsDao;
+    @Inject
+    private VGPUTypesDao vgpuTypesDao;
 
     @PostConstruct
     void init() {
@@ -649,6 +664,7 @@ public class ApiDBUtils {
         s_networkRuleConfigDao = networkRuleConfigDao;
         s_podDao = podDao;
         s_serviceOfferingDao = serviceOfferingDao;
+        s_serviceOfferingDetailsDao = serviceOfferingDetailsDao;
         s_serviceOfferingJoinDao = serviceOfferingJoinDao;
         s_snapshotDao = snapshotDao;
         s_storagePoolDao = storagePoolDao;
@@ -727,6 +743,8 @@ public class ApiDBUtils {
         s_networkACLDao = networkACLDao;
         s_accountService = accountService;
         s_resourceDetailsService = resourceDetailsService;
+        s_hostGpuGroupsDao = hostGpuGroupsDao;
+        s_vgpuTypesDao = vgpuTypesDao;
 
     }
 
@@ -960,6 +978,10 @@ public class ApiDBUtils {
         return s_serviceOfferingDao.findByIdIncludingRemoved(serviceOfferingId);
     }
 
+    public static ServiceOfferingDetailsVO findServiceOfferingDetail(long serviceOfferingId, String key) {
+        return s_serviceOfferingDetailsDao.findDetail(serviceOfferingId, key);
+    }
+
     public static Snapshot findSnapshotById(long snapshotId) {
         SnapshotVO snapshot = s_snapshotDao.findById(snapshotId);
         if (snapshot != null && snapshot.getRemoved() == null && snapshot.getState() == Snapshot.State.BackedUp) {
@@ -1057,6 +1079,14 @@ public class ApiDBUtils {
         return type;
     }
 
+    public static List<HostGpuGroupsVO> getGpuGroups(long hostId) {
+        return s_hostGpuGroupsDao.listByHostId(hostId);
+    }
+
+    public static List<VGPUTypesVO> getVgpus(long groupId) {
+        return s_vgpuTypesDao.listByGroupId(groupId);
+    }
+
     public static List<UserStatisticsVO> listUserStatsBy(Long accountId) {
         return s_userStatsDao.listBy(accountId);
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java
index 1b95d9b..6c890fc 100644
--- a/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java
+++ b/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java
@@ -31,12 +31,16 @@ import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
 import org.apache.cloudstack.api.ApiConstants.HostDetails;
+import org.apache.cloudstack.api.response.GpuResponse;
 import org.apache.cloudstack.api.response.HostForMigrationResponse;
 import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.VgpuResponse;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 
 import com.cloud.api.ApiDBUtils;
 import com.cloud.api.query.vo.HostJoinVO;
+import com.cloud.gpu.HostGpuGroupsVO;
+import com.cloud.gpu.VGPUTypesVO;
 import com.cloud.host.Host;
 import com.cloud.host.HostStats;
 import com.cloud.storage.StorageStats;
@@ -92,6 +96,27 @@ public class HostJoinDaoImpl extends GenericDaoBase<HostJoinVO, Long> implements
         hostResponse.setVersion(host.getVersion());
         hostResponse.setCreated(host.getCreated());
 
+        List<HostGpuGroupsVO> gpuGroups = ApiDBUtils.getGpuGroups(host.getId());
+        if (gpuGroups != null && !gpuGroups.isEmpty()) {
+            List<GpuResponse> gpus = new ArrayList<GpuResponse>();
+            for (HostGpuGroupsVO entry : gpuGroups) {
+                GpuResponse gpuResponse = new GpuResponse();
+                gpuResponse.setGpuGroupName(entry.getGroupName());
+                List<VGPUTypesVO> vgpuTypes = ApiDBUtils.getVgpus(entry.getId());
+                if (vgpuTypes != null && !vgpuTypes.isEmpty()) {
+                    List<VgpuResponse> vgpus = new ArrayList<VgpuResponse>();
+                    for (VGPUTypesVO vgpuType : vgpuTypes) {
+                        VgpuResponse vgpuResponse = new VgpuResponse();
+                        vgpuResponse.setName(vgpuType.getVgpuType());
+                        vgpuResponse.setCapacity(vgpuType.getRemainingCapacity());
+                        vgpus.add(vgpuResponse);
+                    }
+                    gpuResponse.setVgpu(vgpus);
+                }
+                gpus.add(gpuResponse);
+            }
+            hostResponse.setGpuGroups(gpus);
+        }
         if (details.contains(HostDetails.all) || details.contains(HostDetails.capacity) || details.contains(HostDetails.stats) || details.contains(HostDetails.events)) {
 
             hostResponse.setOsCategoryId(host.getOsCategoryUuid());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java
index 08478e2..235902c 100644
--- a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java
+++ b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java
@@ -40,7 +40,9 @@ import org.springframework.stereotype.Component;
 import com.cloud.api.ApiDBUtils;
 import com.cloud.api.query.vo.ResourceTagJoinVO;
 import com.cloud.api.query.vo.UserVmJoinVO;
+import com.cloud.gpu.GPU;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.service.ServiceOfferingDetailsVO;
 import com.cloud.user.Account;
 import com.cloud.uservm.UserVm;
 import com.cloud.utils.db.GenericDaoBase;
@@ -157,6 +159,10 @@ public class UserVmJoinDaoImpl extends GenericDaoBase<UserVmJoinVO, Long> implem
             userVmResponse.setCpuNumber(userVm.getCpu());
             userVmResponse.setCpuSpeed(userVm.getSpeed());
             userVmResponse.setMemory(userVm.getRamSize());
+            ServiceOfferingDetailsVO serviceOfferingDetail = ApiDBUtils.findServiceOfferingDetail(userVm.getServiceOfferingId(), GPU.Keys.vgpuType.toString());
+            if (serviceOfferingDetail != null) {
+                userVmResponse.setVgpu(serviceOfferingDetail.getValue());
+            }
         }
         userVmResponse.setGuestOsId(userVm.getGuestOsUuid());
         if (details.contains(VMDetails.all) || details.contains(VMDetails.volume)) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index 08cc5a6..863d71b 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -130,6 +130,7 @@ import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.PermissionDeniedException;
 import com.cloud.exception.ResourceAllocationException;
 import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.gpu.GPU;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.network.IpAddressManager;
 import com.cloud.network.Network;
@@ -2079,13 +2080,56 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
 
         offering.setHypervisorSnapshotReserve(hypervisorSnapshotReserve);
 
-        if ((offering = _serviceOfferingDao.persist(offering)) != null) {
-            if (details != null) {
-                List<ServiceOfferingDetailsVO> detailsVO = new ArrayList<ServiceOfferingDetailsVO>();
-                for (Entry<String, String> detailEntry : details.entrySet()) {
-                    detailsVO.add(new ServiceOfferingDetailsVO(offering.getId(), detailEntry.getKey(), detailEntry.getValue(), true));
+        List<ServiceOfferingDetailsVO> detailsVO = null;
+        if (details != null) {
+            // Check if the user has passed the gpu-type before passing the VGPU type
+            if (!details.containsKey(GPU.Keys.pciDevice.toString()) && details.containsKey(GPU.Keys.vgpuType.toString())) {
+                throw new InvalidParameterValueException("Please specify the gpu type");
+            }
+            detailsVO = new ArrayList<ServiceOfferingDetailsVO>();
+            for (Entry<String, String> detailEntry : details.entrySet()) {
+                String value = null;
+                if (detailEntry.getKey().equals(GPU.Keys.pciDevice.toString())) {
+                    for (GPU.Type type : GPU.Type.values()) {
+                        if (detailEntry.getValue().equals(type.toString())) {
+                            value = detailEntry.getValue();
+                        }
+                    }
+                    if (value == null) {
+                        throw new InvalidParameterValueException("Please specify valid gpu type");
+                    }
+                }
+                if (detailEntry.getKey().equals(GPU.Keys.vgpuType.toString())) {
+                    if (details.get(GPU.Keys.pciDevice.toString()).equals(GPU.Type.GPU_Passthrough.toString())) {
+                        throw new InvalidParameterValueException("vgpuTypes are supported only with vGPU pciDevice");
+                    }
+                    if (detailEntry.getValue() == null) {
+                        throw new InvalidParameterValueException("With vGPU as pciDevice, vGPUType value cannot be null");
+                    }
+                    for (GPU.vGPUType entry : GPU.vGPUType.values()) {
+                        if (detailEntry.getValue().equals(entry.getType())) {
+                            value = entry.getType();
+                        }
+                    }
+                    if (value == null || detailEntry.getValue().equals(GPU.vGPUType.passthrough.getType())) {
+                        throw new InvalidParameterValueException("Please specify valid vGPU type");
+                    }
                 }
+                detailsVO.add(new ServiceOfferingDetailsVO(offering.getId(), detailEntry.getKey(), detailEntry.getValue(), true));
+            }
+            // If pciDevice type is passed, put the default VGPU type as 'passthrough'
+            if (details.containsKey(GPU.Keys.pciDevice.toString())
+                    && !details.containsKey(GPU.Keys.vgpuType.toString())) {
+                detailsVO.add(new ServiceOfferingDetailsVO(offering.getId(),
+                        GPU.Keys.vgpuType.toString(), GPU.vGPUType.passthrough.getType(), true));
+            }
+        }
 
+        if ((offering = _serviceOfferingDao.persist(offering)) != null) {
+            if (detailsVO != null && !detailsVO.isEmpty()) {
+                for (int index = 0; index < detailsVO.size(); index++) {
+                    detailsVO.get(index).setResourceId(offering.getId());
+                }
                 _serviceOfferingDetailsDao.saveDetails(detailsVO);
             }
             CallContext.current().setEventDetails("Service offering id=" + offering.getId());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
index 3c87b24..f76e485 100644
--- a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
+++ b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
@@ -81,6 +81,7 @@ import com.cloud.deploy.dao.PlannerHostReservationDao;
 import com.cloud.exception.AffinityConflictException;
 import com.cloud.exception.ConnectionException;
 import com.cloud.exception.InsufficientServerCapacityException;
+import com.cloud.gpu.GPU;
 import com.cloud.host.Host;
 import com.cloud.host.HostVO;
 import com.cloud.host.Status;
@@ -89,7 +90,10 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.offering.ServiceOffering;
 import com.cloud.org.Cluster;
 import com.cloud.org.Grouping;
+import com.cloud.resource.ResourceManager;
 import com.cloud.resource.ResourceState;
+import com.cloud.service.ServiceOfferingDetailsVO;
+import com.cloud.service.dao.ServiceOfferingDetailsDao;
 import com.cloud.storage.DiskOfferingVO;
 import com.cloud.storage.ScopeType;
 import com.cloud.storage.Storage;
@@ -213,6 +217,10 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
     DataStoreManager dataStoreMgr;
     @Inject
     protected ClusterDetailsDao _clusterDetailsDao;
+    @Inject
+    protected ResourceManager _resourceMgr;
+    @Inject
+    protected ServiceOfferingDetailsDao _serviceOfferingDetailsDao;
 
     protected List<DeploymentPlanner> _planners;
 
@@ -353,6 +361,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
             s_logger.debug("This VM has last host_id specified, trying to choose the same host: " + vm.getLastHostId());
 
             HostVO host = _hostDao.findById(vm.getLastHostId());
+            ServiceOfferingDetailsVO offeringDetails = null;
             if (host == null) {
                 s_logger.debug("The last host of this VM cannot be found");
             } else if (avoids.shouldAvoid(host)) {
@@ -360,6 +369,9 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
             } else if (_capacityMgr.checkIfHostReachMaxGuestLimit(host)) {
                 s_logger.debug("The last Host, hostId: " + host.getId() +
                     " already has max Running VMs(count includes system VMs), skipping this and trying other available hosts");
+            } else if ((offeringDetails  = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.vgpuType.toString())) != null
+                    && !_resourceMgr.isGPUDeviceAvailable(host.getId(), offeringDetails.getValue())){
+                s_logger.debug("The last host of this VM does not have required GPU devices available");
             } else {
                 if (host.getStatus() == Status.Up && host.getResourceState() == ResourceState.Enabled) {
                     boolean hostTagsMatch = true;
@@ -1397,4 +1409,4 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
         }
         return true;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c7d31fe2/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
index 7fb79fa..4af20c6 100644
--- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
+++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
@@ -25,8 +25,12 @@ import com.cloud.agent.api.Command;
 import com.cloud.agent.api.to.DiskTO;
 import com.cloud.agent.api.to.NicTO;
 import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.gpu.GPU;
 import com.cloud.offering.ServiceOffering;
+import com.cloud.resource.ResourceManager;
 import com.cloud.server.ConfigurationServer;
+import com.cloud.service.ServiceOfferingDetailsVO;
+import com.cloud.service.dao.ServiceOfferingDetailsDao;
 import com.cloud.storage.dao.VMTemplateDetailsDao;
 import com.cloud.utils.Pair;
 import com.cloud.utils.component.AdapterBase;
@@ -55,6 +59,10 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
     NicSecondaryIpDao _nicSecIpDao;
     @Inject
     ConfigurationServer _configServer;
+    @Inject
+    ResourceManager _resourceMgr;
+    @Inject
+    ServiceOfferingDetailsDao _serviceOfferingDetailsDao;
 
     protected HypervisorGuruBase() {
         super();
@@ -125,6 +133,13 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
         if (detailsInVm != null) {
             to.setDetails(detailsInVm);
         }
+
+        // Set GPU details
+        ServiceOfferingDetailsVO offeringDetail = null;
+        if ((offeringDetail  = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.vgpuType.toString())) != null) {
+            to.setGpuDevice(_resourceMgr.getGPUDevice(vm.getHostId(), offeringDetail.getValue()));
+        }
+
         // 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)


[28/50] [abbrv] git commit: updated refs/heads/distributedrouter to 6b5e234

Posted by mu...@apache.org.
findbugs: another array pointer in error message

Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/d182a511
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/d182a511
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/d182a511

Branch: refs/heads/distributedrouter
Commit: d182a51162ad081f1e24faa7a2bd45246de5e326
Parents: e0d20fb
Author: Daan Hoogland <da...@onecht.net>
Authored: Mon Mar 10 13:21:13 2014 +0100
Committer: Daan Hoogland <da...@onecht.net>
Committed: Mon Mar 10 13:21:13 2014 +0100

----------------------------------------------------------------------
 server/src/com/cloud/network/IpAddressManagerImpl.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d182a511/server/src/com/cloud/network/IpAddressManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/IpAddressManagerImpl.java b/server/src/com/cloud/network/IpAddressManagerImpl.java
index ed709e9..15d1458 100644
--- a/server/src/com/cloud/network/IpAddressManagerImpl.java
+++ b/server/src/com/cloud/network/IpAddressManagerImpl.java
@@ -733,7 +733,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                     if (useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
                         fetchFromDedicatedRange = false;
                         sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
-                        errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray());
+                        errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
                         addrs = _ipAddressDao.lockRows(sc, filter, true);
                     }
                 }