Fixed add/delete/modify RPC for group/flow/remove reach the test provider
[controller.git] / opendaylight / md-sal / forwardingrules-manager / src / main / java / org / opendaylight / controller / forwardingrulesmanager / consumer / impl / GroupConsumerImpl.java
index 851e7d9b2685420b5093d8771770a64a3fe52250..f4064f22ceeeda56740468d11451da999d6a1a5d 100644 (file)
@@ -2,6 +2,7 @@ package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -33,52 +34,40 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.Add
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupAdded;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupRemoved;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder;
 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.group.update.OriginalGroupBuilder;
 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.GroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
 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.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings("unused")
-public class GroupConsumerImpl implements IForwardingRulesManager {
+public class GroupConsumerImpl {
 
     protected static final Logger logger = LoggerFactory.getLogger(GroupConsumerImpl.class);
     private final GroupEventListener groupEventListener = new GroupEventListener();
     private Registration<NotificationListener> groupListener;
     private SalGroupService groupService;
-    private GroupDataCommitHandler commitHandler;
+    private GroupDataCommitHandler groupCommitHandler;
 
-    private ConcurrentMap<GroupKey, Group> originalSwGroupView;
-    private ConcurrentMap<GroupKey, Group> installedSwGroupView;
-
-    private ConcurrentMap<Node, List<Group>> nodeGroups;
-    private ConcurrentMap<GroupKey, Group> inactiveGroups;
-
-    private IClusterContainerServices clusterGroupContainerService = null;
     private IContainer container;
 
     public GroupConsumerImpl() {
 
-        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Groups.class).child(Group.class)
-                .toInstance();
-        groupService = FRMConsumerImpl.getProviderSession().getRpcService(SalGroupService.class);
-
-        clusterGroupContainerService = FRMConsumerImpl.getClusterContainerService();
-        container = FRMConsumerImpl.getContainer();
-
-        if (!(cacheStartup())) {
-            logger.error("Unanle to allocate/retrieve group cache");
-            System.out.println("Unable to allocate/retrieve group cache");
-        }
+        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Groups.class).toInstance();
+        groupService = FRMConsumerImpl.getProviderSession().getRpcService(SalGroupService.class);      
 
         if (null == groupService) {
             logger.error("Consumer SAL Group Service is down or NULL. FRM may not function as intended");
@@ -95,148 +84,25 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
             return;
         }
 
-        commitHandler = new GroupDataCommitHandler();
-        FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, commitHandler);
-    }
-
-    private boolean allocateGroupCaches() {
-        if (this.clusterGroupContainerService == null) {
-            logger.warn("Group: Un-initialized clusterGroupContainerService, can't create cache");
-            return false;
-        }
-
-        try {
-            clusterGroupContainerService.createCache("frm.originalSwGroupView",
-                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
-
-            clusterGroupContainerService.createCache("frm.installedSwGroupView",
-                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
-
-            clusterGroupContainerService.createCache("frm.inactiveGroups",
-                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
-
-            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) {
-            logger.error("Group CacheConfigException");
-            return false;
-
-        } catch (CacheExistException cce) {
-            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>>();
-        inactiveGroups = new ConcurrentHashMap<GroupKey, Group>();
-    }
-
-    @SuppressWarnings({ "unchecked" })
-    private boolean retrieveGroupCaches() {
-        ConcurrentMap<?, ?> map;
-
-        if (this.clusterGroupContainerService == null) {
-            logger.warn("Group: un-initialized clusterGroupContainerService, can't retrieve cache");
-            nonClusterGroupObjectCreate();
-            return false;
-        }
+        groupCommitHandler = new GroupDataCommitHandler();
+        FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, groupCommitHandler);
+    }  
 
-        map = clusterGroupContainerService.getCache("frm.originalSwGroupView");
-        if (map != null) {
-            originalSwGroupView = (ConcurrentMap<GroupKey, Group>) map;
-        } else {
-            logger.error("Retrieval of cache(originalSwGroupView) failed");
-            return false;
-        }
-
-        map = clusterGroupContainerService.getCache("frm.installedSwGroupView");
-        if (map != null) {
-            installedSwGroupView = (ConcurrentMap<GroupKey, Group>) map;
-        } else {
-            logger.error("Retrieval of cache(installedSwGroupView) failed");
-            return false;
-        }
-
-        map = clusterGroupContainerService.getCache("frm.inactiveGroups");
-        if (map != null) {
-            inactiveGroups = (ConcurrentMap<GroupKey, Group>) map;
-        } else {
-            logger.error("Retrieval of cache(inactiveGroups) failed");
-            return false;
-        }
-
-        map = clusterGroupContainerService.getCache("frm.nodeGroups");
-        if (map != null) {
-            nodeGroups = (ConcurrentMap<Node, List<Group>>) map;
-        } else {
-            logger.error("Retrieval of cache(nodeGroup) failed");
-            return false;
-        }
-
-        return true;
-    }
-
-    private boolean cacheStartup() {
-        if (allocateGroupCaches()) {
-            if (retrieveGroupCaches()) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    public Status validateGroup(Group group, FRMUtil.operation operation) {
-        String containerName;
+    public Status validateGroup(Group group) {        
         String groupName;
         Iterator<Bucket> bucketIterator;
         boolean returnResult;
         Buckets groupBuckets;
 
-        if (null != group) {
-            containerName = group.getContainerName();
-
-            if (null == containerName) {
-                containerName = GlobalConstants.DEFAULT.toString();
-            } else if (!FRMUtil.isNameValid(containerName)) {
-                logger.error("Container Name is invalid %s" + containerName);
-                return new Status(StatusCode.BADREQUEST, "Container Name is invalid");
-            }
-
+        if (null != group) {   
             groupName = group.getGroupName();
             if (!FRMUtil.isNameValid(groupName)) {
                 logger.error("Group Name is invalid %s" + groupName);
                 return new Status(StatusCode.BADREQUEST, "Group Name is invalid");
             }
-
-            returnResult = doesGroupEntryExists(group.getKey(), groupName, containerName);
-
-            if (FRMUtil.operation.ADD == operation && returnResult) {
-                logger.error("Record with same Group Name exists");
-                return new Status(StatusCode.BADREQUEST, "Group record exists");
-            } else if (!returnResult) {
-                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() >= GroupTypes.GroupAll.getIntValue() && group.getGroupType()
+                    .getIntValue() <= GroupTypes.GroupFf.getIntValue())) {
                 logger.error("Invalid Group type %d" + group.getGroupType().getIntValue());
                 return new Status(StatusCode.BADREQUEST, "Invalid Group type");
             }
@@ -256,22 +122,6 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
         }
 
         return new Status(StatusCode.SUCCESS);
-
-    }
-
-    private boolean doesGroupEntryExists(GroupKey key, String groupName, String containerName) {
-        if (!originalSwGroupView.containsKey(key)) {
-            return false;
-        }
-
-        for (ConcurrentMap.Entry<GroupKey, Group> entry : originalSwGroupView.entrySet()) {
-            if (entry.getValue().getGroupName().equals(groupName)) {
-                if (entry.getValue().getContainerName().equals(containerName)) {
-                    return true;
-                }
-            }
-        }
-        return false;
     }
 
     /**
@@ -281,38 +131,25 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
      * @param path
      * @param dataObject
      */
-    private Status updateGroup(InstanceIdentifier<?> path, Group groupUpdateDataObject) {
-        GroupKey groupKey = groupUpdateDataObject.getKey();
+    private void updateGroup(InstanceIdentifier<?> path, 
+        Group updatedGroupDataObject, Group originalGroupDataObject) {
         UpdatedGroupBuilder updateGroupBuilder = null;
-
-        Status groupOperationStatus = validateGroup(groupUpdateDataObject, FRMUtil.operation.UPDATE);
-
+        Status groupOperationStatus = validateGroup(updatedGroupDataObject);
+        
         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.
-
-            if (installedSwGroupView.containsKey(groupKey)) {
-                installedSwGroupView.remove(groupKey);
-                installedSwGroupView.put(groupKey, groupUpdateDataObject);
-            }
-
-            groupService.updateGroup(groupData.build());
+            logger.error("Group data object validation failed %s" + updatedGroupDataObject.getGroupName());
+            return;
         }
-
-        return groupOperationStatus;
+        
+        UpdateGroupInputBuilder groupInputBuilder = new UpdateGroupInputBuilder();        
+        updateGroupBuilder = new UpdatedGroupBuilder(updatedGroupDataObject);        
+        updateGroupBuilder.setGroupId(new GroupId(updatedGroupDataObject.getId())); 
+        groupInputBuilder.setNode(updatedGroupDataObject.getNode());
+        groupInputBuilder.setUpdatedGroup(updateGroupBuilder.build());       
+        OriginalGroupBuilder originalGroupBuilder = new OriginalGroupBuilder(originalGroupDataObject);
+        groupInputBuilder.setOriginalGroup(originalGroupBuilder.build());     
+        groupService.updateGroup(groupInputBuilder.build());
+        return;
     }
 
     /**
@@ -321,119 +158,115 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
      * @param path
      * @param dataObject
      */
-    private Status addGroup(InstanceIdentifier<?> path, Group groupAddDataObject) {
+    private void addGroup(InstanceIdentifier<?> path, Group groupAddDataObject) {
         GroupKey groupKey = groupAddDataObject.getKey();
-        Status groupOperationStatus = validateGroup(groupAddDataObject, FRMUtil.operation.ADD);
+        Status groupOperationStatus = validateGroup(groupAddDataObject);
 
         if (!groupOperationStatus.isSuccess()) {
             logger.error("Group data object validation failed %s" + groupAddDataObject.getGroupName());
-            return groupOperationStatus;
-        }
-
-        originalSwGroupView.put(groupKey, groupAddDataObject);
-
-        if (groupAddDataObject.isInstall()) {
-            AddGroupInputBuilder groupData = new AddGroupInputBuilder();
-            groupData.setBuckets(groupAddDataObject.getBuckets());
-            groupData.setContainerName(groupAddDataObject.getContainerName());
-            groupData.setGroupId(groupAddDataObject.getGroupId());
-            groupData.setGroupType(groupAddDataObject.getGroupType());
-            groupData.setNode(groupAddDataObject.getNode());
-            installedSwGroupView.put(groupKey, groupAddDataObject);
-            groupService.addGroup(groupData.build());
+            return;
         }
-
-        return groupOperationStatus;
+        
+        AddGroupInputBuilder groupData = new AddGroupInputBuilder();
+        groupData.fieldsFrom(groupAddDataObject);       
+        groupData.setGroupId(new GroupId(groupAddDataObject.getId()));     
+        groupData.setNode(groupAddDataObject.getNode());    
+        groupService.addGroup(groupData.build());
+        return;
     }
 
-    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()) {
-                transaction.updates.remove(entry.getKey());
-                return Rpcs.getRpcResult(false, null, null);
-            }
-        }
+    /**
+     * Remove Group to the southbound plugin and our internal database
+     *
+     * @param path
+     * @param dataObject
+     */
+    private void removeGroup(InstanceIdentifier<?> path, Group groupRemoveDataObject) {
+        GroupKey groupKey = groupRemoveDataObject.getKey();
+        Status groupOperationStatus = validateGroup(groupRemoveDataObject);
 
-        for (InstanceIdentifier<?> removal : transaction.removals) {
-            // removeFlow(removal);
+        if (!groupOperationStatus.isSuccess()) {
+            logger.error("Group data object validation failed %s" + groupRemoveDataObject.getGroupName());
+            return;
         }
-
-        return Rpcs.getRpcResult(true, null, null);
+       
+        RemoveGroupInputBuilder groupData = new RemoveGroupInputBuilder();
+        groupData.fieldsFrom(groupRemoveDataObject);
+        groupData.setGroupId(new GroupId(groupRemoveDataObject.getId()));    
+        groupData.setNode(groupRemoveDataObject.getNode());
+        groupService.removeGroup(groupData.build());  
+        return;
+    }
+    
+    private RpcResult<Void> commitToPlugin(InternalTransaction transaction) {
+        DataModification<InstanceIdentifier<?>, DataObject> modification = transaction.modification;         
+        //get created entries      
+        Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries = 
+                                        modification.getCreatedConfigurationData().entrySet();
+        
+        //get updated entries
+        Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updatedEntries = 
+                    new HashSet<Entry<InstanceIdentifier<? extends DataObject>, DataObject>>(); 
+        
+        updatedEntries.addAll(modification.getUpdatedConfigurationData().entrySet());
+        updatedEntries.removeAll(createdEntries);
+
+        //get removed entries
+        Set<InstanceIdentifier<? extends DataObject>> removeEntriesInstanceIdentifiers = 
+                                                    modification.getRemovedConfigurationData();
+        
+        for (Entry<InstanceIdentifier<? extends DataObject >, DataObject> entry : createdEntries) { 
+            if(entry.getValue() instanceof Group) {   
+                addGroup(entry.getKey(), (Group)entry.getValue());   
+            }   
+        } 
+        
+        for (Entry<InstanceIdentifier<?>, DataObject> entry : updatedEntries) { 
+            if(entry.getValue() instanceof Group) {   
+                Group originalGroup = (Group) modification.getOriginalConfigurationData().get(entry.getKey());    
+                Group updatedGroup = (Group) entry.getValue(); 
+                updateGroup(entry.getKey(), originalGroup, updatedGroup);   
+            }   
+        }   
+
+        for (InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers ) {    
+            DataObject removeValue = modification.getOriginalConfigurationData().get(instanceId);   
+            if(removeValue instanceof Group) {   
+                removeGroup(instanceId, (Group)removeValue); 
+            }   
+        }
+
+        return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
     }
 
     private final class GroupDataCommitHandler implements DataCommitHandler<InstanceIdentifier<?>, DataObject> {
 
-        @SuppressWarnings("unchecked")
         @Override
         public DataCommitTransaction<InstanceIdentifier<?>, DataObject> requestCommit(
-                DataModification<InstanceIdentifier<?>, DataObject> modification) {
-            // We should verify transaction
-            System.out.println("Coming in GroupDatacommitHandler");
-            internalTransaction transaction = new internalTransaction(modification);
+                DataModification<InstanceIdentifier<?>, DataObject> modification) {            
+            InternalTransaction transaction = new InternalTransaction(modification);
             transaction.prepareUpdate();
             return transaction;
         }
     }
 
-    private final class internalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {
+    private final class InternalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {      
 
         private final DataModification<InstanceIdentifier<?>, DataObject> modification;
-
-        @Override
-        public DataModification<InstanceIdentifier<?>, DataObject> getModification() {
-            return modification;
-        }
-
-        public internalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {
+        
+        public InternalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {   
             this.modification = modification;
         }
-
-        Map<InstanceIdentifier<?>, Group> additions = new HashMap<>();
-        Map<InstanceIdentifier<?>, Group> updates = new HashMap<>();
-        Set<InstanceIdentifier<?>> removals = new HashSet<>();
-
+        
         /**
          * We create a plan which flows will be added, which will be updated and
          * which will be removed based on our internal state.
          *
          */
         void prepareUpdate() {
-
-            Set<Entry<InstanceIdentifier<?>, DataObject>> puts = modification.getUpdatedConfigurationData().entrySet();
-            for (Entry<InstanceIdentifier<?>, DataObject> entry : puts) {
-                if (entry.getValue() instanceof Group) {
-                    Group group = (Group) entry.getValue();
-                    preparePutEntry(entry.getKey(), group);
-                }
-
-            }
-
-            removals = modification.getRemovedConfigurationData();
+               
         }
-
-        private void preparePutEntry(InstanceIdentifier<?> key, Group group) {
-
-            Group original = originalSwGroupView.get(key);
-            if (original != null) {
-                // It is update for us
-
-                updates.put(key, group);
-            } else {
-                // It is addition for us
-
-                additions.put(key, group);
-            }
-        }
-
+        
         /**
          * We are OK to go with execution of plan
          *
@@ -441,9 +274,7 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
         @Override
         public RpcResult<Void> finish() throws IllegalStateException {
 
-            RpcResult<Void> rpcStatus = commitToPlugin(this);
-            // We return true if internal transaction is successful.
-            // return Rpcs.getRpcResult(true, null, Collections.emptySet());
+            RpcResult<Void> rpcStatus = commitToPlugin(this);            
             return rpcStatus;
         }
 
@@ -453,12 +284,15 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
          *
          */
         @Override
-        public RpcResult<Void> rollback() throws IllegalStateException {
-            // NOOP - we did not modified any internal state during
-            // requestCommit phase
-            // return Rpcs.getRpcResult(true, null, Collections.emptySet());
-            return Rpcs.getRpcResult(true, null, null);
+        public RpcResult<Void> rollback() throws IllegalStateException { 
+            
+            ///needs to be implemented as per gerrit 3314
+            return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
+        }
 
+        @Override
+        public DataModification<InstanceIdentifier<?>, DataObject> getModification() {            
+            return modification;
         }
 
     }
@@ -471,7 +305,6 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
 
         @Override
         public void onGroupAdded(GroupAdded notification) {
-            System.out.println("added Group..........................");
             addedGroups.add(notification);
         }
 
@@ -487,31 +320,4 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
 
         }
     }
-
-    @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;
-    }
-}
+ }