l3 support (partial): move event dispatch from southBoundHandler
[netvirt.git] / openstack / net-virt / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / NetworkHandler.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, Hsin-Yi Shen
9  */
10 package org.opendaylight.ovsdb.openstack.netvirt;
11
12 import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkAware;
13 import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
14 import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
15 import org.opendaylight.controller.sal.core.Node;
16 import org.opendaylight.ovsdb.lib.notation.Row;
17 import org.opendaylight.ovsdb.lib.notation.UUID;
18 import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager;
19 import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
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;
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.concurrent.ConcurrentMap;
32
33 /**
34  * Handle requests for Neutron Network.
35  */
36 public class NetworkHandler extends AbstractHandler
37                             implements INeutronNetworkAware {
38
39     public static final String NETWORK_TYPE_VXLAN = "vxlan";
40     public static final String NETWORK_TYPE_GRE = "gre";
41     public static final String NETWORK_TYPE_VLAN = "vlan";
42
43     /**
44      * Logger instance.
45      */
46     static final Logger logger = LoggerFactory.getLogger(NetworkHandler.class);
47
48     // The implementation for each of these services is resolved by the OSGi Service Manager
49     private volatile TenantNetworkManager tenantNetworkManager;
50     private volatile BridgeConfigurationManager bridgeConfigurationManager;
51     private volatile org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService configurationService;
52     private volatile OvsdbConfigurationService ovsdbConfigurationService;
53     private volatile OvsdbConnectionService connectionService;
54     private volatile INeutronNetworkCRUD neutronNetworkCache;
55     private volatile OvsdbInventoryListener ovsdbInventoryListener;
56
57     /**
58      * Invoked when a network creation is requested
59      * to indicate if the specified network can be created.
60      *
61      * @param network  An instance of proposed new Neutron Network object.
62      * @return A HTTP status code to the creation request.
63      */
64     @Override
65     public int canCreateNetwork(NeutronNetwork network) {
66         if (network.isShared()) {
67             logger.error(" Network shared attribute not supported ");
68             return HttpURLConnection.HTTP_NOT_ACCEPTABLE;
69         }
70
71         return HttpURLConnection.HTTP_CREATED;
72     }
73
74     /**
75      * Invoked to take action after a network has been created.
76      *
77      * @param network  An instance of new Neutron Network object.
78      */
79     @Override
80     public void neutronNetworkCreated(NeutronNetwork network) {
81         int result = HttpURLConnection.HTTP_BAD_REQUEST;
82         logger.trace("neutronNetworkCreated: network: {}", network);
83         result = canCreateNetwork(network);
84         if (result != HttpURLConnection.HTTP_CREATED) {
85             logger.debug("Network creation failed {} ", result);
86             return;
87         }
88
89     }
90
91     /**
92      * Invoked when a network update is requested
93      * to indicate if the specified network can be changed
94      * using the specified delta.
95      *
96      * @param delta     Updates to the network object using patch semantics.
97      * @param original  An instance of the Neutron Network object
98      *                  to be updated.
99      * @return A HTTP status code to the update request.
100      */
101     @Override
102     public int canUpdateNetwork(NeutronNetwork delta,
103                                 NeutronNetwork original) {
104         logger.trace("canUpdateNetwork: network delta {} --- original {}", delta, original);
105         return HttpURLConnection.HTTP_OK;
106     }
107
108     /**
109      * Invoked to take action after a network has been updated.
110      *
111      * @param network An instance of modified Neutron Network object.
112      */
113     @Override
114     public void neutronNetworkUpdated(NeutronNetwork network) {
115         logger.trace("neutronNetworkUpdated: network: {}", network);
116         return;
117     }
118
119     /**
120      * Invoked when a network deletion is requested
121      * to indicate if the specified network can be deleted.
122      *
123      * @param network  An instance of the Neutron Network object to be deleted.
124      * @return A HTTP status code to the deletion request.
125      */
126     @Override
127     public int canDeleteNetwork(NeutronNetwork network) {
128         return HttpURLConnection.HTTP_OK;
129     }
130
131     /**
132      * Invoked to take action after a network has been deleted.
133      *
134      * @param network  An instance of deleted Neutron Network object.
135      */
136     @Override
137     public void neutronNetworkDeleted(NeutronNetwork network) {
138
139         int result = canDeleteNetwork(network);
140         logger.trace("canDeleteNetwork: network: {}", network);
141         if  (result != HttpURLConnection.HTTP_OK) {
142             logger.error(" deleteNetwork validation failed for result - {} ",
143                     result);
144             return;
145         }
146         /* Is this the last Neutron tenant network */
147         List <NeutronNetwork> networks;
148         if (neutronNetworkCache != null) {
149             networks = neutronNetworkCache.getAllNetworks();
150             if (networks.isEmpty()) {
151                 logger.trace("neutronNetworkDeleted: last tenant network, delete tunnel ports...");
152                 List<Node> nodes = connectionService.getNodes();
153
154                 for (Node node : nodes) {
155                     List<String> phyIfName = bridgeConfigurationManager.getAllPhysicalInterfaceNames(node);
156                     try {
157                         ConcurrentMap<String, Row> ports =
158                                 this.ovsdbConfigurationService.getRows(node,
159                                                                 ovsdbConfigurationService.getTableName(node, Port.class));
160                         if (ports != null) {
161                             for (Row portRow : ports.values()) {
162                                 Port port = ovsdbConfigurationService.getTypedRow(node, Port.class, portRow);
163                                 for (UUID interfaceUuid : port.getInterfacesColumn().getData()) {
164                                     Interface interfaceRow = (Interface) ovsdbConfigurationService
165                                             .getRow(node,
166                                                     ovsdbConfigurationService.getTableName(node, Interface.class),
167                                                     interfaceUuid.toString());
168
169                                     String interfaceType = interfaceRow.getTypeColumn().getData();
170                                     if (interfaceType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)
171                                         || interfaceType.equalsIgnoreCase(
172                                             NetworkHandler.NETWORK_TYPE_GRE)) {
173                                         /* delete tunnel ports on this node */
174                                         logger.trace("Delete tunnel interface {}", interfaceRow);
175                                         ovsdbConfigurationService.deleteRow(node,
176                                                                      ovsdbConfigurationService.getTableName(node, Port.class),
177                                                                      port.getUuid().toString());
178                                         break;
179                                     } else if (!phyIfName.isEmpty() && phyIfName.contains(interfaceRow.getName())) {
180                                         logger.trace("Delete physical interface {}", interfaceRow);
181                                         ovsdbConfigurationService.deleteRow(node,
182                                                                      ovsdbConfigurationService.getTableName(node, Port.class),
183                                                                      port.getUuid().toString());
184                                         break;
185                                     }
186                                 }
187                             }
188                         }
189                     } catch (Exception e) {
190                         logger.error("Exception during handlingNeutron network delete");
191                     }
192                 }
193             }
194         }
195         tenantNetworkManager.networkDeleted(network.getID());
196     }
197
198     /**
199      * Process the event.
200      *
201      * @param abstractEvent the {@link org.opendaylight.ovsdb.openstack.netvirt.AbstractEvent} event to be handled.
202      * @see org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher
203      */
204     @Override
205     public void processEvent(AbstractEvent abstractEvent) {
206         if (!(abstractEvent instanceof NorthboundEvent)) {
207             logger.error("Unable to process abstract event " + abstractEvent);
208             return;
209         }
210         NorthboundEvent ev = (NorthboundEvent) abstractEvent;
211         switch (ev.getAction()) {
212             // TODO: add handling of events here, once callbacks do something
213             //       other than logging.
214             default:
215                 logger.warn("Unable to process event action " + ev.getAction());
216                 break;
217         }
218     }
219
220 }