Refactor and fix TenantManage for repeated queries 20/30520/1
authorGary Wu <gary.wu1@huawei.com>
Thu, 3 Dec 2015 01:05:13 +0000 (17:05 -0800)
committerGary Wu <gary.wu1@huawei.com>
Thu, 3 Dec 2015 01:05:13 +0000 (17:05 -0800)
Refactor and fix TenantManage so that when repeated
requests are made to getUsers(), the data is
re-queried from MD-SAL.

Change-Id: I7fd97d491ba7799a73d432bcdce12589c2bb4a21
Signed-off-by: Gary Wu <gary.wu1@huawei.com>
nemo-impl/src/main/java/org/opendaylight/nemo/user/tenantmanager/AAA.java
nemo-impl/src/main/java/org/opendaylight/nemo/user/tenantmanager/RegisterUser.java
nemo-impl/src/main/java/org/opendaylight/nemo/user/tenantmanager/TenantManage.java
nemo-impl/src/test/java/org/opendaylight/nemo/user/tenantmanager/AAATest.java
nemo-impl/src/test/java/org/opendaylight/nemo/user/tenantmanager/RegisterUserTest.java
nemo-impl/src/test/java/org/opendaylight/nemo/user/tenantmanager/TenantManageTest.java

index 51e693e035fbef15188a3c56a21cc467491d01a8..3af90fcf2a8e95d7195aa816b4e7c9a661ccea9a 100644 (file)
@@ -36,12 +36,11 @@ public class AAA {
 \r
     private String checkUser(UserId userId, UserName userName, UserPassword userPassword, UserRoleName userRoleName)\r
     {\r
-        tenantManage.fetchUsers();\r
         final Map<UserId, User> users = tenantManage.getUsers();\r
         String errorInfo = null;\r
-        final User user = users.get(userId);\r
+        final User user = (users != null) ? users.get(userId) : null;\r
 \r
-        if (users.containsKey(userId) && user != null) {\r
+        if (user != null) {\r
             if (!user.getUserName().equals(userName)) {\r
                 errorInfo = "The user name is not right.";\r
             } else if (!user.getUserPassword().equals(userPassword)) {\r
@@ -49,6 +48,7 @@ public class AAA {
             } else if (!user.getUserRole().equals(userRoleName)) {\r
                 errorInfo = "The role is not right.";\r
             }\r
+\r
         } else {\r
             errorInfo = "The user is not exist.";\r
         }\r
index 5dbf6a04aa6339b94ee925ee331fbca2a3da845b..4559649f0b38de384dfe58f46ff3d2278d72e54e 100644 (file)
@@ -30,12 +30,10 @@ public class RegisterUser {
     {\r
         String errorInfo = null;\r
 \r
-        tenantManage.fetchUserRoles();\r
         Map<UserRoleName, UserRole> userRoles = tenantManage.getUserRoles();\r
-        tenantManage.fetchUsers();\r
         Map<UserId, User> users = tenantManage.getUsers();\r
 \r
-        if (userRoles.isEmpty())\r
+        if (userRoles == null || userRoles.isEmpty())\r
         {\r
             errorInfo = "There are no roles be defined.";\r
         }\r
@@ -43,7 +41,7 @@ public class RegisterUser {
         {\r
             if (userRoles.containsKey(input.getUserRole()))\r
             {\r
-                if (users.containsKey(input.getUserId()))\r
+                if (users != null && users.containsKey(input.getUserId()))\r
                 {\r
                     errorInfo = "The user has been registered.";\r
                 }\r
index cbf22e1fe1fc180fece9eea91e5e13407a7e15ef..6bacfb9357f13170634ca9b5088f1effffc02f89 100644 (file)
@@ -8,11 +8,8 @@
 package org.opendaylight.nemo.user.tenantmanager;\r
 \r
 import java.util.HashMap;\r
-import java.util.List;\r
 import java.util.Map;\r
 import java.util.concurrent.ExecutionException;\r
-import java.util.concurrent.TimeUnit;\r
-import java.util.concurrent.TimeoutException;\r
 \r
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
@@ -31,12 +28,13 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
 \r
+import com.google.common.base.Function;\r
 import com.google.common.base.Optional;\r
+import com.google.common.collect.Maps;\r
 import com.google.common.util.concurrent.CheckedFuture;\r
 import com.google.common.util.concurrent.FutureCallback;\r
 import com.google.common.util.concurrent.Futures;\r
 import com.google.common.util.concurrent.ListenableFuture;\r
-import com.google.common.util.concurrent.SettableFuture;\r
 \r
 /**\r
  * Created by z00293636 on 2015/8/29.\r
@@ -46,8 +44,6 @@ import com.google.common.util.concurrent.SettableFuture;
 public class TenantManage {\r
     private static final Logger LOG = LoggerFactory.getLogger(TenantManage.class);\r
     private DataBroker dataBroker;\r
-    private final SettableFuture<List<UserRole>> userRoleListFuture = SettableFuture.create();\r
-    private final SettableFuture<List<User>> usersListFuture = SettableFuture.create();\r
     private User user;\r
 \r
     public TenantManage(DataBroker dataBroker)\r
@@ -55,121 +51,87 @@ public class TenantManage {
         this.dataBroker = dataBroker;\r
     }\r
 \r
-    private void setUserRoleList(List<UserRole> userRoleList)\r
-    {\r
-        this.userRoleListFuture.set(userRoleList);\r
-    }\r
-\r
-    private void setUserList(List<User> userList)\r
-    {\r
-        this.usersListFuture.set(userList);\r
-    }\r
-\r
     private void setUser(User user)\r
     {\r
         this.user = user;\r
     }\r
 \r
-    public List<UserRole> getUserRoleList() {\r
-        try {\r
-            return userRoleListFuture.get(1, TimeUnit.SECONDS);\r
-        } catch (InterruptedException | ExecutionException | TimeoutException e) {\r
-            LOG.error("Cannot read role information.", e);\r
-            return null;\r
-        }\r
+    public User getUser()\r
+    {\r
+        return user;\r
     }\r
 \r
     /**\r
      *\r
-     * @return Map from UserRoleName to UserRole.  If no roles exist, an empty (not-null) map is returned.\r
+     * @return null if an error was encountered, or an empty map if there was no\r
+     *         error but no data was retrieved.\r
      */\r
     public Map<UserRoleName, UserRole> getUserRoles() {\r
-        final Map<UserRoleName, UserRole> map = new HashMap<>();\r
-        final List<UserRole> userRoleList = getUserRoleList();\r
-        if (userRoleList != null) {\r
-            for (UserRole role : userRoleList) {\r
-                map.put(role.getRoleName(), role);\r
-            }\r
-        }\r
-        return map;\r
-    }\r
 \r
-    public List<User> getUsersList() {\r
+        InstanceIdentifier<UserRoles> userRolesInsId = InstanceIdentifier.builder(UserRoles.class).build();\r
+        ListenableFuture<Optional<UserRoles>> userRolesFuture = this.dataBroker.newReadOnlyTransaction().read(\r
+                LogicalDatastoreType.CONFIGURATION, userRolesInsId);\r
+\r
+        final Optional<UserRoles> userRolesOpt;\r
         try {\r
-            return usersListFuture.get(1, TimeUnit.SECONDS);\r
-        } catch (InterruptedException | ExecutionException | TimeoutException e) {\r
-            LOG.error("Cannot read user information.", e);\r
+            // TODO: consider time out here?\r
+            userRolesOpt = userRolesFuture.get();\r
+        } catch (InterruptedException | ExecutionException e) {\r
+            LOG.error("Cannot read role information.", e);\r
             return null;\r
         }\r
-    }\r
-\r
-    /**\r
-     *\r
-     * @return Map from UserId to User.  If no users exist, an empty (not-null) map is returned.\r
-     */\r
-    public Map<UserId, User> getUsers()\r
-    {\r
-        final Map<UserId, User> map = new HashMap<>();\r
-        final List<User> userList = getUsersList();\r
-        if (userList != null) {\r
-            for (User user : userList) {\r
-                map.put(user.getUserId(), user);\r
-            }\r
-        }\r
-        return map;\r
-    }\r
-\r
-    public User getUser()\r
-    {\r
-        return user;\r
-    }\r
-\r
-    public void fetchUserRoles(){\r
-\r
-        InstanceIdentifier<UserRoles> userRolesInsId = InstanceIdentifier.builder(UserRoles.class).build();\r
-        ListenableFuture<Optional<UserRoles>> userRolesFuture = this.dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, userRolesInsId);\r
-        Futures.addCallback(userRolesFuture, new FutureCallback<Optional<UserRoles>>() {\r
-            @Override\r
-            public void onSuccess(Optional<UserRoles> result)\r
-            {\r
-                setUserRoleList(result.get().getUserRole());\r
-            }\r
 \r
+        // TODO: change to Java 8 lambda expressions\r
+        return userRolesOpt.transform(new Function<UserRoles, Map<UserRoleName, UserRole>>() {\r
             @Override\r
-            public void onFailure(Throwable t)\r
-            {\r
-                LOG.error("Can not read role information.", t);\r
+            public Map<UserRoleName, UserRole> apply(UserRoles input) {\r
+                return Maps.uniqueIndex(input.getUserRole(), new Function<UserRole, UserRoleName>() {\r
+                    @Override\r
+                    public UserRoleName apply(UserRole role) {\r
+                        return role.getRoleName();\r
+                    }\r
+                });\r
             }\r
-        });\r
+        }).or(new HashMap<UserRoleName, UserRole>());\r
     }\r
 \r
-    public void fetchUsers(){\r
+    /**\r
+    *\r
+    * @return null if an error was encountered, or an empty map if there was no\r
+    *         error but no data was retrieved.\r
+    */\r
+    public Map<UserId, User> getUsers() {\r
         InstanceIdentifier<Users> usersInsId = InstanceIdentifier.builder(Users.class).build();\r
-        ListenableFuture<Optional<Users>> usersFuture = dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, usersInsId);\r
-        Futures.addCallback(usersFuture, new FutureCallback<Optional<Users>>() {\r
-            @Override\r
-            public void onSuccess(Optional<Users> result)\r
-            {\r
-                setUserList(result.get().getUser());\r
-            }\r
+        ListenableFuture<Optional<Users>> usersFuture = dataBroker.newReadOnlyTransaction().read(\r
+                LogicalDatastoreType.CONFIGURATION, usersInsId);\r
+\r
+        final Optional<Users> usersOpt;\r
+        try {\r
+            // TODO: consider time out here?\r
+            usersOpt = usersFuture.get();\r
+        } catch (InterruptedException | ExecutionException e) {\r
+            LOG.error("Cannot read user information.", e);\r
+            return null;\r
+        }\r
 \r
+        // TODO: change to Java 8 lambda expressions\r
+        return usersOpt.transform(new Function<Users, Map<UserId, User>>() {\r
             @Override\r
-            public void onFailure(Throwable t)\r
-            {\r
-                LOG.error("Can not read users information.", t);\r
+            public Map<UserId, User> apply(Users input) {\r
+                return Maps.uniqueIndex(input.getUser(), new Function<User, UserId>() {\r
+                    @Override\r
+                    public UserId apply(User user) {\r
+                        return user.getUserId();\r
+                    }\r
+                });\r
             }\r
-        });\r
+        }).or(new HashMap<UserId, User>());\r
     }\r
 \r
     public void fetchVNSpace(UserId userId)\r
     {\r
-        fetchUsers();\r
         final Map<UserId, User> users = getUsers();\r
-\r
-        User user = users.get(userId);\r
-        if (users.containsKey(userId) && user != null) {\r
-            setUser(user);\r
-        }\r
+        setUser((users != null) ? users.get(userId) : null);\r
     }\r
 \r
     public void addUser(RegisterUserInput registerUserInput){\r
index 24f50ac385ad35da9ab550ed53440ead1ae1653b..7fd37f07d499d540460721b28407ed344df5b5a2 100644 (file)
 */
 package org.opendaylight.nemo.user.tenantmanager;
 
-import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+
 import junit.framework.TestCase;
 
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.user.rev151010.UserInstance;
 
 /**
@@ -43,11 +47,9 @@ public class AAATest extends TestCase {
 
     @Test
     public void testCheckUser() throws Exception {
-        doNothing().when(tenantManage).fetchUsers();
-        when(tenantManage.getUsersList()).thenReturn(null);
+        when(tenantManage.getUsers()).thenReturn(new HashMap<UserId, User>());
         String acutal = aaa.checkUser(userInstance);
         String expected = "The user is not exist.";
-        verify(tenantManage).fetchUsers();
         verify(tenantManage).getUsers();
         Assert.assertNotNull(aaa);
         Assert.assertEquals(expected,acutal);
index 26ce1765d016f3c17339451f2badbdb07c799b01..b98400bf5b29eb90ec61f520a0c13c11706dea02 100644 (file)
 package org.opendaylight.nemo.user.tenantmanager;
 
 
-import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import java.util.LinkedList;
+import java.util.HashMap;
 
 import junit.framework.TestCase;
 
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserRoleName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.RegisterUserInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;
@@ -51,15 +51,13 @@ public class RegisterUserTest extends TestCase {
     public void testRegisterUser() throws Exception {
 
         //no data test
-        doNothing().when(tenantManage).fetchUserRoles();
-        when(tenantManage.getUserRoleList()).thenReturn(null);//return nothing
-        doNothing().when(tenantManage).fetchUsers();
-        when(tenantManage.getUsersList()).thenReturn(null);
+        when(tenantManage.getUserRoles()).thenReturn(null);//return nothing
+        when(tenantManage.getUsers()).thenReturn(null);
         registerUser.registerUser(input);
 
         //data exists . and test other branch
-        when(tenantManage.getUserRoleList()).thenReturn(new LinkedList<UserRole>());//return nothing
-        when(tenantManage.getUsersList()).thenReturn(new LinkedList<User>());
+        when(tenantManage.getUserRoles()).thenReturn(new HashMap<UserRoleName, UserRole>());//return nothing
+        when(tenantManage.getUsers()).thenReturn(new HashMap<UserId, User>());
         when(input.getUserRole()).thenReturn(mock(UserRoleName.class));
         registerUser.registerUser(input);
 
index f1ba81b3a3ff5b452eff4a363f6ed0b40c934751..9d9b2df61815daaf2b61e7b3d3c66605a84f830b 100644 (file)
@@ -19,8 +19,8 @@ import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import java.util.LinkedList;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
 
 import junit.framework.TestCase;
 
@@ -32,11 +32,13 @@ import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserRoleName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.RegisterUserInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.user.rev151010.user.roles.UserRole;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
+import com.google.common.base.Optional;
 import com.google.common.util.concurrent.CheckedFuture;
 /**
  * Created by zhangmeng on 2015/11/20.
@@ -44,33 +46,20 @@ import com.google.common.util.concurrent.CheckedFuture;
 public class TenantManageTest extends TestCase {
     private TenantManage tenantManage;
     private DataBroker dataBroker;
-    private List<UserRole> userRoleList;
-    private List<User> usersList ;
+    private Map<UserRoleName, UserRole> userRoles;
+    private Map<UserId, User> users ;
     private User user;
+    @Override
     @Before
     public void setUp() throws Exception {
-        userRoleList = new LinkedList<UserRole>();
-        usersList = new LinkedList<User>();
+        userRoles = new HashMap<UserRoleName, UserRole>();
+        users = new HashMap<UserId, User>();
         user = mock(User.class);
 
         dataBroker = mock(DataBroker.class);
         tenantManage = new TenantManage(dataBroker);
     }
 
-    @Test
-    public void testGetUserRoleList() throws Exception {
-        Assert.assertNotNull(userRoleList);
-        userRoleList = tenantManage.getUserRoleList();
-        Assert.assertNotEquals(new LinkedList<UserRole>(),userRoleList);
-    }
-
-    @Test
-    public void testGetUsersList() throws Exception {
-        Assert.assertNotNull(usersList);
-        usersList = tenantManage.getUsersList();
-        Assert.assertNotEquals(new LinkedList<User>(),usersList);
-    }
-
     @Test
     public void testGetUser() throws Exception {
         user = tenantManage.getUser();
@@ -78,7 +67,7 @@ public class TenantManageTest extends TestCase {
     }
 
     @Test
-    public void testFetchUserRoles() throws Exception {
+    public void testGetUserRoles() throws Exception {
         //ListenableFuture<Optional<UserRoles>> userRolesFuture = mock(ListenableFuture.class);
         CheckedFuture userRolesFuture = mock(CheckedFuture.class);
         ReadOnlyTransaction readOnlyTransaction = mock(ReadOnlyTransaction.class);
@@ -86,20 +75,22 @@ public class TenantManageTest extends TestCase {
 //      any(InstanceIdentifier.class))).thenReturn(userRolesFuture);
         when(dataBroker.newReadOnlyTransaction()).thenReturn(readOnlyTransaction);
         when(readOnlyTransaction.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).thenReturn(userRolesFuture);
-        tenantManage.fetchUserRoles();
+        when(userRolesFuture.get()).thenReturn(Optional.absent());
+        tenantManage.getUserRoles();
         verify(dataBroker).newReadOnlyTransaction();
         verify(readOnlyTransaction).read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         Assert.assertNotNull(tenantManage);
     }
 
     @Test
-    public void testFetchUsers() throws Exception {
+    public void testGetUsers() throws Exception {
         CheckedFuture usersFuture = mock(CheckedFuture.class);
         ReadOnlyTransaction readOnlyTransaction = mock(ReadOnlyTransaction.class);
 
         when(dataBroker.newReadOnlyTransaction()).thenReturn(readOnlyTransaction);
         when(readOnlyTransaction.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).thenReturn(usersFuture);
-        tenantManage.fetchUsers();
+        when(usersFuture.get()).thenReturn(Optional.absent());
+        tenantManage.getUsers();
         verify(dataBroker).newReadOnlyTransaction();
         verify(readOnlyTransaction).read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         Assert.assertNotNull(tenantManage);
@@ -112,6 +103,7 @@ public class TenantManageTest extends TestCase {
 
         when(dataBroker.newReadOnlyTransaction()).thenReturn(readOnlyTransaction);
         when(readOnlyTransaction.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).thenReturn(usersFuture);
+        when(usersFuture.get()).thenReturn(Optional.absent());
         tenantManage.fetchVNSpace(mock(UserId.class));
         verify(dataBroker).newReadOnlyTransaction();
         verify(readOnlyTransaction).read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));