usage: refactor on UsageManagerImpl.createVPNUserEvent (#4085)

Refactor on UsageManagerImpl.createVPNUserEvent. Currently, the present method creates and removes a VPN user event. So this PR abstract this method into an handle, and creates methods to create and delete VPN user events.

Additionally, the new created method prevents duplicated entries for same user, with same userId, domainId and zoneId
This commit is contained in:
Rodrigo D. Lopez 2020-06-18 00:41:51 -03:00 committed by GitHub
parent 2a82fb99ce
commit 7b5700a040
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 250 additions and 147 deletions

View File

@ -75,11 +75,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>com/cloud/usage/UsageManagerTest.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>

View File

@ -37,6 +37,7 @@ import org.apache.cloudstack.quota.QuotaAlertManager;
import org.apache.cloudstack.quota.QuotaManager;
import org.apache.cloudstack.quota.QuotaStatement;
import org.apache.cloudstack.utils.usage.UsageUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
@ -990,7 +991,7 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna
} else if (isNetworkOfferingEvent(eventType)) {
createNetworkOfferingEvent(event);
} else if (isVPNUserEvent(eventType)) {
createVPNUserEvent(event);
handleVpnUserEvent(event);
} else if (isSecurityGroupEvent(eventType)) {
createSecurityGroupEvent(event);
} else if (isVmSnapshotEvent(eventType)) {
@ -1766,39 +1767,92 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna
}
}
private void createVPNUserEvent(UsageEventVO event) {
long zoneId = 0L;
/**
* Handles VPN user create and remove events:
* <ul>
* <li>EventTypes#EVENT_VPN_USER_ADD</li>
* <li>EventTypes#EVENT_VPN_USER_ADD</li>
* </ul>
* if the event received by this method is neither add nor remove, we ignore it.
*/
protected void handleVpnUserEvent(UsageEventVO event) {
long accountId = event.getAccountId();
Account account = _accountDao.findByIdIncludingRemoved(accountId);
long zoneId = event.getZoneId();
long userId = event.getResourceId();
if (EventTypes.EVENT_VPN_USER_ADD.equals(event.getType())) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Creating VPN user: " + userId + " for account: " + event.getAccountId());
}
Account acct = _accountDao.findByIdIncludingRemoved(event.getAccountId());
String userName = event.getResourceName();
UsageVPNUserVO vpnUser = new UsageVPNUserVO(zoneId, event.getAccountId(), acct.getDomainId(), userId, userName, event.getCreateDate(), null);
_usageVPNUserDao.persist(vpnUser);
} else if (EventTypes.EVENT_VPN_USER_REMOVE.equals(event.getType())) {
SearchCriteria<UsageVPNUserVO> sc = _usageVPNUserDao.createSearchCriteria();
sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId());
sc.addAnd("userId", SearchCriteria.Op.EQ, userId);
sc.addAnd("deleted", SearchCriteria.Op.NULL);
List<UsageVPNUserVO> vuVOs = _usageVPNUserDao.search(sc, null);
if (vuVOs.size() > 1) {
s_logger.warn("More that one usage entry for vpn user: " + userId + " assigned to account: " + event.getAccountId() + "; marking them all as deleted...");
}
for (UsageVPNUserVO vuVO : vuVOs) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("deleting vpn user: " + vuVO.getUserId());
}
vuVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one
_usageVPNUserDao.update(vuVO);
}
switch (event.getType()) {
case EventTypes.EVENT_VPN_USER_ADD:
createUsageVpnUser(event, account);
break;
case EventTypes.EVENT_VPN_USER_REMOVE:
deleteUsageVpnUser(event, account);
break;
default:
s_logger.debug(String.format("The event [type=%s, zoneId=%s, accountId=%s, userId=%s, resourceName=%s, createDate=%s] is neither of type [%s] nor [%s]",
event.getType(), zoneId, accountId, userId, event.getResourceName(), event.getCreateDate(), EventTypes.EVENT_VPN_USER_ADD, EventTypes.EVENT_VPN_USER_REMOVE));
}
}
/**
* Find and delete, if exists, usage VPN user entries
*/
protected void deleteUsageVpnUser(UsageEventVO event, Account account) {
long accountId = account.getId();
long userId = event.getResourceId();
long zoneId = event.getZoneId();
long domainId = account.getDomainId();
List<UsageVPNUserVO> usageVpnUsers = findUsageVpnUsers(accountId, zoneId, userId, domainId);
if (CollectionUtils.isEmpty(usageVpnUsers)) {
s_logger.warn(String.format("No usage entry for vpn user [%s] assigned to account [%s] domain [%s] and zone [%s] was found.",
userId, accountId, domainId, zoneId));
}
if (usageVpnUsers.size() > 1) {
s_logger.warn(String.format("More than one usage entry for vpn user [%s] assigned to account [%s] domain [%s] and zone [%s]; marking them all as deleted.", userId,
accountId, domainId, zoneId));
}
for (UsageVPNUserVO vpnUser : usageVpnUsers) {
s_logger.debug(String.format("Deleting vpn user [%s] assigned to account [%s] domain [%s] and zone [%s] that was created at [%s].", vpnUser.getUserId(),
vpnUser.getAccountId(), vpnUser.getDomainId(), vpnUser.getZoneId(), vpnUser.getCreated()));
vpnUser.setDeleted(new Date());
_usageVPNUserDao.update(vpnUser);
}
}
/**
* Creates an entry for the Usage VPN User.
* If there is already an entry in the database with the same accountId, domainId, userId and zoneId, we do not persist a new entry.
*/
protected void createUsageVpnUser(UsageEventVO event, Account account) {
long accountId = account.getId();
long userId = event.getResourceId();
long zoneId = event.getZoneId();
long domainId = account.getDomainId();
List<UsageVPNUserVO> usageVpnUsers = findUsageVpnUsers(accountId, zoneId, userId, domainId);
if (usageVpnUsers.size() > 0) {
s_logger.debug(String.format("We do not need to create the usage VPN user [%s] assigned to account [%s] because it already exists.", userId, accountId));
} else {
s_logger.debug(String.format("Creating VPN user user [%s] assigned to account [%s] domain [%s], zone [%s], and created at [%s]", userId, accountId, domainId, zoneId,
event.getCreateDate()));
UsageVPNUserVO vpnUser = new UsageVPNUserVO(zoneId, accountId, domainId, userId, event.getResourceName(), event.getCreateDate(), null);
_usageVPNUserDao.persist(vpnUser);
}
}
protected List<UsageVPNUserVO> findUsageVpnUsers(long accountId, long zoneId, long userId, long domainId) {
SearchCriteria<UsageVPNUserVO> sc = _usageVPNUserDao.createSearchCriteria();
sc.addAnd("zoneId", SearchCriteria.Op.EQ, zoneId);
sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
sc.addAnd("userId", SearchCriteria.Op.EQ, userId);
sc.addAnd("deleted", SearchCriteria.Op.NULL);
return _usageVPNUserDao.search(sc, null);
}
private void createSecurityGroupEvent(UsageEventVO event) {
long zoneId = -1L;

View File

@ -0,0 +1,167 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.usage;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.Spy;
import com.cloud.event.EventTypes;
import com.cloud.event.UsageEventVO;
import com.cloud.usage.dao.UsageVPNUserDao;
import com.cloud.user.AccountVO;
import com.cloud.user.dao.AccountDao;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class UsageManagerImplTest {
@Spy
@InjectMocks
private UsageManagerImpl usageManagerImpl;
@Mock
private UsageVPNUserDao usageVPNUserDaoMock;
@Mock
private AccountDao accountDaoMock;
@Mock
private UsageVPNUserVO vpnUserMock;
@Mock
private AccountVO accountMock;
@Mock
private UsageEventVO usageEventVOMock;
private long accountMockId = 1l;
private long acountDomainIdMock = 2l;
@Before
public void before() {
Mockito.when(accountMock.getId()).thenReturn(accountMockId);
Mockito.when(accountMock.getDomainId()).thenReturn(acountDomainIdMock);
Mockito.doReturn(accountMock).when(accountDaoMock).findByIdIncludingRemoved(Mockito.anyLong());
}
@Test
public void createUsageVpnUserTestUserExits() {
List<UsageVPNUserVO> vpnUsersMock = new ArrayList<UsageVPNUserVO>();
vpnUsersMock.add(vpnUserMock);
Mockito.doReturn(vpnUsersMock).when(usageManagerImpl).findUsageVpnUsers(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong());
usageManagerImpl.createUsageVpnUser(usageEventVOMock, accountMock);
Mockito.verify(usageVPNUserDaoMock, Mockito.never()).persist(Mockito.any(UsageVPNUserVO.class));
}
@Test
public void createUsageVpnUserTestUserDoesNotExits() {
List<UsageVPNUserVO> vpnUsersMock = new ArrayList<UsageVPNUserVO>();
Mockito.doReturn(vpnUsersMock).when(usageManagerImpl).findUsageVpnUsers(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong());
Mockito.doReturn(vpnUserMock).when(usageVPNUserDaoMock).persist(Mockito.any(UsageVPNUserVO.class));
usageManagerImpl.createUsageVpnUser(usageEventVOMock, accountMock);
Mockito.verify(usageVPNUserDaoMock, Mockito.times(1)).persist(Mockito.any(UsageVPNUserVO.class));
}
@Test
public void deleteUsageVpnUserNoUserFound() {
List<UsageVPNUserVO> vpnUsersMock = new ArrayList<UsageVPNUserVO>();
Mockito.doReturn(vpnUsersMock).when(usageManagerImpl).findUsageVpnUsers(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong());
usageManagerImpl.deleteUsageVpnUser(usageEventVOMock, accountMock);
Mockito.verify(usageVPNUserDaoMock, Mockito.never()).update(Mockito.any(UsageVPNUserVO.class));
}
@Test
public void deleteUsageVpnUserOneUserFound() {
List<UsageVPNUserVO> vpnUsersMock = new ArrayList<UsageVPNUserVO>();
vpnUsersMock.add(vpnUserMock);
Mockito.doReturn(vpnUsersMock).when(usageManagerImpl).findUsageVpnUsers(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong());
Mockito.doNothing().when(usageVPNUserDaoMock).update(Mockito.any(UsageVPNUserVO.class));
usageManagerImpl.deleteUsageVpnUser(usageEventVOMock, accountMock);
Mockito.verify(usageVPNUserDaoMock, Mockito.times(1)).update(Mockito.any(UsageVPNUserVO.class));
}
@Test
public void deleteUsageVpnUserMultipleUsersFound() {
List<UsageVPNUserVO> vpnUsersMock = new ArrayList<UsageVPNUserVO>();
vpnUsersMock.add(vpnUserMock);
vpnUsersMock.add(Mockito.mock(UsageVPNUserVO.class));
vpnUsersMock.add(Mockito.mock(UsageVPNUserVO.class));
Mockito.doReturn(vpnUsersMock).when(usageManagerImpl).findUsageVpnUsers(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong());
Mockito.doNothing().when(usageVPNUserDaoMock).update(Mockito.any(UsageVPNUserVO.class));
usageManagerImpl.deleteUsageVpnUser(usageEventVOMock, accountMock);
Mockito.verify(usageVPNUserDaoMock, Mockito.times(3)).update(Mockito.any(UsageVPNUserVO.class));
}
@Test
public void handleVpnUserEventTestAddUser() {
Mockito.when(this.usageEventVOMock.getType()).thenReturn(EventTypes.EVENT_VPN_USER_ADD);
Mockito.doNothing().when(this.usageManagerImpl).createUsageVpnUser(usageEventVOMock, accountMock);
this.usageManagerImpl.handleVpnUserEvent(usageEventVOMock);
Mockito.verify(usageManagerImpl).createUsageVpnUser(usageEventVOMock, accountMock);
Mockito.verify(usageManagerImpl, Mockito.never()).deleteUsageVpnUser(usageEventVOMock, accountMock);
}
@Test
public void handleVpnUserEventTestRemoveUser() {
Mockito.when(this.usageEventVOMock.getType()).thenReturn(EventTypes.EVENT_VPN_USER_REMOVE);
Mockito.doNothing().when(this.usageManagerImpl).deleteUsageVpnUser(usageEventVOMock, accountMock);
this.usageManagerImpl.handleVpnUserEvent(usageEventVOMock);
Mockito.verify(usageManagerImpl, Mockito.never()).createUsageVpnUser(usageEventVOMock, accountMock);
Mockito.verify(usageManagerImpl).deleteUsageVpnUser(usageEventVOMock, accountMock);
}
@Test
public void handleVpnUserEventTestEventIsNeitherAddNorRemove() {
Mockito.when(this.usageEventVOMock.getType()).thenReturn("VPN.USER.UPDATE");
this.usageManagerImpl.handleVpnUserEvent(usageEventVOMock);
Mockito.verify(usageManagerImpl, Mockito.never()).createUsageVpnUser(usageEventVOMock,accountMock);
Mockito.verify(usageManagerImpl, Mockito.never()).deleteUsageVpnUser(usageEventVOMock, accountMock);
}
}

View File

@ -1,113 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.usage;
import java.util.Date;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.cloud.usage.parser.IPAddressUsageParser;
import com.cloud.usage.parser.LoadBalancerUsageParser;
import com.cloud.usage.parser.NetworkOfferingUsageParser;
import com.cloud.usage.parser.NetworkUsageParser;
import com.cloud.usage.parser.PortForwardingUsageParser;
import com.cloud.usage.parser.SecurityGroupUsageParser;
import com.cloud.usage.parser.StorageUsageParser;
import com.cloud.usage.parser.VMInstanceUsageParser;
import com.cloud.usage.parser.VPNUserUsageParser;
import com.cloud.usage.parser.VmDiskUsageParser;
import com.cloud.usage.parser.VolumeUsageParser;
import com.cloud.user.AccountVO;
import com.cloud.utils.component.ComponentContext;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/UsageManagerTestContext.xml")
public class UsageManagerTest extends TestCase {
@Inject
UsageManagerImpl _usageMgr = null;
@Inject
VMInstanceUsageParser vmParser = null;
@Inject
IPAddressUsageParser ipParser = null;
@Inject
LoadBalancerUsageParser lbParser = null;
@Inject
NetworkOfferingUsageParser noParser = null;
@Inject
NetworkUsageParser netParser = null;
@Inject
VmDiskUsageParser vmdiskParser = null;
@Inject
PortForwardingUsageParser pfParser = null;
@Inject
SecurityGroupUsageParser sgParser = null;
@Inject
StorageUsageParser stParser = null;
@Inject
VolumeUsageParser volParser = null;
@Inject
VPNUserUsageParser vpnParser = null;
Date startDate = null;
Date endDate = null;
@Before
public void setup() throws Exception {
System.setProperty("pid", "5678");
ComponentContext.initComponentsLifeCycle();
startDate = new Date();
endDate = new Date(100000L + System.currentTimeMillis());
}
@Test
public void testParse() throws ConfigurationException {
UsageJobVO job = new UsageJobVO();
_usageMgr.parse(job, System.currentTimeMillis(), 100000L + System.currentTimeMillis());
}
@Test
public void testSchedule() throws ConfigurationException {
_usageMgr.scheduleParse();
}
@Test
public void testParsers() throws ConfigurationException {
AccountVO account = new AccountVO();
account.setId(2L);
VMInstanceUsageParser.parse(account, startDate, endDate);
IPAddressUsageParser.parse(account, startDate, endDate);
LoadBalancerUsageParser.parse(account, startDate, endDate);
NetworkOfferingUsageParser.parse(account, startDate, endDate);
NetworkUsageParser.parse(account, startDate, endDate);
VmDiskUsageParser.parse(account, startDate, endDate);
PortForwardingUsageParser.parse(account, startDate, endDate);
SecurityGroupUsageParser.parse(account, startDate, endDate);
StorageUsageParser.parse(account, startDate, endDate);
VolumeUsageParser.parse(account, startDate, endDate);
VPNUserUsageParser.parse(account, startDate, endDate);
}
}