<artifactId>openflowplugin-blueprint-config</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.openflowplugin</groupId>
+ <artifactId>openflowplugin-blueprint-config</artifactId>
+ <version>${project.version}</version>
+ <type>cfg</type>
+ <classifier>config</classifier>
+ </dependency>
<dependency>
<groupId>org.opendaylight.dlux</groupId>
<bundle>mvn:org.opendaylight.openflowplugin/openflowplugin-extension-api/{{VERSION}}</bundle>
<bundle>mvn:org.opendaylight.controller/liblldp/{{VERSION}}</bundle>
<bundle>mvn:org.opendaylight.openflowplugin/openflowplugin-blueprint-config/{{VERSION}}</bundle>
+ <configfile finalname="etc/org.opendaylight.openflowplugin.cfg">mvn:org.opendaylight.openflowplugin/openflowplugin-blueprint-config/{{VERSION}}/cfg/config</configfile>
<configfile finalname="etc/opendaylight/karaf/42-openflowplugin-Li.xml">mvn:org.opendaylight.openflowplugin/openflowplugin-controller-config/{{VERSION}}/xml/config-Li</configfile>
</feature>
package org.opendaylight.openflowplugin.api.openflow;
import java.util.Collection;
+import java.util.Map;
import org.opendaylight.controller.md.sal.binding.api.BindingService;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
void setBarrierInterval(long barrierTimeoutLimit);
void setEchoReplyTimeout(long echoReplyTimeout);
+
+
+ void setNotificationFlowRemovedOff(boolean isNotificationFlowRemovedOff);
+
+ void update(Map<String,Object> props);
}
*/
void notifyDeviceValidListeners(final DeviceInfo deviceInfo, final boolean deviceValid);
+ void setIsNotificationFlowRemovedOff(boolean value);
+
+ boolean getIsNotificationFlowRemovedOff();
+
}
type uint32;
default 60;
}
+
+ leaf notification-flow-removed-off {
+ description "Turning off flow removed notification";
+ type boolean;
+ default "false";
+ }
}
}
\ No newline at end of file
</instructions>
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/initial/openflowplugin.cfg</file>
+ <type>cfg</type>
+ <classifier>config</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
</project>
--- /dev/null
+notification-flow-removed-off=false
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+ xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
odl:use-default-for-reference-types="true">
<reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker" odl:type="pingpong"/>
<ref component-id="legacySwitchConnProvider"/>
</list>
</argument>
+ <cm:managed-properties persistent-id="org.opendaylight.openflowplugin"
+ update-strategy="component-managed"
+ update-method="update"/>
</bean>
<service ref="openflowPluginProvider" odl:type="openflow-plugin-provider-impl">
openflowPluginProvider.setBarrierCountLimit(providerConfig.getBarrierCountLimit().getValue());
openflowPluginProvider.setBarrierInterval(providerConfig.getBarrierIntervalTimeoutLimit().getValue());
openflowPluginProvider.setEchoReplyTimeout(providerConfig.getEchoReplyTimeout().getValue());
+ openflowPluginProvider.setNotificationFlowRemovedOff(providerConfig.isNotificationFlowRemovedOff());
openflowPluginProvider.initialize();
"EchoReplyTimeout:{}, " +
"ThreadPoolMinThreads:{}, " +
"ThreadPoolMaxThreads:{}, " +
- "ThreadPoolTimeout:{}",
+ "ThreadPoolTimeout:{}, " +
+ "NotificationFlowRemovedOff:{}",
providerConfig.isIsStatisticsPollingOff(),
providerConfig.isSwitchFeaturesMandatory(),
providerConfig.getBarrierCountLimit().getValue(),
providerConfig.getEchoReplyTimeout().getValue(),
providerConfig.getThreadPoolMinThreads(),
providerConfig.getThreadPoolMaxThreads().getValue(),
- providerConfig.getThreadPoolTimeout());
+ providerConfig.getThreadPoolTimeout(),
+ providerConfig.isNotificationFlowRemovedOff());
return openflowPluginProvider;
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
private boolean switchFeaturesMandatory = false;
private boolean isStatisticsPollingOff = false;
private boolean isStatisticsRpcEnabled;
+ private boolean isNotificationFlowRemovedOff = false;
+ private Map<String,Object> managedProperties;
private final LifecycleConductor conductor;
private final ThreadPoolExecutor threadPool;
this.echoReplyTimeout = echoReplyTimeout;
}
+ @Override
+ public void setNotificationFlowRemovedOff(boolean isNotificationFlowRemovedOff) {
+ this.isNotificationFlowRemovedOff = isNotificationFlowRemovedOff;
+ }
+
@Override
public void setSwitchFeaturesMandatory(final boolean switchFeaturesMandatory) {
switchFeaturesMandatory,
barrierInterval,
barrierCountLimit,
- conductor);
+ conductor,
+ isNotificationFlowRemovedOff);
((ExtensionConverterProviderKeeper) conductor).setExtensionConverterProvider(extensionConverterManager);
((ExtensionConverterProviderKeeper) deviceManager).setExtensionConverterProvider(extensionConverterManager);
startSwitchConnections();
}
+ @Override
+ public void update(Map<String,Object> props) {
+ LOG.debug("Update managed properties = {}", props.toString());
+ this.managedProperties = props;
+
+ if(deviceManager != null && props.containsKey("notification-flow-removed-off")) {
+ deviceManager.setIsNotificationFlowRemovedOff(Boolean.valueOf(props.get("notification-flow-removed-off").toString()));
+ }
+ }
+
private static void registerMXBean(final MessageIntelligenceAgency messageIntelligenceAgency) {
final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
try {
import org.opendaylight.openflowplugin.api.openflow.connection.OutboundQueueProvider;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceManager;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
private final TranslatorLibrary translatorLibrary;
private final ItemLifeCycleRegistry itemLifeCycleSourceRegistry;
private ExtensionConverterProvider extensionConverterProvider;
+ private final DeviceManager deviceManager;
private final DeviceInfo deviceInfo;
private volatile CONTEXT_STATE contextState;
+
@VisibleForTesting
DeviceContextImpl(@Nonnull final ConnectionContext primaryConnectionContext,
@Nonnull final DeviceState deviceState,
@Nonnull final DataBroker dataBroker,
@Nonnull final LifecycleConductor conductor,
@Nonnull final OutboundQueueProvider outboundQueueProvider,
- @Nonnull final TranslatorLibrary translatorLibrary) {
+ @Nonnull final TranslatorLibrary translatorLibrary,
+ final DeviceManager manager) {
this.primaryConnectionContext = Preconditions.checkNotNull(primaryConnectionContext);
this.deviceState = Preconditions.checkNotNull(deviceState);
this.dataBroker = Preconditions.checkNotNull(dataBroker);
deviceGroupRegistry = new DeviceGroupRegistryImpl();
deviceMeterRegistry = new DeviceMeterRegistryImpl();
messageSpy = conductor.getMessageIntelligenceAgency();
-
+ this.deviceManager = Preconditions.checkNotNull(manager);
packetInLimiter = new PacketInRateLimiter(primaryConnectionContext.getConnectionAdapter(),
/*initial*/ 1000, /*initial*/2000, messageSpy, REJECTED_DRAIN_FACTOR);
//1. translate to general flow (table, priority, match, cookie)
final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved flowRemovedNotification =
flowRemovedTranslator.translate(flowRemoved, deviceInfo, null);
- // Trigger off a notification
- notificationPublishService.offerNotification(flowRemovedNotification);
+
+ if(!deviceManager.getIsNotificationFlowRemovedOff()) {
+ // Trigger off a notification
+ notificationPublishService.offerNotification(flowRemovedNotification);
+ } else if(LOG.isDebugEnabled()) {
+ LOG.debug("For nodeId={} isNotificationFlowRemovedOff={}", getDeviceInfo().getNodeId(), deviceManager.getIsNotificationFlowRemovedOff());
+ }
final ItemLifecycleListener itemLifecycleListener = flowLifeCycleKeeper.getItemLifecycleListener();
if (itemLifecycleListener != null) {
private final long globalNotificationQuota;
private final boolean switchFeaturesMandatory;
+ private boolean isNotificationFlowRemovedOff;
private final int spyRate = 10;
public DeviceManagerImpl(@Nonnull final DataBroker dataBroker,
final long globalNotificationQuota, final boolean switchFeaturesMandatory,
final long barrierInterval, final int barrierCountLimit,
- final LifecycleConductor lifecycleConductor) {
+ final LifecycleConductor lifecycleConductor, boolean isNotificationFlowRemovedOff) {
this.switchFeaturesMandatory = switchFeaturesMandatory;
this.globalNotificationQuota = globalNotificationQuota;
+ this.isNotificationFlowRemovedOff = isNotificationFlowRemovedOff;
this.dataBroker = Preconditions.checkNotNull(dataBroker);
/* merge empty nodes to oper DS to predict any problems with missing parent for Node */
final WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
dataBroker,
conductor,
outboundQueueProvider,
- translatorLibrary);
+ translatorLibrary,
+ this);
Verify.verify(deviceContexts.putIfAbsent(deviceInfo, deviceContext) == null, "DeviceCtx still not closed.");
}
}
+ @Override
+ public void setIsNotificationFlowRemovedOff(boolean isNotificationFlowRemovedOff) {
+ this.isNotificationFlowRemovedOff = isNotificationFlowRemovedOff;
+ }
+
+ @Override
+ public boolean getIsNotificationFlowRemovedOff() {
+ return this.isNotificationFlowRemovedOff;
+ }
+
private ListenableFuture<Void> onDeviceTakeClusterLeadership(final DeviceInfo deviceInfo) {
LOG.trace("onDeviceTakeClusterLeadership for node: {}", deviceInfo.getNodeId());
/* validation */
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
+import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.opendaylight.openflowplugin.api.openflow.connection.OutboundQueueProvider;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceManager;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.Notification;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private LifecycleConductor lifecycleConductor;
@Mock
private DeviceInfo deviceInfo;
+ @Mock
+ private DeviceManager deviceManager;
private InOrder inOrderDevState;
.thenReturn(messageTranslatorFlowRemoved);
Mockito.when(lifecycleConductor.getMessageIntelligenceAgency()).thenReturn(messageIntelligenceAgency);
- deviceContext = new DeviceContextImpl(connectionContext, deviceState, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary);
+ deviceContext = new DeviceContextImpl(connectionContext, deviceState, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary, deviceManager);
deviceContextSpy = Mockito.spy(deviceContext);
xid = new Xid(atomicLong.incrementAndGet());
@Test(expected = NullPointerException.class)
public void testDeviceContextImplConstructorNullDataBroker() throws Exception {
- new DeviceContextImpl(connectionContext, deviceState, null, lifecycleConductor, outboundQueueProvider, translatorLibrary).close();
+ new DeviceContextImpl(connectionContext, deviceState, null, lifecycleConductor, outboundQueueProvider, translatorLibrary, deviceManager).close();
}
@Test(expected = NullPointerException.class)
public void testDeviceContextImplConstructorNullDeviceState() throws Exception {
- new DeviceContextImpl(connectionContext, null, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary).close();
+ new DeviceContextImpl(connectionContext, null, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary, deviceManager).close();
}
@Test(expected = NullPointerException.class)
public void testDeviceContextImplConstructorNullTimer() throws Exception {
- new DeviceContextImpl(null, deviceState, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary).close();
+ new DeviceContextImpl(null, deviceState, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary, deviceManager).close();
}
@Test
.child(Table.class, new TableKey((short) 0))
.child(Flow.class, new FlowKey(new FlowId("ut-ofp:f456")));
+ Mockito.when(deviceManager.getIsNotificationFlowRemovedOff()).thenReturn(true);
+
deviceContext.setNotificationPublishService(mockedNotificationPublishService);
deviceContext.processFlowRemovedMessage(flowRemovedBld.build());
+
Mockito.verify(itemLifecycleListener).onRemoved(flowToBeRemovedPath);
+ Mockito.verify(mockedNotificationPublishService, Mockito.never()).offerNotification(Matchers.any(Notification.class));
+
+ Mockito.when(deviceManager.getIsNotificationFlowRemovedOff()).thenReturn(false);
+ deviceContext.processFlowRemovedMessage(flowRemovedBld.build());
+
+ Mockito.verify(mockedNotificationPublishService).offerNotification(Matchers.any(Notification.class));
}
@Test
when(mockedWriteTransaction.submit()).thenReturn(mockedFuture);
final DeviceManagerImpl deviceManager = new DeviceManagerImpl(mockedDataBroker,
- TEST_VALUE_GLOBAL_NOTIFICATION_QUOTA, false, barrierIntervalNanos, barrierCountLimit, lifecycleConductor);
+ TEST_VALUE_GLOBAL_NOTIFICATION_QUOTA, false, barrierIntervalNanos, barrierCountLimit, lifecycleConductor, true);
deviceManager.setDeviceInitializationPhaseHandler(deviceInitPhaseHandler);
deviceManager.setDeviceTerminationPhaseHandler(deviceTerminationPhaseHandler);