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;
+ }
+
+}