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.Constants;
18 import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
19 import org.opendaylight.ovsdb.plugin.api.OvsdbConnectionService;
20 import org.opendaylight.ovsdb.plugin.api.OvsdbInventoryListener;
21 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
22 import org.opendaylight.ovsdb.schema.openvswitch.Port;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
27 import java.net.HttpURLConnection;
28 import java.util.List;
30 import java.util.concurrent.ConcurrentMap;
33 * Handle requests for Neutron Port.
35 public class PortHandler extends AbstractHandler
36 implements INeutronPortAware {
41 static final Logger logger = LoggerFactory.getLogger(PortHandler.class);
43 // The implementation for each of these services is resolved by the OSGi Service Manager
44 private volatile OvsdbConfigurationService ovsdbConfigurationService;
45 private volatile OvsdbConnectionService connectionService;
46 private volatile OvsdbInventoryListener ovsdbInventoryListener;
49 * Invoked when a port creation is requested
50 * to indicate if the specified port can be created.
52 * @param port An instance of proposed new Port object.
53 * @return A HTTP status code to the creation request.
56 public int canCreatePort(NeutronPort port) {
57 return HttpURLConnection.HTTP_CREATED;
61 * Invoked to take action after a port has been created.
63 * @param port An instance of new Neutron Port object.
66 public void neutronPortCreated(NeutronPort port) {
67 int result = canCreatePort(port);
68 if (result != HttpURLConnection.HTTP_CREATED) {
69 logger.error(" Port create validation failed result - {} ", result);
73 enqueueEvent(new NorthboundEvent(port, NorthboundEvent.Action.ADD));
75 private void doNeutronPortCreated(NeutronPort port) {
76 logger.debug(" Port-ADD successful for tenant-id - {}," +
77 " network-id - {}, port-id - {}",
78 port.getTenantID(), port.getNetworkUUID(),
83 * Invoked when a port update is requested
84 * to indicate if the specified port can be changed
85 * using the specified delta.
87 * @param delta Updates to the port object using patch semantics.
88 * @param original An instance of the Neutron Port object
90 * @return A HTTP status code to the update request.
93 public int canUpdatePort(NeutronPort delta,
94 NeutronPort original) {
95 int result = HttpURLConnection.HTTP_OK;
97 * To basic validation of the request
100 if ((original == null) || (delta == null)) {
101 logger.error("port object not specified");
102 return HttpURLConnection.HTTP_BAD_REQUEST;
108 * Invoked to take action after a port has been updated.
110 * @param port An instance of modified Neutron Port object.
113 public void neutronPortUpdated(NeutronPort port) {
117 * Invoked when a port deletion is requested
118 * to indicate if the specified port can be deleted.
120 * @param port An instance of the Neutron Port object to be deleted.
121 * @return A HTTP status code to the deletion request.
124 public int canDeletePort(NeutronPort port) {
125 return HttpURLConnection.HTTP_OK;
129 * Invoked to take action after a port has been deleted.
131 * @param neutronPort An instance of deleted Neutron Port object.
134 public void neutronPortDeleted(NeutronPort neutronPort) {
136 int result = canDeletePort(neutronPort);
137 if (result != HttpURLConnection.HTTP_OK) {
138 logger.error(" deletePort validation failed - result {} ", result);
142 enqueueEvent(new NorthboundEvent(neutronPort, NorthboundEvent.Action.DELETE));
144 private void doNeutronPortDeleted(NeutronPort neutronPort) {
145 logger.debug("Handling neutron delete port " + neutronPort);
147 List<Node> nodes = connectionService.getNodes();
148 for (Node node : nodes) {
150 ConcurrentMap<String, Row> portRows =
151 this.ovsdbConfigurationService.getRows(node,
152 ovsdbConfigurationService.getTableName(node, Port.class));
153 if (portRows != null) {
154 for (Row portRow : portRows.values()) {
155 Port port = ovsdbConfigurationService.getTypedRow(node, Port.class, portRow);
156 for (UUID interfaceUuid : port.getInterfacesColumn().getData()) {
157 Interface interfaceRow = (Interface) ovsdbConfigurationService
159 ovsdbConfigurationService.getTableName(node, Interface.class),
160 interfaceUuid.toString());
162 Map<String, String> externalIds = interfaceRow.getExternalIdsColumn().getData();
164 if (externalIds == null) {
165 logger.trace("No external_ids seen in {}", interfaceRow);
169 /* Compare Neutron port uuid */
170 String neutronPortId = externalIds.get(Constants.EXTERNAL_ID_INTERFACE_ID);
171 if (neutronPortId == null) {
175 if (neutronPortId.equalsIgnoreCase(neutronPort.getPortUUID())) {
176 logger.trace("neutronPortDeleted: Delete interface {}", interfaceRow.getName());
177 ovsdbConfigurationService.deleteRow(node,
178 ovsdbConfigurationService.getTableName(node, Port.class),
179 port.getUuid().toString());
185 } catch (Exception e) {
186 logger.error("Exception during handlingNeutron network delete");
189 logger.debug(" PORT delete successful for tenant-id - {}, " +
190 " network-id - {}, port-id - {}",
191 neutronPort.getTenantID(), neutronPort.getNetworkUUID(),
192 neutronPort.getID());
199 * @param abstractEvent the {@link org.opendaylight.ovsdb.openstack.netvirt.AbstractEvent} event to be handled.
200 * @see EventDispatcher
203 public void processEvent(AbstractEvent abstractEvent) {
204 if (!(abstractEvent instanceof NorthboundEvent)) {
205 logger.error("Unable to process abstract event " + abstractEvent);
208 NorthboundEvent ev = (NorthboundEvent) abstractEvent;
209 switch (ev.getAction()) {
211 doNeutronPortCreated(ev.getPort());
214 doNeutronPortDeleted(ev.getPort());
217 logger.warn("Unable to process event action " + ev.getAction());