2 * Copyright (C) 2013 Red Hat, Inc.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 * Authors : Madhu Venugopal, Brent Salisbury
10 package org.opendaylight.ovsdb.openstack.netvirt;
12 import org.opendaylight.controller.networkconfig.neutron.INeutronPortAware;
13 import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
14 import org.opendaylight.controller.sal.core.Node;
15 import org.opendaylight.ovsdb.lib.notation.Row;
16 import org.opendaylight.ovsdb.lib.notation.UUID;
17 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
18 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
19 import org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter;
20 import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
21 import org.opendaylight.ovsdb.plugin.api.OvsdbConnectionService;
22 import org.opendaylight.ovsdb.plugin.api.OvsdbInventoryListener;
23 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
24 import org.opendaylight.ovsdb.schema.openvswitch.Port;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
29 import java.net.HttpURLConnection;
30 import java.util.List;
32 import java.util.concurrent.ConcurrentMap;
35 * Handle requests for Neutron Port.
37 public class PortHandler extends AbstractHandler
38 implements INeutronPortAware {
43 static final Logger logger = LoggerFactory.getLogger(PortHandler.class);
45 // The implementation for each of these services is resolved by the OSGi Service Manager
46 private volatile OvsdbConfigurationService ovsdbConfigurationService;
47 private volatile OvsdbConnectionService connectionService;
48 private volatile OvsdbInventoryListener ovsdbInventoryListener;
49 private volatile NeutronL3Adapter neutronL3Adapter;
52 * Invoked when a port creation is requested
53 * to indicate if the specified port can be created.
55 * @param port An instance of proposed new Port object.
56 * @return A HTTP status code to the creation request.
59 public int canCreatePort(NeutronPort port) {
60 return HttpURLConnection.HTTP_CREATED;
64 * Invoked to take action after a port has been created.
66 * @param port An instance of new Neutron Port object.
69 public void neutronPortCreated(NeutronPort neutronPort) {
70 int result = canCreatePort(neutronPort);
71 if (result != HttpURLConnection.HTTP_CREATED) {
72 logger.error(" Port create validation failed result - {} ", result);
76 enqueueEvent(new NorthboundEvent(neutronPort, Action.ADD));
78 private void doNeutronPortCreated(NeutronPort neutronPort) {
79 logger.debug(" Port-ADD successful for tenant-id - {}," +
80 " network-id - {}, port-id - {}",
81 neutronPort.getTenantID(), neutronPort.getNetworkUUID(),
83 neutronL3Adapter.handleNeutronPortEvent(neutronPort, Action.ADD);
87 * Invoked when a port update is requested
88 * to indicate if the specified port can be changed
89 * using the specified delta.
91 * @param delta Updates to the port object using patch semantics.
92 * @param original An instance of the Neutron Port object
94 * @return A HTTP status code to the update request.
97 public int canUpdatePort(NeutronPort delta,
98 NeutronPort original) {
99 int result = HttpURLConnection.HTTP_OK;
101 * To basic validation of the request
104 if ((original == null) || (delta == null)) {
105 logger.error("port object not specified");
106 return HttpURLConnection.HTTP_BAD_REQUEST;
112 * Invoked to take action after a port has been updated.
114 * @param port An instance of modified Neutron Port object.
117 public void neutronPortUpdated(NeutronPort neutronPort) {
118 enqueueEvent(new NorthboundEvent(neutronPort, Action.UPDATE));
120 private void doNeutronPortUpdated(NeutronPort neutronPort) {
121 logger.debug("Handling neutron update port " + neutronPort);
122 neutronL3Adapter.handleNeutronPortEvent(neutronPort, Action.UPDATE);
126 * Invoked when a port deletion is requested
127 * to indicate if the specified port can be deleted.
129 * @param port An instance of the Neutron Port object to be deleted.
130 * @return A HTTP status code to the deletion request.
133 public int canDeletePort(NeutronPort port) {
134 return HttpURLConnection.HTTP_OK;
138 * Invoked to take action after a port has been deleted.
140 * @param neutronPort An instance of deleted Neutron Port object.
143 public void neutronPortDeleted(NeutronPort neutronPort) {
145 int result = canDeletePort(neutronPort);
146 if (result != HttpURLConnection.HTTP_OK) {
147 logger.error(" deletePort validation failed - result {} ", result);
151 enqueueEvent(new NorthboundEvent(neutronPort, Action.DELETE));
153 private void doNeutronPortDeleted(NeutronPort neutronPort) {
154 logger.debug("Handling neutron delete port " + neutronPort);
155 neutronL3Adapter.handleNeutronPortEvent(neutronPort, Action.DELETE);
157 List<Node> nodes = connectionService.getNodes();
158 for (Node node : nodes) {
160 ConcurrentMap<String, Row> portRows =
161 this.ovsdbConfigurationService.getRows(node,
162 ovsdbConfigurationService.getTableName(node, Port.class));
163 if (portRows != null) {
164 for (Row portRow : portRows.values()) {
165 Port port = ovsdbConfigurationService.getTypedRow(node, Port.class, portRow);
166 for (UUID interfaceUuid : port.getInterfacesColumn().getData()) {
167 Interface interfaceRow = (Interface) ovsdbConfigurationService
169 ovsdbConfigurationService.getTableName(node, Interface.class),
170 interfaceUuid.toString());
172 Map<String, String> externalIds = interfaceRow.getExternalIdsColumn().getData();
174 if (externalIds == null) {
175 logger.trace("No external_ids seen in {}", interfaceRow);
179 /* Compare Neutron port uuid */
180 String neutronPortId = externalIds.get(Constants.EXTERNAL_ID_INTERFACE_ID);
181 if (neutronPortId == null) {
185 if (neutronPortId.equalsIgnoreCase(neutronPort.getPortUUID())) {
186 logger.trace("neutronPortDeleted: Delete interface {}", interfaceRow.getName());
187 ovsdbConfigurationService.deleteRow(node,
188 ovsdbConfigurationService.getTableName(node, Port.class),
189 port.getUuid().toString());
195 } catch (Exception e) {
196 logger.error("Exception during handlingNeutron network delete");
199 logger.debug(" PORT delete successful for tenant-id - {}, " +
200 " network-id - {}, port-id - {}",
201 neutronPort.getTenantID(), neutronPort.getNetworkUUID(),
202 neutronPort.getID());
209 * @param abstractEvent the {@link org.opendaylight.ovsdb.openstack.netvirt.AbstractEvent} event to be handled.
210 * @see EventDispatcher
213 public void processEvent(AbstractEvent abstractEvent) {
214 if (!(abstractEvent instanceof NorthboundEvent)) {
215 logger.error("Unable to process abstract event " + abstractEvent);
218 NorthboundEvent ev = (NorthboundEvent) abstractEvent;
219 switch (ev.getAction()) {
221 doNeutronPortCreated(ev.getPort());
224 doNeutronPortDeleted(ev.getPort());
227 doNeutronPortUpdated(ev.getPort());
230 logger.warn("Unable to process event action " + ev.getAction());