Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/src/org/apache/cloudstack/api/ApiConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ public class ApiConstants {
public static final String VIRTUAL_MACHINE_ID = "virtualmachineid";
public static final String VIRTUAL_MACHINE_IDS = "virtualmachineids";
public static final String VIRTUAL_MACHINE_ID_IP = "vmidipmap";
public static final String VIRTUAL_MACHINE_COUNT = "virtualmachinecount";
public static final String USAGE_ID = "usageid";

public static final String VLAN = "vlan";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,13 @@
import java.util.LinkedHashSet;
import java.util.Set;

import com.google.gson.annotations.SerializedName;

import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;

import com.cloud.network.security.SecurityGroup;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;

@SuppressWarnings("unused")
@EntityReference(value = SecurityGroup.class)
Expand Down Expand Up @@ -76,7 +75,16 @@ public class SecurityGroupResponse extends BaseResponse implements ControlledVie
@Param(description = "the list of resource tags associated with the rule", responseObject = ResourceTagResponse.class)
private Set<ResourceTagResponse> tags;

@SerializedName(ApiConstants.VIRTUAL_MACHINE_COUNT)
@Param(description = "the number of virtualmachines associated with this securitygroup", since = "4.6.0")
private Integer virtualMachineCount;

@SerializedName(ApiConstants.VIRTUAL_MACHINE_IDS)
@Param(description = "the list of virtualmachine ids associated with this securitygroup", since = "4.6.0")
private Set<String> virtualMachineIds;

public SecurityGroupResponse() {
this.virtualMachineIds = new LinkedHashSet<String>();
this.ingressRules = new LinkedHashSet<SecurityGroupRuleResponse>();
this.egressRules = new LinkedHashSet<SecurityGroupRuleResponse>();
this.tags = new LinkedHashSet<ResourceTagResponse>();
Expand Down Expand Up @@ -176,4 +184,16 @@ public void setTags(Set<ResourceTagResponse> tags) {
public void addTag(ResourceTagResponse tag) {
this.tags.add(tag);
}

public void setVirtualMachineCount(Integer virtualMachineCount) {
this.virtualMachineCount = virtualMachineCount;
}

public void setVirtualMachineIds(Set<String> virtualMachineIds) {
this.virtualMachineIds = virtualMachineIds;
}

public void addVirtualMachineId(String virtualMachineId) {
this.virtualMachineIds.add(virtualMachineId);
}
}
27 changes: 22 additions & 5 deletions server/src/com/cloud/api/query/dao/SecurityGroupJoinDaoImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,28 @@
import javax.ejb.Local;
import javax.inject.Inject;

import com.cloud.server.ResourceTag;
import org.apache.cloudstack.api.response.ResourceTagResponse;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import org.apache.cloudstack.api.response.SecurityGroupResponse;
import org.apache.cloudstack.api.response.SecurityGroupRuleResponse;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import com.cloud.api.ApiDBUtils;
import com.cloud.api.ApiResponseHelper;
import com.cloud.api.query.vo.ResourceTagJoinVO;
import com.cloud.api.query.vo.SecurityGroupJoinVO;
import com.cloud.network.security.SecurityGroup;
import com.cloud.network.security.SecurityGroupVMMapVO;
import com.cloud.network.security.SecurityRule.SecurityRuleType;
import com.cloud.network.security.dao.SecurityGroupVMMapDao;
import com.cloud.server.ResourceTag;
import com.cloud.user.Account;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.dao.UserVmDao;

@Component
@Local(value = {SecurityGroupJoinDao.class})
Expand All @@ -51,9 +54,12 @@ public class SecurityGroupJoinDaoImpl extends GenericDaoBase<SecurityGroupJoinVO

@Inject
private ConfigurationDao _configDao;

@Inject
private ResourceTagJoinDao _resourceTagJoinDao;
@Inject
private SecurityGroupVMMapDao _securityGroupVMMapDao;
@Inject
private UserVmDao _userVmDao;

private final SearchBuilder<SecurityGroupJoinVO> sgSearch;

Expand Down Expand Up @@ -125,6 +131,17 @@ public SecurityGroupResponse newSecurityGroupResponse(SecurityGroupJoinVO vsg, A
}
}

List<SecurityGroupVMMapVO> securityGroupVmMap = _securityGroupVMMapDao.listBySecurityGroup(vsg.getId());
s_logger.debug("newSecurityGroupResponse() -> virtualmachine count: " + securityGroupVmMap.size());
sgResponse.setVirtualMachineCount(securityGroupVmMap.size());

for(SecurityGroupVMMapVO securityGroupVMMapVO : securityGroupVmMap) {
final UserVmVO userVmVO = _userVmDao.findById(securityGroupVMMapVO.getInstanceId());
if (userVmVO != null) {
sgResponse.addVirtualMachineId(userVmVO.getUuid());
}
}

// update tag information
Long tag_id = vsg.getTagId();
if (tag_id != null && tag_id.longValue() > 0) {
Expand Down
205 changes: 205 additions & 0 deletions server/test/com/cloud/api/query/dao/SecurityGroupJoinDaoImplTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
// 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.api.query.dao;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.cloudstack.api.response.SecurityGroupResponse;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.runners.MockitoJUnitRunner;

import com.cloud.api.query.vo.ResourceTagJoinVO;
import com.cloud.api.query.vo.SecurityGroupJoinVO;
import com.cloud.network.security.SecurityGroupVMMapVO;
import com.cloud.network.security.dao.SecurityGroupVMMapDao;
import com.cloud.server.ResourceTag.ResourceObjectType;
import com.cloud.user.Account;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.dao.UserVmDao;

import junit.framework.TestCase;

@RunWith(MockitoJUnitRunner.class)
public class SecurityGroupJoinDaoImplTest extends TestCase {

// Mock private variables.
@Mock (name = "_resourceTagJoinDao")
private ResourceTagJoinDao _resourceTagJoinDao;
@Mock (name = "_securityGroupVMMapDao")
private SecurityGroupVMMapDao _securityGroupVMMapDao;
@Mock (name = "_userVmDao")
private UserVmDao _userVmDao;

// Inject mocks in class to be tested.
@InjectMocks
private SecurityGroupJoinDaoImpl _securityGroupJoinDaoImpl;

// Mock a caller and a SecurityGroupJoinVO
@Mock
private Account caller;
@Mock
private SecurityGroupJoinVO vsg;

// Mock securitygroups
@Mock
private SecurityGroupVMMapVO securityGroupVMMapVOone;
@Mock
private SecurityGroupVMMapVO securityGroupVMMapVOtwo;

// Mock 2 UserVmVOs
@Mock
private UserVmVO userVmVOone;
@Mock
private UserVmVO userVmVOtwo;

// Random generated UUIDs
private final String uuidOne = "463e022a-249d-4212-bdf4-726bc9047aa7";
private final String uuidTwo = "d8714c5f-766f-4b14-bdf4-17571042b9c5";

@Before
public void setup() {
MockitoAnnotations.initMocks(this);

// Security group without vms associated.
List<SecurityGroupVMMapVO> securityGroupVmMap_empty = new ArrayList<SecurityGroupVMMapVO>();

// Security group with one vm associated.
List<SecurityGroupVMMapVO> securityGroupVmMap_one = new ArrayList<SecurityGroupVMMapVO>();
securityGroupVmMap_one.add(securityGroupVMMapVOone);

// Security group with two or many vms associated
List<SecurityGroupVMMapVO> securityGroupVmMap_two = new ArrayList<SecurityGroupVMMapVO>();
securityGroupVmMap_two.add(securityGroupVMMapVOone);
securityGroupVmMap_two.add(securityGroupVMMapVOtwo);

// Mock the resource tags to return an empty list.
when(_resourceTagJoinDao.listBy(anyString(), any(ResourceObjectType.class))).thenReturn(new ArrayList<ResourceTagJoinVO>());

// Mock the listBySecurityGroup method to return a specified list when being called.
when(_securityGroupVMMapDao.listBySecurityGroup(1L)).thenReturn(securityGroupVmMap_empty);
when(_securityGroupVMMapDao.listBySecurityGroup(2L)).thenReturn(securityGroupVmMap_one);
when(_securityGroupVMMapDao.listBySecurityGroup(3L)).thenReturn(securityGroupVmMap_two);

// Mock the securityGroupVMMapVOs to return a specified instance id.
when(securityGroupVMMapVOone.getInstanceId()).thenReturn(1L);
when(securityGroupVMMapVOtwo.getInstanceId()).thenReturn(2L);

// Mock _userVmDao to return a non null instance of UserVmVO.
when(_userVmDao.findById(1L)).thenReturn(userVmVOone);
when(_userVmDao.findById(2L)).thenReturn(userVmVOtwo);

// Mock _userVmDao to return a non null instance of UserVmVO.
when(userVmVOone.getUuid()).thenReturn(uuidOne);
when(userVmVOtwo.getUuid()).thenReturn(uuidTwo);
}

@Test
public void virtualMachineCountEmptyTest() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {

when(vsg.getId()).thenReturn(1L);

SecurityGroupResponse securityGroupResponse = _securityGroupJoinDaoImpl.newSecurityGroupResponse(vsg, caller);

Field virtualMachineCount = securityGroupResponse.getClass().getDeclaredField("virtualMachineCount");
virtualMachineCount.setAccessible(true);
assertEquals(0, ((Integer)virtualMachineCount.get(securityGroupResponse)).intValue());
}

@Test
public void virtualMachineCountOneTest() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {

when(vsg.getId()).thenReturn(2L);

SecurityGroupResponse securityGroupResponse = _securityGroupJoinDaoImpl.newSecurityGroupResponse(vsg, caller);

Field virtualMachineCount = securityGroupResponse.getClass().getDeclaredField("virtualMachineCount");
virtualMachineCount.setAccessible(true);
assertEquals(1, ((Integer)virtualMachineCount.get(securityGroupResponse)).intValue());
}

@Test
public void virtualMachineCountTwoTest() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {

when(vsg.getId()).thenReturn(3L);

SecurityGroupResponse securityGroupResponse = _securityGroupJoinDaoImpl.newSecurityGroupResponse(vsg, caller);

Field virtualMachineCount = securityGroupResponse.getClass().getDeclaredField("virtualMachineCount");
virtualMachineCount.setAccessible(true);
assertEquals(2, ((Integer)virtualMachineCount.get(securityGroupResponse)).intValue());
}

@Test
public void virtualMachineIDsEmptyTest() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {

when(vsg.getId()).thenReturn(1L);

SecurityGroupResponse securityGroupResponse = _securityGroupJoinDaoImpl.newSecurityGroupResponse(vsg, caller);

Field fieldVirtualMachineIds = securityGroupResponse.getClass().getDeclaredField("virtualMachineIds");
fieldVirtualMachineIds.setAccessible(true);

Set<String> virtualMachineIds = (Set<String>)fieldVirtualMachineIds.get(securityGroupResponse);

assertEquals(0, virtualMachineIds.size());
}

@Test
public void virtualMachineIDsOneTest() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {

when(vsg.getId()).thenReturn(2L);

SecurityGroupResponse securityGroupResponse = _securityGroupJoinDaoImpl.newSecurityGroupResponse(vsg, caller);

Field fieldVirtualMachineIds = securityGroupResponse.getClass().getDeclaredField("virtualMachineIds");
fieldVirtualMachineIds.setAccessible(true);

Set<String> virtualMachineIds = (Set<String>)fieldVirtualMachineIds.get(securityGroupResponse);

assertEquals(1, virtualMachineIds.size());
assertTrue(virtualMachineIds.contains(uuidOne));
}

@Test
public void virtualMachineIDsTwoTest() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {

when(vsg.getId()).thenReturn(3L);

SecurityGroupResponse securityGroupResponse = _securityGroupJoinDaoImpl.newSecurityGroupResponse(vsg, caller);

Field fieldVirtualMachineIds = securityGroupResponse.getClass().getDeclaredField("virtualMachineIds");
fieldVirtualMachineIds.setAccessible(true);

Set<String> virtualMachineIds = (Set<String>)fieldVirtualMachineIds.get(securityGroupResponse);

assertEquals(2, virtualMachineIds.size());
assertTrue(virtualMachineIds.contains(uuidOne));
assertTrue(virtualMachineIds.contains(uuidTwo));
}
}