Refactor of the OVSDB Plugin
[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.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;
23
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 import java.net.HttpURLConnection;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.concurrent.ConcurrentMap;
31
32 /**
33  * Handle requests for Neutron Port.
34  */
35 public class PortHandler extends AbstractHandler
36                          implements INeutronPortAware {
37
38     /**
39      * Logger instance.
40      */
41     static final Logger logger = LoggerFactory.getLogger(PortHandler.class);
42
43     private volatile OvsdbConfigurationService ovsdbConfigurationService;
44     private volatile OvsdbConnectionService connectionService;
45     private volatile OvsdbInventoryListener ovsdbInventoryListener;
46
47     /**
48      * Invoked when a port creation is requested
49      * to indicate if the specified port can be created.
50      *
51      * @param port     An instance of proposed new Port object.
52      * @return A HTTP status code to the creation request.
53      */
54     @Override
55     public int canCreatePort(NeutronPort port) {
56         return HttpURLConnection.HTTP_CREATED;
57     }
58
59     /**
60      * Invoked to take action after a port has been created.
61      *
62      * @param port An instance of new Neutron Port object.
63      */
64     @Override
65     public void neutronPortCreated(NeutronPort port) {
66         int result = canCreatePort(port);
67         if (result != HttpURLConnection.HTTP_CREATED) {
68             logger.error(" Port create validation failed result - {} ", result);
69             return;
70         }
71
72         logger.debug(" Port-ADD successful for tenant-id - {}," +
73                      " network-id - {}, port-id - {}, result - {} ",
74                      port.getTenantID(), port.getNetworkUUID(),
75                      port.getID(), result);
76     }
77
78     /**
79      * Invoked when a port update is requested
80      * to indicate if the specified port can be changed
81      * using the specified delta.
82      *
83      * @param delta    Updates to the port object using patch semantics.
84      * @param original An instance of the Neutron Port object
85      *                  to be updated.
86      * @return A HTTP status code to the update request.
87      */
88     @Override
89     public int canUpdatePort(NeutronPort delta,
90                              NeutronPort original) {
91         int result = HttpURLConnection.HTTP_OK;
92         /**
93          * To basic validation of the request
94          */
95
96         if ((original == null) || (delta == null)) {
97             logger.error("port object not specified");
98             return HttpURLConnection.HTTP_BAD_REQUEST;
99         }
100         return result;
101     }
102
103     /**
104      * Invoked to take action after a port has been updated.
105      *
106      * @param port An instance of modified Neutron Port object.
107      */
108     @Override
109     public void neutronPortUpdated(NeutronPort port) {
110     }
111
112     /**
113      * Invoked when a port deletion is requested
114      * to indicate if the specified port can be deleted.
115      *
116      * @param port     An instance of the Neutron Port object to be deleted.
117      * @return A HTTP status code to the deletion request.
118      */
119     @Override
120     public int canDeletePort(NeutronPort port) {
121         return HttpURLConnection.HTTP_OK;
122     }
123
124     /**
125      * Invoked to take action after a port has been deleted.
126      *
127      * @param neutronPort  An instance of deleted Neutron Port object.
128      */
129     @Override
130     public void neutronPortDeleted(NeutronPort neutronPort) {
131
132         int result = canDeletePort(neutronPort);
133         if  (result != HttpURLConnection.HTTP_OK) {
134             logger.error(" deletePort validation failed - result {} ", result);
135             return;
136         }
137
138         List<Node> nodes = connectionService.getNodes();
139         for (Node node : nodes) {
140             try {
141                 ConcurrentMap<String, Row> portRows =
142                         this.ovsdbConfigurationService.getRows(node,
143                                                         ovsdbConfigurationService.getTableName(node, Port.class));
144                 if (portRows != null) {
145                     for (Row portRow : portRows.values()) {
146                         Port port = ovsdbConfigurationService.getTypedRow(node, Port.class, portRow);
147                         for (UUID interfaceUuid : port.getInterfacesColumn().getData()) {
148                             Interface interfaceRow = (Interface) ovsdbConfigurationService
149                                     .getRow(node,
150                                             ovsdbConfigurationService.getTableName(node, Interface.class),
151                                             interfaceUuid.toString());
152
153                             Map<String, String> externalIds = interfaceRow.getExternalIdsColumn().getData();
154
155                             if (externalIds == null) {
156                                 logger.trace("No external_ids seen in {}", interfaceRow);
157                                 continue;
158                             }
159
160                             /* Compare Neutron port uuid */
161                             String neutronPortId = externalIds.get(Constants.EXTERNAL_ID_INTERFACE_ID);
162                             if (neutronPortId == null) {
163                                 continue;
164                             }
165
166                             if (neutronPortId.equalsIgnoreCase(neutronPort.getPortUUID())) {
167                                 logger.trace("neutronPortDeleted: Delete interface {}", interfaceRow.getName());
168                                 ovsdbConfigurationService.deleteRow(node,
169                                                              ovsdbConfigurationService.getTableName(node, Port.class),
170                                                              port.getUuid().toString());
171                                 break;
172                             }
173                         }
174                     }
175                 }
176             } catch (Exception e) {
177                 logger.error("Exception during handlingNeutron network delete");
178             }
179         }
180         logger.debug(" PORT delete successful for tenant-id - {}, " +
181                      " network-id - {}, port-id - {}",
182                      neutronPort.getTenantID(), neutronPort.getNetworkUUID(),
183                      neutronPort.getID());
184
185     }
186 }