private static final Logger LOG = LoggerFactory.getLogger(DeviceMastership.class);
private final NodeId nodeId;
private final ServiceGroupIdentifier identifier;
- private final ClusterSingletonServiceRegistration clusterSingletonServiceRegistration;
+ private final ClusterSingletonServiceProvider clusterSingletonServiceProvider;
+ private ClusterSingletonServiceRegistration clusterSingletonServiceRegistration;
private boolean deviceMastered;
public DeviceMastership(final NodeId nodeId, final ClusterSingletonServiceProvider clusterSingletonService) {
this.nodeId = nodeId;
this.identifier = ServiceGroupIdentifier.create(nodeId.getValue());
this.deviceMastered = false;
- clusterSingletonServiceRegistration = clusterSingletonService.registerClusterSingletonService(this);
+ this.clusterSingletonServiceProvider = clusterSingletonService;
}
@Override
public void instantiateServiceInstance() {
- LOG.debug("FRM started for: {}", nodeId.getValue());
+ LOG.info("FRM started for: {}", nodeId.getValue());
deviceMastered = true;
}
@Override
public ListenableFuture<Void> closeServiceInstance() {
- LOG.debug("FRM stopped for: {}", nodeId.getValue());
+ LOG.info("FRM stopped for: {}", nodeId.getValue());
deviceMastered = false;
return Futures.immediateFuture(null);
}
return deviceMastered;
}
+ public void registerClusterSingletonService() {
+ LOG.info("Registering FRM as a cluster singleton service listner for service id : {}",getIdentifier());
+ clusterSingletonServiceRegistration = clusterSingletonServiceProvider.registerClusterSingletonService(this);
+ }
}
import com.google.common.annotations.VisibleForTesting;
import java.util.concurrent.ConcurrentHashMap;
+
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Manager for clustering service registrations of {@link DeviceMastership}.
*/
-public class DeviceMastershipManager {
+public class DeviceMastershipManager implements OpendaylightInventoryListener, AutoCloseable{
private static final Logger LOG = LoggerFactory.getLogger(DeviceMastershipManager.class);
private final ClusterSingletonServiceProvider clusterSingletonService;
+ private final ListenerRegistration<?> notifListenerRegistration;
private final ConcurrentHashMap<NodeId, DeviceMastership> deviceMasterships = new ConcurrentHashMap();
- public DeviceMastershipManager(final ClusterSingletonServiceProvider clusterSingletonService) {
+ public DeviceMastershipManager(final ClusterSingletonServiceProvider clusterSingletonService,
+ final NotificationProviderService notificationService) {
this.clusterSingletonService = clusterSingletonService;
+ this.notifListenerRegistration = notificationService.registerNotificationListener(this);
}
public void onDeviceConnected(final NodeId nodeId) {
- LOG.debug("FRM service registered for: {}", nodeId.getValue());
- final DeviceMastership mastership = new DeviceMastership(nodeId, clusterSingletonService);
- deviceMasterships.put(nodeId, mastership);
+ //No-op
}
public void onDeviceDisconnected(final NodeId nodeId) {
- final DeviceMastership mastership = deviceMasterships.remove(nodeId);
- if (mastership != null) {
- mastership.close();
- }
- LOG.debug("FRM service unregistered for: {}", nodeId.getValue());
+ //No-op
}
public boolean isDeviceMastered(final NodeId nodeId) {
ConcurrentHashMap<NodeId, DeviceMastership> getDeviceMasterships() {
return deviceMasterships;
}
+
+ @Override
+ public void onNodeUpdated(NodeUpdated notification) {
+ LOG.debug("NodeUpdate notification received : {}", notification);
+ DeviceMastership membership = deviceMasterships.computeIfAbsent(notification.getId(), device ->
+ new DeviceMastership(notification.getId(), clusterSingletonService));
+ membership.registerClusterSingletonService();
+ }
+
+ @Override
+ public void onNodeConnectorUpdated(NodeConnectorUpdated notification) {
+ //Not published by plugin
+ }
+
+ @Override
+ public void onNodeRemoved(NodeRemoved notification) {
+ LOG.debug("NodeRemoved notification received : {}", notification);
+ NodeId nodeId = notification.getNodeRef().getValue().firstKeyOf(Node.class).getId();
+ final DeviceMastership mastership = deviceMasterships.remove(nodeId);
+ if (mastership != null) {
+ mastership.close();
+ LOG.info("Unregistered FRM cluster singleton service for service id : {}", nodeId.getValue());
+ }
+ }
+
+ @Override
+ public void onNodeConnectorRemoved(NodeConnectorRemoved notification) {
+ //Not published by plugin
+ }
+
+ @Override
+ public void close() throws Exception {
+ if (notifListenerRegistration != null) {
+ notifListenerRegistration.close();
+ }
+ }
}
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.openflowplugin.applications.frm.FlowNodeReconciliation;
private final ForwardingRulesManagerConfig forwardingRulesManagerConfig;
private FlowNodeConnectorInventoryTranslatorImpl flowNodeConnectorInventoryTranslatorImpl;
private final ClusterSingletonServiceProvider clusterSingletonServiceProvider;
+ private final NotificationProviderService notificationService;
private DeviceMastershipManager deviceMastershipManager;
public ForwardingRulesManagerImpl(final DataBroker dataBroker,
final RpcConsumerRegistry rpcRegistry,
final ForwardingRulesManagerConfig config,
- final ClusterSingletonServiceProvider clusterSingletonService) {
+ final ClusterSingletonServiceProvider clusterSingletonService,
+ final NotificationProviderService notificationService) {
this.dataService = Preconditions.checkNotNull(dataBroker, "DataBroker can not be null!");
this.forwardingRulesManagerConfig = Preconditions.checkNotNull(config, "Configuration for FRM cannot be null");
this.clusterSingletonServiceProvider = Preconditions.checkNotNull(clusterSingletonService,
"ClusterSingletonService provider can not be null");
+ this.notificationService = Preconditions.checkNotNull(notificationService, "Notification publisher service is" +
+ " not available");
Preconditions.checkArgument(rpcRegistry != null, "RpcConsumerRegistry can not be null !");
@Override
public void start() {
- this.deviceMastershipManager = new DeviceMastershipManager(clusterSingletonServiceProvider);
+ this.deviceMastershipManager = new DeviceMastershipManager(clusterSingletonServiceProvider,
+ notificationService);
this.flowListener = new FlowForwarder(this, dataService);
this.groupListener = new GroupForwarder(this, dataService);
this.meterListener = new MeterForwarder(this, dataService);
this.nodeListener.close();
this.nodeListener = null;
}
+ if (deviceMastershipManager != null) {
+ deviceMastershipManager.close();
+ }
}
@Override
<reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"/>
<reference id="rpcRegistry" interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry"/>
+ <reference id="notificationService" interface="org.opendaylight.controller.sal.binding.api.NotificationProviderService"/>
<reference id="clusterSingletonService" interface="org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider"/>
<odl:clustered-app-config id="frmConfig"
<argument ref="rpcRegistry"/>
<argument ref="frmConfig"/>
<argument ref="clusterSingletonService"/>
+ <argument ref="notificationService"/>
</bean>
</blueprint>
\ No newline at end of file
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemovedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
/**
* Test for {@link DeviceMastershipManager}.
private ClusterSingletonServiceRegistration registration;
@Mock
private ClusterSingletonServiceProvider clusterSingletonService;
+ @Mock
+ private NotificationProviderService notificationService;
@Before
public void setUp() throws Exception {
- deviceMastershipManager = new DeviceMastershipManager(clusterSingletonService);
+ deviceMastershipManager = new DeviceMastershipManager(clusterSingletonService,
+ notificationService);
Mockito.when(clusterSingletonService.registerClusterSingletonService(Matchers.<ClusterSingletonService>any()))
.thenReturn(registration);
}
public void testOnDeviceConnectedAndDisconnected() throws Exception {
// no context
Assert.assertNull(deviceMastershipManager.getDeviceMasterships().get(NODE_ID));
- // create context - register
- deviceMastershipManager.onDeviceConnected(NODE_ID);
+ NodeUpdatedBuilder nodeUpdatedBuilder = new NodeUpdatedBuilder();
+ nodeUpdatedBuilder.setId(NODE_ID);
+ deviceMastershipManager.onNodeUpdated(nodeUpdatedBuilder.build());
DeviceMastership serviceInstance = deviceMastershipManager.getDeviceMasterships().get(NODE_ID);
Assert.assertNotNull(serviceInstance);
- Mockito.verify(clusterSingletonService).registerClusterSingletonService(serviceInstance);
// destroy context - unregister
deviceMastershipManager.onDeviceDisconnected(NODE_ID);
+ Assert.assertNotNull(deviceMastershipManager.getDeviceMasterships().get(NODE_ID));
+ NodeRemovedBuilder nodeRemovedBuilder = new NodeRemovedBuilder();
+ InstanceIdentifier<Node> nodeIId = InstanceIdentifier.create(Nodes.class).
+ child(Node.class, new NodeKey(NODE_ID));
+ nodeRemovedBuilder.setNodeRef(new NodeRef(nodeIId));
+ deviceMastershipManager.onNodeRemoved(nodeRemovedBuilder.build());
Assert.assertNull(deviceMastershipManager.getDeviceMasterships().get(NODE_ID));
- Mockito.verify(registration).close();
}
@Test
public void testIsDeviceMasteredOrSlaved() {
// no context
Assert.assertFalse(deviceMastershipManager.isDeviceMastered(NODE_ID));
- deviceMastershipManager.onDeviceConnected(NODE_ID);
+ NodeUpdatedBuilder nodeUpdatedBuilder = new NodeUpdatedBuilder();
+ nodeUpdatedBuilder.setId(NODE_ID);
+ deviceMastershipManager.onNodeUpdated(nodeUpdatedBuilder.build());
// is master
deviceMastershipManager.getDeviceMasterships().get(NODE_ID).instantiateServiceInstance();
Assert.assertTrue(deviceMastershipManager.isDeviceMastered(NODE_ID));
import org.mockito.runners.MockitoJUnitRunner;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
ClusterSingletonServiceProvider clusterSingletonService;
@Mock
DeviceMastershipManager deviceMastershipManager;
+ @Mock
+ private NotificationProviderService notificationService;
@Before
public void setUp() {
getDataBroker(),
rpcProviderRegistryMock,
getConfig(),
- clusterSingletonService);
+ clusterSingletonService,
+ notificationService);
forwardingRulesManager.start();
// TODO consider tests rewrite (added because of complicated access)
forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
import org.mockito.runners.MockitoJUnitRunner;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
ClusterSingletonServiceProvider clusterSingletonService;
@Mock
DeviceMastershipManager deviceMastershipManager;
+ @Mock
+ private NotificationProviderService notificationService;
@Before
public void setUp() {
getDataBroker(),
rpcProviderRegistryMock,
getConfig(),
- clusterSingletonService);
+ clusterSingletonService,
+ notificationService);
forwardingRulesManager.start();
// TODO consider tests rewrite (added because of complicated access)
forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
import org.mockito.runners.MockitoJUnitRunner;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
ClusterSingletonServiceProvider clusterSingletonService;
@Mock
DeviceMastershipManager deviceMastershipManager;
+ @Mock
+ private NotificationProviderService notificationService;
@Before
public void setUp() {
getDataBroker(),
rpcProviderRegistryMock,
getConfig(),
- clusterSingletonService);
+ clusterSingletonService,
+ notificationService);
forwardingRulesManager.start();
// TODO consider tests rewrite (added because of complicated access)
forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.openflowplugin.applications.frm.impl.ForwardingRulesManagerImpl;
RpcProviderRegistry rpcProviderRegistryMock = new RpcProviderRegistryMock();
@Mock
ClusterSingletonServiceProvider clusterSingletonService;
+ @Mock
+ private NotificationProviderService notificationService;
@Before
public void setUp() {
getDataBroker(),
rpcProviderRegistryMock,
getConfig(),
- clusterSingletonService);
+ clusterSingletonService,
+ notificationService);
forwardingRulesManager.start();
}
import org.mockito.runners.MockitoJUnitRunner;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
ClusterSingletonServiceProvider clusterSingletonService;
@Mock
DeviceMastershipManager deviceMastershipManager;
+ @Mock
+ private NotificationProviderService notificationService;
@Before
public void setUp() {
getDataBroker(),
rpcProviderRegistryMock,
getConfig(),
- clusterSingletonService);
+ clusterSingletonService,
+ notificationService);
forwardingRulesManager.start();
// TODO consider tests rewrite (added because of complicated access)
forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
]]></odl:default-config>
</odl:clustered-app-config>
- <odl:rpc-service id="packetProcessingService"
+ <odl:action-service id="packetProcessingService"
interface="org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService"/>
<bean id="lldpSpeaker" class="org.opendaylight.openflowplugin.applications.lldpspeaker.LLDPSpeaker"
</bean>
<odl:rpc-implementation ref="operationalStatusChangeService"/>
-</blueprint>
\ No newline at end of file
+</blueprint>
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import java.util.Collection;
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+
/**
* statistics-manager
* org.opendaylight.openflowplugin.applications.statistics.manager.impl
protected final Map<InstanceIdentifier<Node>, Map<InstanceIdentifier<T>, Integer>> mapNodesForDelete = new ConcurrentHashMap<>();
protected final Map<InstanceIdentifier<Node>, Integer> mapNodeFeautureRepeater = new ConcurrentHashMap<>();
+ protected final Map<InstanceIdentifier<Node>, ArrayList<T>> removedDataBetweenStatsCycle = new
+ ConcurrentHashMap<>();
private final Class<T> clazz;
- private final DataBroker dataBroker;
+ protected final DataBroker dataBroker;
protected final StatNodeRegistration nodeRegistrationManager;
*/
protected abstract InstanceIdentifier<T> getWildCardedRegistrationPath();
+ protected abstract void processDataChange(Collection<DataTreeModification<T>> changes);
+
@Override
public void onDataTreeChanged(Collection<DataTreeModification<T>> changes) {
Preconditions.checkNotNull(changes, "Changes must not be null!");
* Latest read transaction will be allocated on another read using readLatestConfiguration
*/
currentReadTxStale = true;
+ processDataChange(changes);
}
@SuppressWarnings("unchecked")
@Override
public void cleanForDisconnect(final InstanceIdentifier<Node> nodeIdent) {
mapNodesForDelete.remove(nodeIdent);
+ removedDataBetweenStatsCycle.remove(nodeIdent);
}
@Override
import com.google.common.base.Optional;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.UUID;
-import java.util.concurrent.atomic.AtomicInteger;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionAware;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
+
/**
* statistics-manager
* org.opendaylight.openflowplugin.applications.statistics.manager.impl
tx.merge(LogicalDatastoreType.OPERATIONAL, tableRef, tableNew);
}
+ protected void processDataChange(Collection<DataTreeModification<Flow>> changes) {
+ if (!changes.isEmpty()) {
+ for (DataTreeModification<Flow> dataChange : changes) {
+ if (dataChange.getRootNode().getModificationType() == DataObjectModification.ModificationType.DELETE) {
+ final InstanceIdentifier<Node> nodeIdent = dataChange.getRootPath().getRootIdentifier()
+ .firstIdentifierOf(Node.class);
+ if (!removedDataBetweenStatsCycle.containsKey(nodeIdent)) {
+ removedDataBetweenStatsCycle.put(nodeIdent, new ArrayList<>());
+ }
+ Flow data = dataChange.getRootNode().getDataBefore();
+ removedDataBetweenStatsCycle.get(nodeIdent).add(data);
+ LOG.debug("Node: {} :: Flow removed {}",nodeIdent.firstKeyOf(Node.class).getId(), data.toString());
+ }
+ }
+ }
+ }
+
@Override
public void onFlowsStatisticsUpdate(final FlowsStatisticsUpdate notification) {
final TransactionId transId = notification.getTransactionId();
final NodeId nodeId = notification.getId();
if ( ! isExpectedStatistics(transId, nodeId)) {
- LOG.debug("STAT-MANAGER - FlowsStatisticsUpdate: unregistred notification detect TransactionId {}", transId);
+ LOG.debug("STAT-MANAGER - FlowsStatisticsUpdate: unregistered notification detect TransactionId {}",
+ transId);
return;
}
manager.getRpcMsgManager().addNotification(notification, nodeId);
final InstanceIdentifier<FlowCapableNode> fNodeIdent = nodeIdent.augmentation(FlowCapableNode.class);
+ //cleanup the hashmap ID for the flows deleted between two stats cycle, also cleanup the
+ // data change cache as well.
+ ArrayList<Flow> deletedFlows = removedDataBetweenStatsCycle.remove(nodeIdent);
+
+ if (deletedFlows != null && !deletedFlows.isEmpty()) {
+ LOG.trace("Number of flows deleted from node {} between two stats cycles are {}", nodeIdent, deletedFlows
+ .size());
+ }
+
final Optional<FlowCapableNode> fNode;
try {
fNode = tx.read(LogicalDatastoreType.OPERATIONAL, fNodeIdent).checkedGet();
for (final FlowAndStatisticsMapList flowStat : list) {
final TableKey tableKey = new TableKey(flowStat.getTableId());
final TableFlowUpdateState tableState = nodeState.getTable(tableKey, tx);
- tableState.reportFlow(flowStat,tx);
+ Flow removedConfigFlow = getFlowIfRemoved(flowStat, deletedFlows);
+ if (removedConfigFlow == null) {
+ tableState.reportFlow(flowStat,tx, false);
+ } else {
+ deletedFlows.remove(removedConfigFlow);
+ tableState.reportFlow(flowStat,tx, true);
+ }
}
+ if (deletedFlows != null ) {
+ deletedFlows.clear();
+ }
for (final TableFlowUpdateState table : nodeState.getTables()) {
table.removeUnreportedFlows(tx);
}
}
+ private Flow getFlowIfRemoved(FlowAndStatisticsMapList flowStat, ArrayList<Flow> deletedFlows) {
+ if (deletedFlows != null && !deletedFlows.isEmpty()) {
+ for (Flow flow : deletedFlows) {
+ final FlowAndStatisticsMapList configFlowStats = new FlowAndStatisticsMapListBuilder(flow).build();
+ if ( flowStat.getMatch().equals(configFlowStats.getMatch()) &&
+ flowStat.getPriority().equals(configFlowStats.getPriority()) &&
+ flowStat.getCookie().equals(configFlowStats.getCookie()!=null?configFlowStats.getCookie():
+ new FlowCookie(new BigInteger("0")))) {
+ LOG.debug("Flow statistics {} are related to flow {}, but it's REMOVED from the config data store" +
+ "store", flowStat, flow);
+ return flow;
+ }
+ }
+ }
+ return null;
+ }
/**
* Method adds statistics to Flow
*
//flowHashId.getKey() too verbose for standard log.
if(LOG.isDebugEnabled()) {
final FlowId currData = flowIdByHash.get(flowHashId.getKey());
- LOG.debug("flow hashing hit a duplicate for {} -> {}. Curr value: {} Equals:{}. Exception was raised:",
+ LOG.debug("Flow hashing hit a duplicate for {} -> {}. Curr value: {} Equals:{}. " +
+ "Exception was raised:",
flowHashId.getKey(), flowHashId.getFlowId(), currData, flowHashId.getFlowId().equals(currData), e);
}
else
{
- LOG.warn("flow hashing hit a duplicate {}. Exception was raised: {}. Enable DEBUG for more detail.",
+ LOG.warn("Flow hashing hit a duplicate {}. Exception was raised: {}. Enable DEBUG for" +
+ " more detail.",
flowHashId.getFlowId().toString().substring(0, Math.min(TRUNCATED_LOG_MESSAGE_LENGTH,flowHashId.getFlowId().toString().length())),
e.getMessage().substring(0,Math.min(TRUNCATED_LOG_MESSAGE_LENGTH,e.getMessage().length())));
}
}
}
- private FlowKey getFlowKeyAndRemoveHash(final FlowHashIdMapKey key) {
+ private FlowKey getFlowKeyByHash(final FlowHashIdMapKey key) {
final FlowId ret = flowIdByHash.get(key);
if(ret != null) {
- flowIdByHash.remove(key);
return new FlowKey(ret);
}
return null;
return flowIdByHash;
}
- void reportFlow(final FlowAndStatisticsMapList flowStat, final ReadWriteTransaction trans) {
+ void reportFlow(final FlowAndStatisticsMapList flowStat,
+ final ReadWriteTransaction trans,
+ boolean wasRemoved) {
ensureTableFowHashIdMapping(trans);
final FlowHashIdMapKey hashingKey = new FlowHashIdMapKey(buildFlowIdOperKey(flowStat));
- FlowKey flowKey = getFlowKeyAndRemoveHash(hashingKey);
- if (flowKey == null) {
+ FlowKey flowKey = getFlowKeyByHash(hashingKey);
+ if (flowKey == null || wasRemoved) {
flowKey = searchInConfiguration(flowStat, trans);
if ( flowKey == null) {
flowKey = makeAlienFlowKey();
}
updateHashCache(trans,flowKey,hashingKey);
+ } else {
+ flowIdByHash.remove(hashingKey);
}
final FlowBuilder flowBuilder = new FlowBuilder(flowStat);
flowBuilder.setKey(flowKey);
package org.opendaylight.openflowplugin.applications.statistics.manager.impl;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.openflowplugin.applications.statistics.manager.StatisticsManager.StatDataStoreOperation;
import org.opendaylight.openflowplugin.applications.statistics.manager.StatisticsManager.StatDataStoreOperation.StatsManagerOperationType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionAware;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdated;
.augmentation(FlowCapableNode.class).child(Group.class);
}
+ @Override
+ protected void processDataChange(Collection<DataTreeModification<Group>> changes) {
+ //NO-OP
+ }
+
@Override
public void onGroupDescStatsUpdated(final GroupDescStatsUpdated notification) {
final TransactionId transId = notification.getTransactionId();
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
.augmentation(FlowCapableNode.class).child(Meter.class);
}
+ @Override
+ protected void processDataChange(Collection<DataTreeModification<Meter>> changes) {
+ //NO-OP
+ }
+
@Override
protected OpendaylightMeterStatisticsListener getStatNotificationListener() {
return this;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
+
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
.augmentation(FlowCapableNodeConnector.class).child(Queue.class);
}
+ @Override
+ protected void processDataChange(Collection<DataTreeModification<Queue>> changes) {
+ //NO-OP
+ }
+
@Override
public void onQueueStatisticsUpdate(final QueueStatisticsUpdate notification) {
final TransactionId transId = notification.getTransactionId();
import org.opendaylight.yangtools.yang.binding.NotificationListener;
import java.util.ArrayList;
+import java.util.Collection;
/**
return InstanceIdentifier.create(DataObject.class);
}
+ @Override
+ protected void processDataChange(Collection changes) {
+
+ }
+
@Override
protected NotificationListener getStatNotificationListener() {
return mockNotificationListener;
* | | +--ro (action)?
* </pre>
*/
- GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION(null);
-
+ GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION(null),
+ /**
+ * openflowplugin-extension-general.yang
+ * <pre>
+ * module: opendaylight-direct-statistics
+ * notifications:
+ * +---n get-flow-statistics
+ * | +--ro flow-and-statistics-map-list* [flow-id]
+ * | | +--ro instructions
+ * | | | +--ro instruction* [order]
+ * | | | +--ro (instruction)?
+ * | | | +--:(write-actions-case)
+ * | | | | +--ro write-actions
+ * | | | | +--ro action* [order]
+ * | | | | +--ro (action)?
+ * </pre>
+ */
+ RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION(null),
+ /**
+ * openflowplugin-extension-general.yang
+ * <pre>
+ * module: opendaylight-direct-statistics
+ * notifications:
+ * +---n get-flow-statistics
+ * | +--ro flow-and-statistics-map-list* [flow-id]
+ * | | +--ro instructions
+ * | | | +--ro instruction* [order]
+ * | | | +--ro (instruction)?
+ * | | | +--:(apply-actions-case)
+ * | | | | +--ro apply-actions
+ * | | | | +--ro action* [order]
+ * | | | | +--ro (action)?
+ * </pre>
+ */
+ RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION(null);
+
private final InstanceIdentifier<Extension> iid;
private ActionPath(InstanceIdentifier<Extension> iid) {
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionConntrackGrouping;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionConntrackNotifFlowsStatisticsUpdateApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionConntrackNotifFlowsStatisticsUpdateWriteActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionConntrackNotifGroupDescStatsUpdatedCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionConntrackNodesNodeTableFlowWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.conntrack.grouping.NxConntrack;
return new NxActionConntrackNotifFlowsStatisticsUpdateApplyActionsCaseBuilder().setNxConntrack(value).build();
case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION:
return new NxActionConntrackNotifGroupDescStatsUpdatedCaseBuilder().setNxConntrack(value).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION:
+ return new NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCaseBuilder().setNxConntrack(value).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION:
+ return new NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCaseBuilder().setNxConntrack(value).build();
default:
throw new CodecPreconditionException(path);
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionFinTimeoutGrouping;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionFinTimeoutNotifFlowsStatisticsUpdateApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionFinTimeoutNotifFlowsStatisticsUpdateWriteActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionFinTimeoutNotifDirectStatisticsUpdateApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionFinTimeoutNotifDirectStatisticsUpdateWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionFinTimeoutNotifGroupDescStatsUpdatedCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionFinTimeoutNodesNodeTableFlowWriteActionsCaseBuilder;
case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION:
return new NxActionFinTimeoutNotifGroupDescStatsUpdatedCaseBuilder()
.setNxActionFinTimeout(nxActionFinTimeout).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION:
+ return new NxActionFinTimeoutNotifDirectStatisticsUpdateWriteActionsCaseBuilder()
+ .setNxActionFinTimeout(nxActionFinTimeout).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION:
+ return new NxActionFinTimeoutNotifDirectStatisticsUpdateApplyActionsCaseBuilder()
+ .setNxActionFinTimeout(nxActionFinTimeout).build();
default:
throw new CodecPreconditionException(path);
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionLearnGrouping;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionLearnNotifFlowsStatisticsUpdateApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionLearnNotifFlowsStatisticsUpdateWriteActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionLearnNotifDirectStatisticsUpdateApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionLearnNotifDirectStatisticsUpdateWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionLearnNotifGroupDescStatsUpdatedCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionLearnNodesNodeTableFlowWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.learn.grouping.NxLearn;
return new NxActionLearnNotifFlowsStatisticsUpdateApplyActionsCaseBuilder().setNxLearn(value).build();
case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION:
return new NxActionLearnNotifGroupDescStatsUpdatedCaseBuilder().setNxLearn(value).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION:
+ return new NxActionLearnNotifDirectStatisticsUpdateWriteActionsCaseBuilder().setNxLearn(value).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION:
+ return new NxActionLearnNotifDirectStatisticsUpdateApplyActionsCaseBuilder().setNxLearn(value).build();
default:
throw new CodecPreconditionException(path);
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionMultipathGrouping;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionMultipathNotifFlowsStatisticsUpdateApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionMultipathNotifFlowsStatisticsUpdateWriteActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionMultipathNotifDirectStatisticsUpdateApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionMultipathNotifDirectStatisticsUpdateWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionMultipathNotifGroupDescStatsUpdatedCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionMultipathNodesNodeTableFlowWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.multipath.grouping.NxMultipath;
return new NxActionMultipathNotifFlowsStatisticsUpdateApplyActionsCaseBuilder().setNxMultipath(value).build();
case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION:
return new NxActionMultipathNotifGroupDescStatsUpdatedCaseBuilder().setNxMultipath(value).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION:
+ return new NxActionMultipathNotifDirectStatisticsUpdateWriteActionsCaseBuilder().setNxMultipath(value).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION:
+ return new NxActionMultipathNotifDirectStatisticsUpdateApplyActionsCaseBuilder().setNxMultipath(value).build();
default:
throw new CodecPreconditionException(path);
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionOutputRegGrouping;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionOutputRegNotifFlowsStatisticsUpdateApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionOutputRegNotifFlowsStatisticsUpdateWriteActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionOutputRegNotifDirectStatisticsUpdateApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionOutputRegNotifDirectStatisticsUpdateWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionOutputRegNotifGroupDescStatsUpdatedCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionOutputRegNodesNodeTableFlowWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.NxOutputReg;
return new NxActionOutputRegNotifFlowsStatisticsUpdateApplyActionsCaseBuilder().setNxOutputReg(value).build();
case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION:
return new NxActionOutputRegNotifGroupDescStatsUpdatedCaseBuilder().setNxOutputReg(value).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION:
+ return new NxActionOutputRegNotifDirectStatisticsUpdateWriteActionsCaseBuilder().setNxOutputReg(value).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION:
+ return new NxActionOutputRegNotifDirectStatisticsUpdateApplyActionsCaseBuilder().setNxOutputReg(value).build();
default:
throw new CodecPreconditionException(path);
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionPopNshGrouping;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionPopNshNotifFlowsStatisticsUpdateApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionPopNshNotifFlowsStatisticsUpdateWriteActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionPopNshNotifDirectStatisticsUpdateApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionPopNshNotifDirectStatisticsUpdateWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionPopNshNotifGroupDescStatsUpdatedCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionPopNshNodesNodeTableFlowWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.pop.nsh.grouping.NxPopNsh;
return new NxActionPopNshNotifFlowsStatisticsUpdateApplyActionsCaseBuilder().setNxPopNsh(value).build();
case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION:
return new NxActionPopNshNotifGroupDescStatsUpdatedCaseBuilder().setNxPopNsh(value).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION:
+ return new NxActionPopNshNotifDirectStatisticsUpdateWriteActionsCaseBuilder().setNxPopNsh(value).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION:
+ return new NxActionPopNshNotifDirectStatisticsUpdateApplyActionsCaseBuilder().setNxPopNsh(value).build();
default:
throw new CodecPreconditionException(path);
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionPushNshGrouping;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionPushNshNotifFlowsStatisticsUpdateApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionPushNshNotifFlowsStatisticsUpdateWriteActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionPushNshNotifDirectStatisticsUpdateApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionPushNshNotifDirectStatisticsUpdateWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionPushNshNotifGroupDescStatsUpdatedCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionPushNshNodesNodeTableFlowWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.push.nsh.grouping.NxPushNsh;
return new NxActionPushNshNotifFlowsStatisticsUpdateApplyActionsCaseBuilder().setNxPushNsh(value).build();
case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION:
return new NxActionPushNshNotifGroupDescStatsUpdatedCaseBuilder().setNxPushNsh(value).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION:
+ return new NxActionPushNshNotifDirectStatisticsUpdateWriteActionsCaseBuilder().setNxPushNsh(value).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION:
+ return new NxActionPushNshNotifDirectStatisticsUpdateApplyActionsCaseBuilder().setNxPushNsh(value).build();
default:
throw new CodecPreconditionException(path);
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionRegLoadGrouping;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNotifFlowsStatisticsUpdateApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegLoadNotifFlowsStatisticsUpdateWriteActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionRegLoadNotifGroupDescStatsUpdatedCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegLoadNodesNodeTableFlowWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
return new NxActionRegLoadNotifFlowsStatisticsUpdateApplyActionsCaseBuilder().setNxRegLoad(value).build();
case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION:
return new NxActionRegLoadNotifGroupDescStatsUpdatedCaseBuilder().setNxRegLoad(value).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION:
+ return new NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCaseBuilder().setNxRegLoad(value).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION:
+ return new NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCaseBuilder().setNxRegLoad(value).build();
default:
throw new CodecPreconditionException(path);
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfMplsLabelCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegMoveNotifFlowsStatisticsUpdateApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegMoveNotifFlowsStatisticsUpdateWriteActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegMoveNotifDirectStatisticsUpdateApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegMoveNotifDirectStatisticsUpdateWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionRegMoveNotifGroupDescStatsUpdatedCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegMoveNodesNodeTableFlowWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.NxRegMove;
return new NxActionRegMoveNotifFlowsStatisticsUpdateApplyActionsCaseBuilder().setNxRegMove(value).build();
case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION:
return new NxActionRegMoveNotifGroupDescStatsUpdatedCaseBuilder().setNxRegMove(value).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION:
+ return new NxActionRegMoveNotifDirectStatisticsUpdateWriteActionsCaseBuilder().setNxRegMove(value).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION:
+ return new NxActionRegMoveNotifDirectStatisticsUpdateApplyActionsCaseBuilder().setNxRegMove(value).build();
default:
throw new CodecPreconditionException(path);
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionResubmitGrouping;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionResubmitNotifFlowsStatisticsUpdateApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionResubmitNotifFlowsStatisticsUpdateWriteActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionResubmitNotifDirectStatisticsUpdateApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionResubmitNotifDirectStatisticsUpdateWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionResubmitNotifGroupDescStatsUpdatedCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionResubmitNodesNodeTableFlowWriteActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.resubmit.grouping.NxResubmit;
return new NxActionResubmitNotifFlowsStatisticsUpdateApplyActionsCaseBuilder().setNxResubmit(value).build();
case GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION:
return new NxActionResubmitNotifGroupDescStatsUpdatedCaseBuilder().setNxResubmit(value).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION:
+ return new NxActionResubmitNotifDirectStatisticsUpdateWriteActionsCaseBuilder().setNxResubmit(value).build();
+ case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION:
+ return new NxActionResubmitNotifDirectStatisticsUpdateApplyActionsCaseBuilder().setNxResubmit(value).build();
default:
throw new CodecPreconditionException(path);
}
import openflowplugin-extension-general {prefix ext-gen;revision-date "2014-07-14";}
import openflow-action {prefix ofaction;revision-date "2015-02-03";}
import nicira-action {prefix nicira-action;revision-date "2014-04-21";}
+ import opendaylight-direct-statistics {prefix directstat;revision-date "2016-05-11";}
description
"Nicira openflow action extensions.";
uses nx-action-learn-grouping;
}
}
+ augment "/directstat:get-flow-statistics/directstat:output/directstat:flow-and-statistics-map-list/directstat:instructions/directstat:instruction/directstat:instruction/directstat:apply-actions-case/directstat:apply-actions/directstat:action/directstat:action" {
+ case "nx-action-reg-load-notif-direct-statistics-update-apply-actions-case" {
+ uses nx-action-reg-load-grouping;
+ }
+ case "nx-action-reg-move-notif-direct-statistics-update-apply-actions-case" {
+ uses nx-action-reg-move-grouping;
+ }
+ case "nx-action-output-reg-notif-direct-statistics-update-apply-actions-case" {
+ uses nx-action-output-reg-grouping;
+ }
+ case "nx-action-resubmit-notif-direct-statistics-update-apply-actions-case" {
+ uses nx-action-resubmit-grouping;
+ }
+ case "nx-action-fin-timeout-notif-direct-statistics-update-apply-actions-case" {
+ uses nx-action-fin-timeout-grouping;
+ }
+ case "nx-action-multipath-notif-direct-statistics-update-apply-actions-case" {
+ uses nx-action-multipath-grouping;
+ }
+ case "nx-action-push-nsh-notif-direct-statistics-update-apply-actions-case" {
+ uses nx-action-push-nsh-grouping;
+ }
+ case "nx-action-pop-nsh-notif-direct-statistics-update-apply-actions-case" {
+ uses nx-action-pop-nsh-grouping;
+ }
+ case "nx-action-conntrack-notif-direct-statistics-update-apply-actions-case" {
+ uses nx-action-conntrack-grouping;
+ }
+ case "nx-action-learn-notif-direct-statistics-update-apply-actions-case" {
+ uses nx-action-learn-grouping;
+ }
+ }
+
+ augment "/directstat:get-flow-statistics/directstat:output/directstat:flow-and-statistics-map-list/directstat:instructions/directstat:instruction/directstat:instruction/directstat:write-actions-case/directstat:write-actions/directstat:action/directstat:action" {
+ case "nx-action-reg-load-notif-direct-statistics-update-write-actions-case" {
+ uses nx-action-reg-load-grouping;
+ }
+ case "nx-action-reg-move-notif-direct-statistics-update-write-actions-case" {
+ uses nx-action-reg-move-grouping;
+ }
+ case "nx-action-output-reg-notif-direct-statistics-update-write-actions-case" {
+ uses nx-action-output-reg-grouping;
+ }
+ case "nx-action-resubmit-notif-direct-statistics-update-write-actions-case" {
+ uses nx-action-resubmit-grouping;
+ }
+ case "nx-action-fin-timeout-notif-direct-statistics-update-write-actions-case" {
+ uses nx-action-fin-timeout-grouping;
+ }
+ case "nx-action-multipath-notif-direct-statistics-update-write-actions-case" {
+ uses nx-action-multipath-grouping;
+ }
+ case "nx-action-push-nsh-notif-direct-statistics-update-write-actions-case" {
+ uses nx-action-push-nsh-grouping;
+ }
+ case "nx-action-pop-nsh-notif-direct-statistics-update-write-actions-case" {
+ uses nx-action-pop-nsh-grouping;
+ }
+ case "nx-action-conntrack-notif-direct-statistics-update-write-actions-case" {
+ uses nx-action-conntrack-grouping;
+ }
+ case "nx-action-learn-notif-direct-statistics-update-write-actions-case" {
+ uses nx-action-learn-grouping;
+ }
+ }
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack.grouping.NxActionConntrackBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionConntrackNotifFlowsStatisticsUpdateApplyActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionConntrackNotifFlowsStatisticsUpdateWriteActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionConntrackNotifGroupDescStatsUpdatedCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionConntrackNodesNodeTableFlowWriteActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionConntrackNodesNodeTableFlowWriteActionsCaseBuilder;
= conntrackConvertor.convert(groupingAction, ActionPath.FLOWSSTATISTICSUPDATE_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION);
final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action3
= conntrackConvertor.convert(groupingAction, ActionPath.GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION);
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action4
+ = conntrackConvertor.convert(groupingAction, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION);
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action5
+ = conntrackConvertor.convert(groupingAction, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION);
Assert.assertEquals(1, ((NxActionConntrackNodesNodeTableFlowWriteActionsCase) action).getNxConntrack().getConntrackZone().longValue());
Assert.assertEquals(1L, ((NxActionConntrackNodesNodeTableFlowWriteActionsCase) action).getNxConntrack().getZoneSrc().longValue());
Assert.assertEquals(1, ((NxActionConntrackNotifGroupDescStatsUpdatedCase) action3).getNxConntrack().getRecircTable().intValue());
Assert.assertEquals(1, ((NxActionConntrackNotifGroupDescStatsUpdatedCase) action3).getNxConntrack().getFlags().intValue());
- }
+ Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCase) action4).getNxConntrack().getConntrackZone().longValue());
+ Assert.assertEquals(1L, ((NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCase) action4).getNxConntrack().getZoneSrc().longValue());
+ Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCase) action4).getNxConntrack().getRecircTable().intValue());
+ Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCase) action4).getNxConntrack().getFlags().intValue());
+ Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCase) action5).getNxConntrack().getConntrackZone().longValue());
+ Assert.assertEquals(1L, ((NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCase) action5).getNxConntrack().getZoneSrc().longValue());
+ Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCase) action5).getNxConntrack().getRecircTable().intValue());
+ Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCase) action5).getNxConntrack().getFlags().intValue());
+ }
}
\ No newline at end of file
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.fin.timeout.grouping.NxActionFinTimeout;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionFinTimeoutNotifFlowsStatisticsUpdateApplyActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionFinTimeoutNotifFlowsStatisticsUpdateWriteActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionFinTimeoutNotifDirectStatisticsUpdateApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionFinTimeoutNotifDirectStatisticsUpdateWriteActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionFinTimeoutNotifGroupDescStatsUpdatedCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionFinTimeoutNodesNodeTableFlowWriteActionsCase;
final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult3 =
finTimeoutConvertor.convert(action,
ActionPath.NODES_NODE_TABLE_FLOW_INSTRUCTIONS_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION_EXTENSIONLIST_EXTENSION);
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult4 =
+ finTimeoutConvertor.convert(action,
+ ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION);
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult5 =
+ finTimeoutConvertor.convert(action,
+ ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION);
Assert.assertEquals(3, ((NxActionFinTimeoutNotifFlowsStatisticsUpdateApplyActionsCase) actionResult)
.getNxActionFinTimeout().getFinIdleTimeout().intValue());
.getNxActionFinTimeout().getFinIdleTimeout().intValue());
Assert.assertEquals(4, ((NxActionFinTimeoutNodesNodeTableFlowWriteActionsCase) actionResult3)
.getNxActionFinTimeout().getFinHardTimeout().intValue());
- }
+ Assert.assertEquals(3, ((NxActionFinTimeoutNotifDirectStatisticsUpdateApplyActionsCase) actionResult4)
+ .getNxActionFinTimeout().getFinIdleTimeout().intValue());
+ Assert.assertEquals(4, ((NxActionFinTimeoutNotifDirectStatisticsUpdateApplyActionsCase) actionResult4)
+ .getNxActionFinTimeout().getFinHardTimeout().intValue());
+
+ Assert.assertEquals(3, ((NxActionFinTimeoutNotifDirectStatisticsUpdateWriteActionsCase) actionResult5)
+ .getNxActionFinTimeout().getFinIdleTimeout().intValue());
+ Assert.assertEquals(4, ((NxActionFinTimeoutNotifDirectStatisticsUpdateWriteActionsCase) actionResult5)
+ .getNxActionFinTimeout().getFinHardTimeout().intValue());
+ }
}
\ No newline at end of file
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNspCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionMultipathNotifFlowsStatisticsUpdateApplyActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionMultipathNotifFlowsStatisticsUpdateWriteActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionMultipathNotifDirectStatisticsUpdateApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionMultipathNotifDirectStatisticsUpdateWriteActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionMultipathNotifGroupDescStatsUpdatedCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionMultipathNodesNodeTableFlowWriteActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.multipath.grouping.NxMultipath;
= multipathConvertor.convert(action, ActionPath.GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION);
final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult3
= multipathConvertor.convert(action, ActionPath.NODES_NODE_TABLE_FLOW_INSTRUCTIONS_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION_EXTENSIONLIST_EXTENSION);
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult4
+ = multipathConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION);
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult5
+ = multipathConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION);
Assert.assertEquals(Integer.valueOf(1), ((NxActionMultipathNotifFlowsStatisticsUpdateApplyActionsCase) actionResult).getNxMultipath().getBasis());
Assert.assertEquals(OfjNxMpAlgorithm.NXMPALGHRW, ((NxActionMultipathNotifFlowsStatisticsUpdateApplyActionsCase) actionResult).getNxMultipath().getAlgorithm());
Assert.assertEquals(OfjNxMpAlgorithm.NXMPALGHRW, ((NxActionMultipathNodesNodeTableFlowWriteActionsCase) actionResult3).getNxMultipath().getAlgorithm());
Assert.assertEquals(Long.valueOf(2L), ((NxActionMultipathNodesNodeTableFlowWriteActionsCase) actionResult3).getNxMultipath().getArg());
Assert.assertEquals(Integer.valueOf(2), ((NxActionMultipathNodesNodeTableFlowWriteActionsCase) actionResult3).getNxMultipath().getMaxLink());
+
+ Assert.assertEquals(Integer.valueOf(1), ((NxActionMultipathNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxMultipath().getBasis());
+ Assert.assertEquals(OfjNxMpAlgorithm.NXMPALGHRW, ((NxActionMultipathNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxMultipath().getAlgorithm());
+ Assert.assertEquals(Long.valueOf(2L), ((NxActionMultipathNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxMultipath().getArg());
+ Assert.assertEquals(Integer.valueOf(2), ((NxActionMultipathNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxMultipath().getMaxLink());
+
+ Assert.assertEquals(Integer.valueOf(1), ((NxActionMultipathNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxMultipath().getBasis());
+ Assert.assertEquals(OfjNxMpAlgorithm.NXMPALGHRW, ((NxActionMultipathNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxMultipath().getAlgorithm());
+ Assert.assertEquals(Long.valueOf(2L), ((NxActionMultipathNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxMultipath().getArg());
+ Assert.assertEquals(Integer.valueOf(2), ((NxActionMultipathNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxMultipath().getMaxLink());
}
}
\ No newline at end of file
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.output.reg.grouping.NxActionOutputReg;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionOutputRegNotifFlowsStatisticsUpdateApplyActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionOutputRegNotifFlowsStatisticsUpdateWriteActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionOutputRegNotifDirectStatisticsUpdateApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionOutputRegNotifDirectStatisticsUpdateWriteActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionOutputRegNotifGroupDescStatsUpdatedCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionOutputRegNodesNodeGroupBucketsBucketActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionOutputRegNodesNodeTableFlowWriteActionsCase;
= outputRegConvertor.convert(action, ActionPath.FLOWSSTATISTICSUPDATE_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION);
final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult3
= outputRegConvertor.convert(action, ActionPath.GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION);
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult4
+ = outputRegConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION);
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult5
+ = outputRegConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION);
Assert.assertEquals(Integer.valueOf(3), ((NxActionOutputRegNotifFlowsStatisticsUpdateApplyActionsCase) actionResult).getNxOutputReg().getMaxLen());
Assert.assertEquals(Integer.valueOf(4), ((NxActionOutputRegNotifFlowsStatisticsUpdateApplyActionsCase) actionResult).getNxOutputReg().getSrc().getOfsNbits());
Assert.assertEquals(Integer.valueOf(3), ((NxActionOutputRegNotifGroupDescStatsUpdatedCase) actionResult3).getNxOutputReg().getMaxLen());
Assert.assertEquals(Integer.valueOf(4), ((NxActionOutputRegNotifGroupDescStatsUpdatedCase) actionResult3).getNxOutputReg().getSrc().getOfsNbits());
+
+ Assert.assertEquals(Integer.valueOf(3), ((NxActionOutputRegNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxOutputReg().getMaxLen());
+ Assert.assertEquals(Integer.valueOf(4), ((NxActionOutputRegNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxOutputReg().getSrc().getOfsNbits());
+
+ Assert.assertEquals(Integer.valueOf(3), ((NxActionOutputRegNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxOutputReg().getMaxLen());
+ Assert.assertEquals(Integer.valueOf(4), ((NxActionOutputRegNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxOutputReg().getSrc().getOfsNbits());
+
}
}
\ No newline at end of file
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxTunIdCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNotifFlowsStatisticsUpdateApplyActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegLoadNotifFlowsStatisticsUpdateWriteActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionRegLoadNotifGroupDescStatsUpdatedCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionRegLoadNodesNodeGroupBucketsBucketActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegLoadNodesNodeTableFlowWriteActionsCase;
= regLoadConvertor.convert(action, ActionPath.FLOWSSTATISTICSUPDATE_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION);
org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult3
= regLoadConvertor.convert(action, ActionPath.GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION);
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult4
+ = regLoadConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION);
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult5
+ = regLoadConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION);
Assert.assertEquals(Integer.valueOf(0), ((NxActionRegLoadNodesNodeTableFlowWriteActionsCase) actionResult).getNxRegLoad().getDst().getStart());
Assert.assertEquals(Integer.valueOf(4), ((NxActionRegLoadNodesNodeTableFlowWriteActionsCase) actionResult).getNxRegLoad().getDst().getEnd());
Assert.assertEquals(Integer.valueOf(4), ((NxActionRegLoadNotifGroupDescStatsUpdatedCase) actionResult3).getNxRegLoad().getDst().getEnd());
Assert.assertEquals(BigInteger.ONE, ((NxActionRegLoadNotifGroupDescStatsUpdatedCase) actionResult3).getNxRegLoad().getValue());
+ Assert.assertEquals(Integer.valueOf(0), ((NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxRegLoad().getDst().getStart());
+ Assert.assertEquals(Integer.valueOf(4), ((NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxRegLoad().getDst().getEnd());
+ Assert.assertEquals(BigInteger.ONE, ((NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxRegLoad().getValue());
+
+ Assert.assertEquals(Integer.valueOf(0), ((NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxRegLoad().getDst().getStart());
+ Assert.assertEquals(Integer.valueOf(4), ((NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxRegLoad().getDst().getEnd());
+ Assert.assertEquals(BigInteger.ONE, ((NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxRegLoad().getValue());
+
}
}
\ No newline at end of file
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfIpSrcCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegMoveNotifFlowsStatisticsUpdateApplyActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegMoveNotifFlowsStatisticsUpdateWriteActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegMoveNotifDirectStatisticsUpdateApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegMoveNotifDirectStatisticsUpdateWriteActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionRegMoveNotifGroupDescStatsUpdatedCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegMoveNodesNodeTableFlowWriteActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.NxRegMove;
= regMoveConvertor.convert(action, ActionPath.FLOWSSTATISTICSUPDATE_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION);
final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult3
= regMoveConvertor.convert(action, ActionPath.GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION);
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult4
+ = regMoveConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION);
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult5
+ = regMoveConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION);
Assert.assertEquals(Integer.valueOf(0), ((NxActionRegMoveNotifFlowsStatisticsUpdateApplyActionsCase) actionResult).getNxRegMove().getDst().getStart());
Assert.assertEquals(Integer.valueOf(6), ((NxActionRegMoveNotifFlowsStatisticsUpdateApplyActionsCase) actionResult).getNxRegMove().getDst().getEnd());
Assert.assertEquals(Integer.valueOf(6), ((NxActionRegMoveNotifFlowsStatisticsUpdateWriteActionsCase) actionResult2).getNxRegMove().getDst().getEnd());
Assert.assertEquals(Integer.valueOf(0), ((NxActionRegMoveNotifGroupDescStatsUpdatedCase) actionResult3).getNxRegMove().getDst().getStart());
Assert.assertEquals(Integer.valueOf(6), ((NxActionRegMoveNotifGroupDescStatsUpdatedCase) actionResult3).getNxRegMove().getDst().getEnd());
+ Assert.assertEquals(Integer.valueOf(0), ((NxActionRegMoveNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxRegMove().getDst().getStart());
+ Assert.assertEquals(Integer.valueOf(6), ((NxActionRegMoveNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxRegMove().getDst().getEnd());
+ Assert.assertEquals(Integer.valueOf(0), ((NxActionRegMoveNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxRegMove().getDst().getStart());
+ Assert.assertEquals(Integer.valueOf(6), ((NxActionRegMoveNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxRegMove().getDst().getEnd());
+
}
@Test
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.resubmit.grouping.NxActionResubmit;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionResubmitNotifFlowsStatisticsUpdateApplyActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionResubmitNotifFlowsStatisticsUpdateWriteActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionResubmitNotifDirectStatisticsUpdateApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionResubmitNotifDirectStatisticsUpdateWriteActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionResubmitNotifGroupDescStatsUpdatedCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionResubmitNodesNodeTableFlowWriteActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.resubmit.grouping.NxResubmit;
= resubmitConvertor.convert(action, ActionPath.GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION);
final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult3
= resubmitConvertor.convert(action, ActionPath.NODES_NODE_TABLE_FLOW_INSTRUCTIONS_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION_EXTENSIONLIST_EXTENSION);
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult4
+ = resubmitConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION);
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult5
+ = resubmitConvertor.convert(action, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION);
Assert.assertEquals(3, ((NxActionResubmitNotifFlowsStatisticsUpdateApplyActionsCase) actionResult).getNxResubmit().getInPort().intValue());
Assert.assertEquals(4, ((NxActionResubmitNotifFlowsStatisticsUpdateApplyActionsCase) actionResult).getNxResubmit().getTable().intValue());
Assert.assertEquals(3, ((NxActionResubmitNodesNodeTableFlowWriteActionsCase) actionResult3).getNxResubmit().getInPort().intValue());
Assert.assertEquals(4, ((NxActionResubmitNodesNodeTableFlowWriteActionsCase) actionResult3).getNxResubmit().getTable().intValue());
- }
+ Assert.assertEquals(3, ((NxActionResubmitNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxResubmit().getInPort().intValue());
+ Assert.assertEquals(4, ((NxActionResubmitNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxResubmit().getTable().intValue());
+
+ Assert.assertEquals(3, ((NxActionResubmitNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxResubmit().getInPort().intValue());
+ Assert.assertEquals(4, ((NxActionResubmitNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxResubmit().getTable().intValue());
+ }
}
\ No newline at end of file
bit SEND_FLOW_REM;
}
}
+ typedef removed-flow-reason {
+ type enumeration {
+ enum OFPRR_IDLE_TIMEOUT{
+ value 0;
+ description "Flow idle time exceeded idle_timeout.";
+ }
+ enum OFPRR_HARD_TIMEOUT {
+ value 1;
+ description "Time exceeded hard_timeout.";
+ }
+ enum OFPRR_DELETE {
+ value 2;
+ description "Evicted by a DELETE flow mod.";
+ }
+ enum OFPRR_GROUP_DELETE {
+ value 3;
+ description "Group was removed.";
+ }
- typedef removed_reason_flags {
- type bits {
- bit IDLE_TIMEOUT;
- bit HARD_TIMEOUT;
- bit DELETE;
- bit GROUP_DELETE;
- }
- }
+ }
+ }
grouping generic_flow_attributes {
leaf priority {
uses generic_flow_attributes;
leaf removed_reason {
- type removed_reason_flags;
+ type removed-flow-reason;
}
leaf duration_nsec {
import yang-ext {prefix ext; revision-date "2013-07-09";}
import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
- import opendaylight-flow-types {prefix types;revision-date "2013-10-26";}
+ import opendaylight-flow-types {prefix types;revision-date "2013-10-26";}
import opendaylight-group-types {prefix group-type;revision-date "2013-10-18";}
import opendaylight-meter-types {prefix meter-type;revision-date "2013-09-18";}
import flow-capable-transaction {prefix tr; revision-date "2015-03-04";}
leaf flow-ref {
type types:flow-ref;
}
+ leaf reason {
+ type types:removed-flow-reason;
+ }
uses node-flow;
uses tr:transaction-aware;
}
/**
* About to stop services in cluster not master anymore or going down
* @return Future most of services need time to be closed
- * @param connectionInterrupted true if clustering services stopping by device disconnect
*/
- default ListenableFuture<Void> stopClusterServices(boolean connectionInterrupted) {
+ default ListenableFuture<Void> stopClusterServices() {
return Futures.immediateFailedFuture(new RejectedExecutionException("Cannot stop abstract services, check implementation of cluster services"));
}
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
import org.opendaylight.controller.md.sal.binding.api.NotificationService;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider;
void setNotificationPublishService(NotificationPublishService notificationPublishService);
+ void setClusteringSingletonServicesProvider(ClusterSingletonServiceProvider singletonServicesProvider);
+
+ void setEntityOwnershipServiceProvider(EntityOwnershipService entityOwnershipService);
/**
* Method initializes all DeviceManager, RpcManager and related contexts.
*/
void update(Map<String,Object> props);
- void setClusteringSingletonServicesProvider(ClusterSingletonServiceProvider singletonServicesProvider);
-
void setSkipTableFeatures(boolean skipTableFeatures);
void setBasicTimerDelay(long basicTimerDelay);
* @return listenable future from sal role service
*/
ListenableFuture<RpcResult<SetRoleOutput>> makeDeviceSlave();
+
+ void sendNodeAddedNotification();
+
+ void sendNodeRemovedNotification();
+
+ void cleanupDeviceData();
}
package org.opendaylight.openflowplugin.api.openflow.device;
import com.google.common.util.concurrent.CheckedFuture;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.openflowplugin.api.openflow.OFPManager;
import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceConnectedHandler;
OFPManager,
DeviceConnectedHandler,
DeviceDisconnectedHandler,
- TranslatorLibrarian {
+ TranslatorLibrarian,
+ EntityOwnershipListener {
/**
* invoked after all services injected
package org.opendaylight.openflowplugin.api.openflow.lifecycle;
import javax.annotation.CheckForNull;
+
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.openflowplugin.api.openflow.OFPContext;
providerConfig.getThreadPoolMaxThreads().getValue(),
providerConfig.getThreadPoolTimeout());
+ //Set services
openflowPluginProvider.setSwitchConnectionProviders(switchConnectionProviders);
openflowPluginProvider.setDataBroker(dataBroker);
openflowPluginProvider.setRpcProviderRegistry(rpcRegistry);
openflowPluginProvider.setNotificationProviderService(notificationService);
openflowPluginProvider.setNotificationPublishService(notificationPublishService);
+ openflowPluginProvider.setEntityOwnershipServiceProvider(entityOwnershipService);
+ openflowPluginProvider.setClusteringSingletonServicesProvider(singletonServiceProvider);
+
+ //Set config parameters
openflowPluginProvider.setSwitchFeaturesMandatory(providerConfig.isSwitchFeaturesMandatory());
openflowPluginProvider.setFlowRemovedNotification(providerConfig.isEnableFlowRemovedNotification());
openflowPluginProvider.setIsStatisticsRpcEnabled(providerConfig.isIsStatisticsRpcEnabled());
openflowPluginProvider.setBarrierInterval(providerConfig.getBarrierIntervalTimeoutLimit().getValue());
openflowPluginProvider.setEchoReplyTimeout(providerConfig.getEchoReplyTimeout().getValue());
openflowPluginProvider.setStatisticsPollingOn(providerConfig.isIsStatisticsPollingOn());
- openflowPluginProvider.setClusteringSingletonServicesProvider(singletonServiceProvider);
openflowPluginProvider.setSkipTableFeatures(providerConfig.isSkipTableFeatures());
openflowPluginProvider.setBasicTimerDelay(providerConfig.getBasicTimerDelay().getValue());
openflowPluginProvider.setMaximumTimerDelay(providerConfig.getMaximumTimerDelay().getValue());
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
import org.opendaylight.controller.md.sal.binding.api.NotificationService;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider;
private ConnectionManager connectionManager;
private NotificationService notificationProviderService;
private NotificationPublishService notificationPublishService;
+ private EntityOwnershipService entityOwnershipService;
+ private ClusterSingletonServiceProvider singletonServicesProvider;
private ExtensionConverterManager extensionConverterManager;
private DataBroker dataBroker;
private Collection<SwitchConnectionProvider> switchConnectionProviders;
private long maximumTimerDelay;
private final ThreadPoolExecutor threadPool;
- private ClusterSingletonServiceProvider singletonServicesProvider;
public OpenFlowPluginProviderImpl(final long rpcRequestsQuota,
final long globalNotificationQuota,
this.singletonServicesProvider = singletonServicesProvider;
}
+ @Override
+ public void setEntityOwnershipServiceProvider(EntityOwnershipService entityOwnershipService) {
+ this.entityOwnershipService = entityOwnershipService;
+ }
+
@Override
public void setSkipTableFeatures(final boolean skipTableFeatures){
this.skipTableFeatures = skipTableFeatures;
getMessageIntelligenceAgency(),
isFlowRemovedNotificationOn,
singletonServicesProvider,
- notificationPublishService,
+ entityOwnershipService,
hashedWheelTimer,
convertorManager,
- skipTableFeatures);
+ skipTableFeatures,
+ notificationPublishService);
((ExtensionConverterProviderKeeper) deviceManager).setExtensionConverterProvider(extensionConverterManager);
import com.google.common.base.Preconditions;
import com.google.common.base.Verify;
import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.JdkFutureAdapters;
import io.netty.util.HashedWheelTimer;
import io.netty.util.Timeout;
import io.netty.util.TimerTask;
-import java.math.BigInteger;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemovedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdatedBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
public class DeviceContextImpl implements DeviceContext, ExtensionConverterProviderKeeper {
private static final Logger LOG = LoggerFactory.getLogger(DeviceContextImpl.class);
private volatile CONTEXT_STATE state;
private ClusterInitializationPhaseHandler clusterInitializationPhaseHandler;
private final DeviceManager myManager;
+ private Boolean isAddNotificationSent = false;
DeviceContextImpl(
@Nonnull final ConnectionContext primaryConnectionContext,
final ItemLifecycleListener itemLifecycleListener = flowLifeCycleKeeper.getItemLifecycleListener();
if (itemLifecycleListener != null) {
//2. create registry key
- final FlowRegistryKey flowRegKey = FlowRegistryKeyFactory.create(flowRemovedNotification);
+ final FlowRegistryKey flowRegKey = FlowRegistryKeyFactory.create(getDeviceInfo().getVersion(), flowRemovedNotification);
//3. lookup flowId
final FlowDescriptor flowDescriptor = deviceFlowRegistry.retrieveIdForFlow(flowRegKey);
//4. if flowId present:
}
}
+ @Override
+ public void sendNodeAddedNotification() {
+ if (!isAddNotificationSent) {
+ isAddNotificationSent = true;
+ NodeUpdatedBuilder builder = new NodeUpdatedBuilder();
+ builder.setId(getDeviceInfo().getNodeId());
+ builder.setNodeRef(new NodeRef(getDeviceInfo().getNodeInstanceIdentifier()));
+ LOG.debug("Publishing node added notification for {}", builder.build());
+ notificationPublishService.offerNotification(builder.build());
+ }
+ }
+
+ @Override
+ public void sendNodeRemovedNotification() {
+ NodeRemovedBuilder builder = new NodeRemovedBuilder();
+ builder.setNodeRef(new NodeRef(getDeviceInfo().getNodeInstanceIdentifier()));
+ LOG.debug("Publishing node removed notification for {}", builder.build());
+ notificationPublishService.offerNotification(builder.build());
+ }
+
@Override
public void processPortStatusMessage(final PortStatusMessage portStatus) {
messageSpy.spyMessage(portStatus.getImplementedInterface(), MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_SUCCESS);
}
@Override
- public ListenableFuture<Void> stopClusterServices(boolean connectionInterrupted) {
+ public ListenableFuture<Void> stopClusterServices() {
final ListenableFuture<Void> deactivateTxManagerFuture = initialized
? transactionChainManager.deactivateTransactionManager()
: Futures.immediateFuture(null);
+ final boolean connectionInterrupted =
+ this.getPrimaryConnectionContext()
+ .getConnectionState()
+ .equals(ConnectionContext.CONNECTION_STATE.RIP);
if (!connectionInterrupted) {
- final ListenableFuture<Void> makeSlaveFuture = Futures.transform(makeDeviceSlave(), new Function<RpcResult<SetRoleOutput>, Void>() {
- @Nullable
- @Override
- public Void apply(@Nullable RpcResult<SetRoleOutput> setRoleOutputRpcResult) {
- return null;
- }
- });
-
- Futures.addCallback(makeSlaveFuture, new FutureCallback<Void>() {
- @Override
- public void onSuccess(@Nullable Void aVoid) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Role SLAVE was successfully propagated on device, node {}", deviceInfo.getLOGValue());
- }
- }
-
- @Override
- public void onFailure(final Throwable throwable) {
- LOG.warn("Was not able to set role SLAVE to device on node {} ", deviceInfo.getLOGValue());
- LOG.trace("Error occurred on device role setting, probably connection loss: ", throwable);
- }
- });
-
- return Futures.transform(deactivateTxManagerFuture, new AsyncFunction<Void, Void>() {
- @Override
- public ListenableFuture<Void> apply(Void aVoid) throws Exception {
- // Add fallback to remove device from operational DS if setting slave fails
- return Futures.withFallback(makeSlaveFuture, t ->
- myManager.removeDeviceFromOperationalDS(deviceInfo));
- }
- });
- } else {
- return Futures.transform(deactivateTxManagerFuture, new AsyncFunction<Void, Void>() {
- @Override
- public ListenableFuture<Void> apply(Void aVoid) throws Exception {
- return myManager.removeDeviceFromOperationalDS(deviceInfo);
- }
- });
+ LOG.info("This controller instance is now acting as a non-owner for node {}", deviceInfo.getLOGValue());
}
+
+ return deactivateTxManagerFuture;
+ }
+
+ @Override
+ public void cleanupDeviceData() {
+ myManager.removeDeviceFromOperationalDS(deviceInfo);
}
@Override
} else {
this.state = CONTEXT_STATE.TERMINATION;
}
+ sendNodeRemovedNotification();
}
@Override
LOG.debug("Transaction chain manager for node {} created", deviceInfo.getLOGValue());
}
this.transactionChainManager = new TransactionChainManager(dataBroker, deviceInfo);
- this.deviceFlowRegistry = new DeviceFlowRegistryImpl(dataBroker, deviceInfo.getNodeInstanceIdentifier());
+ this.deviceFlowRegistry = new DeviceFlowRegistryImpl(deviceInfo.getVersion(), dataBroker, deviceInfo.getNodeInstanceIdentifier());
this.deviceGroupRegistry = new DeviceGroupRegistryImpl();
this.deviceMeterRegistry = new DeviceMeterRegistryImpl();
this.initialized = true;
if (LOG.isDebugEnabled()) {
LOG.debug("Role MASTER was successfully set on device, node {}", deviceInfo.getLOGValue());
}
+ sendNodeAddedNotification();
}
@Override
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
+import com.google.common.base.Verify;
import com.google.common.collect.Iterators;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.FutureCallback;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.openflowplugin.impl.device.listener.OpenflowProtocolListenerFullImpl;
import org.opendaylight.openflowplugin.impl.lifecycle.LifecycleServiceImpl;
import org.opendaylight.openflowplugin.impl.services.SalRoleServiceImpl;
+import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleOutput;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProviderKeeper {
private static final Logger LOG = LoggerFactory.getLogger(DeviceManagerImpl.class);
+ private static final String SERVICE_ENTITY_TYPE = "org.opendaylight.mdsal.ServiceEntityType";
private final long globalNotificationQuota;
private final boolean switchFeaturesMandatory;
+ private final EntityOwnershipListenerRegistration eosListenerRegistration;
private boolean isFlowRemovedNotificationOn;
private boolean skipTableFeatures;
private static final int SPY_RATE = 10;
private DeviceTerminationPhaseHandler deviceTerminPhaseHandler;
private final ConcurrentMap<DeviceInfo, DeviceContext> deviceContexts = new ConcurrentHashMap<>();
+ private final ConcurrentMap<DeviceInfo, DeviceContext> removeddeviceContexts = new ConcurrentHashMap<>();
private final ConcurrentMap<DeviceInfo, LifecycleService> lifecycleServices = new ConcurrentHashMap<>();
private long barrierIntervalNanos;
private ExtensionConverterProvider extensionConverterProvider;
private ScheduledThreadPoolExecutor spyPool;
private final ClusterSingletonServiceProvider singletonServiceProvider;
+ private final EntityOwnershipService entityOwnershipService;
private final NotificationPublishService notificationPublishService;
private final MessageSpy messageSpy;
private final HashedWheelTimer hashedWheelTimer;
final MessageSpy messageSpy,
final boolean isFlowRemovedNotificationOn,
final ClusterSingletonServiceProvider singletonServiceProvider,
- final NotificationPublishService notificationPublishService,
+ final EntityOwnershipService entityOwnershipService,
final HashedWheelTimer hashedWheelTimer,
final ConvertorExecutor convertorExecutor,
- final boolean skipTableFeatures) {
+ final boolean skipTableFeatures,
+ final NotificationPublishService notificationPublishService) {
- this.dataBroker = dataBroker;
-
- /* merge empty nodes to oper DS to predict any problems with missing parent for Node */
- final WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
- final NodesBuilder nodesBuilder = new NodesBuilder();
- nodesBuilder.setNode(Collections.<Node>emptyList());
- tx.merge(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class), nodesBuilder.build());
- try {
- tx.submit().get();
- } catch (ExecutionException | InterruptedException e) {
- LOG.error("Creation of node failed.", e);
- throw new IllegalStateException(e);
- }
+ this.dataBroker = dataBroker;
+ this.entityOwnershipService = entityOwnershipService;
this.switchFeaturesMandatory = switchFeaturesMandatory;
this.globalNotificationQuota = globalNotificationQuota;
this.isFlowRemovedNotificationOn = isFlowRemovedNotificationOn;
this.singletonServiceProvider = singletonServiceProvider;
this.notificationPublishService = notificationPublishService;
this.messageSpy = messageSpy;
+
+ this.eosListenerRegistration = Verify.verifyNotNull(entityOwnershipService.registerListener
+ (SERVICE_ENTITY_TYPE, this));
+
+ /* merge empty nodes to oper DS to predict any problems with missing parent for Node */
+ final WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
+ final NodesBuilder nodesBuilder = new NodesBuilder();
+ nodesBuilder.setNode(Collections.<Node>emptyList());
+ tx.merge(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class), nodesBuilder.build());
+ try {
+ tx.submit().get();
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.error("Creation of node failed.", e);
+ throw new IllegalStateException(e);
+ }
}
Optional.ofNullable(spyPool).ifPresent(ScheduledThreadPoolExecutor::shutdownNow);
spyPool = null;
+ if (Objects.nonNull(eosListenerRegistration)) {
+ try {
+ LOG.debug("Closing entity ownership listener");
+ eosListenerRegistration.close();
+ } catch (Exception e) {
+ LOG.debug("Failed to close entity ownership listener registration with exception",e);
+ }
+ }
+
}
@Override
@Override
public CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(final DeviceInfo deviceInfo) {
+ return removeDeviceFromOperationalDS(deviceInfo.getNodeInstanceIdentifier(), deviceInfo.getLOGValue());
+ }
+
+ private CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(
+ final KeyedInstanceIdentifier<Node, NodeKey> nodeIid, final String nodeName) {
+ Preconditions.checkNotNull(nodeIid, "Node IID must not be null");
+
final WriteTransaction delWtx = dataBroker.newWriteOnlyTransaction();
- delWtx.delete(LogicalDatastoreType.OPERATIONAL, deviceInfo.getNodeInstanceIdentifier());
+ delWtx.delete(LogicalDatastoreType.OPERATIONAL, nodeIid);
final CheckedFuture<Void, TransactionCommitFailedException> delFuture = delWtx.submit();
Futures.addCallback(delFuture, new FutureCallback<Void>() {
@Override
public void onSuccess(final Void result) {
if (LOG.isDebugEnabled()) {
- LOG.debug("Delete Node {} was successful", deviceInfo.getLOGValue());
+ LOG.debug("Delete Node {} was successful", nodeName);
}
}
@Override
public void onFailure(@Nonnull final Throwable t) {
- LOG.warn("Delete node {} failed with exception {}", deviceInfo.getLOGValue(), t);
+ LOG.warn("Delete node {} failed with exception {}", nodeName, t);
}
});
return delFuture;
}
-
private void addCallbackToDeviceInitializeToSlave(final DeviceInfo deviceInfo, final DeviceContext deviceContext, final LifecycleService lifecycleService) {
Futures.addCallback(deviceContext.makeDeviceSlave(), new FutureCallback<RpcResult<SetRoleOutput>>() {
@Override
if (LOG.isDebugEnabled()) {
LOG.debug("Role SLAVE was successfully propagated on device, node {}", deviceInfo.getLOGValue());
}
+ deviceContext.sendNodeAddedNotification();
}
@Override
}
public void onDeviceRemoved(DeviceInfo deviceInfo) {
- deviceContexts.remove(deviceInfo);
+ DeviceContext deviceContext = deviceContexts.remove(deviceInfo);
+ removeddeviceContexts.putIfAbsent(deviceInfo, deviceContext);
LOG.debug("Device context removed for node {}", deviceInfo.getLOGValue());
lifecycleServices.remove(deviceInfo);
LOG.debug("Lifecycle service removed for node {}", deviceInfo.getLOGValue());
}
+
+ @Override
+ public void ownershipChanged(EntityOwnershipChange entityOwnershipChange) {
+ if (!entityOwnershipChange.hasOwner()) {
+ final YangInstanceIdentifier yii = entityOwnershipChange.getEntity().getId();
+ final YangInstanceIdentifier.NodeIdentifierWithPredicates niiwp =
+ (YangInstanceIdentifier.NodeIdentifierWithPredicates) yii.getLastPathArgument();
+ String entityName = niiwp.getKeyValues().values().iterator().next().toString();
+ LOG.info("Entity ownership changed for device : {} : {}", entityName, entityOwnershipChange);
+
+ if (entityName != null ){
+ if (!removeddeviceContexts.isEmpty()) {
+ for (DeviceInfo device : removeddeviceContexts.keySet()) {
+ if (device.getNodeId().getValue().equals(entityName)) {
+ LOG.info("Cleaning up operational data of the node : {}", entityName);
+ // No owner present for the entity, clean up the data and remove it from
+ // removed context.
+ removeddeviceContexts.remove(device).cleanupDeviceData();
+ return;
+ }
+ }
+ }
+ removeDeviceFromOperationalDS(DeviceStateUtil.createNodeInstanceIdentifier(new NodeId(entityName)),
+ entityName);
+ }
+ }
+ }
}
import java.util.List;
import java.util.Objects;
import javax.annotation.Nullable;
+
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
import org.slf4j.LoggerFactory;
public class LifecycleServiceImpl implements LifecycleService {
-
private static final Logger LOG = LoggerFactory.getLogger(LifecycleServiceImpl.class);
+
+ private final List<DeviceRemovedHandler> deviceRemovedHandlers = new ArrayList<>();
+ private volatile CONTEXT_STATE state = CONTEXT_STATE.INITIALIZATION;
private DeviceContext deviceContext;
private RpcContext rpcContext;
private StatisticsContext statContext;
private ClusterSingletonServiceRegistration registration;
private ClusterInitializationPhaseHandler clusterInitializationPhaseHandler;
- private final List<DeviceRemovedHandler> deviceRemovedHandlers = new ArrayList<>();
- private volatile CONTEXT_STATE state = CONTEXT_STATE.INITIALIZATION;
@Override
@Override
public ListenableFuture<Void> closeServiceInstance() {
- final boolean connectionInterrupted =
- this.deviceContext
- .getPrimaryConnectionContext()
- .getConnectionState()
- .equals(ConnectionContext.CONNECTION_STATE.RIP);
// Chain all jobs that will stop our services
final List<ListenableFuture<Void>> futureList = new ArrayList<>();
- futureList.add(statContext.stopClusterServices(connectionInterrupted));
- futureList.add(rpcContext.stopClusterServices(connectionInterrupted));
- futureList.add(deviceContext.stopClusterServices(connectionInterrupted));
+ futureList.add(statContext.stopClusterServices());
+ futureList.add(rpcContext.stopClusterServices());
+ futureList.add(deviceContext.stopClusterServices());
return Futures.transform(Futures.successfulAsList(futureList), new Function<List<Void>, Void>() {
@Nullable
// If we are still registered and we are not already closing, then close the registration
if (Objects.nonNull(registration)) {
try {
- LOG.debug("Closing clustering MASTER services for node {}", getDeviceInfo().getLOGValue());
+ LOG.debug("Closing clustering singleton services for node {}", getDeviceInfo().getLOGValue());
registration.close();
} catch (Exception e) {
- LOG.debug("Failed to close clustering MASTER services for node {} with exception: ",
+ LOG.debug("Failed to close clustering singleton services for node {} with exception: ",
getDeviceInfo().getLOGValue(), e);
}
}
@Override
public void registerService(final ClusterSingletonServiceProvider singletonServiceProvider) {
- LOG.debug("Registered clustering MASTER services for node {}", getDeviceInfo().getLOGValue());
+ LOG.debug("Registered clustering singleton services for node {}", getDeviceInfo().getLOGValue());
// lifecycle service -> device context -> statistics context -> rpc context -> role context -> lifecycle service
this.clusterInitializationPhaseHandler = deviceContext;
// Register cluster singleton service
try {
this.registration = Verify.verifyNotNull(singletonServiceProvider.registerClusterSingletonService(this));
- LOG.info("Registered clustering MASTER services for node {}", getDeviceInfo().getLOGValue());
+ LOG.info("Registered clustering singleton services for node {}", getDeviceInfo().getLOGValue());
} catch (Exception e) {
LOG.warn("Failed to register cluster singleton service for node {}, with exception: {}", getDeviceInfo(), e);
closeConnection();
private final DataBroker dataBroker;
private final KeyedInstanceIdentifier<Node, NodeKey> instanceIdentifier;
private final List<ListenableFuture<List<Optional<FlowCapableNode>>>> lastFillFutures = new ArrayList<>();
+ private final Consumer<Flow> flowConsumer;
- // Specifies what to do with flow read from datastore
- private final Consumer<Flow> flowConsumer = flow -> {
- // Create flow registry key from flow
- final FlowRegistryKey key = FlowRegistryKeyFactory.create(flow);
-
- // Now, we will update the registry, but we will also try to prevent duplicate entries
- if (!flowRegistry.containsKey(key)) {
- LOG.trace("Found flow with table ID : {} and flow ID : {}", flow.getTableId(), flow.getId().getValue());
- final FlowDescriptor descriptor = FlowDescriptorFactory.create(flow.getTableId(), flow.getId());
- store(key, descriptor);
- }
- };
-
- public DeviceFlowRegistryImpl(final DataBroker dataBroker, final KeyedInstanceIdentifier<Node, NodeKey> instanceIdentifier) {
+ public DeviceFlowRegistryImpl(final short version, final DataBroker dataBroker, final KeyedInstanceIdentifier<Node, NodeKey> instanceIdentifier) {
this.dataBroker = dataBroker;
this.instanceIdentifier = instanceIdentifier;
+
+ // Specifies what to do with flow read from datastore
+ flowConsumer = flow -> {
+ // Create flow registry key from flow
+ final FlowRegistryKey key = FlowRegistryKeyFactory.create(version, flow);
+
+ // Now, we will update the registry, but we will also try to prevent duplicate entries
+ if (!flowRegistry.containsKey(key)) {
+ LOG.trace("Found flow with table ID : {} and flow ID : {}", flow.getTableId(), flow.getId().getValue());
+ final FlowDescriptor descriptor = FlowDescriptorFactory.create(flow.getTableId(), flow.getId());
+ store(key, descriptor);
+ }
+ };
}
@Override
LOG.trace("Failed to retrieve flow descriptor for flow hash : {}, trying with custom equals method", flowRegistryKey.hashCode());
}
for(Map.Entry<FlowRegistryKey, FlowDescriptor> fd : flowRegistry.entrySet()) {
- if (fd.getKey().equals(flowRegistryKey)) {
+ if (flowRegistryKey.equals(fd.getKey())) {
flowDescriptor = fd.getValue();
break;
}
final String alienId = ALIEN_SYSTEM_FLOW_ID + tableId + '-' + UNACCOUNTED_FLOWS_COUNTER.incrementAndGet();
return new FlowId(alienId);
}
-}
\ No newline at end of file
+}
// Hide implicit constructor
}
- public static FlowRegistryKey create(final Flow flow) {
- return new FlowRegistryKeyDto(flow);
+ public static FlowRegistryKey create(final short version, final Flow flow) {
+ return new FlowRegistryKeyDto(version, flow);
}
private static final class FlowRegistryKeyDto implements FlowRegistryKey {
private final int priority;
private final BigInteger cookie;
private final Match match;
+ private final short version;
- private FlowRegistryKeyDto(final Flow flow) {
+ private FlowRegistryKeyDto(final short version, final Flow flow) {
//TODO: mandatory flow input values (or default values) should be specified via yang model
tableId = Preconditions.checkNotNull(flow.getTableId(), "flow tableId must not be null");
priority = MoreObjects.firstNonNull(flow.getPriority(), OFConstants.DEFAULT_FLOW_PRIORITY);
match = MoreObjects.firstNonNull(flow.getMatch(), OFConstants.EMPTY_MATCH);
cookie = MoreObjects.firstNonNull(flow.getCookie(), OFConstants.DEFAULT_FLOW_COOKIE).getValue();
+ this.version = version;
}
@Override
return getPriority() == that.getPriority() &&
getTableId() == that.getTableId() &&
getCookie().equals(that.getCookie()) &&
- MatchComparatorFactory.createMatch().areObjectsEqual(getMatch(), that.getMatch());
+ MatchComparatorFactory.createMatch().areObjectsEqual(version, getMatch(), that.getMatch());
}
@Override
}
} else {
try {
- stopClusterServices(true).get();
+ stopClusterServices().get();
} catch (Exception e) {
LOG.debug("Failed to close RpcContext for node {} with exception: ", getDeviceInfo().getLOGValue(), e);
}
}
@Override
- public ListenableFuture<Void> stopClusterServices(boolean connectionInterrupted) {
+ public ListenableFuture<Void> stopClusterServices() {
if (CONTEXT_STATE.TERMINATION.equals(getState())) {
return Futures.immediateCancelledFuture();
}
*/
package org.opendaylight.openflowplugin.impl.services;
-import com.google.common.base.Function;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.Collections;
-import java.util.List;
+import com.google.common.base.Optional;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
import org.opendaylight.openflowplugin.impl.statistics.StatisticsGatheringUtils;
import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
final class MultipartRequestOnTheFlyCallback extends AbstractRequestCallback<List<MultipartReply>> {
private static final Logger LOG = LoggerFactory.getLogger(MultipartRequestOnTheFlyCallback.class);
private final SinglePurposeMultipartReplyTranslator multipartReplyTranslator;
private final DeviceInfo deviceInfo;
private final DeviceFlowRegistry registry;
- private boolean virgin = true;
- private boolean finished = false;
private final EventIdentifier doneEventIdentifier;
private final TxFacade txFacade;
+ private Optional<FlowCapableNode> fcNodeOpt;
+ private AtomicBoolean virgin = new AtomicBoolean(true);
+ private AtomicBoolean finished = new AtomicBoolean(false);
public MultipartRequestOnTheFlyCallback(final RequestContext<List<MultipartReply>> context,
final Class<?> requestType,
@Override
public void onSuccess(final OfHeader result) {
+
if (result == null) {
LOG.info("Ofheader was null.");
- if (!finished) {
+ if (!finished.getAndSet(true)) {
endCollecting();
return;
}
- } else if (finished) {
+ } else if (finished.get()) {
LOG.debug("Unexpected multipart response received: xid={}, {}", result.getXid(), result.getImplementedInterface());
return;
}
if (!(result instanceof MultipartReply)) {
- LOG.info("Unexpected response type received {}.", result.getClass());
- final RpcResultBuilder<List<MultipartReply>> rpcResultBuilder =
- RpcResultBuilder.<List<MultipartReply>>failed().withError(RpcError.ErrorType.APPLICATION,
- String.format("Unexpected response type received %s.", result.getClass()));
- setResult(rpcResultBuilder.build());
- endCollecting();
+ if(!finished.getAndSet(true)) {
+ LOG.info("Unexpected response type received {}.", result.getClass());
+ final RpcResultBuilder<List<MultipartReply>> rpcResultBuilder =
+ RpcResultBuilder.<List<MultipartReply>>failed().withError(RpcError.ErrorType.APPLICATION,
+ String.format("Unexpected response type received %s.", result.getClass()));
+ setResult(rpcResultBuilder.build());
+ endCollecting();
+ }
} else {
final MultipartReply multipartReply = (MultipartReply) result;
+ if (virgin.get()) {
+ synchronized (this) {
+ if (virgin.get()) {
+ fcNodeOpt = StatisticsGatheringUtils.deleteAllKnownFlows(deviceInfo, txFacade);
+ virgin.set(false);
+ }
+ }
+ }
final MultipartReply singleReply = multipartReply;
final List<? extends DataObject> multipartDataList = multipartReplyTranslator.translate(
deviceInfo.getDatapathId(), deviceInfo.getVersion(), singleReply);
- final Iterable<? extends DataObject> allMultipartData = multipartDataList;
+ final Iterable<FlowsStatisticsUpdate> allMultipartData = (Iterable<FlowsStatisticsUpdate>) multipartDataList;
- //TODO: following part is focused on flow stats only - need more general approach if used for more than flow stats
- ListenableFuture<Void> future;
- if (virgin) {
- future = StatisticsGatheringUtils.deleteAllKnownFlows(deviceInfo, registry, txFacade);
- virgin = false;
- } else {
- future = Futures.immediateFuture(null);
+ StatisticsGatheringUtils.writeFlowStatistics(allMultipartData, deviceInfo, registry, txFacade);
+ if (!multipartReply.getFlags().isOFPMPFREQMORE()) {
+ endCollecting();
}
-
- Futures.transform(future, new Function<Void, Void>() {
-
- @Override
- public Void apply(final Void input) {
- StatisticsGatheringUtils.writeFlowStatistics((Iterable<FlowsStatisticsUpdate>) allMultipartData,
- deviceInfo, registry, txFacade);
-
- if (!multipartReply.getFlags().isOFPMPFREQMORE()) {
- endCollecting();
- }
- return input;
- }
- });
}
}
private void endCollecting() {
+ finished.set(true);
EventsTimeCounter.markEnd(getDoneEventIdentifier());
EventsTimeCounter.markEnd(getEventIdentifier());
final RpcResult<List<MultipartReply>> rpcResult = RpcResultBuilder.success(Collections.<MultipartReply>emptyList()).build();
spyMessage(MessageSpy.STATISTIC_GROUP.FROM_SWITCH_TRANSLATE_OUT_SUCCESS);
- txFacade.submitTransaction();
setResult(rpcResult);
- finished = true;
+ txFacade.submitTransaction();
}
}
@Override
public Future<RpcResult<AddFlowOutput>> addFlow(final AddFlowInput input) {
- final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(input);
+ final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceContext.getDeviceInfo().getVersion(), input);
final ListenableFuture<RpcResult<AddFlowOutput>> future =
flowAdd.processFlowModInputBuilders(flowAdd.toFlowModInputs(input));
Futures.addCallback(future, new AddFlowCallback(input, flowRegistryKey));
if (LOG.isDebugEnabled()) {
LOG.debug("Flow remove finished without error for flow={}", input);
}
- FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(input);
+ FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceContext.getDeviceInfo().getVersion(), input);
deviceContext.getDeviceFlowRegistry().removeDescriptor(flowRegistryKey);
if (itemLifecycleListener != null) {
final UpdatedFlow updated = input.getUpdatedFlow();
final OriginalFlow original = input.getOriginalFlow();
- final FlowRegistryKey origFlowRegistryKey = FlowRegistryKeyFactory.create(original);
- final FlowRegistryKey updatedFlowRegistryKey = FlowRegistryKeyFactory.create(updated);
+ final FlowRegistryKey origFlowRegistryKey = FlowRegistryKeyFactory.create(deviceContext.getDeviceInfo().getVersion(), original);
+ final FlowRegistryKey updatedFlowRegistryKey = FlowRegistryKeyFactory.create(deviceContext.getDeviceInfo().getVersion(), updated);
final FlowDescriptor origFlowDescriptor = deviceFlowRegistry.retrieveIdForFlow(origFlowRegistryKey);
final boolean isUpdate = Objects.nonNull(origFlowDescriptor);
LOG.warn("Service call for updating flow={} failed, reason: {}", input, throwable);
}
}
-}
\ No newline at end of file
+}
import javax.annotation.concurrent.GuardedBy;
import org.opendaylight.mdsal.common.api.TransactionChainClosedException;
import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
+import org.opendaylight.openflowplugin.api.ConnectionException;
import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
}
} else {
try {
- stopClusterServices(true).get();
+ stopClusterServices().get();
} catch (Exception e) {
LOG.debug("Failed to close StatisticsContext for node {} with exception: ", getDeviceInfo().getLOGValue(), e);
}
final String errMsg = String.format("Device connection is closed for Node : %s.",
getDeviceInfo().getNodeId());
LOG.debug(errMsg);
- resultFuture.setException(new IllegalStateException(errMsg));
+ resultFuture.setException(new ConnectionException(errMsg));
return;
}
if ( ! iterator.hasNext()) {
}
@Override
- public ListenableFuture<Void> stopClusterServices(boolean connectionInterrupted) {
+ public ListenableFuture<Void> stopClusterServices() {
if (CONTEXT_STATE.TERMINATION.equals(getState())) {
return Futures.immediateCancelledFuture();
}
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.JdkFutureAdapters;
import com.google.common.util.concurrent.ListenableFuture;
-import java.text.SimpleDateFormat;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import javax.annotation.Nullable;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.annotation.Nullable;
+import java.text.SimpleDateFormat;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+
/**
* Utils for gathering statistics.
*/
final boolean initial,
final EventIdentifier eventIdentifier) {
final ListenableFuture<Void> deleteFuture
- = initial ? Futures.immediateFuture(null) : deleteAllKnownFlows(deviceInfo,
- flowRegistry, txFacade);
+ = initial ? Futures.immediateFuture(null) : deleteAllKnownFlows(deviceInfo, flowRegistry, txFacade);
return Futures.transform(deleteFuture, (Function<Void, Boolean>) input -> {
writeFlowStatistics(data, deviceInfo, flowRegistry, txFacade);
txFacade.submitTransaction();
for (final FlowsStatisticsUpdate flowsStatistics : data) {
for (final FlowAndStatisticsMapList flowStat : flowsStatistics.getFlowAndStatisticsMapList()) {
final FlowBuilder flowBuilder = new FlowBuilder(flowStat);
- flowBuilder.addAugmentation(
- FlowStatisticsData.class,
+ flowBuilder.addAugmentation(FlowStatisticsData.class,
refineFlowStatisticsAugmentation(flowStat).build());
final short tableId = flowStat.getTableId();
- final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(flowBuilder.build());
+ final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowBuilder.build());
final FlowId flowId = registry.storeIfNecessary(flowRegistryKey);
final FlowKey flowKey = new FlowKey(flowId);
}
}
} catch (TransactionChainClosedException e) {
- LOG.warn("Not able to write to transaction: {}", e.getMessage());
+ LOG.warn("Not able to write to transaction chain: {}", e.getMessage());
}
}
*/
return Futures.transform(
flowCapableNodeFuture, (AsyncFunction<Optional<FlowCapableNode>, Void>) flowCapNodeOpt -> {
- if (flowCapNodeOpt.isPresent()) {
- for (final Table tableData : flowCapNodeOpt.get().getTable()) {
- final Table table = new TableBuilder(tableData).setFlow(Collections.<Flow>emptyList()).build();
- final InstanceIdentifier<Table> iiToTable
- = flowCapableNodePath.child(Table.class, tableData.getKey());
- txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, iiToTable, table);
+ if (flowCapNodeOpt.isPresent()) {
+ for (final Table tableData : flowCapNodeOpt.get().getTable()) {
+ final Table table = new TableBuilder(tableData).setFlow(Collections.<Flow>emptyList()).build();
+ final InstanceIdentifier<Table> iiToTable
+ = flowCapableNodePath.child(Table.class, tableData.getKey());
+ txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, iiToTable, table);
+ }
}
+ readTx.close();
+ return Futures.immediateFuture(null);
+ });
+ }
+
+ public static Optional<FlowCapableNode> deleteAllKnownFlows(final DeviceInfo deviceInfo,
+ final TxFacade txFacade) {
+ final InstanceIdentifier<FlowCapableNode> flowCapableNodePath
+ = assembleFlowCapableNodeInstanceIdentifier(deviceInfo);
+ final ReadOnlyTransaction readTx = txFacade.getReadTransaction();
+ final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowCapableNodeFuture = readTx.read(
+ LogicalDatastoreType.OPERATIONAL, flowCapableNodePath);
+
+ try {
+ Optional<FlowCapableNode> fcNodeOpt = flowCapableNodeFuture.get();
+ if ( fcNodeOpt != null && fcNodeOpt.isPresent()){
+ for (final Table tableData : flowCapableNodeFuture.get().get().getTable()) {
+ final Table table = new TableBuilder(tableData).setFlow(Collections.<Flow>emptyList()).build();
+ final InstanceIdentifier<Table> iiToTable = flowCapableNodePath.child(Table.class, tableData.getKey());
+ txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, iiToTable, table);
}
+ return fcNodeOpt;
+ }
+ } catch (InterruptedException|ExecutionException e) {
+ LOG.error("Failed to read current OpenFlow node {] operational data", deviceInfo.getNodeId());
+ } finally {
+ if (readTx != null){
readTx.close();
- return Futures.immediateFuture(null);
- });
+ }
+ }
+ return Optional.absent();
}
private static void processQueueStatistics(
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
+import java.util.concurrent.CancellationException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Future;
import javax.annotation.Nonnull;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.openflowplugin.api.ConnectionException;
import org.opendaylight.openflowplugin.api.openflow.OFPContext;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
LOG.trace("Gathering for node {} failure: ", deviceInfo.getLOGValue(), throwable);
}
calculateTimerDelay(timeCounter);
- if (throwable instanceof IllegalStateException) {
+ if (throwable instanceof ConnectionException) {
+ // ConnectionException is raised by StatisticsContextImpl class when the connections
+ // move to RIP state. In this particular case, there is no need to reschedule
+ // because this statistics manager should be closed soon
+ LOG.warn("Node {} is no more connected, stopping the statistics collection",
+ deviceInfo.getLOGValue(),throwable);
stopScheduling(deviceInfo);
} else {
+ if (!(throwable instanceof CancellationException)) {
+ LOG.warn("Unexpected error occurred during statistics collection for node {}, rescheduling " +
+ "statistics collections", deviceInfo.getLOGValue(),throwable);
+ }
scheduleNextPolling(deviceState, deviceInfo, statisticsContext, timeCounter);
}
}
final FlowBuilder flowBuilder = new FlowBuilder(flowStatistics)
.addAugmentation(FlowStatisticsData.class, flowStatisticsDataBld.build());
- final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(flowBuilder.build());
+ final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(getVersion(), flowBuilder.build());
return getDeviceRegistry().getDeviceFlowRegistry().storeIfNecessary(flowRegistryKey);
}
}
*/
package org.opendaylight.openflowplugin.impl.translator;
+import java.util.Objects;
import java.util.Optional;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemovedBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.RemovedFlowReason;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemoved;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* translate {@link FlowRemoved} message to FlowRemoved notification (omit instructions)
*/
public class FlowRemovedTranslator implements MessageTranslator<FlowRemoved, org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved> {
private final ConvertorExecutor convertorExecutor;
-
+ private static final Logger logger = LoggerFactory.getLogger(FlowRemovedTranslator.class);
public FlowRemovedTranslator(ConvertorExecutor convertorExecutor) {
this.convertorExecutor = convertorExecutor;
}
.setPriority(input.getPriority())
.setTableId(translateTableId(input));
+ if(Objects.nonNull(input.getReason())) {
+ flowRemovedBld.setReason(translateReason(input));
+ }
+
return flowRemovedBld.build();
}
protected Short translateTableId(FlowRemoved flowRemoved) {
return flowRemoved.getTableId().getValue().shortValue();
}
+
+
+ private RemovedFlowReason translateReason(FlowRemoved removedFlow) {
+ logger.debug("--Entering translateReason within FlowRemovedTranslator with reason:{} " + removedFlow.getReason());
+ switch (removedFlow.getReason()) {
+ case OFPRRIDLETIMEOUT:
+ return RemovedFlowReason.OFPRRIDLETIMEOUT;
+ case OFPRRHARDTIMEOUT:
+ return RemovedFlowReason.OFPRRHARDTIMEOUT;
+ case OFPRRDELETE:
+ return RemovedFlowReason.OFPRRDELETE;
+ case OFPRRGROUPDELETE:
+ return RemovedFlowReason.OFPRRGROUPDELETE;
+ default:
+ logger.debug("The flow is being deleted for some unknown reason ");
+ return RemovedFlowReason.OFPRRDELETE;
+ }
+ }
}
package org.opendaylight.openflowplugin.impl.util;
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
-
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import java.util.ArrayList;
import java.util.Collection;
* Comparation by whole object
*/
@Override
- public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+ public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
return (statsMatch == null) == (storedMatch == null);
}
};
* Comparation by VLAN
*/
@Override
- public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+ public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
if (storedMatch == null) {
return false;
}
* Comparation by tunnel
*/
@Override
- public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+ public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
if (storedMatch == null) {
return false;
}
* Comparation by protocol fields
*/
@Override
- public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+ public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
if (storedMatch == null) {
return false;
}
* Comparation by metadata
*/
@Override
- public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+ public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
if (storedMatch == null) {
return false;
}
* Comparation by layer4
*/
@Override
- public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+ public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
if (storedMatch == null) {
return false;
}
* Comparation by layer3
*/
@Override
- public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+ public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
if (storedMatch == null) {
return false;
}
* Comparation by Ip
*/
@Override
- public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+ public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
if (storedMatch == null) {
return false;
}
};
}
+
+ /**
+ * Converts both ports in node connector id format to number format and compare them
+ *
+ * @param version openflow version
+ * @param left first object to compare
+ * @param right second object to compare
+ * @return true if equal
+ */
+ private static boolean arePortNumbersEqual(short version, NodeConnectorId left, NodeConnectorId right) {
+ final OpenflowVersion ofVersion = OpenflowVersion.get(version);
+
+ final Long leftPort = InventoryDataServiceUtil.portNumberfromNodeConnectorId(ofVersion, left);
+ final Long rightPort = InventoryDataServiceUtil.portNumberfromNodeConnectorId(ofVersion, right);
+
+ if (leftPort == null) {
+ if (rightPort != null) {
+ return false;
+ }
+ } else if (!leftPort.equals(rightPort)) {
+ return false;
+ }
+
+ return true;
+ }
+
public static SimpleComparator<Match> createInPort() {
return new SimpleComparator<Match>() {
/**
* Comparation by InPort
*/
@Override
- public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+ public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
if (storedMatch == null) {
return false;
}
if (statsMatch.getInPort() != null) {
return false;
}
- } else if (!storedMatch.getInPort().equals(statsMatch.getInPort())) {
+ } else if (!arePortNumbersEqual(version, storedMatch.getInPort(), statsMatch.getInPort())) {
return false;
}
return true;
* Comparation by InPhyPort
*/
@Override
- public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+ public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
if (storedMatch == null) {
return false;
}
if (statsMatch.getInPhyPort() != null) {
return false;
}
- } else if (!storedMatch.getInPhyPort().equals(statsMatch.getInPhyPort())) {
+ } else if (!arePortNumbersEqual(version, storedMatch.getInPhyPort(), statsMatch.getInPhyPort())) {
return false;
}
return true;
* Comparation by Ethernet
*/
@Override
- public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+ public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
if (storedMatch == null) {
return false;
}
* Comparation by Icmpv4
*/
@Override
- public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
+ public boolean areObjectsEqual(short version, Match statsMatch, Match storedMatch) {
if (storedMatch == null) {
return false;
}
* Compares flows by whole match
*/
@Override
- public boolean areObjectsEqual(final Match statsFlow, final Match storedFlow) {
+ public boolean areObjectsEqual(short version, final Match statsFlow, final Match storedFlow) {
if (statsFlow == null) {
if (storedFlow != null) {
return false;
}
- } else if (!compareMatches(statsFlow, storedFlow)) {
+ } else if (!compareMatches(version, statsFlow, storedFlow)) {
return false;
}
return true;
* @param storedMatch
* @return
*/
- private static boolean compareMatches(final Match statsMatch, final Match storedMatch) {
+ private static boolean compareMatches(final short version, final Match statsMatch, final Match storedMatch) {
if (statsMatch == storedMatch) {
return true;
}
for (SimpleComparator<Match> matchComp : MATCH_COMPARATORS) {
- if (!matchComp.areObjectsEqual(statsMatch, storedMatch)) {
+ if (!matchComp.areObjectsEqual(version, statsMatch, storedMatch)) {
return false;
}
}
/**
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2015, 2017 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
private static final int IPV4_ADDRESS_LENGTH = 32;
private static final int IPV6_ADDRESS_LENGTH = 128;
private static final int BYTE_SIZE = 8;
+ private static final String NO_ETH_MASK = "ff:ff:ff:ff:ff:ff";
/*
* Custom EthernetMatch is required because mac address string provided by user in EthernetMatch can be in any case
} else {
verdict = macAddressEquals(statsEthernetMatchFields.getAddress(), storedEthernetMatchFields.getAddress());
if (verdict) {
- verdict = macAddressEquals(statsEthernetMatchFields.getMask(), storedEthernetMatchFields.getMask());
+ verdict = macAddressMaskEquals(statsEthernetMatchFields.getMask(), storedEthernetMatchFields.getMask());
}
}
return verdict;
return verdict;
}
+ static boolean macAddressMaskEquals(final MacAddress statsMacAddressMask, final MacAddress storedMacAddressMask) {
+ boolean verdict = true;
+ //User sent the mask with all bit set, which actually means no mask. Switch might just ignore it.
+ if(statsMacAddressMask == null && storedMacAddressMask != null &&
+ storedMacAddressMask.getValue().equalsIgnoreCase(NO_ETH_MASK)) {
+ return verdict;
+ }
+ final Boolean checkNullValues = checkNullValues(statsMacAddressMask, storedMacAddressMask);
+ if (checkNullValues != null) {
+ verdict = checkNullValues;
+ } else {
+ verdict = statsMacAddressMask.getValue().equalsIgnoreCase(storedMacAddressMask.getValue());
+ }
+ return verdict;
+ }
+
@VisibleForTesting
static boolean layer3MatchEquals(final Layer3Match statsLayer3Match, final Layer3Match storedLayer3Match) {
boolean verdict = true;
public interface SimpleComparator<T> {
- boolean areObjectsEqual(T obj1, T obj2);
+ boolean areObjectsEqual(short version, T obj1, T obj2);
-}
\ No newline at end of file
+}
<service ref="ofPluginProviderFactory" interface="org.opendaylight.openflowplugin.api.openflow.OpenFlowPluginProviderFactory"
odl:type="default"/>
-</blueprint>
\ No newline at end of file
+
+ <odl:action-provider interface="org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService"/>
+</blueprint>
provider.setNotificationProviderService(notificationService);
provider.setSwitchConnectionProviders(Lists.newArrayList(switchConnectionProvider));
provider.setClusteringSingletonServicesProvider(clusterSingletonServiceProvider);
+ provider.setEntityOwnershipServiceProvider(entityOwnershipService);
}
@After
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregateCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestDescCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestExperimenterCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupDescCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeaturesCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeaturesCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortDescCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group._case.MultipartRequestGroup;
final MultipartRequestInput mpRqInput =
MultipartRequestInputFactory.makeMultipartRequestInput(xid, ofVersion, mpType);
checkHeader(mpRqInput, mpType, ofVersion);
- checkEmptyBody(mpRqInput.getMultipartRequestBody(), MultipartRequestDescCase.class);
}
@Test
final MultipartRequestInput mpRqInput =
MultipartRequestInputFactory.makeMultipartRequestInput(xid, ofVersion, mpType);
checkHeader(mpRqInput, mpType, ofVersion);
- checkEmptyBody(mpRqInput.getMultipartRequestBody(), MultipartRequestAggregateCase.class);
}
@Test
final MultipartRequestInput mpRqInput =
MultipartRequestInputFactory.makeMultipartRequestInput(xid, ofVersion, mpType);
checkHeader(mpRqInput, mpType, ofVersion);
- checkEmptyBody(mpRqInput.getMultipartRequestBody(), MultipartRequestTableCase.class);
}
@Test
final MultipartRequestInput mpRqInput =
MultipartRequestInputFactory.makeMultipartRequestInput(xid, ofVersion, mpType);
checkHeader(mpRqInput, mpType, ofVersion);
- checkEmptyBody(mpRqInput.getMultipartRequestBody(), MultipartRequestGroupDescCase.class);
}
@Test
final MultipartRequestInput mpRqInput =
MultipartRequestInputFactory.makeMultipartRequestInput(xid, ofVersion, mpType);
checkHeader(mpRqInput, mpType, ofVersion);
- checkEmptyBody(mpRqInput.getMultipartRequestBody(), MultipartRequestGroupFeaturesCase.class);
}
@Test
Assert.assertTrue(mpRqBody instanceof MultipartRequestMeterConfigCase);
MultipartRequestMeterConfig mpRq = ((MultipartRequestMeterConfigCase) mpRqBody).getMultipartRequestMeterConfig();
- Assert.assertEquals(OFConstants.OFPM_ALL, mpRq.getMeterId().getValue());
}
@Test
final MultipartRequestInput mpRqInput =
MultipartRequestInputFactory.makeMultipartRequestInput(xid, ofVersion, mpType);
checkHeader(mpRqInput, mpType, ofVersion);
- checkEmptyBody(mpRqInput.getMultipartRequestBody(), MultipartRequestMeterFeaturesCase.class);
}
@Test
final MultipartRequestInput mpRqInput =
MultipartRequestInputFactory.makeMultipartRequestInput(xid, ofVersion, mpType);
checkHeader(mpRqInput, mpType, ofVersion);
- checkEmptyBody(mpRqInput.getMultipartRequestBody(), MultipartRequestPortDescCase.class);
}
@Test
final MultipartRequestInput mpRqInput =
MultipartRequestInputFactory.makeMultipartRequestInput(xid, ofVersion, mpType);
checkHeader(mpRqInput, mpType, ofVersion);
- checkEmptyBody(mpRqInput.getMultipartRequestBody(), MultipartRequestExperimenterCase.class);
}
private void checkHeader(MultipartRequestInput mpRqInput, MultipartType mpType, short ofVersion) {
Assert.assertEquals(xid, mpRqInput.getXid().longValue());
}
- private void checkEmptyBody(MultipartRequestBody mpRqBody, Class<? extends MultipartRequestBody> expectedMpRqBodyClass) throws Exception {
- Assert.assertTrue(expectedMpRqBodyClass.isAssignableFrom(mpRqBody.getImplementedInterface()));
- final String expectedDump = expectedMpRqBodyClass.getSimpleName() + " [augmentation=[]]";
- Assert.assertEquals(expectedDump, String.valueOf(mpRqBody));
- }
}
\ No newline at end of file
.thenReturn(flowRemovedMdsalBld.build());
// insert flow+flowId into local registry
- final FlowRegistryKey flowRegKey = FlowRegistryKeyFactory.create(flowRemovedMdsalBld.build());
+ final FlowRegistryKey flowRegKey = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowRemovedMdsalBld.build());
final FlowDescriptor flowDescriptor = FlowDescriptorFactory.create((short) 0, new FlowId("ut-ofp:f456"));
deviceContext.getDeviceFlowRegistry().store(flowRegKey, flowDescriptor);
import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
@Mock
private ClusterSingletonServiceProvider clusterSingletonServiceProvider;
@Mock
+ private EntityOwnershipService entityOwnershipService;
+ @Mock
+ private EntityOwnershipListenerRegistration entityOwnershipListenerRegistration;
+ @Mock
private ConvertorExecutor convertorExecutor;
@Mock
private KeyedInstanceIdentifier<Node, NodeKey> key;
when(mockedDataBroker.newWriteOnlyTransaction()).thenReturn(mockedWriteTransaction);
when(mockedWriteTransaction.submit()).thenReturn(mockedFuture);
+ when(entityOwnershipService.registerListener(any(), any())).thenReturn(entityOwnershipListenerRegistration);
final DeviceManagerImpl deviceManager = new DeviceManagerImpl(
mockedDataBroker,
messageIntelligenceAgency,
true,
clusterSingletonServiceProvider,
- null,
- new HashedWheelTimer(),
- convertorExecutor,
- false);
+ entityOwnershipService, new HashedWheelTimer(), convertorExecutor, false, null
+ );
deviceManager.setDeviceInitializationPhaseHandler(deviceInitPhaseHandler);
deviceManager.setDeviceTerminationPhaseHandler(deviceTerminationPhaseHandler);
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
private ClusterSingletonServiceProvider clusterSingletonServiceProvider;
@Mock
private ClusterSingletonServiceRegistration clusterSingletonServiceRegistration;
+ @Mock
+ EntityOwnershipListenerRegistration entityOwnershipListenerRegistration;
private LifecycleService lifecycleService;
Mockito.when(clusterSingletonServiceProvider.registerClusterSingletonService(Mockito.any()))
.thenReturn(clusterSingletonServiceRegistration);
- Mockito.when(deviceContext.stopClusterServices(Mockito.anyBoolean())).thenReturn(Futures.immediateFuture(null));
- Mockito.when(statContext.stopClusterServices(Mockito.anyBoolean())).thenReturn(Futures.immediateFuture(null));
- Mockito.when(rpcContext.stopClusterServices(Mockito.anyBoolean())).thenReturn(Futures.immediateFuture(null));
+ Mockito.when(deviceContext.stopClusterServices()).thenReturn(Futures.immediateFuture(null));
+ Mockito.when(statContext.stopClusterServices()).thenReturn(Futures.immediateFuture(null));
+ Mockito.when(rpcContext.stopClusterServices()).thenReturn(Futures.immediateFuture(null));
lifecycleService = new LifecycleServiceImpl();
lifecycleService.setDeviceContext(deviceContext);
@Test
public void closeServiceInstance() throws Exception {
lifecycleService.closeServiceInstance().get();
- Mockito.verify(statContext).stopClusterServices(false);
- Mockito.verify(deviceContext).stopClusterServices(false);
- Mockito.verify(rpcContext).stopClusterServices(false);
+ Mockito.verify(statContext).stopClusterServices();
+ Mockito.verify(deviceContext).stopClusterServices();
+ Mockito.verify(rpcContext).stopClusterServices();
}
@Test
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
public void setUp() throws Exception {
nodeInstanceIdentifier = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(new NodeId(NODE_ID)));
when(dataBroker.newReadOnlyTransaction()).thenReturn(readOnlyTransaction);
- deviceFlowRegistry = new DeviceFlowRegistryImpl(dataBroker, nodeInstanceIdentifier);
+ deviceFlowRegistry = new DeviceFlowRegistryImpl(OFConstants.OFP_VERSION_1_3, dataBroker, nodeInstanceIdentifier);
final FlowAndStatisticsMapList flowStats = TestFlowHelper.createFlowAndStatisticsMapListBuilder(1).build();
- key = FlowRegistryKeyFactory.create(flowStats);
+ key = FlowRegistryKeyFactory.create(OFConstants.OFP_VERSION_1_3, flowStats);
descriptor = FlowDescriptorFactory.create(key.getTableId(), new FlowId("ut:1"));
Assert.assertEquals(0, deviceFlowRegistry.getAllFlowDescriptors().size());
.build();
final Map<FlowRegistryKey, FlowDescriptor> allFlowDescriptors = testFill(path, flowCapableNode);
- final FlowRegistryKey key = FlowRegistryKeyFactory.create(flow);
+ final FlowRegistryKey key = FlowRegistryKeyFactory.create(OFConstants.OFP_VERSION_1_3, flow);
InOrder order = inOrder(dataBroker, readOnlyTransaction);
order.verify(dataBroker).newReadOnlyTransaction();
// store new key with old value
final FlowAndStatisticsMapList flowStats = TestFlowHelper.createFlowAndStatisticsMapListBuilder(2).build();
- final FlowRegistryKey key2 = FlowRegistryKeyFactory.create(flowStats);
+ final FlowRegistryKey key2 = FlowRegistryKeyFactory.create(OFConstants.OFP_VERSION_1_3, flowStats);
deviceFlowRegistry.store(key2, descriptor);
Assert.assertEquals(2, deviceFlowRegistry.getAllFlowDescriptors().size());
Assert.assertEquals("ut:1", deviceFlowRegistry.retrieveIdForFlow(key2).getFlowId().getValue());
//store new key
final String alienPrefix = "#UF$TABLE*2-";
- final FlowRegistryKey key2 = FlowRegistryKeyFactory.create(TestFlowHelper.createFlowAndStatisticsMapListBuilder(2).build());
+ final FlowRegistryKey key2 = FlowRegistryKeyFactory.create(OFConstants.OFP_VERSION_1_3, TestFlowHelper.createFlowAndStatisticsMapListBuilder(2).build());
newFlowId = deviceFlowRegistry.storeIfNecessary(key2);
Assert.assertTrue(newFlowId.getValue().startsWith(alienPrefix));
return null;
}
-}
\ No newline at end of file
+}
HashSet<FlowRegistryKey> flowRegistryKeys = new HashSet<>();
for (FlowAndStatisticsMapList item : flowStats.getFlowAndStatisticsMapList()) {
- final FlowRegistryKey key1 = FlowRegistryKeyFactory.create(item);
- final FlowRegistryKey key2 = FlowRegistryKeyFactory.create(item);
+ final FlowRegistryKey key1 = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), item);
+ final FlowRegistryKey key2 = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), item);
flowRegistryKeys.add(key1);
flowRegistryKeys.add(key1);
flowRegistryKeys.add(key2);
@Test
public void testEqualsNegative() throws Exception {
final FlowAndStatisticsMapList flowStatisticsMapList1 = TestFlowHelper.createFlowAndStatisticsMapListBuilder(1).build();
- final FlowRegistryKey key1 = FlowRegistryKeyFactory.create(flowStatisticsMapList1);
+ final FlowRegistryKey key1 = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowStatisticsMapList1);
FlowRegistryKey key2;
FlowAndStatisticsMapListBuilder flowStatisticsMapListBld2;
// different priority
flowStatisticsMapListBld2 = new FlowAndStatisticsMapListBuilder(flowStatisticsMapList1);
flowStatisticsMapListBld2.setPriority(flowStatisticsMapListBld2.getPriority() + 1);
- key2 = FlowRegistryKeyFactory.create(flowStatisticsMapListBld2.build());
+ key2 = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowStatisticsMapListBld2.build());
Assert.assertFalse(key1.equals(key2));
// different match
flowStatisticsMapListBld2 = new FlowAndStatisticsMapListBuilder(flowStatisticsMapList1);
flowStatisticsMapListBld2.setMatch(new MatchBuilder().build());
- key2 = FlowRegistryKeyFactory.create(flowStatisticsMapListBld2.build());
+ key2 = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowStatisticsMapListBld2.build());
Assert.assertFalse(key1.equals(key2));
// different tableId
flowStatisticsMapListBld2 = new FlowAndStatisticsMapListBuilder(flowStatisticsMapList1);
flowStatisticsMapListBld2.setTableId((short) (flowStatisticsMapListBld2.getTableId() + 1));
- key2 = FlowRegistryKeyFactory.create(flowStatisticsMapListBld2.build());
+ key2 = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowStatisticsMapListBld2.build());
Assert.assertFalse(key1.equals(key2));
Assert.assertFalse(key1.equals(null));
.setPriority(2)
.setTableId((short) 0);
- FlowRegistryKey flow1Hash = FlowRegistryKeyFactory.create(flow1Builder.build());
+ FlowRegistryKey flow1Hash = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flow1Builder.build());
LOG.info("flowHash1: {}", flow1Hash.hashCode());
.setCookie(new FlowCookie(BigInteger.valueOf(148)))
.setMatch(match2Builder.build());
- FlowRegistryKey flow2Hash = FlowRegistryKeyFactory.create(flow2Builder.build());
+ FlowRegistryKey flow2Hash = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flow2Builder.build());
LOG.info("flowHash2: {}", flow2Hash.hashCode());
Assert.assertNotSame(flow1Hash, flow2Hash);
FlowBuilder fb1 = new FlowBuilder(flow1Builder.build());
fb1.setTableId(null);
try {
- FlowRegistryKeyFactory.create(fb1.build());
+ FlowRegistryKeyFactory.create(deviceInfo.getVersion(), fb1.build());
Assert.fail("hash creation should have failed because of NPE");
} catch (Exception e) {
// expected
FlowBuilder fb2 = new FlowBuilder(flow1Builder.build());
fb2.setPriority(null);
try {
- FlowRegistryKeyFactory.create(fb2.build());
+ FlowRegistryKeyFactory.create(deviceInfo.getVersion(), fb2.build());
} catch (Exception e) {
// not expected
Assert.fail("no exception was expected while hash was creating.");
FlowBuilder fb3 = new FlowBuilder(flow1Builder.build());
fb3.setCookie(null);
- FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(fb3.build());
+ FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), fb3.build());
Assert.assertNotNull(flowRegistryKey.getCookie());
Assert.assertEquals(OFConstants.DEFAULT_COOKIE, flowRegistryKey.getCookie());
}
FlowsStatisticsUpdate flowStats = FLOWS_STATISTICS_UPDATE_BUILDER.build();
for (FlowAndStatisticsMapList item : flowStats.getFlowAndStatisticsMapList()) {
- FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(item);
+ FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), item);
FlowRegistryKey lastHash = null;
if (null != lastHash) {
assertNotEquals(lastHash, flowRegistryKey);
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
private final short tableId = 0;
@Before
- public void initialization() {
+ public void initialization() throws Exception{
when(mockedDeviceContext.getMessageSpy()).thenReturn(new MessageIntelligenceAgencyImpl());
when(mockedNodeId.toString()).thenReturn(DUMMY_NODE_ID);
when(mockedPrimaryConnection.getNodeId()).thenReturn(mockedNodeId);
final FlowCapableNodeBuilder flowNodeBuilder = new FlowCapableNodeBuilder();
flowNodeBuilder.setTable(Collections.<Table> emptyList());
final Optional<FlowCapableNode> flowNodeOpt = Optional.of(flowNodeBuilder.build());
+
final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowNodeFuture = Futures.immediateCheckedFuture(flowNodeOpt);
- when(mockedReadOnlyTx.read(LogicalDatastoreType.OPERATIONAL, nodePath)).thenReturn(flowNodeFuture);
+ final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowNodeFutureSpy = spy(flowNodeFuture);
+ when(mockedReadOnlyTx.read(LogicalDatastoreType.OPERATIONAL, nodePath)).thenReturn(flowNodeFutureSpy);
+ when(flowNodeFutureSpy.get()).thenReturn(flowNodeOpt);
when(mockedDeviceContext.getReadTransaction()).thenReturn(mockedReadOnlyTx);
dummyRequestContext = new AbstractRequestContext<List<MultipartReply>>(DUMMY_XID) {
final Optional<FlowCapableNode> flowNodeOpt = Optional.of(flowNodeBuilder.build());
final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowNodeFuture = Futures
.immediateCheckedFuture(flowNodeOpt);
- when(mockedReadOnlyTx.read(LogicalDatastoreType.OPERATIONAL, nodePath)).thenReturn(flowNodeFuture);
+ final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowNodeFutureSpy = spy(flowNodeFuture);
+
+ when(mockedReadOnlyTx.read(LogicalDatastoreType.OPERATIONAL, nodePath)).thenReturn(flowNodeFutureSpy);
+ when(flowNodeFutureSpy.get()).thenReturn(flowNodeOpt);
when(mockedDeviceContext.getReadTransaction()).thenReturn(mockedReadOnlyTx);
multipartRequestOnTheFlyCallback.onSuccess(mpReplyMessage.build());
*/
@Test
public void testOnSuccessWithValidMultipart2() throws Exception {
+ final MatchBuilder matchBuilder = new MatchBuilder()
+ .setMatchEntry(Collections.<MatchEntry>emptyList());
+ final FlowStatsBuilder flowStatsBuilder = new FlowStatsBuilder()
+ .setTableId(tableId)
+ .setPriority(2)
+ .setCookie(BigInteger.ZERO)
+ .setByteCount(BigInteger.TEN)
+ .setPacketCount(BigInteger.ONE)
+ .setDurationSec(11L)
+ .setDurationNsec(12L)
+ .setMatch(matchBuilder.build())
+ .setFlags(new FlowModFlags(true, false, false, false, false));
+ final MultipartReplyFlowBuilder multipartReplyFlowBuilder = new MultipartReplyFlowBuilder()
+ .setFlowStats(Collections.singletonList(flowStatsBuilder.build()));
+ final MultipartReplyFlowCaseBuilder multipartReplyFlowCaseBuilder = new MultipartReplyFlowCaseBuilder()
+ .setMultipartReplyFlow(multipartReplyFlowBuilder.build());
final MultipartReplyMessageBuilder mpReplyMessage = new MultipartReplyMessageBuilder()
- .setType(MultipartType.OFPMPDESC)
- .setFlags(new MultipartRequestFlags(false));
+ .setType(MultipartType.OFPMPFLOW)
+ .setFlags(new MultipartRequestFlags(false))
+ .setMultipartReplyBody(multipartReplyFlowCaseBuilder.build())
+ .setXid(21L);
- multipartRequestOnTheFlyCallback.onSuccess(mpReplyMessage.build());
+ final InstanceIdentifier<FlowCapableNode> nodePath = mockedDeviceInfo.getNodeInstanceIdentifier()
+ .augmentation(FlowCapableNode.class);
+ final FlowCapableNodeBuilder flowNodeBuilder = new FlowCapableNodeBuilder();
+ final TableBuilder tableDataBld = new TableBuilder();
+ tableDataBld.setId(tableId);
+ flowNodeBuilder.setTable(Collections.singletonList(tableDataBld.build()));
+ final Optional<FlowCapableNode> flowNodeOpt = Optional.of(flowNodeBuilder.build());
+ final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowNodeFuture = Futures
+ .immediateCheckedFuture(flowNodeOpt);
+ final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowNodeFutureSpy = spy(flowNodeFuture);
- final RpcResult<List<MultipartReply>> actualResult = dummyRequestContext.getFuture().get();
- assertNotNull(actualResult.getErrors());
- assertTrue(actualResult.getErrors().isEmpty());
- assertNotNull(actualResult.getResult());
- assertTrue(actualResult.getResult().isEmpty());
+ when(mockedReadOnlyTx.read(LogicalDatastoreType.OPERATIONAL, nodePath)).thenReturn(flowNodeFutureSpy);
+ when(flowNodeFutureSpy.get()).thenReturn(flowNodeOpt);
+ when(mockedDeviceContext.getReadTransaction()).thenReturn(mockedReadOnlyTx);
- Mockito.verify(mockedFlowRegistry, Mockito.never()).storeIfNecessary(Matchers.any());
- Mockito.verify(mockedDeviceContext, Mockito.never()).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL),
- Matchers.<InstanceIdentifier>any(), Matchers.<DataObject>any());
+ multipartRequestOnTheFlyCallback.onSuccess(mpReplyMessage.build());
+ final InstanceIdentifier<Table> tableIdent = nodePath.child(Table.class, new TableKey(tableId));
+
+ verify(mockedReadOnlyTx, times(1)).read(LogicalDatastoreType.OPERATIONAL, nodePath);
+ verify(mockedReadOnlyTx, times(1)).close();
+ verify(mockedDeviceContext, times(1)).writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL),
+ eq(tableIdent), Matchers.<Table> any());
+ /*
+ * One call for Table one call for Flow
+ * we are not able to create Flow InstanceIdentifier because we are missing FlowId
+ */
+ verify(mockedDeviceContext, times(2)).writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL),
+ Matchers.<InstanceIdentifier> any(), Matchers.<DataObject> any());
}
}
when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockedPrimConnectionContext);
when(mockedDeviceContext.getMessageSpy()).thenReturn(mockedMessagSpy);
- when(mockedDeviceContext.getDeviceFlowRegistry()).thenReturn(new DeviceFlowRegistryImpl(dataBroker, NODE_II));
+ when(mockedDeviceContext.getDeviceFlowRegistry()).thenReturn(new DeviceFlowRegistryImpl(DUMMY_VERSION, dataBroker, NODE_II));
when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
when(mockedDeviceContext.getDeviceInfo()).thenReturn(mockedDeviceInfo);
when(mockedDeviceContext.getMultiMsgCollector(Matchers.any())).thenReturn(multiMessageCollector);
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue;
+import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
when(mockedDeviceContext.getDeviceInfo()).thenReturn(mockedDeviceInfo);
when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockedPrimConnectionContext);
when(mockedDeviceContext.getMessageSpy()).thenReturn(mockedMessagSpy);
- when(mockedDeviceContext.getDeviceFlowRegistry()).thenReturn(new DeviceFlowRegistryImpl(dataBroker, nodePath));
+ when(mockedDeviceContext.getDeviceFlowRegistry()).thenReturn(new DeviceFlowRegistryImpl(OFConstants.OFP_VERSION_1_3, dataBroker, nodePath));
when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
when(mockedDeviceContext.getMultiMsgCollector(
Matchers.<RequestContext<List<MultipartReply>>>any())).thenAnswer(
--- /dev/null
+/*
+ * Copyright (c) 2014, 2017 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.openflowplugin.impl.util;
+
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchArbitraryBitMaskBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchArbitraryBitMaskBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.opendaylight.ipv6.arbitrary.bitmask.fields.rev160224.Ipv6ArbitraryMask;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * @author sai.marapareddy@gmail.com (arbitrary masks)
+ */
+
+/**
+ * test of {@link MatchComparatorHelper}
+ */
+public class MatchComparatorHelperTest {
+
+ /**
+ * mask for /32
+ */
+ private static final int DEFAULT_IPV4_MASK = 0xffffffff;
+
+ /**
+ * mask for /30
+ */
+ private static final int IPV4_30_MASK = 0xfffffffc;
+ private static final int IP_ADDRESS = 0xC0A80101;
+
+ /**
+ * The test of conversion valid IP addres without mask to binary form.
+ */
+ @Test
+ public void validIpWithoutMaskTest() {
+ IntegerIpAddress intIp = MatchComparatorHelper.strIpToIntIp("192.168.1.1");
+ assertEquals(IP_ADDRESS, intIp.getIp());
+ assertEquals(DEFAULT_IPV4_MASK, intIp.getMask());
+ }
+
+ /**
+ * The test of conversion of valid IP address with valid mask to binary form.
+ */
+ @Test
+ public void validIpWithValidMaskTest() {
+ IntegerIpAddress intIp = MatchComparatorHelper.strIpToIntIp("192.168.1.1/30");
+ assertEquals(IP_ADDRESS, intIp.getIp());
+ assertEquals(IPV4_30_MASK, intIp.getMask());
+ }
+
+ /**
+ * The test of conversion of valid IP address invalid mask to binary form.
+ */
+ @Test
+ public void validIpWithInvalidMaskTest() {
+ try {
+ MatchComparatorHelper.strIpToIntIp("192.168.1.1/40");
+ } catch (IllegalStateException e) {
+ assertEquals("Valid values for mask are from range 0 - 32. Value 40 is invalid.", e.getMessage());
+ return;
+ }
+ fail("IllegalStateException was awaited (40 subnet is invalid)");
+ }
+
+ /**
+ * The test of conversion invalid IP address with valid mask to binary form.
+ */
+ @Test
+ public void invalidIpWithValidMaskTest() {
+ try {
+ MatchComparatorHelper.strIpToIntIp("257.168.1.1/25");
+ } catch (IllegalArgumentException e) {
+ assertEquals("'257.168.1.1' is not an IP string literal.", e.getMessage());
+ }
+ }
+
+ @Test
+ public void ethernetMatchEqualsTest() {
+ final EthernetMatchBuilder statsEthernetBuilder = new EthernetMatchBuilder();
+ final EthernetMatchBuilder storedEthernetBuilder = new EthernetMatchBuilder();
+
+ assertEquals(true, MatchComparatorHelper.ethernetMatchEquals(null, null));
+
+ statsEthernetBuilder.setEthernetSource(new EthernetSourceBuilder().setAddress(
+ new MacAddress("11:22:33:44:55:66")).build());
+ storedEthernetBuilder.setEthernetSource(new EthernetSourceBuilder().setAddress(
+ new MacAddress("11:22:33:44:55:77")).build());
+ assertEquals(false,
+ MatchComparatorHelper.ethernetMatchEquals(statsEthernetBuilder.build(), storedEthernetBuilder.build()));
+
+ storedEthernetBuilder.setEthernetSource(new EthernetSourceBuilder().setAddress(
+ new MacAddress("11:22:33:44:55:66")).build());
+ statsEthernetBuilder.setEthernetDestination(new EthernetDestinationBuilder().setAddress(
+ new MacAddress("66:55:44:33:22:11")).build());
+ storedEthernetBuilder.setEthernetDestination(new EthernetDestinationBuilder().setAddress(
+ new MacAddress("77:55:44:33:22:11")).build());
+ assertEquals(false,
+ MatchComparatorHelper.ethernetMatchEquals(statsEthernetBuilder.build(), storedEthernetBuilder.build()));
+
+ storedEthernetBuilder.setEthernetDestination(new EthernetDestinationBuilder().setAddress(
+ new MacAddress("66:55:44:33:22:11")).build());
+ statsEthernetBuilder.setEthernetType(new EthernetTypeBuilder().setType(new EtherType((long) 1)).build());
+ storedEthernetBuilder.setEthernetType(new EthernetTypeBuilder().setType(new EtherType((long) 1)).build());
+ assertEquals(true,
+ MatchComparatorHelper.ethernetMatchEquals(statsEthernetBuilder.build(), storedEthernetBuilder.build()));
+
+ statsEthernetBuilder.setEthernetType(null).build();
+ assertEquals(false,
+ MatchComparatorHelper.ethernetMatchEquals(statsEthernetBuilder.build(), storedEthernetBuilder.build()));
+
+ storedEthernetBuilder.setEthernetType(null).build();
+ assertEquals(true,
+ MatchComparatorHelper.ethernetMatchEquals(statsEthernetBuilder.build(), storedEthernetBuilder.build()));
+
+ }
+
+ // Please see following bug for more details https://bugs.opendaylight.org/show_bug.cgi?id=7910
+ @Test
+ public void ethernetMatchWithFullMaskTest() {
+ final EthernetSourceBuilder statsBuilder = new EthernetSourceBuilder();
+ final EthernetSourceBuilder storedBuilder = new EthernetSourceBuilder();
+
+ assertEquals(true, MatchComparatorHelper.ethernetMatchFieldsEquals(null, null));
+
+ statsBuilder.setAddress(new MacAddress("11:22:33:44:55:66"));
+
+ storedBuilder.setAddress(new MacAddress("11:22:33:44:55:66"));
+ storedBuilder.setMask(new MacAddress("FF:FF:FF:FF:FF:FF"));
+
+ assertEquals(true,
+ MatchComparatorHelper.ethernetMatchFieldsEquals(statsBuilder.build(), storedBuilder.build()));
+ }
+
+ @Test
+ public void ethernetMatchFieldsEqualsTest() {
+ final EthernetSourceBuilder statsBuilder = new EthernetSourceBuilder();
+ final EthernetSourceBuilder storedBuilder = new EthernetSourceBuilder();
+
+ assertEquals(true, MatchComparatorHelper.ethernetMatchFieldsEquals(null, null));
+
+ statsBuilder.setAddress(new MacAddress("11:22:33:44:55:66"));
+ storedBuilder.setAddress(new MacAddress("11:22:33:44:55:77"));
+ assertEquals(false,
+ MatchComparatorHelper.ethernetMatchFieldsEquals(statsBuilder.build(), storedBuilder.build()));
+
+ storedBuilder.setAddress(new MacAddress("11:22:33:44:55:66"));
+ assertEquals(true, MatchComparatorHelper.ethernetMatchFieldsEquals(statsBuilder.build(), storedBuilder.build()));
+ }
+
+ @Test
+ public void macAddressEqualsTest() {
+ assertEquals(true, MatchComparatorHelper.macAddressEquals(null, null));
+ assertEquals(true, MatchComparatorHelper.macAddressEquals(new MacAddress("11:22:33:44:55:66"), new MacAddress(
+ "11:22:33:44:55:66")));
+ assertEquals(false, MatchComparatorHelper.macAddressEquals(new MacAddress("11:22:33:44:55:66"), new MacAddress(
+ "11:22:33:44:55:77")));
+ }
+
+ @Test
+ public void checkNullValuesTest() {
+ assertEquals(false, MatchComparatorHelper.checkNullValues(null, ""));
+ assertEquals(false, MatchComparatorHelper.checkNullValues("", null));
+ assertEquals(true, MatchComparatorHelper.checkNullValues(null, null));
+ assertTrue(MatchComparatorHelper.checkNullValues("", "") == null);
+ }
+
+ @Test
+ public void compareIpv4PrefixNullSafeTest() {
+ assertEquals(true, MatchComparatorHelper.compareIpv4PrefixNullSafe(null, null));
+ assertEquals(true, MatchComparatorHelper.compareIpv4PrefixNullSafe(new Ipv4Prefix("192.168.1.1/31"),
+ new Ipv4Prefix("192.168.1.1/31")));
+
+ assertEquals(false, MatchComparatorHelper.compareIpv4PrefixNullSafe(new Ipv4Prefix("192.168.1.1/31"),
+ new Ipv4Prefix("191.168.1.1/31")));
+ }
+
+ @Test
+ public void compareStringNullSafeTest() {
+ assertEquals(true, MatchComparatorHelper.compareStringNullSafe(null,null));
+ assertEquals(true, MatchComparatorHelper.compareStringNullSafe("Hello", "Hello"));
+ assertEquals(false, MatchComparatorHelper.compareStringNullSafe("Hello", "hello"));
+ }
+
+ private static final int ip_192_168_1_1 = 0xC0A80101;
+ private static final int ip_192_168_1_4 = 0xC0A80104;
+
+ @Test
+ public void ipBasedMatchTest() {
+ // are equals because only IP address is compared
+ assertEquals(true, MatchComparatorHelper.ipBasedMatch(new IntegerIpAddress(ip_192_168_1_1, 32),
+ new IntegerIpAddress(ip_192_168_1_1, 16)));
+ }
+
+ @Test
+ public void ipAndMaskBasedMatchTest() {
+ // true because both cases are network 192.168.1.0
+ assertEquals(true, MatchComparatorHelper.ipBasedMatch(new IntegerIpAddress(ip_192_168_1_1, 31),
+ new IntegerIpAddress(ip_192_168_1_1, 30)));
+
+ // false because first is network 192.168.1.0 and second is 192.168.1.4
+ assertEquals(false, MatchComparatorHelper.ipBasedMatch(new IntegerIpAddress(ip_192_168_1_1, 31),
+ new IntegerIpAddress(ip_192_168_1_4, 30)));
+ }
+
+ @Test
+ public void layer3MatchEqualsTest() {
+ final Ipv4MatchBuilder statsBuilder = new Ipv4MatchBuilder();
+ final Ipv4MatchBuilder storedBuilder = new Ipv4MatchBuilder();
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+ statsBuilder.setIpv4Destination(new Ipv4Prefix("192.168.1.1/30"));
+ storedBuilder.setIpv4Destination(new Ipv4Prefix("191.168.1.1/30"));
+ assertEquals(false, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
+ assertEquals(true,
+ MatchComparatorHelper.layer3MatchEquals(new ArpMatchBuilder().build(), new ArpMatchBuilder().build()));
+ }
+
+ @Test
+ public void layer3MatchEqualsIpv6Test() {
+ final Ipv6MatchBuilder statsBuilder = new Ipv6MatchBuilder();
+ final Ipv6MatchBuilder storedBuilder = new Ipv6MatchBuilder();
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+
+ statsBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000D:0000:0000:0000:5D99/64"));
+ storedBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000D:0000:0000:0000:4D99/64"));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+
+ statsBuilder.setIpv6Destination(new Ipv6Prefix("aabb:1234:2acf:000d:0000:0000:0000:5d99/64"));
+ storedBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000D:0000:0000:0000:4D99/64"));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+
+ statsBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000C:0000:0000:0000:5D99/64"));
+ storedBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000D:0000:0000:0000:4D99/64"));
+ assertEquals(false, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+
+ statsBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000C:0000:0000:0000:5D99/63"));
+ storedBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000D:0000:0000:0000:4D99/63"));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+
+ statsBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000D:0000:0000:0000:5D99/63"));
+ storedBuilder.setIpv6Destination(new Ipv6Prefix("AABB:1234:2ACF:000E:0000:0000:0000:4D99/63"));
+ assertEquals(false, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+ }
+
+ @Test
+ public void layer3MatchEqualsIpv4ArbitraryMaskTest(){
+ final Ipv4MatchBuilder statsBuilder = new Ipv4MatchBuilder();
+ final Ipv4MatchArbitraryBitMaskBuilder storedBuilder = new Ipv4MatchArbitraryBitMaskBuilder();
+ assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
+ statsBuilder.setIpv4Destination(new Ipv4Prefix("192.168.1.1/24"));
+ storedBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.1.1"));
+ storedBuilder.setIpv4DestinationArbitraryBitmask(new DottedQuad("255.255.255.0"));
+ statsBuilder.setIpv4Source(new Ipv4Prefix("192.168.1.1/24"));
+ storedBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.168.1.1"));
+ storedBuilder.setIpv4SourceArbitraryBitmask(new DottedQuad("255.255.255.0"));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
+
+ }
+
+ @Test
+ public void layer3MatchEqualsIpv4ArbitraryMaskRandomTest() {
+ final Ipv4MatchArbitraryBitMaskBuilder statsBuilder = new Ipv4MatchArbitraryBitMaskBuilder();
+ final Ipv4MatchArbitraryBitMaskBuilder storedBuilder = new Ipv4MatchArbitraryBitMaskBuilder();
+ assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
+ statsBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.0.1"));
+ statsBuilder.setIpv4DestinationArbitraryBitmask(new DottedQuad("255.255.0.255"));
+ storedBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.1.1"));
+ storedBuilder.setIpv4DestinationArbitraryBitmask(new DottedQuad("255.255.0.255"));
+ statsBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.0.0.1"));
+ statsBuilder.setIpv4SourceArbitraryBitmask(new DottedQuad("255.0.0.255"));
+ storedBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.7.1.1"));
+ storedBuilder.setIpv4SourceArbitraryBitmask(new DottedQuad("255.0.0.255"));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
+ }
+
+ @Test
+ public void layer3MatchEqualsIpv4ArbitraryMaskEqualsNullTest() {
+ final Ipv4MatchBuilder statsBuilder = new Ipv4MatchBuilder();
+ final Ipv4MatchArbitraryBitMaskBuilder storedBuilder = new Ipv4MatchArbitraryBitMaskBuilder();
+ assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
+ statsBuilder.setIpv4Source(new Ipv4Prefix("192.168.0.1/32"));
+ storedBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.0.1"));
+ statsBuilder.setIpv4Destination(new Ipv4Prefix("192.1.0.0/32"));
+ storedBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.1.0.0"));
+ assertEquals(false, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
+ }
+
+ @Test
+ public void layer3MatchEqualsIpv4ArbitraryEmptyBitMaskTest(){
+ final Ipv4MatchBuilder statsBuilder = new Ipv4MatchBuilder();
+ final Ipv4MatchArbitraryBitMaskBuilder storedBuilder = new Ipv4MatchArbitraryBitMaskBuilder();
+ assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
+ statsBuilder.setIpv4Destination(new Ipv4Prefix("192.168.1.1/32"));
+ storedBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.1.1"));
+ statsBuilder.setIpv4Source(new Ipv4Prefix("192.168.1.1/32"));
+ storedBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.168.1.1"));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
+ }
+
+ @Test
+ public void extractIpv4AddressTest() {
+ Ipv4Address ipAddress = new Ipv4Address("1.1.1.1");
+ DottedQuad netMask = new DottedQuad("255.255.255.0");
+ String extractedIpAddress;
+ extractedIpAddress = MatchComparatorHelper.normalizeIpv4Address(ipAddress,netMask);
+ assertEquals(extractedIpAddress,"1.1.1.0");
+ }
+
+ @Test
+ public void convertArbitraryMaskToByteArrayTest() {
+ int value = 0xffffffff;
+ byte[] bytes = new byte[]{
+ (byte)(value >>> 24), (byte)(value >> 16 & 0xff), (byte)(value >> 8 & 0xff), (byte)(value & 0xff) };
+ byte[] maskBytes;
+ maskBytes = MatchComparatorHelper.convertArbitraryMaskToByteArray(new DottedQuad("255.255.255.255"));
+ for (int i=0; i<bytes.length;i++) {
+ int mask = maskBytes[i];
+ assertEquals(bytes[i],mask);
+ }
+ }
+
+ @Test
+ public void isArbitraryBitMaskTest() {
+ boolean arbitraryBitMask;
+ arbitraryBitMask = MatchComparatorHelper.isArbitraryBitMask(new byte[] {1,1,1,1});
+ assertEquals(arbitraryBitMask,true);
+ arbitraryBitMask = MatchComparatorHelper.isArbitraryBitMask(new byte[] {-1,-1,-1,-1});
+ assertEquals(arbitraryBitMask,false);
+ arbitraryBitMask = MatchComparatorHelper.isArbitraryBitMask(new byte[] {-1,-1,0,-1});
+ assertEquals(arbitraryBitMask,true);
+ arbitraryBitMask = MatchComparatorHelper.isArbitraryBitMask(null);
+ assertEquals(arbitraryBitMask,false);
+ }
+
+ @Test
+ public void createPrefixTest() {
+ Ipv4Address ipv4Address = new Ipv4Address("1.1.1.1");
+ byte [] byteMask = new byte[] {-1,-1,-1,-1};
+ Ipv4Prefix ipv4Prefix = MatchComparatorHelper.createPrefix(ipv4Address,byteMask);
+ assertEquals(ipv4Prefix,new Ipv4Prefix("1.1.1.1/32"));
+ String nullMask = "";
+ Ipv4Prefix ipv4PrefixNullMask = MatchComparatorHelper.createPrefix(ipv4Address,nullMask);
+ assertEquals(ipv4PrefixNullMask,new Ipv4Prefix("1.1.1.1/32"));
+ Ipv4Prefix ipv4PrefixNoMask = MatchComparatorHelper.createPrefix(ipv4Address);
+ assertEquals(ipv4PrefixNoMask,new Ipv4Prefix("1.1.1.1/32"));
+ }
+
+ @Test
+ public void layer3MatchEqualsIpv6ArbitraryMaskTest(){
+ final Ipv6MatchBuilder statsBuilder = new Ipv6MatchBuilder();
+ final Ipv6MatchArbitraryBitMaskBuilder storedBuilder = new Ipv6MatchArbitraryBitMaskBuilder();
+ assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
+ statsBuilder.setIpv6Destination(new Ipv6Prefix("1:2:3:4:5:6:7:8/16"));
+ storedBuilder.setIpv6DestinationAddressNoMask(new Ipv6Address("1:2:3:4:5:6:7:8"));
+ storedBuilder.setIpv6DestinationArbitraryBitmask(new Ipv6ArbitraryMask("FFFF:0000:0000:0000:0000:0000:0000:0000"));
+ statsBuilder.setIpv6Source(new Ipv6Prefix("1:2:3:4:5:6:7:8/32"));
+ storedBuilder.setIpv6SourceAddressNoMask(new Ipv6Address("1:2:3:4:5:6:7:8"));
+ storedBuilder.setIpv6SourceArbitraryBitmask(new Ipv6ArbitraryMask("FFFF:FFFF::"));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
+ }
+
+
+ @Test
+ public void layer3MatchEqualsIpv6ArbitraryMaskRandomTest() {
+ final Ipv6MatchArbitraryBitMaskBuilder statsBuilder = new Ipv6MatchArbitraryBitMaskBuilder();
+ final Ipv6MatchArbitraryBitMaskBuilder storedBuilder = new Ipv6MatchArbitraryBitMaskBuilder();
+ assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
+ statsBuilder.setIpv6DestinationAddressNoMask(new Ipv6Address("1::8"));
+ statsBuilder.setIpv6DestinationArbitraryBitmask(new Ipv6ArbitraryMask("FFFF::FFFF"));
+ storedBuilder.setIpv6DestinationAddressNoMask(new Ipv6Address("1:92:93:94:95:96:97:8"));
+ storedBuilder.setIpv6DestinationArbitraryBitmask(new Ipv6ArbitraryMask("FFFF::FFFF"));
+ statsBuilder.setIpv6SourceAddressNoMask(new Ipv6Address("1::8"));
+ statsBuilder.setIpv6SourceArbitraryBitmask(new Ipv6ArbitraryMask("FFFF::FFFF"));
+ storedBuilder.setIpv6SourceAddressNoMask(new Ipv6Address("1:92:93:94:95:96:97:8"));
+ storedBuilder.setIpv6SourceArbitraryBitmask(new Ipv6ArbitraryMask("FFFF::FFFF"));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
+ }
+
+ @Test
+ public void layer3MatchEqualsIpv6ArbitraryMaskEqualsNullTest() {
+ final Ipv6MatchBuilder statsBuilder = new Ipv6MatchBuilder();
+ final Ipv6MatchArbitraryBitMaskBuilder storedBuilder = new Ipv6MatchArbitraryBitMaskBuilder();
+ assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
+ statsBuilder.setIpv6Source(new Ipv6Prefix("1:2:3:4:5:6:7:8/128"));
+ storedBuilder.setIpv6DestinationAddressNoMask(new Ipv6Address("1:2:3:4:5:6:7:8"));
+ statsBuilder.setIpv6Destination(new Ipv6Prefix("1:2:3:4:5:6::/128"));
+ storedBuilder.setIpv6SourceAddressNoMask(new Ipv6Address("1:2:3:4:5:6::"));
+ assertEquals(false, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
+ }
+
+ @Test
+ public void layer3MatchEqualsIpv6ArbitraryEmptyBitMaskTest(){
+ final Ipv6MatchBuilder statsBuilder = new Ipv6MatchBuilder();
+ final Ipv6MatchArbitraryBitMaskBuilder storedBuilder = new Ipv6MatchArbitraryBitMaskBuilder();
+ assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
+ statsBuilder.setIpv6Destination(new Ipv6Prefix("1:2:3:4:5:6:7:8/128"));
+ storedBuilder.setIpv6DestinationAddressNoMask(new Ipv6Address("1:2:3:4:5:6:7:8"));
+ statsBuilder.setIpv6Source(new Ipv6Prefix("1:2:3:4:5:6::/128"));
+ storedBuilder.setIpv6SourceAddressNoMask(new Ipv6Address("1:2:3:4:5:6::"));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
+ }
+}
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
import org.opendaylight.openflowjava.util.ByteBufUtils;
import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemovedBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.RemovedReasonFlags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.RemovedFlowReason;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.mod.removed.Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.mod.removed.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.protocol.match.fields.PbbBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowRemovedReason;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Ipv6ExthdrFlags;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpOp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpSha;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.UdpSrcCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.VlanPcpCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.VlanVidCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemoved;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TunnelIpv4Dst;
salFlowRemoved.setHardTimeout(ofFlow.getHardTimeout());
salFlowRemoved.setPacketCount(ofFlow.getPacketCount());
salFlowRemoved.setByteCount(ofFlow.getByteCount());
- RemovedReasonFlags removeReasonFlag = new RemovedReasonFlags(
- FlowRemovedReason.OFPRRDELETE.equals(ofFlow.getReason()),
- FlowRemovedReason.OFPRRGROUPDELETE.equals(ofFlow.getReason()),
- FlowRemovedReason.OFPRRHARDTIMEOUT.equals(ofFlow.getReason()),
- FlowRemovedReason.OFPRRIDLETIMEOUT.equals(ofFlow.getReason())
- );
- salFlowRemoved.setRemovedReason(removeReasonFlag);
+ if(Objects.nonNull(ofFlow.getReason())) {
+ salFlowRemoved.setRemovedReason(translateReason(ofFlow));
+ }
OpenflowVersion ofVersion = OpenflowVersion.get(sc.getPrimaryConductor().getVersion());
org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match ofMatch = ofFlow
return Collections.emptyList();
}
}
-
+ private RemovedFlowReason translateReason(FlowRemoved removedFlow) {
+ LOG.debug("--Entering translateReason within FlowRemovedTranslator with reason:{} " + removedFlow.getReason());
+ switch (removedFlow.getReason()) {
+ case OFPRRIDLETIMEOUT:
+ return RemovedFlowReason.OFPRRIDLETIMEOUT;
+ case OFPRRHARDTIMEOUT:
+ return RemovedFlowReason.OFPRRHARDTIMEOUT;
+ case OFPRRDELETE:
+ return RemovedFlowReason.OFPRRDELETE;
+ case OFPRRGROUPDELETE:
+ return RemovedFlowReason.OFPRRGROUPDELETE;
+ default:
+ LOG.debug("The flow being default and hence deleting it ");
+ return RemovedFlowReason.OFPRRDELETE;
+ }
+ }
public Match fromMatch(final org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match ofMatch,
final BigInteger datapathid, final OpenflowVersion ofVersion) {
import java.math.BigInteger;\r
import java.util.ArrayList;\r
import java.util.Collection;\r
+import java.util.Collections;\r
import java.util.HashMap;\r
import java.util.List;\r
import java.util.Map;\r
import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;\r
import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;\r
import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionContext;\r
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;\r
import org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl;\r
import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContextOFImpl;\r
import org.opendaylight.openflowplugin.openflow.md.core.session.SwitchConnectionCookieOFImpl;\r
import org.opendaylight.openflowplugin.openflow.md.queue.QueueProcessorLightImpl;\r
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PacketInReason;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessageBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceivedBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.SendToController;\r
import org.opendaylight.yangtools.yang.binding.DataObject;\r
import org.slf4j.Logger;\r
import org.slf4j.LoggerFactory;\r
List<DataObject> salPacketIn = packetInV10Translator.translate(cookie,\r
sessionContextOFImpl, message);\r
\r
- //TODO: rewrite to object and involve object comparison in Assert\r
- String expectedString = "[PacketReceived [_ingress=NodeConnectorRef [_value=KeyedInstanceIdentifier"\r
- + "{targetType=interface org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector,"\r
- + " path=[org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes,"\r
- + " org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node["\r
- + "key=NodeKey [_id=Uri [_value=openflow:"\r
- + datapathId.toString()\r
- + "]]],"\r
- + " org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector["\r
- + "key=NodeConnectorKey [_id=Uri [_value=openflow:"\r
- + datapathId.toString()\r
- + ":"\r
- + message.getInPort().toString()\r
- + "]]]]}], _packetInReason=class org.opendaylight.yang.gen.v1.urn.opendaylight."\r
- + "packet.service.rev130709.SendToController, _payload=[115, 101, 110, 100, 79, 117,"\r
- + " 116, 112, 117, 116, 77, 115, 103, 95, 84, 69, 83, 84], augmentation=[]]]";\r
- Assert.assertEquals(expectedString, salPacketIn.toString());\r
+ Assert.assertEquals(Collections.singletonList(new PacketReceivedBuilder()\r
+ .setIngress(InventoryDataServiceUtil.nodeConnectorRefFromDatapathIdPortno(datapathId, (long) message.getInPort(), OpenflowVersion.OF10))\r
+ .setPacketInReason(SendToController.class)\r
+ .setPayload(data)\r
+ .build()).toString(), salPacketIn.toString());\r
+\r
LOG.debug("Test translate done.");\r
}\r
\r