Get for flow/meter/group and flow update 68/2768/1
authorGaurav Bhagwani <gaurav.bhagwani@ericsson.com>
Fri, 15 Nov 2013 09:29:09 +0000 (14:59 +0530)
committerGaurav Bhagwani <gaurav.bhagwani@ericsson.com>
Fri, 15 Nov 2013 09:34:11 +0000 (15:04 +0530)
Signed-off-by: Gaurav Bhagwani <gaurav.bhagwani@ericsson.com>
Change-Id: Id8a545c37d75e6edc9826d809d6846f8bff4a43a

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/IForwardingRulesManager.java [new file with mode: 0644]
opendaylight/forwardingrulesmanager_mdsal/openflow/src/main/java/org/opendaylight/controller/forwardingrulesmanager_mdsal/consumer/impl/MeterConsumerImpl.java

index 372573853cb0bd600f61fe4e10abd93e9c0f6e17..d17bf8da11dbbeb9f012589c49297faf535b71bf 100644 (file)
@@ -40,6 +40,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.Remo
 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.service.rev130819.UpdateFlowInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder;
 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;
@@ -54,9 +56,9 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class FlowConsumerImpl {
+public class FlowConsumerImpl implements IForwardingRulesManager {
     protected static final Logger logger = LoggerFactory.getLogger(FlowConsumerImpl.class);
-    private FlowEventListener flowEventListener = new FlowEventListener();
+    private final FlowEventListener flowEventListener = new FlowEventListener();
     private Registration<NotificationListener> listener1Reg;
     private SalFlowService flowService;
     // private FlowDataListener listener;
@@ -201,7 +203,7 @@ public class FlowConsumerImpl {
         // updating the staticflow cache
         Integer ordinal = staticFlowsOrdinal.get(0);
         staticFlowsOrdinal.put(0, ++ordinal);
-        staticFlows.put(ordinal, (Flow) dataObject);
+        staticFlows.put(ordinal, dataObject);
 
         // We send flow to the sounthbound plugin
         flowService.addFlow(input.build());
@@ -241,6 +243,29 @@ public class FlowConsumerImpl {
         updateLocalDatabase((NodeFlow) dataObject, false);
     }
 
+    /**
+     * Update flow to the southbound plugin and our internal database
+     *
+     * @param path
+     * @param dataObject
+     */
+    private void updateFlow(InstanceIdentifier<?> path, Flow dataObject) {
+
+        UpdateFlowInputBuilder input = new UpdateFlowInputBuilder();
+        UpdatedFlowBuilder updatedflowbuilder = new UpdatedFlowBuilder();
+        updatedflowbuilder.fieldsFrom(dataObject);
+        input.setUpdatedFlow(updatedflowbuilder.build());
+
+        // updating the staticflow cache
+        Integer ordinal = staticFlowsOrdinal.get(0);
+        staticFlowsOrdinal.put(0, ++ordinal);
+        staticFlows.put(ordinal, dataObject);
+
+        // We send flow to the sounthbound plugin
+        flowService.updateFlow(input.build());
+        updateLocalDatabase((NodeFlow) dataObject, true);
+    }
+
     @SuppressWarnings("unchecked")
     private void commitToPlugin(internalTransaction transaction) {
         for (Entry<InstanceIdentifier<?>, Flow> entry : transaction.additions.entrySet()) {
@@ -250,7 +275,7 @@ public class FlowConsumerImpl {
         for (@SuppressWarnings("unused")
         Entry<InstanceIdentifier<?>, Flow> entry : transaction.updates.entrySet()) {
             System.out.println("Coming update cc in FlowDatacommitHandler");
-            // updateFlow(entry.getKey(),entry.getValue());
+            updateFlow(entry.getKey(), entry.getValue());
         }
 
         for (Entry<InstanceIdentifier<?>, Flow> entry : transaction.removals.entrySet()) {
@@ -316,7 +341,7 @@ public class FlowConsumerImpl {
                     logger.error(error);
                     return;
                 }
-                if (originalSwView.containsKey((FlowKey) entry)) {
+                if (originalSwView.containsKey(entry)) {
                     logger.warn("Operation Rejected: A flow with same match and priority exists on the target node");
                     logger.trace("Aborting to install {}", entry);
                     continue;
@@ -463,10 +488,10 @@ public class FlowConsumerImpl {
         public void onFlowUpdated(FlowUpdated notification) {
             updatedFlows.add(notification);
         }
-        
+
         @Override
         public void onSwitchFlowRemoved(SwitchFlowRemoved notification) {
-            //TODO
+            // TODO
         };
 
     }
@@ -526,10 +551,39 @@ public class FlowConsumerImpl {
             FlowConsumerImpl.originalSwView.put((FlowKey) entry, (Flow) entry);
             installedSwView.put((FlowKey) entry, (Flow) entry);
         } else {
-            originalSwView.remove((Flow) entry);
-            installedSwView.remove((FlowKey) entry);
+            originalSwView.remove(entry);
+            installedSwView.remove(entry);
+
+        }
+    }
+
+    @Override
+    public List<DataObject> get() {
 
+        List<DataObject> orderedList = new ArrayList<DataObject>();
+        ConcurrentMap<Integer, Flow> flowMap = staticFlows;
+        int maxKey = staticFlowsOrdinal.get(0).intValue();
+        for (int i = 0; i <= maxKey; i++) {
+            Flow entry = flowMap.get(i);
+            if (entry != null) {
+                orderedList.add(entry);
+            }
+        }
+        return orderedList;
+    }
+
+    @Override
+    public DataObject getWithName(String name, org.opendaylight.controller.sal.core.Node n) {
+        if (this instanceof FlowConsumerImpl) {
+            for (ConcurrentMap.Entry<Integer, Flow> flowEntry : staticFlows.entrySet()) {
+                Flow flow = flowEntry.getValue();
+                if (flow.getNode().equals(n) && flow.getFlowName().equals(name)) {
+
+                    return flowEntry.getValue();
+                }
+            }
         }
+        return null;
     }
 
     /*
@@ -550,7 +604,7 @@ public class FlowConsumerImpl {
         if (add) {
             nodeIndeces.add((Flow) entry);
         } else {
-            nodeIndeces.remove((Flow) entry);
+            nodeIndeces.remove(entry);
         }
 
         // Update cache across cluster
index ce8ee5aaf3564c8a9fb9a7a06d8cce61076670ee..20ab46d4ad5015a71464176ce2299d87ced25ce9 100644 (file)
@@ -1,14 +1,15 @@
 package org.opendaylight.controller.forwardingrulesmanager_mdsal.consumer.impl;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.Map.Entry;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
@@ -17,8 +18,8 @@ import org.opendaylight.controller.clustering.services.CacheExistException;
 import org.opendaylight.controller.clustering.services.IClusterContainerServices;
 import org.opendaylight.controller.clustering.services.IClusterServices;
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
-import org.opendaylight.controller.md.sal.common.api.data.DataModification;
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
 import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.core.IContainer;
 import org.opendaylight.controller.sal.core.Node;
@@ -35,13 +36,10 @@ 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;
@@ -51,10 +49,10 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings("unused")
-public class GroupConsumerImpl {
+public class GroupConsumerImpl implements IForwardingRulesManager {
 
     protected static final Logger logger = LoggerFactory.getLogger(GroupConsumerImpl.class);
-    private GroupEventListener groupEventListener = new GroupEventListener();
+    private final GroupEventListener groupEventListener = new GroupEventListener();
     private Registration<NotificationListener> groupListener;
     private SalGroupService groupService;
     private GroupDataCommitHandler commitHandler;
@@ -69,8 +67,9 @@ 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();
@@ -118,32 +117,36 @@ 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 +155,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 +234,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,39 +282,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;
         }
-         
+
         if (originalSwGroupView.containsKey(groupKey)) {
             originalSwGroupView.remove(groupKey);
             originalSwGroupView.put(groupKey, groupUpdateDataObject);
         }
-        
+
         if (groupUpdateDataObject.isInstall()) {
             UpdateGroupInputBuilder groupData = new UpdateGroupInputBuilder();
             updateGroupBuilder = new UpdatedGroupBuilder();
             updateGroupBuilder.fieldsFrom(groupUpdateDataObject);
             groupData.setUpdatedGroup(updateGroupBuilder.build());
-            //TODO how to get original group and modified group. 
-            
+            // TODO how to get original group and modified group.
+
             if (installedSwGroupView.containsKey(groupKey)) {
                 installedSwGroupView.remove(groupKey);
                 installedSwGroupView.put(groupKey, groupUpdateDataObject);
             }
-            
+
             groupService.updateGroup(groupData.build());
         }
-        
+
         return groupOperationStatus;
     }
-    
+
     /**
      * Adds Group to the southbound plugin and our internal database
      *
@@ -342,26 +345,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(Entry<InstanceIdentifier<?>, Group> entry :transaction.updates.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);
@@ -371,7 +374,8 @@ public class GroupConsumerImpl {
 
         @SuppressWarnings("unchecked")
         @Override
-        public DataCommitTransaction<InstanceIdentifier<?>, DataObject> requestCommit(DataModification<InstanceIdentifier<?>, DataObject> modification) {
+        public DataCommitTransaction<InstanceIdentifier<?>, DataObject> requestCommit(
+                DataModification<InstanceIdentifier<?>, DataObject> modification) {
             // We should verify transaction
             System.out.println("Coming in GroupDatacommitHandler");
             internalTransaction transaction = new internalTransaction(modification);
@@ -483,4 +487,31 @@ public class GroupConsumerImpl {
 
         }
     }
+
+    @Override
+    public List<DataObject> get() {
+
+        List<DataObject> orderedList = new ArrayList<DataObject>();
+        Collection<Group> groupList = originalSwGroupView.values();
+        for (Iterator<Group> iterator = groupList.iterator(); iterator.hasNext();) {
+            orderedList.add(iterator.next());
+        }
+        return orderedList;
+    }
+
+    @Override
+    public DataObject getWithName(String name, Node n) {
+
+        if (this instanceof GroupConsumerImpl) {
+            Collection<Group> groupList = originalSwGroupView.values();
+            for (Iterator<Group> iterator = groupList.iterator(); iterator.hasNext();) {
+                Group group = iterator.next();
+                if (group.getNode().equals(n) && group.getGroupName().equals(name)) {
+
+                    return group;
+                }
+            }
+        }
+        return null;
+    }
 }
diff --git a/opendaylight/forwardingrulesmanager_mdsal/openflow/src/main/java/org/opendaylight/controller/forwardingrulesmanager_mdsal/consumer/impl/IForwardingRulesManager.java b/opendaylight/forwardingrulesmanager_mdsal/openflow/src/main/java/org/opendaylight/controller/forwardingrulesmanager_mdsal/consumer/impl/IForwardingRulesManager.java
new file mode 100644 (file)
index 0000000..fa279bc
--- /dev/null
@@ -0,0 +1,33 @@
+package org.opendaylight.controller.forwardingrulesmanager_mdsal.consumer.impl;
+
+import java.util.List;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * Interface that describes methods for accessing the flows database.
+ */
+public interface IForwardingRulesManager {
+
+    /**
+     * Returns the specifications of all the flows configured for all the
+     * switches on the current container
+     *
+     * @return the list of flow configurations present in the database
+     */
+    public List<DataObject> get();
+
+    /**
+     * Returns the specification of the flow configured for the given network
+     * node on the current container
+     *
+     * @param name
+     *            the flow name
+     * @param n
+     *            the network node identifier
+     * @return the {@code FlowConfig} object
+     */
+    public DataObject getWithName(String name, Node n);
+
+}
index c69b60bb62f91b3cbb866032b5ede29232145120..34adc28fc5453c8816d4cab752020728d4589ded 100644 (file)
@@ -1,13 +1,15 @@
 package org.opendaylight.controller.forwardingrulesmanager_mdsal.consumer.impl;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.Map.Entry;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
@@ -16,8 +18,8 @@ import org.opendaylight.controller.clustering.services.CacheExistException;
 import org.opendaylight.controller.clustering.services.IClusterContainerServices;
 import org.opendaylight.controller.clustering.services.IClusterServices;
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
-import org.opendaylight.controller.md.sal.common.api.data.DataModification;
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
 import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.core.IContainer;
 import org.opendaylight.controller.sal.core.Node;
@@ -25,6 +27,7 @@ import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.Meters;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.meters.Meter;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.meters.MeterKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterAdded;
@@ -38,7 +41,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.
 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;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.Experimenter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.meters.Meter;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -47,9 +49,9 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class MeterConsumerImpl {
+public class MeterConsumerImpl implements IForwardingRulesManager {
     protected static final Logger logger = LoggerFactory.getLogger(MeterConsumerImpl.class);
-    private MeterEventListener meterEventListener = new MeterEventListener();
+    private final MeterEventListener meterEventListener = new MeterEventListener();
     private Registration<NotificationListener> meterListener;
     private SalMeterService meterService;
     private MeterDataCommitHandler commitHandler;
@@ -64,8 +66,9 @@ 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,10 +221,9 @@ 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");
         }
 
@@ -235,35 +237,32 @@ public class MeterConsumerImpl {
      *
      * @param dataObject
      */
-    private Status updateMeter(InstanceIdentifier<?> path, Meter meterUpdateDataObject) {        
+    private Status updateMeter(InstanceIdentifier<?> path, Meter meterUpdateDataObject) {
         MeterKey meterKey = meterUpdateDataObject.getKey();
         UpdatedMeterBuilder updateMeterBuilder = null;
-        
-        
-        if (null != meterKey && 
-                validateMeter(meterUpdateDataObject, FRMUtil.operation.UPDATE).isSuccess()) {
-            
+
+        if (null != meterKey && validateMeter(meterUpdateDataObject, FRMUtil.operation.UPDATE).isSuccess()) {
+
             if (originalSwMeterView.containsKey(meterKey)) {
                 originalSwMeterView.remove(meterKey);
                 originalSwMeterView.put(meterKey, meterUpdateDataObject);
             }
-            
+
             if (meterUpdateDataObject.isInstall()) {
-                UpdateMeterInputBuilder updateMeterInputBuilder = new UpdateMeterInputBuilder(); 
+                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 {
+
+        } else {
             return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
         }
 
@@ -277,21 +276,19 @@ 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();                
-                
+                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");
         }
 
@@ -525,4 +522,30 @@ public class MeterConsumerImpl {
 
         }
     }
+
+    @Override
+    public List<DataObject> get() {
+
+        List<DataObject> orderedList = new ArrayList<DataObject>();
+        Collection<Meter> meterList = originalSwMeterView.values();
+        for (Iterator<Meter> iterator = meterList.iterator(); iterator.hasNext();) {
+            orderedList.add(iterator.next());
+        }
+        return orderedList;
+    }
+
+    @Override
+    public DataObject getWithName(String name, Node n) {
+        if (this instanceof MeterConsumerImpl) {
+            Collection<Meter> meterList = originalSwMeterView.values();
+            for (Iterator<Meter> iterator = meterList.iterator(); iterator.hasNext();) {
+                Meter meter = iterator.next();
+                if (meter.getNode().equals(n) && meter.getMeterName().equals(name)) {
+
+                    return meter;
+                }
+            }
+        }
+        return null;
+    }
 }