/**
* Abiquo community edition
* cloud management application for hybrid clouds
* Copyright (C) 2008-2010 - Abiquo Holdings S.L.
*
* This application is free software; you can redistribute it and/or
* modify it under the terms of the GNU LESSER GENERAL PUBLIC
* LICENSE as published by the Free Software Foundation under
* version 3 of the License
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* LESSER GENERAL PUBLIC LICENSE v.3 for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
package com.abiquo.api.resources.cloud;
import static com.abiquo.api.common.Assert.assertErrors;
import static com.abiquo.api.common.UriTestResolver.resolvePrivateNetworksURI;
import static com.abiquo.testng.TestConfig.BASIC_INTEGRATION_TESTS;
import static com.abiquo.testng.TestConfig.NETWORK_INTEGRATION_TESTS;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.ws.rs.core.Response.Status;
import org.apache.wink.client.ClientResponse;
import org.apache.wink.client.Resource;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.abiquo.api.exceptions.APIError;
import com.abiquo.api.resources.AbstractJpaGeneratorIT;
import com.abiquo.model.enumerator.RemoteServiceType;
import com.abiquo.model.transport.error.ErrorDto;
import com.abiquo.model.transport.error.ErrorsDto;
import com.abiquo.server.core.cloud.VirtualDatacenter;
import com.abiquo.server.core.enterprise.Enterprise;
import com.abiquo.server.core.enterprise.Privilege;
import com.abiquo.server.core.enterprise.Role;
import com.abiquo.server.core.enterprise.User;
import com.abiquo.server.core.infrastructure.RemoteService;
import com.abiquo.server.core.infrastructure.network.VLANNetwork;
import com.abiquo.server.core.infrastructure.network.VLANNetworkDto;
import com.abiquo.server.core.infrastructure.network.VLANNetworksDto;
/**
* Acceptance test for the creation of PrivateNetworks and retrieve of a list of them.
*
* @author jdevesa@abiquo.com
*/
@Test(groups = {NETWORK_INTEGRATION_TESTS})
public class PrivateNetworksResourceIT extends AbstractJpaGeneratorIT
{
VirtualDatacenter vdc;
RemoteService rs;
VLANNetwork vlan;
Enterprise sysEnterprise;
@BeforeMethod(groups = {BASIC_INTEGRATION_TESTS, NETWORK_INTEGRATION_TESTS})
public void setUp()
{
rs = remoteServiceGenerator.createInstance(RemoteServiceType.DHCP_SERVICE);
vdc = vdcGenerator.createInstance(rs.getDatacenter());
sysEnterprise = enterpriseGenerator.createUniqueInstance();
Role r = roleGenerator.createInstanceSysAdmin();
User u = userGenerator.createInstance(sysEnterprise, r, "sysadmin", "sysadmin");
List<Object> entitiesToSetup = new ArrayList<Object>();
entitiesToSetup.add(sysEnterprise);
for (Privilege p : r.getPrivileges())
{
entitiesToSetup.add(p);
}
entitiesToSetup.add(r);
entitiesToSetup.add(u);
entitiesToSetup.add(vdc.getDatacenter());
entitiesToSetup.add(rs);
entitiesToSetup.add(vdc.getEnterprise());
entitiesToSetup.add(vdc.getNetwork());
entitiesToSetup.add(vdc);
setup(entitiesToSetup.toArray());
}
@Override
@AfterMethod(groups = {BASIC_INTEGRATION_TESTS, NETWORK_INTEGRATION_TESTS})
public void tearDown()
{
super.tearDown();
}
@Test
public void getPrivateNetworks()
{
vlan = vlanGenerator.createInstance(vdc.getNetwork(), rs, "255.255.255.0");
VLANNetwork vlan2 = vlanGenerator.createInstance(vdc.getNetwork(), rs, "255.255.255.0");
setup(vlan.getConfiguration(), vlan, vlan2.getConfiguration(), vlan2);
ClientResponse response =
get(resolvePrivateNetworksURI(vdc.getId()), "sysadmin", "sysadmin",
VLANNetworksDto.MEDIA_TYPE);
assertEquals(200, response.getStatusCode());
VLANNetworksDto entity = response.getEntity(VLANNetworksDto.class);
assertNotNull(entity);
assertNotNull(entity.getCollection());
assertEquals(entity.getCollection().size(), 2);
}
@Test
public void getPrivateNetworksListInvalidVDC() throws Exception
{
ClientResponse response =
get(resolvePrivateNetworksURI(new Random().nextInt(1000)), "sysadmin", "sysadmin",
VLANNetworksDto.MEDIA_TYPE);
assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
}
@Test(groups = {BASIC_INTEGRATION_TESTS})
public void createPrivateNetwork()
{
VLANNetworkDto dto = createValidNetworkDto();
ClientResponse response =
post(resolvePrivateNetworksURI(vdc.getId()), dto, "sysadmin", "sysadmin");
assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
VLANNetworkDto dtoResponse = response.getEntity(VLANNetworkDto.class);
assertEquals(dto.getName(), dtoResponse.getName());
assertEquals(dto.getAddress(), dtoResponse.getAddress());
assertEquals(dto.getGateway(), dtoResponse.getGateway());
assertTrue(dto.getMask() == dtoResponse.getMask());
assertEquals(dto.getPrimaryDNS(), dtoResponse.getPrimaryDNS());
assertEquals(dto.getSecondaryDNS(), dtoResponse.getSecondaryDNS());
assertEquals(dto.getSufixDNS(), dtoResponse.getSufixDNS());
}
/**
* Checks it return a 404 NotFound when trying to access a VirtualDatacenter invalid
*/
@Test
void createPrivateNetworkRaises404WhenVDCDoesNotExist()
{
VLANNetworkDto dto = createValidNetworkDto();
Integer integer = new Random().nextInt();
integer = integer < 0 ? integer * -1 : integer;
ClientResponse response =
post(resolvePrivateNetworksURI(integer), dto, "sysadmin", "sysadmin");
assertErrors(response, 404, APIError.NON_EXISTENT_VIRTUAL_DATACENTER);
}
/**
* Checks it return a 400 BadRequest when the VirtualDatacenter param is a negative number
*/
@Test
void createPrivateNetworkRaises400WhenVDCIdentifierNegative()
{
VLANNetworkDto dto = createValidNetworkDto();
ClientResponse response = post(resolvePrivateNetworksURI(-1), dto, "sysadmin", "sysadmin");
assertEquals(response.getStatusCode(), 400);
ErrorsDto errors = response.getEntity(ErrorsDto.class);
assertEquals(errors.getCollection().size(), 1);
ErrorDto error = errors.getCollection().get(0);
assertEquals(error.getCode(), "CONSTR-MIN");
}
/**
* Launch a several test to check 400-Bad Request. Since it never creates any VLAN, I put all
* tests in the same method to avoid 'setUp' and 'tearDown' rutines and improve the performance
* of the tests. Check the constraints
*/
@Test
void createPrivateNetworkRaises400ManyCases()
{
Resource res =
client.resource(resolvePrivateNetworksURI(vdc.getId()))
.accept(VLANNetworkDto.MEDIA_TYPE).contentType(VLANNetworkDto.MEDIA_TYPE)
.header("Authorization", "Basic " + basicAuth("sysadmin", "sysadmin"));
// Name null
VLANNetworkDto dto = createValidNetworkDto();
dto.setName(null);
ClientResponse response = res.post(dto);
assertEquals(response.getStatusCode(), 400);
// Address null
dto = createValidNetworkDto();
dto.setAddress(null);
response = res.post(dto);
assertEquals(response.getStatusCode(), 400);
// Address invalid (not IP)
dto = createValidNetworkDto();
dto.setAddress("192.168");
response = res.post(dto);
assertEquals(response.getStatusCode(), 400);
// Gateway null
dto = createValidNetworkDto();
dto.setGateway(null);
response = res.post(dto);
assertEquals(response.getStatusCode(), 400);
// Address invalid (not IP)
dto = createValidNetworkDto();
dto.setGateway("192.168");
response = res.post(dto);
assertEquals(response.getStatusCode(), 400);
// Mask null
dto = createValidNetworkDto();
dto.setMask(null);
response = res.post(dto);
assertEquals(response.getStatusCode(), 400);
// Mask less than 1
dto = createValidNetworkDto();
dto.setMask(-1);
response = res.post(dto);
assertEquals(response.getStatusCode(), 400);
// Mask more than 32
dto = createValidNetworkDto();
dto.setMask(33);
response = res.post(dto);
assertEquals(response.getStatusCode(), 400);
}
/**
* Create the maximum of private networks available per virtualdatacenter. After that, checkt it
* returns a 409 when trying to add another vlan.
*/
@Test
public void createPrivateNetworkRaises409WhenMaximumIsReached()
{
VLANNetworkDto dto;
ClientResponse response;
// Get the max from system property
Integer maxVlans =
Integer.valueOf(System.getProperty("abiquo.server.networking.vlanPerVdc"));
// Create the n-1 first vlans
for (int i = 0; i < maxVlans; i++)
{
dto = createValidNetworkDto();
dto.setName(dto.getName() + i);
response = post(resolvePrivateNetworksURI(vdc.getId()), dto, "sysadmin", "sysadmin");
assertEquals(201, response.getStatusCode());
}
// Assert it doesn't allow you to create more
dto = createValidNetworkDto();
dto.setName(dto.getName() + "nonono");
response = post(resolvePrivateNetworksURI(vdc.getId()), dto, "sysadmin", "sysadmin");
assertErrors(response, 409, APIError.VLANS_PRIVATE_MAXIMUM_REACHED);
}
/**
* Check we can not create two vlans with the same name in a virtualdatacenter.
*/
@Test
public void createPrivateNetworkRaises409WhenDuplicatedVlanNameInTheSameVDC()
{
VLANNetworkDto dto = createValidNetworkDto();
ClientResponse response =
post(resolvePrivateNetworksURI(vdc.getId()), dto, "sysadmin", "sysadmin");
assertEquals(201, response.getStatusCode());
// Check we can not create the dto again caused by the network name.
response = post(resolvePrivateNetworksURI(vdc.getId()), dto, "sysadmin", "sysadmin");
assertErrors(response, 409, APIError.VLANS_DUPLICATED_VLAN_NAME_VDC);
// Ensure we can create it with the same name into another vdc.
VirtualDatacenter vdc2 = vdcGenerator.createInstance(rs.getDatacenter());
setup(vdc2.getEnterprise(), vdc2.getNetwork(), vdc2);
response = post(resolvePrivateNetworksURI(vdc2.getId()), dto, "sysadmin", "sysadmin");
assertEquals(201, response.getStatusCode());
}
/**
* Ensure the network address and the mask are coherent in terms of network adrress.
*/
@Test
public void createPrivateNetworkRaises400WhenInvalidNetworkRelatedToNetworkMask()
{
// 192.168.1.128 is not vaild in terms of mask range
VLANNetworkDto dto = createValidNetworkDto();
dto.setAddress("192.168.1.128");
dto.setMask(24);
ClientResponse response =
post(resolvePrivateNetworksURI(vdc.getId()), dto, "sysadmin", "sysadmin");
assertErrors(response, 400, APIError.VLANS_INVALID_NETWORK_AND_MASK);
// but is valid for the 25 mask...
dto.setMask(25);
dto.setGateway("192.168.1.130");
response = post(resolvePrivateNetworksURI(vdc.getId()), dto, "sysadmin", "sysadmin");
assertEquals(201, response.getStatusCode());
}
/**
* Check if the gateway is inside the range of the network with a couple examples.
*/
@Test
public void createPrivateNetworkRaises400WhenGatewayOutOfRange()
{
// 192.168.1.128 is not vaild in terms of mask range
VLANNetworkDto dto = createValidNetworkDto();
dto.setAddress("192.168.1.0");
dto.setMask(24);
dto.setGateway("192.168.3.0");
ClientResponse response =
post(resolvePrivateNetworksURI(vdc.getId()), dto, "sysadmin", "sysadmin");
assertErrors(response, 400, APIError.VLANS_GATEWAY_OUT_OF_RANGE);
// another non-so-obvious example
dto = createValidNetworkDto();
dto.setAddress("192.168.1.0");
dto.setMask(25);
dto.setGateway("192.168.1.200");
response = post(resolvePrivateNetworksURI(vdc.getId()), dto, "sysadmin", "sysadmin");
assertErrors(response, 400, APIError.VLANS_GATEWAY_OUT_OF_RANGE);
}
/**
* Steps: create VLAN (vlan1) inside the virtual datacenter. * vlan1 is the default one. *
* create vlan2 and put it as default. * ensure vlan2 is the default. * ensure vlan1 is not the
* default any more. TODO: do it after the GET method is developed
*/
@Test
public void createPrivateNewtorkSwapBetweenDefaultNetwork()
{
}
private VLANNetworkDto createValidNetworkDto()
{
VLANNetworkDto networkDto = new VLANNetworkDto();
networkDto.setName("Default Network");
networkDto.setAddress("192.168.0.0");
networkDto.setGateway("192.168.0.1");
networkDto.setMask(24);
networkDto.setPrimaryDNS("10.0.0.1");
networkDto.setSecondaryDNS("10.0.0.1");
networkDto.setSufixDNS("bcn.abiquo.com");
return networkDto;
}
}