import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
- import org.osgi.framework.BundleContext;
+
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
*/
@Override
public int canCreateNetwork(NeutronNetwork network) {
- if (network.isShared()) {
- LOG.error(" Network shared attribute not supported ");
+ if (network.isShared() && !network.getRouterExternal()) {
+ LOG.error("Shared attribute is only supported on external networks");
return HttpURLConnection.HTTP_NOT_ACCEPTABLE;
}
@Override
public int canUpdateNetwork(NeutronNetwork delta,
NeutronNetwork original) {
- if (delta.isShared()) {
- LOG.error(" Network shared attribute not supported ");
+ if (delta.isShared() && !delta.getRouterExternal()) {
+ LOG.error("Shared attribute is only supported on external networks");
return HttpURLConnection.HTTP_NOT_ACCEPTABLE;
}
}
@Override
- public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+ public void setDependencies(ServiceReference serviceReference) {
tenantNetworkManager =
(TenantNetworkManager) ServiceHelper.getGlobalInstance(TenantNetworkManager.class, this);
bridgeConfigurationManager =
(Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
eventDispatcher =
(EventDispatcher) ServiceHelper.getGlobalInstance(EventDispatcher.class, this);
- eventDispatcher.eventHandlerAdded(
- bundleContext.getServiceReference(INeutronNetworkAware.class.getName()), this);
+ eventDispatcher.eventHandlerAdded(serviceReference, this);
}
@Override
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
- import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
this.updateL3ForNeutronPort(neutronPort, currPortShouldBeDeleted);
}
+
+ if (isDelete) {
+ /*
+ * Bug 4277: Remove the router interface cache only after deleting the neutron port l3 flows.
+ */
+ this.cleanupRouterCache(neutronRouterInterface);
+ }
}
/**
}
}
- // Keep cache for finding router's mac from network uuid -- remove
- //
- if (isDelete) {
- networkIdToRouterMacCache.remove(neutronNetwork.getNetworkUUID());
- networkIdToRouterIpListCache.remove(neutronNetwork.getNetworkUUID());
- subnetIdToRouterInterfaceCache.remove(subnet.getSubnetUUID());
- }
+ // Keep cache for finding router's mac from network uuid -- NOTE: remove is done later, via cleanupRouterCache()
}
private void programFlowForNetworkFromExternal(final Node node,
return null;
}
+ private void cleanupRouterCache(final NeutronRouter_Interface neutronRouterInterface) {
+ /*
+ * Fix for 4277
+ * Remove the router cache only after deleting the neutron
+ * port l3 flows.
+ */
+ final NeutronPort neutronPort = neutronPortCache.getPort(neutronRouterInterface.getPortUUID());
+
+ if (neutronPort != null) {
+ networkIdToRouterMacCache.remove(neutronPort.getNetworkUUID());
+ networkIdToRouterIpListCache.remove(neutronPort.getNetworkUUID());
+ subnetIdToRouterInterfaceCache.remove(neutronRouterInterface.getSubnetUUID());
+ }
+ }
+
public void triggerGatewayMacResolver(final Node node, final NeutronPort gatewayPort ){
Preconditions.checkNotNull(node);
}
@Override
- public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+ public void setDependencies(ServiceReference serviceReference) {
tenantNetworkManager =
(TenantNetworkManager) ServiceHelper.getGlobalInstance(TenantNetworkManager.class, this);
configurationService =
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
- import org.osgi.framework.BundleContext;
+
import org.osgi.framework.ServiceReference;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.api.support.membermodification.MemberMatcher;
NeutronPort neutronPort = mock(NeutronPort.class);
when(neutronPort.getMacAddress()).thenReturn(MAC_ADDRESS);
when(neutronPort.getFixedIPs()).thenReturn(ips);
+ when(neutronPort.getNetworkUUID()).thenReturn(UUID);
NeutronSubnet neutronSubnet = mock(NeutronSubnet.class);
when(neutronSubnet.getNetworkUUID()).thenReturn(UUID);
when(neutronSubnet.getGatewayIP()).thenReturn(IP);
when(neutronNetwork.getProviderSegmentationID()).thenReturn(ID);
when(neutronNetwork.getRouterExternal()).thenReturn(false); //might change that to true
when(neutronNetwork.getNetworkUUID()).thenReturn(UUID);
+ NeutronRouter neutronRouter = mock(NeutronRouter.class);
Node node = mock(Node.class);
List<Node> nodes = new ArrayList<Node>();
// init instance variables
INeutronPortCRUD neutronPortCache = mock(INeutronPortCRUD.class);
PowerMockito.when(neutronPortCache.getPort(anyString())).thenReturn(neutronPort);
+ PowerMockito.when(neutronPortCache.getAllPorts()).thenReturn(new ArrayList<NeutronPort>());
INeutronSubnetCRUD neutronSubnetCache = mock(INeutronSubnetCRUD.class);
PowerMockito.when(neutronSubnetCache.getSubnet(anyString())).thenReturn(neutronSubnet);
INeutronNetworkCRUD neutronNetworkCache = mock(INeutronNetworkCRUD.class);
networkIdToRouterMacCache.put(UUID, MAC_ADDRESS);
networkIdToRouterIpListCache.put(UUID, ips);
+ subnetIdToRouterInterfaceCache.put(UUID, intf);
networkIdToRouterMacCacheSize = networkIdToRouterMacCache.size();
networkIdToRouterIpListCacheSize = networkIdToRouterIpListCache.size();
subnetIdToRouterInterfaceCacheSize = subnetIdToRouterInterfaceCache.size();
- Whitebox.invokeMethod(neutronL3Adapter, "programFlowsForNeutronRouterInterface", intf, true);
+ Whitebox.invokeMethod(neutronL3Adapter, "handleNeutronRouterInterfaceEvent", neutronRouter, intf, Action.DELETE);
+ PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programFlowsForNeutronRouterInterface", intf, true);
PowerMockito.verifyPrivate(neutronL3Adapter, times(2)).invoke("getDpidForIntegrationBridge", any(Node.class));
- PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programFlowsForNeutronRouterInterfacePair", any(Node.class), anyLong(), any(NeutronRouter_Interface.class), any(NeutronRouter_Interface.class), any(NeutronNetwork.class), anyString(), anyString(), anyString(), anyInt(), eq(Action.DELETE), anyBoolean());
+ PowerMockito.verifyPrivate(neutronL3Adapter, times(2)).invoke("programFlowsForNeutronRouterInterfacePair", any(Node.class), anyLong(), any(NeutronRouter_Interface.class), any(NeutronRouter_Interface.class), any(NeutronNetwork.class), anyString(), anyString(), anyString(), anyInt(), eq(Action.DELETE), anyBoolean());
PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programFlowForNetworkFromExternal", any(Node.class), anyLong(), anyString(), anyString(), anyString(), anyInt(), eq(Action.DELETE));
PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programStaticArpStage1", anyLong(), anyString(), anyString(), anyString(), eq(Action.DELETE));
PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programIpRewriteExclusionStage1", any(Node.class), anyLong(), anyString(), anyString(), eq(Action.DELETE));
PowerMockito.when(ServiceHelper.getGlobalInstance(NodeCacheManager.class, neutronL3Adapter)).thenReturn(nodeCacheManager);
PowerMockito.when(ServiceHelper.getGlobalInstance(Southbound.class, neutronL3Adapter)).thenReturn(southbound);
- neutronL3Adapter.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+ neutronL3Adapter.setDependencies(mock(ServiceReference.class));
assertEquals("Error, did not return the correct object", getField("tenantNetworkManager"), tenantNetworkManager);
assertEquals("Error, did not return the correct object", getField("configurationService"), configurationService);