Use Topology Node in place of Inventory Node
[ovsdb.git] / openstack / net-virt / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / PortHandler.java
1 /*
2  * Copyright (C) 2013 Red Hat, Inc.
3  *
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
7  *
8  * Authors : Madhu Venugopal, Brent Salisbury
9  */
10 package org.opendaylight.ovsdb.openstack.netvirt;
11
12 import org.opendaylight.neutron.spi.INeutronPortAware;
13 import org.opendaylight.neutron.spi.NeutronPort;
14 import org.opendaylight.ovsdb.lib.notation.Row;
15 import org.opendaylight.ovsdb.lib.notation.UUID;
16 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
17 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
18 import org.opendaylight.ovsdb.openstack.netvirt.api.MdsalConsumer;
19 import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbConfigurationService;
20 import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbConnectionService;
21 import org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter;
22 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
23 import org.opendaylight.ovsdb.schema.openvswitch.Port;
24 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
25
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 import java.net.HttpURLConnection;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.concurrent.ConcurrentMap;
33
34 /**
35  * Handle requests for Neutron Port.
36  */
37 public class PortHandler extends AbstractHandler
38                          implements INeutronPortAware {
39
40     /**
41      * Logger instance.
42      */
43     static final Logger logger = LoggerFactory.getLogger(PortHandler.class);
44
45     // The implementation for each of these services is resolved by the OSGi Service Manager
46     /* TODO SB_MIGRATION */
47     private volatile OvsdbConfigurationService ovsdbConfigurationService;
48     private volatile OvsdbConnectionService connectionService;
49     private volatile MdsalConsumer mdsalConsumer;
50     private volatile NeutronL3Adapter neutronL3Adapter;
51
52     /**
53      * Invoked when a port creation is requested
54      * to indicate if the specified port can be created.
55      *
56      * @param port     An instance of proposed new Port object.
57      * @return A HTTP status code to the creation request.
58      */
59     @Override
60     public int canCreatePort(NeutronPort port) {
61         return HttpURLConnection.HTTP_CREATED;
62     }
63
64     /**
65      * Invoked to take action after a port has been created.
66      *
67      * @param port An instance of new Neutron Port object.
68      */
69     @Override
70     public void neutronPortCreated(NeutronPort neutronPort) {
71         int result = canCreatePort(neutronPort);
72         if (result != HttpURLConnection.HTTP_CREATED) {
73             logger.error(" Port create validation failed result - {} ", result);
74             return;
75         }
76
77         enqueueEvent(new NorthboundEvent(neutronPort, Action.ADD));
78     }
79     private void doNeutronPortCreated(NeutronPort neutronPort) {
80         logger.debug(" Port-ADD successful for tenant-id - {}," +
81                      " network-id - {}, port-id - {}",
82                      neutronPort.getTenantID(), neutronPort.getNetworkUUID(),
83                      neutronPort.getID());
84         neutronL3Adapter.handleNeutronPortEvent(neutronPort, Action.ADD);
85     }
86
87     /**
88      * Invoked when a port update is requested
89      * to indicate if the specified port can be changed
90      * using the specified delta.
91      *
92      * @param delta    Updates to the port object using patch semantics.
93      * @param original An instance of the Neutron Port object
94      *                  to be updated.
95      * @return A HTTP status code to the update request.
96      */
97     @Override
98     public int canUpdatePort(NeutronPort delta,
99                              NeutronPort original) {
100         int result = HttpURLConnection.HTTP_OK;
101         /**
102          * To basic validation of the request
103          */
104
105         if ((original == null) || (delta == null)) {
106             logger.error("port object not specified");
107             return HttpURLConnection.HTTP_BAD_REQUEST;
108         }
109         return result;
110     }
111
112     /**
113      * Invoked to take action after a port has been updated.
114      *
115      * @param port An instance of modified Neutron Port object.
116      */
117     @Override
118     public void neutronPortUpdated(NeutronPort neutronPort) {
119         enqueueEvent(new NorthboundEvent(neutronPort, Action.UPDATE));
120     }
121     private void doNeutronPortUpdated(NeutronPort neutronPort) {
122         logger.debug("Handling neutron update port " + neutronPort);
123         neutronL3Adapter.handleNeutronPortEvent(neutronPort, Action.UPDATE);
124     }
125
126     /**
127      * Invoked when a port deletion is requested
128      * to indicate if the specified port can be deleted.
129      *
130      * @param port     An instance of the Neutron Port object to be deleted.
131      * @return A HTTP status code to the deletion request.
132      */
133     @Override
134     public int canDeletePort(NeutronPort port) {
135         return HttpURLConnection.HTTP_OK;
136     }
137
138     /**
139      * Invoked to take action after a port has been deleted.
140      *
141      * @param neutronPort  An instance of deleted Neutron Port object.
142      */
143     @Override
144     public void neutronPortDeleted(NeutronPort neutronPort) {
145
146         int result = canDeletePort(neutronPort);
147         if  (result != HttpURLConnection.HTTP_OK) {
148             logger.error(" deletePort validation failed - result {} ", result);
149             return;
150         }
151
152         enqueueEvent(new NorthboundEvent(neutronPort, Action.DELETE));
153     }
154     private void doNeutronPortDeleted(NeutronPort neutronPort) {
155         logger.debug("Handling neutron delete port " + neutronPort);
156         neutronL3Adapter.handleNeutronPortEvent(neutronPort, Action.DELETE);
157
158         /* TODO SB_MIGRATION */
159         List<Node> nodes = connectionService.getNodes();
160         for (Node node : nodes) {
161             try {
162                 ConcurrentMap<String, Row> portRows =
163                         this.ovsdbConfigurationService.getRows(node,
164                                                         ovsdbConfigurationService.getTableName(node, Port.class));
165                 if (portRows != null) {
166                     for (Row portRow : portRows.values()) {
167                         Port port = ovsdbConfigurationService.getTypedRow(node, Port.class, portRow);
168                         for (UUID interfaceUuid : port.getInterfacesColumn().getData()) {
169                             Row ifaceRow = ovsdbConfigurationService
170                                     .getRow(node,
171                                             ovsdbConfigurationService.getTableName(node, Interface.class),
172                                             interfaceUuid.toString());
173                             Interface iface = ovsdbConfigurationService.getTypedRow(node, Interface.class, ifaceRow);
174                             Map<String, String> externalIds = iface.getExternalIdsColumn().getData();
175
176                             if (externalIds == null) {
177                                 logger.trace("No external_ids seen in {}", iface.getName());
178                                 continue;
179                             }
180
181                             // Compare Neutron port uuid
182                             String neutronPortId = externalIds.get(Constants.EXTERNAL_ID_INTERFACE_ID);
183                             if (neutronPortId == null) {
184                                 continue;
185                             }
186
187                             if (neutronPortId.equalsIgnoreCase(neutronPort.getPortUUID())) {
188                                 logger.trace("neutronPortDeleted: Delete interface {}", iface.getName());
189                                 ovsdbConfigurationService.deleteRow(node,
190                                                              ovsdbConfigurationService.getTableName(node, Port.class),
191                                                              port.getUuid().toString());
192                                 break;
193                             }
194                         }
195                     }
196                 }
197             } catch (Exception e) {
198                 logger.error("Exception during handlingNeutron port delete", e);
199             }
200         }
201         logger.debug(" PORT delete successful for tenant-id - {}, " +
202                      " network-id - {}, port-id - {}",
203                      neutronPort.getTenantID(), neutronPort.getNetworkUUID(),
204                      neutronPort.getID());
205     }
206
207     /**
208      * Process the event.
209      *
210      * @param abstractEvent the {@link org.opendaylight.ovsdb.openstack.netvirt.AbstractEvent} event to be handled.
211      * @see EventDispatcher
212      */
213     @Override
214     public void processEvent(AbstractEvent abstractEvent) {
215         if (!(abstractEvent instanceof NorthboundEvent)) {
216             logger.error("Unable to process abstract event " + abstractEvent);
217             return;
218         }
219         NorthboundEvent ev = (NorthboundEvent) abstractEvent;
220         switch (ev.getAction()) {
221             case ADD:
222                 doNeutronPortCreated(ev.getPort());
223                 break;
224             case DELETE:
225                 doNeutronPortDeleted(ev.getPort());
226                 break;
227             case UPDATE:
228                 doNeutronPortUpdated(ev.getPort());
229                 break;
230             default:
231                 logger.warn("Unable to process event action " + ev.getAction());
232                 break;
233         }
234     }
235 }