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

[45/50] [abbrv] git commit: updated refs/heads/opendaylight to 858fb69

Add a network plugin for OpenDaylight

This plugin is a technology preview and designed to work with the OVSDB module


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

Branch: refs/heads/opendaylight
Commit: 385ddaeaeb7b86d4b1daf4ba8330a12f8da6bea3
Parents: 7787829
Author: Hugo Trippaers <ht...@schubergphilis.com>
Authored: Thu Dec 19 10:50:44 2013 +0100
Committer: Hugo Trippaers <ht...@schubergphilis.com>
Committed: Fri Jan 3 11:08:48 2014 +0100

----------------------------------------------------------------------
 LICENSE.header                                  |  16 +
 plugins/network-elements/opendaylight/pom.xml   | 132 ++++++++
 .../opendaylight/OpendaylightElement.java       | 174 ++++++++++
 .../OpendaylightGuestNetworkGuru.java           | 276 ++++++++++++++++
 .../agent/OpenDaylightControllerResource.java   | 321 +++++++++++++++++++
 .../OpenDaylightControllerResourceManager.java  |  34 ++
 ...enDaylightControllerResourceManagerImpl.java | 173 ++++++++++
 .../agent/commands/AddHypervisorCommand.java    |  58 ++++
 .../agent/commands/ConfigureNetworkCommand.java |  54 ++++
 .../agent/commands/ConfigurePortCommand.java    |  80 +++++
 .../agent/commands/DestroyNetworkCommand.java   |  45 +++
 .../agent/commands/DestroyPortCommand.java      |  50 +++
 .../StartupOpenDaylightControllerCommand.java   |  29 ++
 .../agent/responses/AddHypervisorAnswer.java    |  35 ++
 .../agent/responses/ConfigureNetworkAnswer.java |  43 +++
 .../agent/responses/ConfigurePortAnswer.java    |  35 ++
 .../agent/responses/DestroyNetworkAnswer.java   |  35 ++
 .../agent/responses/DestroyPortAnswer.java      |  35 ++
 .../dao/OpenDaylightControllerMappingDao.java   |  28 ++
 .../OpenDaylightControllerMappingDaoImpl.java   |  45 +++
 .../dao/OpenDaylightControllerVO.java           | 101 ++++++
 .../cloudstack/opendaylight/module.properties   |  21 ++
 .../spring-opendaylight-context.xml             |  42 +++
 plugins/pom.xml                                 |   1 +
 24 files changed, 1863 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/LICENSE.header
----------------------------------------------------------------------
diff --git a/LICENSE.header b/LICENSE.header
new file mode 100644
index 0000000..4eacb64
--- /dev/null
+++ b/LICENSE.header
@@ -0,0 +1,16 @@
+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.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/pom.xml b/plugins/network-elements/opendaylight/pom.xml
new file mode 100644
index 0000000..8c69b6e
--- /dev/null
+++ b/plugins/network-elements/opendaylight/pom.xml
@@ -0,0 +1,132 @@
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>cloud-plugin-network-opendaylight</artifactId>
+  <name>Apache CloudStack Plugin - Network Opendaylight</name>
+  <parent>
+    <groupId>org.apache.cloudstack</groupId>
+    <artifactId>cloudstack-plugins</artifactId>
+    <version>4.4.0-SNAPSHOT</version>
+    <relativePath>../../pom.xml</relativePath>
+  </parent>
+
+  <!-- not parenting to the maven-default pom, as we want this in services -->
+  <build>
+    <sourceDirectory>${basedir}/src/main/java</sourceDirectory>
+    <scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory>
+    <testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
+    <outputDirectory>${basedir}/target/classes</outputDirectory>
+    <testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory>
+    <resources>
+      <resource>
+        <directory>${basedir}/src/main/resources</directory>
+      </resource>
+    </resources>
+    <testResources>
+      <testResource>
+        <directory>${basedir}/src/test/resources</directory>
+      </testResource>
+    </testResources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <dependencies>
+          <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>checkstyle</artifactId>
+            <version>${project.version}</version>
+          </dependency>
+        </dependencies>
+        <executions>
+          <execution>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <failsOnError>true</failsOnError>
+          <configLocation>tooling/checkstyle.xml</configLocation>
+          <consoleOutput>true</consoleOutput>
+          <includeTestSourceDirectory>true</includeTestSourceDirectory>
+          <sourceDirectory>${project.basedir}</sourceDirectory>
+          <includes>**\/*.java,**\/*.xml,**\/*.ini,**\/*.sh,**\/*.bat</includes>
+          <excludes>**\/target\/,**\/bin\/</excludes>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>com.mycila.maven-license-plugin</groupId>
+        <artifactId>maven-license-plugin</artifactId>
+        <version>1.9.0</version>
+        <executions>
+          <execution>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>format</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <strictCheck>true</strictCheck>
+          <aggregate>true</aggregate>
+          <header>../../../LICENSE.header</header>
+          <mapping>
+                <xml>XML_STYLE</xml>
+                <java>DOUBLESLASH_STYLE</java>
+                <clj>SEMICOLON_STYLE</clj>
+          </mapping>
+          <useDefaultExcludes>false</useDefaultExcludes>
+          <excludes>
+            <exclude>target/**</exclude>
+            <exclude>.settings/**</exclude>
+            <exclude>.checkstyle</exclude>
+            <exclude>.project</exclude>
+            <exclude>.classpath</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <profiles>
+    <profile>
+      <id>integration</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-failsafe-plugin</artifactId>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>integration-test</goal>
+                  <goal>verify</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/OpendaylightElement.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/OpendaylightElement.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/OpendaylightElement.java
new file mode 100644
index 0000000..9761e74
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/OpendaylightElement.java
@@ -0,0 +1,174 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.network.opendaylight;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import org.apache.cloudstack.network.opendaylight.agent.commands.StartupOpenDaylightControllerCommand;
+
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+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.PhysicalNetworkServiceProvider;
+import com.cloud.network.element.ConnectivityProvider;
+import com.cloud.network.element.NetworkElement;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Component
+@Local(value = {NetworkElement.class, ConnectivityProvider.class})
+public class OpendaylightElement extends AdapterBase implements ConnectivityProvider, ResourceStateAdapter {
+
+    private static final Logger s_logger = Logger.getLogger(OpendaylightElement.class);
+    private static final Map<Service, Map<Capability, String>> s_capabilities = setCapabilities();
+
+    @Inject
+    ResourceManager resourceManager;
+
+    @Override
+    public Map<Service, Map<Capability, String>> getCapabilities() {
+        return s_capabilities;
+    }
+
+    @Override
+    public Provider getProvider() {
+        return Provider.Opendaylight;
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        boolean configured = super.configure(name, params);
+        if (configured)
+            resourceManager.registerResourceStateAdapter(name, this);
+        return configured;
+    }
+
+    @Override
+    public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException,
+    ResourceUnavailableException, InsufficientCapacityException {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    @Override
+    public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException,
+    ResourceUnavailableException, InsufficientCapacityException {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    @Override
+    public boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) throws ConcurrentOperationException,
+    ResourceUnavailableException {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    @Override
+    public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
+        return true;
+    }
+
+    @Override
+    public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
+        return true;
+    }
+
+    @Override
+    public boolean isReady(PhysicalNetworkServiceProvider provider) {
+        return true;
+    }
+
+    @Override
+    public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException,
+    ResourceUnavailableException {
+        return true;
+    }
+
+    @Override
+    public boolean canEnableIndividualServices() {
+        return false;
+    }
+
+    @Override
+    public boolean verifyServicesCombination(Set<Service> services) {
+        if (services.contains(Service.Connectivity) && services.size() == 1)
+            return true;
+        return false;
+    }
+
+    @Override
+    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] startup) {
+        if (!(startup[0] instanceof StartupOpenDaylightControllerCommand)) {
+            return null;
+        }
+        throw new CloudRuntimeException("createHostVOForConnectedAgent is not implemented for OpendaylightElement");
+    }
+
+    @Override
+    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
+        if (!(startup[0] instanceof StartupOpenDaylightControllerCommand)) {
+            return null;
+        }
+        host.setType(Host.Type.L2Networking);
+        return host;
+    }
+
+    @Override
+    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
+        return new DeleteHostAnswer(true);
+    }
+
+    private static Map<Service, Map<Capability, String>> setCapabilities() {
+        Map<Service, Map<Capability, String>> capabilities = new HashMap<Service, Map<Capability, String>>();
+
+        // L2 Support : SDN provisioning
+        capabilities.put(Service.Connectivity, null);
+
+        return capabilities;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/OpendaylightGuestNetworkGuru.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/OpendaylightGuestNetworkGuru.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/OpendaylightGuestNetworkGuru.java
new file mode 100644
index 0000000..0b547e7
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/OpendaylightGuestNetworkGuru.java
@@ -0,0 +1,276 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.network.opendaylight;
+
+import java.util.List;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.network.opendaylight.agent.commands.AddHypervisorCommand;
+import org.apache.cloudstack.network.opendaylight.agent.commands.ConfigureNetworkCommand;
+import org.apache.cloudstack.network.opendaylight.agent.commands.ConfigurePortCommand;
+import org.apache.cloudstack.network.opendaylight.agent.commands.DestroyNetworkCommand;
+import org.apache.cloudstack.network.opendaylight.agent.commands.DestroyPortCommand;
+import org.apache.cloudstack.network.opendaylight.agent.responses.AddHypervisorAnswer;
+import org.apache.cloudstack.network.opendaylight.agent.responses.ConfigureNetworkAnswer;
+import org.apache.cloudstack.network.opendaylight.agent.responses.ConfigurePortAnswer;
+import org.apache.cloudstack.network.opendaylight.agent.responses.DestroyNetworkAnswer;
+import org.apache.cloudstack.network.opendaylight.agent.responses.DestroyPortAnswer;
+import org.apache.cloudstack.network.opendaylight.dao.OpenDaylightControllerMappingDao;
+import org.apache.cloudstack.network.opendaylight.dao.OpenDaylightControllerVO;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
+import com.cloud.network.Network;
+import com.cloud.network.Network.GuestType;
+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.NetworkProfile;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetwork.IsolationMethod;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.guru.GuestNetworkGuru;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import com.cloud.user.Account;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachineProfile;
+
+public class OpendaylightGuestNetworkGuru extends GuestNetworkGuru {
+    private static final Logger s_logger = Logger.getLogger(OpendaylightGuestNetworkGuru.class);
+
+    @Inject
+    protected NetworkOfferingServiceMapDao ntwkOfferingSrvcDao;
+    @Inject
+    PhysicalNetworkDao physicalNetworkDao;
+    @Inject
+    OpenDaylightControllerMappingDao openDaylightControllerMappingDao;
+    @Inject
+    NetworkModel networkModel;
+    @Inject
+    AgentManager agentManager;
+    @Inject
+    NetworkDao networkDao;
+
+    public OpendaylightGuestNetworkGuru() {
+        _isolationMethods = new IsolationMethod[] {IsolationMethod.ODL};
+    }
+
+    @Override
+    protected boolean canHandle(NetworkOffering offering, NetworkType networkType, PhysicalNetwork physicalNetwork) {
+        if (networkType == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) && offering.getGuestType() == Network.GuestType.Isolated &&
+                isMyIsolationMethod(physicalNetwork) && ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(offering.getId(), Service.Connectivity)
+                && ntwkOfferingSrvcDao.isProviderForNetworkOffering(offering.getId(), Provider.Opendaylight)) {
+            return true;
+        } else {
+            s_logger.trace("We only take care of Guest networks of type   " + GuestType.Isolated + " in zone of type " + NetworkType.Advanced);
+            return false;
+        }
+    }
+
+    @Override
+    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
+        PhysicalNetworkVO physnet = physicalNetworkDao.findById(plan.getPhysicalNetworkId());
+        DataCenter dc = _dcDao.findById(plan.getDataCenterId());
+        if (!canHandle(offering, dc.getNetworkType(), physnet)) {
+            s_logger.debug("Refusing to design this network");
+            return null;
+        }
+
+        List<OpenDaylightControllerVO> devices = openDaylightControllerMappingDao.listByPhysicalNetwork(physnet.getId());
+        if (devices.isEmpty()) {
+            s_logger.error("No Controller on physical network " + physnet.getName());
+            return null;
+        }
+        s_logger.debug("Controller " + devices.get(0).getUuid() + " found on physical network " + physnet.getId());
+        s_logger.debug("Physical isolation type is ODL, asking GuestNetworkGuru to design this network");
+
+        NetworkVO networkObject = (NetworkVO)super.design(offering, plan, userSpecified, owner);
+        if (networkObject == null) {
+            return null;
+        }
+        // Override the broadcast domain type
+        networkObject.setBroadcastDomainType(BroadcastDomainType.OpenDaylight);
+
+        return networkObject;
+    }
+
+    @Override
+    public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException {
+        assert (network.getState() == State.Implementing) : "Why are we implementing " + network;
+
+        long dcId = dest.getDataCenter().getId();
+
+        //get physical network id
+        Long physicalNetworkId = network.getPhysicalNetworkId();
+
+        // physical network id can be null in Guest Network in Basic zone, so locate the physical network
+        if (physicalNetworkId == null) {
+            physicalNetworkId = networkModel.findPhysicalNetworkId(dcId, offering.getTags(), offering.getTrafficType());
+        }
+
+        NetworkVO implemented = new NetworkVO(network.getTrafficType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), State.Allocated,
+                network.getDataCenterId(), physicalNetworkId);
+
+        if (network.getGateway() != null) {
+            implemented.setGateway(network.getGateway());
+        }
+
+        if (network.getCidr() != null) {
+            implemented.setCidr(network.getCidr());
+        }
+
+        // Name is either the given name or the uuid
+        String name = network.getName();
+        if (name == null || name.isEmpty()) {
+            name = ((NetworkVO)network).getUuid();
+        }
+
+        List<OpenDaylightControllerVO> devices = openDaylightControllerMappingDao.listByPhysicalNetwork(physicalNetworkId);
+        if (devices.isEmpty()) {
+            s_logger.error("No Controller on physical network " + physicalNetworkId);
+            return null;
+        }
+        OpenDaylightControllerVO controller = devices.get(0);
+
+        ConfigureNetworkCommand cmd = new ConfigureNetworkCommand(name, context.getAccount().getAccountName());
+        ConfigureNetworkAnswer answer = (ConfigureNetworkAnswer)agentManager.easySend(controller.getHostId(), cmd);
+
+        if (answer == null || !answer.getResult()) {
+            s_logger.error("ConfigureNetworkCommand failed");
+            return null;
+        }
+
+        implemented.setBroadcastUri(BroadcastDomainType.OpenDaylight.toUri(answer.getNetworkUuid()));
+        implemented.setBroadcastDomainType(BroadcastDomainType.OpenDaylight);
+        s_logger.info("Implemented OK, network linked to  = " + implemented.getBroadcastUri().toString());
+
+        return implemented;
+    }
+
+    @Override
+    public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
+            throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException {
+        super.reserve(nic, network, vm, dest, context);
+
+        //get physical network id
+        Long physicalNetworkId = network.getPhysicalNetworkId();
+
+        List<OpenDaylightControllerVO> devices = openDaylightControllerMappingDao.listByPhysicalNetwork(physicalNetworkId);
+        if (devices.isEmpty()) {
+            s_logger.error("No Controller on physical network " + physicalNetworkId);
+            throw new InsufficientVirtualNetworkCapcityException("No OpenDaylight Controller configured for this network", dest.getPod().getId());
+        }
+        OpenDaylightControllerVO controller = devices.get(0);
+
+        AddHypervisorCommand addCmd = new AddHypervisorCommand(dest.getHost().getUuid(), dest.getHost().getPrivateIpAddress());
+        AddHypervisorAnswer addAnswer = (AddHypervisorAnswer)agentManager.easySend(controller.getHostId(), addCmd);
+        if (addAnswer == null || !addAnswer.getResult()) {
+            s_logger.error("Failed to add " + dest.getHost().getName() + " as a node to the controller");
+            throw new InsufficientVirtualNetworkCapcityException("Failed to add destination hypervisor to the OpenDaylight Controller", dest.getPod().getId());
+        }
+
+        ConfigurePortCommand cmd = new ConfigurePortCommand(UUID.fromString(nic.getUuid()), UUID.fromString(BroadcastDomainType.getValue(network.getBroadcastUri())), context
+                .getAccount().getAccountName(), nic.getMacAddress());
+        ConfigurePortAnswer answer = (ConfigurePortAnswer)agentManager.easySend(controller.getHostId(), cmd);
+
+        if (answer == null || !answer.getResult()) {
+            s_logger.error("ConfigureNetworkCommand failed");
+            throw new InsufficientVirtualNetworkCapcityException("Failed to configure the port on the OpenDaylight Controller", dest.getPod().getId());
+        }
+
+    }
+
+    @Override
+    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
+        boolean success = super.release(nic, vm, reservationId);
+
+        if (success) {
+            //get physical network id
+            NetworkVO network = _networkDao.findById(nic.getNetworkId());
+            Long physicalNetworkId = network.getPhysicalNetworkId();
+
+            List<OpenDaylightControllerVO> devices = openDaylightControllerMappingDao.listByPhysicalNetwork(physicalNetworkId);
+            if (devices.isEmpty()) {
+                s_logger.error("No Controller on physical network " + physicalNetworkId);
+                throw new CloudRuntimeException("No OpenDaylight controller on this physical network");
+            }
+            OpenDaylightControllerVO controller = devices.get(0);
+
+            DestroyPortCommand cmd = new DestroyPortCommand(UUID.fromString(nic.getUuid()));
+            DestroyPortAnswer answer = (DestroyPortAnswer)agentManager.easySend(controller.getHostId(), cmd);
+
+            if (answer == null || !answer.getResult()) {
+                s_logger.error("DestroyPortCommand failed");
+                success = false;
+            }
+        }
+
+        return success;
+    }
+
+    @Override
+    public void shutdown(NetworkProfile profile, NetworkOffering offering) {
+        NetworkVO networkObject = networkDao.findById(profile.getId());
+        if (networkObject.getBroadcastDomainType() != BroadcastDomainType.OpenDaylight || networkObject.getBroadcastUri() == null) {
+            s_logger.warn("BroadcastUri is empty or incorrect for guestnetwork " + networkObject.getDisplayText());
+            return;
+        }
+
+        List<OpenDaylightControllerVO> devices = openDaylightControllerMappingDao.listByPhysicalNetwork(networkObject.getPhysicalNetworkId());
+        if (devices.isEmpty()) {
+            s_logger.error("No Controller on physical network " + networkObject.getPhysicalNetworkId());
+            return;
+        }
+        OpenDaylightControllerVO controller = devices.get(0);
+
+        DestroyNetworkCommand cmd = new DestroyNetworkCommand(BroadcastDomainType.getValue(networkObject.getBroadcastUri()));
+        DestroyNetworkAnswer answer = (DestroyNetworkAnswer)agentManager.easySend(controller.getHostId(), cmd);
+
+        if (answer == null || !answer.getResult()) {
+            s_logger.error("DestroyNetworkCommand failed");
+        }
+
+        super.shutdown(profile, offering);
+    }
+
+    @Override
+    public boolean trash(Network network, NetworkOffering offering) {
+        // TODO Auto-generated method stub
+        return super.trash(network, offering);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/OpenDaylightControllerResource.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/OpenDaylightControllerResource.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/OpenDaylightControllerResource.java
new file mode 100644
index 0000000..5c1e1e4
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/OpenDaylightControllerResource.java
@@ -0,0 +1,321 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.network.opendaylight.agent;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.InvalidParameterException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.UUID;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.network.opendaylight.agent.commands.AddHypervisorCommand;
+import org.apache.cloudstack.network.opendaylight.agent.commands.ConfigureNetworkCommand;
+import org.apache.cloudstack.network.opendaylight.agent.commands.ConfigurePortCommand;
+import org.apache.cloudstack.network.opendaylight.agent.commands.DestroyNetworkCommand;
+import org.apache.cloudstack.network.opendaylight.agent.commands.DestroyPortCommand;
+import org.apache.cloudstack.network.opendaylight.agent.commands.StartupOpenDaylightControllerCommand;
+import org.apache.cloudstack.network.opendaylight.agent.responses.AddHypervisorAnswer;
+import org.apache.cloudstack.network.opendaylight.agent.responses.ConfigureNetworkAnswer;
+import org.apache.cloudstack.network.opendaylight.agent.responses.ConfigurePortAnswer;
+import org.apache.cloudstack.network.opendaylight.agent.responses.DestroyNetworkAnswer;
+import org.apache.cloudstack.network.opendaylight.agent.responses.DestroyPortAnswer;
+import org.apache.cloudstack.network.opendaylight.api.NeutronRestApiException;
+import org.apache.cloudstack.network.opendaylight.api.model.NeutronNetwork;
+import org.apache.cloudstack.network.opendaylight.api.model.NeutronNetworkWrapper;
+import org.apache.cloudstack.network.opendaylight.api.model.NeutronNode;
+import org.apache.cloudstack.network.opendaylight.api.model.NeutronNodeWrapper;
+import org.apache.cloudstack.network.opendaylight.api.model.NeutronNodesList;
+import org.apache.cloudstack.network.opendaylight.api.model.NeutronPort;
+import org.apache.cloudstack.network.opendaylight.api.model.NeutronPortWrapper;
+import org.apache.cloudstack.network.opendaylight.api.resources.NeutronNetworksNorthboundAction;
+import org.apache.cloudstack.network.opendaylight.api.resources.NeutronNodesNorthboundAction;
+import org.apache.cloudstack.network.opendaylight.api.resources.NeutronPortsNorthboundAction;
+
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.MaintainAnswer;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.resource.ServerResource;
+
+public class OpenDaylightControllerResource implements ServerResource {
+    private static final Logger s_logger = Logger.getLogger(OpenDaylightControllerResource.class);
+    private Map<String, Object> configuration = new HashMap<String, Object>();
+
+    private URL controllerUrl;
+    private String controllerUsername;
+    private String controllerPassword;
+
+    private int runLevel;
+
+    @Override
+    public String getName() {
+        if (configuration.containsKey("name"))
+            return (String)configuration.get("name");
+        else
+            return null;
+    }
+
+    @Override
+    public void setName(String name) {
+        configuration.put("name", name);
+    }
+
+    @Override
+    public void setConfigParams(Map<String, Object> params) {
+        for (Entry<String, Object> entry : params.entrySet()) {
+            configuration.put(entry.getKey(), entry.getValue());
+        }
+        updateConfiguration();
+    }
+
+    @Override
+    public Map<String, Object> getConfigParams() {
+        return Collections.unmodifiableMap(configuration);
+    }
+
+    @Override
+    public int getRunLevel() {
+        return runLevel;
+    }
+
+    @Override
+    public void setRunLevel(int level) {
+        runLevel = level;
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        for (Entry<String, Object> entry : params.entrySet()) {
+            configuration.put(entry.getKey(), entry.getValue());
+        }
+        updateConfiguration();
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public Type getType() {
+        return Type.L2Networking;
+    }
+
+    @Override
+    public StartupCommand[] initialize() {
+        StartupOpenDaylightControllerCommand sc = new StartupOpenDaylightControllerCommand();
+        sc.setGuid((String)configuration.get("guid"));
+        sc.setName(getName());
+        sc.setDataCenter((String)configuration.get("zoneId"));
+        sc.setPod("");
+        sc.setPrivateIpAddress("");
+        sc.setStorageIpAddress("");
+        sc.setVersion(OpenDaylightControllerResource.class.getPackage().getImplementationVersion());
+        return new StartupCommand[] {sc};
+
+    }
+
+    @Override
+    public PingCommand getCurrentStatus(long id) {
+        return new PingCommand(Host.Type.L2Networking, id);
+    }
+
+    @Override
+    public Answer executeRequest(Command cmd) {
+        if (cmd instanceof ConfigureNetworkCommand) {
+            return executeRequest((ConfigureNetworkCommand)cmd);
+        } else if (cmd instanceof DestroyNetworkCommand) {
+            return executeRequest((DestroyNetworkCommand)cmd);
+        } else if (cmd instanceof ConfigurePortCommand) {
+            return executeRequest((ConfigurePortCommand)cmd);
+        } else if (cmd instanceof DestroyPortCommand) {
+            return executeRequest((DestroyPortCommand)cmd);
+        } else if (cmd instanceof AddHypervisorCommand) {
+            return executeRequest((AddHypervisorCommand)cmd);
+        } else if (cmd instanceof ReadyCommand) {
+            return executeRequest((ReadyCommand)cmd);
+        } else if (cmd instanceof MaintainCommand) {
+            return executeRequest((MaintainCommand)cmd);
+        } else {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+    }
+
+    @Override
+    public void disconnected() {
+        s_logger.warn("OpenDaylightControllerResource is disconnected from the controller at " + controllerUrl);
+
+    }
+
+    @Override
+    public IAgentControl getAgentControl() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void setAgentControl(IAgentControl agentControl) {
+        // TODO Auto-generated method stub
+
+    }
+
+    private Answer executeRequest(final ReadyCommand cmd) {
+        return new ReadyAnswer(cmd);
+    }
+
+    private Answer executeRequest(final MaintainCommand cmd) {
+        return new MaintainAnswer(cmd);
+    }
+
+    private Answer executeRequest(ConfigureNetworkCommand cmd) {
+        NeutronNetworksNorthboundAction configureNetwork = new NeutronNetworksNorthboundAction(controllerUrl, controllerUsername, controllerPassword);
+        NeutronNetwork newNetwork = new NeutronNetwork();
+
+        // Configuration from the command
+        newNetwork.setName(cmd.getName());
+        newNetwork.setTenantId(cmd.getTenantId());
+
+        // Static configuation
+        newNetwork.setNetworkType("gre");
+        newNetwork.setShared(false);
+        newNetwork.setSegmentationId(100);
+        newNetwork.setId(UUID.randomUUID());
+
+        NeutronNetworkWrapper wrapper = new NeutronNetworkWrapper();
+        wrapper.setNetwork(newNetwork);
+        try {
+            wrapper = configureNetwork.createNeutronNetwork(wrapper);
+        } catch (NeutronRestApiException e) {
+            s_logger.error("createNeutronNetwork failed", e);
+            return new ConfigureNetworkAnswer(cmd, e);
+        }
+
+        return new ConfigureNetworkAnswer(cmd, true, null, wrapper.getNetwork().getId().toString());
+    }
+
+    private Answer executeRequest(DestroyNetworkCommand cmd) {
+        NeutronNetworksNorthboundAction configureNetwork = new NeutronNetworksNorthboundAction(controllerUrl, controllerUsername, controllerPassword);
+        try {
+            configureNetwork.deleteNeutronNetwork(cmd.getNetworkUuid());
+        } catch (NeutronRestApiException e) {
+            s_logger.error("deleteNeutronNetwork failed", e);
+            return new DestroyNetworkAnswer(cmd, e);
+        }
+
+        return new DestroyNetworkAnswer(cmd, true, "Network " + cmd.getNetworkUuid() + " deleted");
+    }
+
+    private Answer executeRequest(ConfigurePortCommand cmd) {
+        NeutronPortsNorthboundAction configurePort = new NeutronPortsNorthboundAction(controllerUrl, controllerUsername, controllerPassword);
+        NeutronPort newPort = new NeutronPort();
+
+        // Configuration from the command
+        newPort.setId(cmd.getPortId());
+        newPort.setTenantId(cmd.getTennantId());
+        newPort.setAdminStateUp(true);
+        newPort.setName(cmd.getPortId().toString());
+        newPort.setNetworkId(cmd.getNetworkId());
+        newPort.setMacAddress(cmd.getMacAddress());
+        newPort.setDeviceId(UUID.randomUUID());
+
+        // Static valus
+        newPort.setStatus("ACTIVE");
+        newPort.setFixedIps(Collections.<String> emptyList());
+
+        NeutronPortWrapper portWrapper = new NeutronPortWrapper();
+        portWrapper.setPort(newPort);
+        try {
+            portWrapper = configurePort.createNeutronPort(portWrapper);
+        } catch (NeutronRestApiException e) {
+            s_logger.error("createPortCommand failed", e);
+            return new ConfigurePortAnswer(cmd, e);
+        }
+
+        return new ConfigurePortAnswer(cmd, true, "Port " + portWrapper.getPort().getId().toString() + " created");
+
+    }
+
+    private Answer executeRequest(DestroyPortCommand cmd) {
+        NeutronPortsNorthboundAction configurePort = new NeutronPortsNorthboundAction(controllerUrl, controllerUsername, controllerPassword);
+        try {
+            configurePort.deleteNeutronPort(cmd.getPortId().toString());
+        } catch (NeutronRestApiException e) {
+            s_logger.error("deleteNeutronPort failed", e);
+            return new DestroyPortAnswer(cmd, e);
+        }
+
+        return new DestroyPortAnswer(cmd, true, "Port " + cmd.getPortId().toString() + " deleted");
+    }
+
+    private Answer executeRequest(AddHypervisorCommand cmd) {
+        NeutronNodesNorthboundAction nodeActions = new NeutronNodesNorthboundAction(controllerUrl, controllerUsername, controllerPassword);
+        try {
+            NeutronNodesList<NeutronNodeWrapper> nodes = nodeActions.listAllNodes();
+            if (nodes.getNodes() != null) {
+                for (NeutronNodeWrapper nodeWrapper : nodes.getNodes()) {
+                    NeutronNode node = nodeWrapper.getNode();
+                    if (node.getId().equals(cmd.getHostId())) {
+                        return new AddHypervisorAnswer(cmd, true, "Hypervisor already connected");
+                    }
+                }
+            }
+
+            // Not found in the existing node list, add it
+            nodeActions.updateNeutronNodeV2("OVS", cmd.getHostId(), cmd.getIpAddress(), 6640);
+        } catch (NeutronRestApiException e) {
+            s_logger.error("Call to OpenDaylight failed", e);
+            return new AddHypervisorAnswer(cmd, e);
+        }
+        return new AddHypervisorAnswer(cmd, true, "Hypervisor " + cmd.getHostId() + " added");
+    }
+
+    private void updateConfiguration() {
+        if (!configuration.containsKey("url") || !configuration.containsKey("username") || !configuration.containsKey("password"))
+            throw new InvalidParameterException("OpenDaylightControllerResource needs a url, username and password.");
+        try {
+            controllerUrl = new URL((String)configuration.get("url"));
+        } catch (MalformedURLException e) {
+            throw new InvalidParameterException("OpenDaylightControllerResource found an invalid controller url");
+        }
+        controllerUsername = (String)configuration.get("username");
+        controllerPassword = (String)configuration.get("password");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/OpenDaylightControllerResourceManager.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/OpenDaylightControllerResourceManager.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/OpenDaylightControllerResourceManager.java
new file mode 100644
index 0000000..1bc0e82
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/OpenDaylightControllerResourceManager.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 org.apache.cloudstack.network.opendaylight.agent;
+
+import org.apache.cloudstack.network.opendaylight.api.commands.AddOpenDaylightControllerCmd;
+import org.apache.cloudstack.network.opendaylight.api.commands.DeleteOpenDaylightControllerCmd;
+import org.apache.cloudstack.network.opendaylight.dao.OpenDaylightControllerVO;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.utils.component.PluggableService;
+
+public interface OpenDaylightControllerResourceManager extends PluggableService {
+
+    public OpenDaylightControllerVO addController(AddOpenDaylightControllerCmd cmd);
+
+    public void deleteController(DeleteOpenDaylightControllerCmd cmd) throws InvalidParameterValueException;
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/OpenDaylightControllerResourceManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/OpenDaylightControllerResourceManagerImpl.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/OpenDaylightControllerResourceManagerImpl.java
new file mode 100644
index 0000000..ad4db15
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/OpenDaylightControllerResourceManagerImpl.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 org.apache.cloudstack.network.opendaylight.agent;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
+import org.apache.cloudstack.network.opendaylight.api.commands.AddOpenDaylightControllerCmd;
+import org.apache.cloudstack.network.opendaylight.api.commands.DeleteOpenDaylightControllerCmd;
+import org.apache.cloudstack.network.opendaylight.dao.OpenDaylightControllerMappingDao;
+import org.apache.cloudstack.network.opendaylight.dao.OpenDaylightControllerVO;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.network.Network;
+import com.cloud.network.Networks;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceState;
+import com.cloud.resource.ServerResource;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class OpenDaylightControllerResourceManagerImpl implements OpenDaylightControllerResourceManager {
+    private final static Logger s_logger = Logger.getLogger(OpenDaylightControllerResourceManagerImpl.class);
+
+    @Inject
+    HostDao hostDao;
+    @Inject
+    ResourceManager resourceManager;
+    @Inject
+    PhysicalNetworkDao physicalNetworkDao;
+    @Inject
+    PhysicalNetworkServiceProviderDao physicalNetworkServiceProviderDao;
+    @Inject
+    OpenDaylightControllerMappingDao openDaylightControllerMappingDao;
+    @Inject
+    NetworkDao networkDao;
+
+    @Override
+    public List<Class<?>> getCommands() {
+        List<Class<?>> commands = new ArrayList<Class<?>>();
+        commands.add(AddOpenDaylightControllerCmd.class);
+        return commands;
+    }
+
+    @Override
+    public OpenDaylightControllerVO addController(AddOpenDaylightControllerCmd cmd) {
+        ServerResource odlController = new OpenDaylightControllerResource();
+
+        final String deviceName = NetworkDevice.OpenDaylightController.getName();
+        NetworkDevice networkDevice = NetworkDevice.getNetworkDevice(deviceName);
+        final Long physicalNetworkId = cmd.getPhysicalNetworkId();
+        PhysicalNetworkVO physicalNetwork = physicalNetworkDao.findById(physicalNetworkId);
+        if (physicalNetwork == null) {
+            throw new InvalidParameterValueException("Could not find phyical network with ID: " + physicalNetworkId);
+        }
+        long zoneId = physicalNetwork.getDataCenterId();
+
+        final PhysicalNetworkServiceProviderVO ntwkSvcProvider = physicalNetworkServiceProviderDao.findByServiceProvider(physicalNetwork.getId(),
+                networkDevice.getNetworkServiceProvder());
+        if (ntwkSvcProvider == null) {
+            throw new CloudRuntimeException("Network Service Provider: " + networkDevice.getNetworkServiceProvder() + " is not enabled in the physical network: "
+                    + physicalNetworkId + "to add this device");
+        } else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) {
+            throw new CloudRuntimeException("Network Service Provider: " + ntwkSvcProvider.getProviderName() + " is in shutdown state in the physical network: "
+                    + physicalNetworkId + "to add this device");
+        }
+
+        final Map<String, String> hostParams = new HashMap<String, String>();
+        hostParams.put("guid", UUID.randomUUID().toString());
+        hostParams.put("zoneId", String.valueOf(physicalNetwork.getDataCenterId()));
+        hostParams.put("physicalNetworkId", String.valueOf(physicalNetwork.getId()));
+        hostParams.put("name", "ODL Controller - " + hostParams.get("guid"));
+        hostParams.put("url", cmd.getUrl());
+        hostParams.put("username", cmd.getUsername());
+        hostParams.put("password", cmd.getPassword());
+
+        Map<String, Object> hostdetails = new HashMap<String, Object>();
+        hostdetails.putAll(hostParams);
+
+        try {
+            odlController.configure(hostParams.get("name"), hostdetails);
+            final Host host = resourceManager.addHost(zoneId, odlController, Host.Type.L2Networking, hostParams);
+            if (host != null) {
+                return Transaction.execute(new TransactionCallback<OpenDaylightControllerVO>() {
+                    @Override
+                    public OpenDaylightControllerVO doInTransaction(TransactionStatus status) {
+                        OpenDaylightControllerVO controller = new OpenDaylightControllerVO(host.getId(), physicalNetworkId, ntwkSvcProvider.getProviderName(), hostParams
+                                .get("name"));
+                        openDaylightControllerMappingDao.persist(controller);
+                        return controller;
+                    }
+                });
+            } else {
+                throw new CloudRuntimeException("Failed to create host object for ODL Controller");
+            }
+        } catch (ConfigurationException e) {
+            throw new CloudRuntimeException("Failed to add ODL Controller as a resource", e);
+        }
+    }
+
+    @Override
+    public void deleteController(DeleteOpenDaylightControllerCmd cmd) throws InvalidParameterValueException {
+        OpenDaylightControllerVO controller = openDaylightControllerMappingDao.findById(cmd.getId());
+        if (controller == null) {
+            throw new InvalidParameterValueException("No ODL Controller with id " + cmd.getId());
+        }
+
+        // Find the physical network we work for
+        Long physicalNetworkId = controller.getPhysicalNetworkId();
+        PhysicalNetworkVO physicalNetwork = physicalNetworkDao.findById(physicalNetworkId);
+        if (physicalNetwork != null) {
+            // Lets see if there are networks that use us
+            List<NetworkVO> networkList = networkDao.listByPhysicalNetwork(physicalNetworkId);
+
+            // Networks with broadcast type lswitch are ours
+            for (NetworkVO network : networkList) {
+                if (network.getBroadcastDomainType() == Networks.BroadcastDomainType.OpenDaylight) {
+                    if ((network.getState() != Network.State.Shutdown) && (network.getState() != Network.State.Destroy)) {
+                        throw new CloudRuntimeException("This Controller can not be deleted as there are one or more logical networks provisioned by cloudstack.");
+                    }
+                }
+            }
+        }
+
+        HostVO host = hostDao.findById(controller.getHostId());
+        Long hostId = host.getId();
+
+        host.setResourceState(ResourceState.Maintenance);
+        hostDao.update(hostId, host);
+        resourceManager.deleteHost(hostId, false, false);
+
+        openDaylightControllerMappingDao.remove(cmd.getId());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/AddHypervisorCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/AddHypervisorCommand.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/AddHypervisorCommand.java
new file mode 100644
index 0000000..06e94b3
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/AddHypervisorCommand.java
@@ -0,0 +1,58 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.network.opendaylight.agent.commands;
+
+import com.cloud.agent.api.Command;
+
+public class AddHypervisorCommand extends Command {
+    private String hostId;
+    private String ipAddress;
+
+    public AddHypervisorCommand() {
+    }
+
+    public AddHypervisorCommand(String hostId, String ipAddress) {
+        this.hostId = hostId;
+        this.ipAddress = ipAddress;
+    }
+
+    public String getHostId() {
+        return hostId;
+    }
+
+    public void setHostId(String hostId) {
+        this.hostId = hostId;
+    }
+
+    public String getIpAddress() {
+        return ipAddress;
+    }
+
+    public void setIpAddress(String ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/ConfigureNetworkCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/ConfigureNetworkCommand.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/ConfigureNetworkCommand.java
new file mode 100644
index 0000000..bfbcde4
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/ConfigureNetworkCommand.java
@@ -0,0 +1,54 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.network.opendaylight.agent.commands;
+
+import com.cloud.agent.api.Command;
+
+public class ConfigureNetworkCommand extends Command {
+    private String name;
+    private String tenantId;
+
+    public ConfigureNetworkCommand(String name, String tenantId) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(String tennantId) {
+        tenantId = tennantId;
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/ConfigurePortCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/ConfigurePortCommand.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/ConfigurePortCommand.java
new file mode 100644
index 0000000..3d4d2a2
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/ConfigurePortCommand.java
@@ -0,0 +1,80 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.network.opendaylight.agent.commands;
+
+import java.util.UUID;
+
+import com.cloud.agent.api.Command;
+
+public class ConfigurePortCommand extends Command {
+    private UUID networkId;
+    private String tennantId;
+    private String macAddress;
+    private UUID portId;
+
+    public ConfigurePortCommand() {
+    }
+
+    public ConfigurePortCommand(UUID portId, UUID networkId, String tennantId, String macAddress) {
+        this.portId = portId;
+        this.networkId = networkId;
+        this.tennantId = tennantId;
+        this.macAddress = macAddress;
+    }
+
+    public UUID getNetworkId() {
+        return networkId;
+    }
+
+    public void setNetworkId(UUID networkId) {
+        this.networkId = networkId;
+    }
+
+    public String getTennantId() {
+        return tennantId;
+    }
+
+    public void setTennantId(String tennantId) {
+        this.tennantId = tennantId;
+    }
+
+    public String getMacAddress() {
+        return macAddress;
+    }
+
+    public void setMacAddress(String macAddress) {
+        this.macAddress = macAddress;
+    }
+
+    public UUID getPortId() {
+        return portId;
+    }
+
+    public void setPortId(UUID portId) {
+        this.portId = portId;
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/DestroyNetworkCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/DestroyNetworkCommand.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/DestroyNetworkCommand.java
new file mode 100644
index 0000000..6d1bc04
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/DestroyNetworkCommand.java
@@ -0,0 +1,45 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.network.opendaylight.agent.commands;
+
+import com.cloud.agent.api.Command;
+
+public class DestroyNetworkCommand extends Command {
+    private String networkUuid;
+
+    public DestroyNetworkCommand(String networkUuid) {
+        this.networkUuid = networkUuid;
+    }
+
+    public String getNetworkUuid() {
+        return networkUuid;
+    }
+
+    public void setNetworkUuid(String networkUuid) {
+        this.networkUuid = networkUuid;
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/DestroyPortCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/DestroyPortCommand.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/DestroyPortCommand.java
new file mode 100644
index 0000000..c0a8937
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/DestroyPortCommand.java
@@ -0,0 +1,50 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.network.opendaylight.agent.commands;
+
+import java.util.UUID;
+
+import com.cloud.agent.api.Command;
+
+public class DestroyPortCommand extends Command {
+    private UUID portId;
+
+    public DestroyPortCommand() {
+    }
+
+    public DestroyPortCommand(UUID portId) {
+        this.portId = portId;
+    }
+
+    public UUID getPortId() {
+        return portId;
+    }
+
+    public void setPortId(UUID portId) {
+        this.portId = portId;
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/StartupOpenDaylightControllerCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/StartupOpenDaylightControllerCommand.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/StartupOpenDaylightControllerCommand.java
new file mode 100644
index 0000000..de3a7a3
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/commands/StartupOpenDaylightControllerCommand.java
@@ -0,0 +1,29 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.network.opendaylight.agent.commands;
+
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.host.Host;
+
+public class StartupOpenDaylightControllerCommand extends StartupCommand {
+    public StartupOpenDaylightControllerCommand() {
+        super(Host.Type.L2Networking);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/AddHypervisorAnswer.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/AddHypervisorAnswer.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/AddHypervisorAnswer.java
new file mode 100644
index 0000000..7986705
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/AddHypervisorAnswer.java
@@ -0,0 +1,35 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.network.opendaylight.agent.responses;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+
+public class AddHypervisorAnswer extends Answer {
+
+    public AddHypervisorAnswer(Command command, boolean success, String details) {
+        super(command, success, details);
+    }
+
+    public AddHypervisorAnswer(Command command, Exception e) {
+        super(command, e);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/ConfigureNetworkAnswer.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/ConfigureNetworkAnswer.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/ConfigureNetworkAnswer.java
new file mode 100644
index 0000000..81c4a6f
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/ConfigureNetworkAnswer.java
@@ -0,0 +1,43 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.network.opendaylight.agent.responses;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+
+public class ConfigureNetworkAnswer extends Answer {
+    private String networkUuid;
+
+    public ConfigureNetworkAnswer(Command command, boolean success, String details, String networkUuid) {
+        this.networkUuid = networkUuid;
+    }
+
+    public ConfigureNetworkAnswer(Command command, boolean success, String details) {
+        super(command, success, details);
+    }
+
+    public ConfigureNetworkAnswer(Command command, Exception e) {
+        super(command, e);
+    }
+
+    public String getNetworkUuid() {
+        return networkUuid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/ConfigurePortAnswer.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/ConfigurePortAnswer.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/ConfigurePortAnswer.java
new file mode 100644
index 0000000..cf9acc1
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/ConfigurePortAnswer.java
@@ -0,0 +1,35 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.network.opendaylight.agent.responses;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+
+public class ConfigurePortAnswer extends Answer {
+
+    public ConfigurePortAnswer(Command command, boolean success, String details) {
+        super(command, success, details);
+    }
+
+    public ConfigurePortAnswer(Command command, Exception e) {
+        super(command, e);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/DestroyNetworkAnswer.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/DestroyNetworkAnswer.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/DestroyNetworkAnswer.java
new file mode 100644
index 0000000..10284b4
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/DestroyNetworkAnswer.java
@@ -0,0 +1,35 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.network.opendaylight.agent.responses;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+
+public class DestroyNetworkAnswer extends Answer {
+
+    public DestroyNetworkAnswer(Command command, boolean success, String details) {
+        super(command, success, details);
+    }
+
+    public DestroyNetworkAnswer(Command command, Exception e) {
+        super(command, e);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/DestroyPortAnswer.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/DestroyPortAnswer.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/DestroyPortAnswer.java
new file mode 100644
index 0000000..07bb0db
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/agent/responses/DestroyPortAnswer.java
@@ -0,0 +1,35 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.network.opendaylight.agent.responses;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+
+public class DestroyPortAnswer extends Answer {
+
+    public DestroyPortAnswer(Command command, boolean success, String details) {
+        super(command, success, details);
+    }
+
+    public DestroyPortAnswer(Command command, Exception e) {
+        super(command, e);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/dao/OpenDaylightControllerMappingDao.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/dao/OpenDaylightControllerMappingDao.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/dao/OpenDaylightControllerMappingDao.java
new file mode 100644
index 0000000..8799982
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/dao/OpenDaylightControllerMappingDao.java
@@ -0,0 +1,28 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.network.opendaylight.dao;
+
+import java.util.List;
+
+import com.cloud.utils.db.GenericDao;
+
+public interface OpenDaylightControllerMappingDao extends GenericDao<OpenDaylightControllerVO, Long> {
+    List<OpenDaylightControllerVO> listByPhysicalNetwork(long physicalNetworkId);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/dao/OpenDaylightControllerMappingDaoImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/dao/OpenDaylightControllerMappingDaoImpl.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/dao/OpenDaylightControllerMappingDaoImpl.java
new file mode 100644
index 0000000..1d0beca
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/dao/OpenDaylightControllerMappingDaoImpl.java
@@ -0,0 +1,45 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.network.opendaylight.dao;
+
+import java.util.List;
+
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+
+public class OpenDaylightControllerMappingDaoImpl extends GenericDaoBase<OpenDaylightControllerVO, Long> implements OpenDaylightControllerMappingDao {
+    private SearchBuilder<OpenDaylightControllerVO> physicalNetworkIdSearch;
+
+    public OpenDaylightControllerMappingDaoImpl() {
+        physicalNetworkIdSearch = createSearchBuilder();
+        physicalNetworkIdSearch.and("physicalNetworkId", physicalNetworkIdSearch.entity().getPhysicalNetworkId(), Op.EQ);
+        physicalNetworkIdSearch.done();
+    }
+
+    @Override
+    public List<OpenDaylightControllerVO> listByPhysicalNetwork(long physicalNetworkId) {
+        SearchCriteria<OpenDaylightControllerVO> sc = physicalNetworkIdSearch.create();
+        sc.setParameters("physicalNetworkId", physicalNetworkId);
+        return search(sc, null);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/385ddaea/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/dao/OpenDaylightControllerVO.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/dao/OpenDaylightControllerVO.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/dao/OpenDaylightControllerVO.java
new file mode 100644
index 0000000..61d5682
--- /dev/null
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/dao/OpenDaylightControllerVO.java
@@ -0,0 +1,101 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.network.opendaylight.dao;
+
+import java.util.UUID;
+
+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 = "external_opendaylight_controllers")
+public class OpenDaylightControllerVO implements InternalIdentity {
+    private static final long serialVersionUID = -575928081553194369L;
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    private long id;
+
+    @Column(name = "uuid")
+    private String uuid;
+
+    @Column(name = "host_id")
+    private long hostId;
+
+    @Column(name = "physical_network_id")
+    private long physicalNetworkId;
+
+    @Column(name = "provider_name")
+    private String providerName;
+
+    @Column(name = "device_name")
+    private String deviceName;
+
+    public OpenDaylightControllerVO() {
+        uuid = UUID.randomUUID().toString();
+    }
+
+    public OpenDaylightControllerVO(final long hostId, final long physicalNetworkId, final String providerName, final String deviceName) {
+        super();
+        this.hostId = hostId;
+        this.physicalNetworkId = physicalNetworkId;
+        this.providerName = providerName;
+        this.deviceName = deviceName;
+        uuid = UUID.randomUUID().toString();
+    }
+
+    @Override
+    public long getId() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    public String getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public long getPhysicalNetworkId() {
+        return physicalNetworkId;
+    }
+
+    public long getHostId() {
+        return hostId;
+    }
+
+    public String getProviderName() {
+        return providerName;
+    }
+
+    public String getDeviceName() {
+        return deviceName;
+    }
+
+}