Flow removed switch event. Group and Meter update RPC 51/2751/1
authorPrasanna Huddar <prasanna.huddar@ericsson.com>
Thu, 14 Nov 2013 17:56:18 +0000 (23:26 +0530)
committerPrasanna Huddar <prasanna.huddar@ericsson.com>
Thu, 14 Nov 2013 17:57:26 +0000 (23:27 +0530)
Signed-off-by: Prasanna Huddar <prasanna.huddar@ericsson.com>
Change-Id: I7b5d1016ae6185d7c1c885a9b87845eee207697c

opendaylight/forwardingrulesmanager_mdsal/openflow/src/main/java/org/opendaylight/controller/forwardingrulesmanager_mdsal/consumer/impl/FRMConsumerImpl.java
opendaylight/forwardingrulesmanager_mdsal/openflow/src/main/java/org/opendaylight/controller/forwardingrulesmanager_mdsal/consumer/impl/FlowConsumerImpl.java
opendaylight/forwardingrulesmanager_mdsal/openflow/src/main/java/org/opendaylight/controller/forwardingrulesmanager_mdsal/consumer/impl/GroupConsumerImpl.java
opendaylight/forwardingrulesmanager_mdsal/openflow/src/main/java/org/opendaylight/controller/forwardingrulesmanager_mdsal/consumer/impl/MeterConsumerImpl.java
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend
opendaylight/md-sal/model/model-flow-base/src/main/yang/flow-types.yang
opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-service.yang
opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java

index a72d063..e26e98e 100644 (file)
@@ -17,7 +17,6 @@ import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.opendaylight.controller.sal.core.IContainer;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
-import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
 import org.slf4j.Logger;
@@ -32,11 +31,10 @@ public class FRMConsumerImpl extends AbstractBindingAwareProvider implements Com
     private GroupConsumerImpl groupImplRef;
     private static DataProviderService dataProviderService;
 
-    private static IClusterContainerServices clusterContainerService = null;
-    private static ISwitchManager switchManager;
-    private static IContainer container;
-
-    @Override
+       private static IClusterContainerServices clusterContainerService = null;
+       private static IContainer container;
+       
+       @Override
     public void onSessionInitiated(ProviderContext session) {
 
         FRMConsumerImpl.p_session = session;
@@ -89,14 +87,6 @@ public class FRMConsumerImpl extends AbstractBindingAwareProvider implements Com
         FRMConsumerImpl.clusterContainerService = clusterContainerService;
     }
 
-    public static ISwitchManager getSwitchManager() {
-        return switchManager;
-    }
-
-    public static void setSwitchManager(ISwitchManager switchManager) {
-        FRMConsumerImpl.switchManager = switchManager;
-    }
-
     public static IContainer getContainer() {
         return container;
     }
@@ -109,41 +99,35 @@ public class FRMConsumerImpl extends AbstractBindingAwareProvider implements Com
         BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
         bundleContext.registerService(CommandProvider.class.getName(), this, null);
     }
-
-    private boolean getDependentModule() {
-        do {
-            clusterContainerService = (IClusterContainerServices) ServiceHelper.getGlobalInstance(
-                    IClusterContainerServices.class, this);
-            try {
-                Thread.sleep(4);
-            } catch (InterruptedException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
-            }
-        } while (clusterContainerService == null);
-
-        do {
-
-            container = (IContainer) ServiceHelper.getGlobalInstance(IContainer.class, this);
-            try {
-                Thread.sleep(5);
-            } catch (InterruptedException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
-            }
-        } while (container == null);
-
-        do {
-            switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, container.getName(), this);
-            try {
-                Thread.sleep(5);
-            } catch (InterruptedException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
-            }
-        } while (null == switchManager);
+       
+       private boolean getDependentModule() {
+           do {
+        clusterContainerService = (IClusterContainerServices) ServiceHelper.getGlobalInstance(IClusterContainerServices.class, this);
+        try {
+            Thread.sleep(4);
+        } catch (InterruptedException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+           } while(clusterContainerService == null);
+           
+           do {
+               
+           
+        container = (IContainer) ServiceHelper.getGlobalInstance(IContainer.class, this);
+        try {
+            Thread.sleep(5);
+        } catch (InterruptedException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+           } while (container == null);
+           
+          
         return true;
-    }
+       }
+
+       
 
     public static DataProviderService getDataProviderService() {
         return dataProviderService;
@@ -154,8 +138,9 @@ public class FRMConsumerImpl extends AbstractBindingAwareProvider implements Com
     }
 
     public GroupConsumerImpl getGroupImplRef() {
-        return groupImplRef;
+       return groupImplRef;
     }
+               
 
     public static ProviderContext getProviderSession() {
         return p_session;
index 7545203..3725738 100644 (file)
@@ -39,6 +39,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.Node
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
@@ -462,6 +463,11 @@ public class FlowConsumerImpl {
         public void onFlowUpdated(FlowUpdated notification) {
             updatedFlows.add(notification);
         }
+        
+        @Override
+        public void onSwitchFlowRemoved(SwitchFlowRemoved notification) {
+            //TODO
+        };
 
     }
 
index b1aaba4..ce8ee5a 100644 (file)
@@ -35,9 +35,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.Gro
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes.GroupType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeterBuilder;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -65,8 +69,8 @@ public class GroupConsumerImpl {
     private IContainer container;
 
     public GroupConsumerImpl() {
-        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder().node(Groups.class)
-                .node(Group.class).toInstance();
+        
+           InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder().node(Groups.class).node(Group.class).toInstance();
         groupService = FRMConsumerImpl.getProviderSession().getRpcService(SalGroupService.class);
 
         clusterGroupContainerService = FRMConsumerImpl.getClusterContainerService();
@@ -114,36 +118,32 @@ public class GroupConsumerImpl {
 
             clusterGroupContainerService.createCache("frm.nodeGroups",
                     EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
-
-            // TODO for cluster mode
-            /*
-             * clusterGroupContainerService.createCache(WORK_STATUS_CACHE,
-             * EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL,
-             * IClusterServices.cacheMode.ASYNC));
-             *
-             * clusterGroupContainerService.createCache(WORK_ORDER_CACHE,
-             * EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL,
-             * IClusterServices.cacheMode.ASYNC));
-             */
-
-        } catch (CacheConfigException cce) {
+            
+//TODO for cluster mode
+           /* clusterGroupContainerService.createCache(WORK_STATUS_CACHE,
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL, IClusterServices.cacheMode.ASYNC));
+
+            clusterGroupContainerService.createCache(WORK_ORDER_CACHE,
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL, IClusterServices.cacheMode.ASYNC));*/
+            
+        } catch (CacheConfigException cce) {            
             logger.error("Group CacheConfigException");
             return false;
-
+            
         } catch (CacheExistException cce) {
-            logger.error(" Group CacheExistException");
+            logger.error(" Group CacheExistException");           
         }
-
+        
         return true;
     }
-
+    
     private void nonClusterGroupObjectCreate() {
         originalSwGroupView = new ConcurrentHashMap<GroupKey, Group>();
         installedSwGroupView = new ConcurrentHashMap<GroupKey, Group>();
-        nodeGroups = new ConcurrentHashMap<Node, List<Group>>();
+        nodeGroups = new ConcurrentHashMap<Node, List<Group>>();        
         inactiveGroups = new ConcurrentHashMap<GroupKey, Group>();
     }
-
+    
     @SuppressWarnings({ "unchecked" })
     private boolean retrieveGroupCaches() {
         ConcurrentMap<?, ?> map;
@@ -152,7 +152,7 @@ public class GroupConsumerImpl {
             logger.warn("Group: un-initialized clusterGroupContainerService, can't retrieve cache");
             nonClusterGroupObjectCreate();
             return false;
-        }
+        }       
 
         map = clusterGroupContainerService.getCache("frm.originalSwGroupView");
         if (map != null) {
@@ -231,11 +231,11 @@ public class GroupConsumerImpl {
                 logger.error("Group record does not exist");
                 return new Status(StatusCode.BADREQUEST, "Group record does not exist");
             }
-
-            if (!(group.getGroupType().getIntValue() >= GroupType.GroupAll.getIntValue() && group.getGroupType()
-                    .getIntValue() <= GroupType.GroupFf.getIntValue())) {
+            
+            if (!(group.getGroupType().getIntValue() >= GroupType.GroupAll.getIntValue() && 
+                    group.getGroupType().getIntValue() <= GroupType.GroupFf.getIntValue())) {
                 logger.error("Invalid Group type %d" + group.getGroupType().getIntValue());
-                return new Status(StatusCode.BADREQUEST, "Invalid Group type");
+                return new Status(StatusCode.BADREQUEST, "Invalid Group type");                
             }
 
             groupBuckets = group.getBuckets();
@@ -279,32 +279,39 @@ public class GroupConsumerImpl {
      * @param dataObject
      */
     private Status updateGroup(InstanceIdentifier<?> path, Group groupUpdateDataObject) {
-        GroupKey groupKey = groupUpdateDataObject.getKey();
+        GroupKey groupKey = groupUpdateDataObject.getKey();        
+        UpdatedGroupBuilder updateGroupBuilder = null;
+        
         Status groupOperationStatus = validateGroup(groupUpdateDataObject, FRMUtil.operation.UPDATE);
-
+        
         if (!groupOperationStatus.isSuccess()) {
             logger.error("Group data object validation failed %s" + groupUpdateDataObject.getGroupName());
             return groupOperationStatus;
         }
-
-        originalSwGroupView.remove(groupKey);
-        originalSwGroupView.put(groupKey, groupUpdateDataObject);
-
+         
+        if (originalSwGroupView.containsKey(groupKey)) {
+            originalSwGroupView.remove(groupKey);
+            originalSwGroupView.put(groupKey, groupUpdateDataObject);
+        }
+        
         if (groupUpdateDataObject.isInstall()) {
             UpdateGroupInputBuilder groupData = new UpdateGroupInputBuilder();
-            // TODO how to get original group and modified group.
-
+            updateGroupBuilder = new UpdatedGroupBuilder();
+            updateGroupBuilder.fieldsFrom(groupUpdateDataObject);
+            groupData.setUpdatedGroup(updateGroupBuilder.build());
+            //TODO how to get original group and modified group. 
+            
             if (installedSwGroupView.containsKey(groupKey)) {
                 installedSwGroupView.remove(groupKey);
+                installedSwGroupView.put(groupKey, groupUpdateDataObject);
             }
-
-            installedSwGroupView.put(groupKey, groupUpdateDataObject);
+            
             groupService.updateGroup(groupData.build());
         }
-
+        
         return groupOperationStatus;
     }
-
+    
     /**
      * Adds Group to the southbound plugin and our internal database
      *
@@ -335,24 +342,26 @@ public class GroupConsumerImpl {
 
         return groupOperationStatus;
     }
-
-    private RpcResult<Void> commitToPlugin(internalTransaction transaction) {
-        for (Entry<InstanceIdentifier<?>, Group> entry : transaction.additions.entrySet()) {
-
-            if (!addGroup(entry.getKey(), entry.getValue()).isSuccess()) {
+    
+       private RpcResult<Void> commitToPlugin(internalTransaction transaction) {
+        for(Entry<InstanceIdentifier<?>, Group> entry :transaction.additions.entrySet()) {
+            
+            if (!addGroup(entry.getKey(),entry.getValue()).isSuccess()) {
+                transaction.additions.remove(entry.getKey());
                 return Rpcs.getRpcResult(false, null, null);
             }
         }
-        for (@SuppressWarnings("unused")
-        Entry<InstanceIdentifier<?>, Group> entry : transaction.additions.entrySet()) {
-
-            if (!updateGroup(entry.getKey(), entry.getValue()).isSuccess()) {
+        
+        for(Entry<InstanceIdentifier<?>, Group> entry :transaction.updates.entrySet()) {
+           
+            if (!updateGroup(entry.getKey(),entry.getValue()).isSuccess()) {
+                transaction.updates.remove(entry.getKey());
                 return Rpcs.getRpcResult(false, null, null);
             }
         }
-
-        for (InstanceIdentifier<?> removal : transaction.removals) {
-            // removeFlow(removal);
+        
+        for(InstanceIdentifier<?> removal : transaction.removals) {
+           // removeFlow(removal);
         }
 
         return Rpcs.getRpcResult(true, null, null);
index 1bf4f45..c69b60b 100644 (file)
@@ -33,6 +33,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.Met
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeterBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.BandType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.Drop;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.DscpRemark;
@@ -63,9 +64,8 @@ public class MeterConsumerImpl {
     private IContainer container;
 
     public MeterConsumerImpl() {
-        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder().node(Meters.class)
-                .node(Meter.class).toInstance();
-        meterService = FRMConsumerImpl.getProviderSession().getRpcService(SalMeterService.class);
+        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder().node(Meters.class).node(Meter.class).toInstance();
+        meterService = FRMConsumerImpl.getProviderSession().getRpcService(SalMeterService.class);        
         clusterMeterContainerService = FRMConsumerImpl.getClusterContainerService();
 
         container = FRMConsumerImpl.getContainer();
@@ -218,9 +218,10 @@ public class MeterConsumerImpl {
                 originalSwMeterView.put(meterKey, meterAddDataObject);
                 meterService.addMeter(meterBuilder.build());
             }
-
-            originalSwMeterView.put(meterKey, meterAddDataObject);
-        } else {
+            
+            originalSwMeterView.put(meterKey, meterAddDataObject);            
+        }
+        else {
             return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
         }
 
@@ -234,19 +235,35 @@ public class MeterConsumerImpl {
      *
      * @param dataObject
      */
-    private Status updateMeter(InstanceIdentifier<?> path, Meter meterUpdateDataObject) {
+    private Status updateMeter(InstanceIdentifier<?> path, Meter meterUpdateDataObject) {        
         MeterKey meterKey = meterUpdateDataObject.getKey();
-
-        if (null != meterKey && validateMeter(meterUpdateDataObject, FRMUtil.operation.ADD).isSuccess()) {
-            if (meterUpdateDataObject.isInstall()) {
-                UpdateMeterInputBuilder updateMeterBuilder = new UpdateMeterInputBuilder();
-
+        UpdatedMeterBuilder updateMeterBuilder = null;
+        
+        
+        if (null != meterKey && 
+                validateMeter(meterUpdateDataObject, FRMUtil.operation.UPDATE).isSuccess()) {
+            
+            if (originalSwMeterView.containsKey(meterKey)) {
+                originalSwMeterView.remove(meterKey);
                 originalSwMeterView.put(meterKey, meterUpdateDataObject);
-                meterService.updateMeter(updateMeterBuilder.build());
             }
-
-            originalSwMeterView.put(meterKey, meterUpdateDataObject);
-        } else {
+            
+            if (meterUpdateDataObject.isInstall()) {
+                UpdateMeterInputBuilder updateMeterInputBuilder = new UpdateMeterInputBuilder(); 
+                updateMeterBuilder = new UpdatedMeterBuilder();
+                updateMeterBuilder.fieldsFrom(meterUpdateDataObject);
+                updateMeterInputBuilder.setUpdatedMeter(updateMeterBuilder.build());
+                
+                if (installedSwMeterView.containsKey(meterKey)) {
+                    installedSwMeterView.remove(meterKey);
+                    installedSwMeterView.put(meterKey, meterUpdateDataObject);
+                }
+                
+                meterService.updateMeter(updateMeterInputBuilder.build());
+            }
+                        
+        }
+        else {
             return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
         }
 
@@ -260,19 +277,21 @@ public class MeterConsumerImpl {
      *
      * @param dataObject
      */
-    private Status RemoveMeter(InstanceIdentifier<?> path, Meter meterUpdateDataObject) {
+    private Status RemoveMeter(InstanceIdentifier<?> path, Meter meterUpdateDataObject) {        
         MeterKey meterKey = meterUpdateDataObject.getKey();
-
-        if (null != meterKey && validateMeter(meterUpdateDataObject, FRMUtil.operation.ADD).isSuccess()) {
+        
+        if (null != meterKey && 
+                validateMeter(meterUpdateDataObject, FRMUtil.operation.ADD).isSuccess()) {
             if (meterUpdateDataObject.isInstall()) {
-                UpdateMeterInputBuilder updateMeterBuilder = new UpdateMeterInputBuilder();
-
-                originalSwMeterView.put(meterKey, meterUpdateDataObject);
+                UpdateMeterInputBuilder updateMeterBuilder = new UpdateMeterInputBuilder();                
+                
+                installedSwMeterView.put(meterKey, meterUpdateDataObject);
                 meterService.updateMeter(updateMeterBuilder.build());
             }
-
-            originalSwMeterView.put(meterKey, meterUpdateDataObject);
-        } else {
+            
+            originalSwMeterView.put(meterKey, meterUpdateDataObject);            
+        }
+        else {
             return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
         }
 
index 7d9c939..15f0685 100644 (file)
@@ -9,6 +9,7 @@ import org.opendaylight.controller.sal.utils.Status
 import org.opendaylight.controller.sal.utils.StatusCode
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdated
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
@@ -132,4 +133,8 @@ class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowLi
         // NOOP : Not supported by AD SAL
     }
     
+    override onSwitchFlowRemoved(SwitchFlowRemoved notification) {
+        // NOOP : Not supported by AD SAL
+    }
+    
 }
index 4145977..b5a70cc 100644 (file)
@@ -69,15 +69,7 @@ module opendaylight-flow-types {
         }
     }
     
-    grouping flow {
-        container match {
-            uses match:match;
-        }
-        
-        container instructions {
-            uses instruction-list;
-        }
-                
+    grouping generic_flow_attributes {
         leaf priority {
             type uint16;
         }
@@ -94,16 +86,28 @@ module opendaylight-flow-types {
             type uint64;
         }
         
+        leaf table_id {
+            type uint8;
+        }
+    }
+    
+    grouping flow {
+        container match {
+            uses match:match;
+        }
+        
+        container instructions {
+            uses instruction-list;
+        }          
+         
+        uses generic_flow_attributes;
+        
         leaf container-name {
             type string; 
         }
         
         leaf cookie_mask {
-            type uint8;
-        }
-        
-        leaf table_id {
-            type uint8;
+            type uint64;
         }
         
         leaf buffer_id {
@@ -118,11 +122,11 @@ module opendaylight-flow-types {
             type uint32;
         }
         
-        leaf flags{
+        leaf flags {
             type flow-mod-flags;
         }
         
-        leaf flow-name{
+        leaf flow-name {
             type string;
         }
         
@@ -173,4 +177,35 @@ module opendaylight-flow-types {
             type yang:counter64;   
         }
     }
+    
+    grouping flow-mod-removed {
+        uses generic_flow_attributes;
+        
+        leaf duration_nsec {
+            type uint32;
+        }
+        
+        leaf duration_sec {
+            type uint32;
+        }
+        
+        leaf idle_timeout {
+            type uint16;
+        }
+        
+        leaf hard_timeout {
+            type uint16;
+        }
+        
+        leaf packet_count {
+            type uint64;
+        }
+        
+        leaf byte_count {
+            type uint64;
+        }
+        container match {
+            uses match:match;
+        }
+    }
 }
\ No newline at end of file
index 5a1b007..f858919 100644 (file)
@@ -16,6 +16,17 @@ module sal-flow {
         type instance-identifier;
     }
     
+    grouping node-flow-removed {
+        leaf node {
+            ext:context-reference "inv:node-context";
+            type inv:node-ref;
+        }
+        leaf flow-table {
+            type flow-table-ref;
+        }
+        uses types:flow-mod-removed;
+    }
+    
     grouping node-flow {
         uses "inv:node-context-ref";
 
@@ -78,4 +89,8 @@ module sal-flow {
     notification flow-removed {
         uses node-flow;
     }
+    
+    notification switch-flow-removed {
+        uses node-flow-removed;
+    }
 }
\ No newline at end of file
index 851826a..1627243 100644 (file)
@@ -19,6 +19,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.Flow
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
 
@@ -191,12 +192,18 @@ public class NoficationTest extends AbstractTest {
         @Override
         public void onFlowRemoved(FlowRemoved notification) {
             removedFlows.add(notification);
-        };
+        }; 
 
         @Override
         public void onFlowUpdated(FlowUpdated notification) {
             updatedFlows.add(notification);
         }
 
+        @Override
+        public void onSwitchFlowRemoved(SwitchFlowRemoved notification) {
+            // TODO Auto-generated method stub
+            
+        }
+
     }
 }