Skip to content

Commit e63837c

Browse files
Henrique Satohsato03
authored andcommitted
Refactor
1 parent 1711d1d commit e63837c

File tree

7 files changed

+97
-65
lines changed

7 files changed

+97
-65
lines changed

engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -377,11 +377,10 @@ void implementNetworkElementsAndResources(DeployDestination dest, ReservationCon
377377
* Returns the maximum number of NICs that the given virtual machine can have considering its hypervisor.
378378
* <br/><br/>
379379
* First we try to retrieve the setting value from the cluster where the virtual machine is deployed. If the cluster does not exist, we try to retrieve the setting value from the virtual machine hypervisor type.
380-
* In last case, if the virtual machine does not have a hypervisor type, we retrieve the smallest value between the {@link NetworkOrchestrationService#VirtualMachineMaxNicsKvm}, {@link NetworkOrchestrationService#VirtualMachineMaxNicsVmware}
381-
* and {@link NetworkOrchestrationService#VirtualMachineMaxNicsXenserver} global settings.
380+
* Returns null if the setting value could not be extracted.
382381
*
383382
* @param virtualMachine Virtual machine to get the maximum number of NICs.
384383
* @return The maximum number of NICs that the virtual machine can have.
385384
*/
386-
int getVirtualMachineMaxNicsValue(VirtualMachine virtualMachine);
385+
Integer getVirtualMachineMaxNicsValue(VirtualMachine virtualMachine);
387386
}

engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,6 @@
267267
import com.cloud.vm.dao.UserVmDao;
268268
import com.cloud.vm.dao.VMInstanceDao;
269269
import com.googlecode.ipv6.IPv6Address;
270-
import org.apache.commons.lang3.math.NumberUtils;
271270

272271
/**
273272
* NetworkManagerImpl implements NetworkManager.
@@ -1142,10 +1141,10 @@ private NicVO checkForRaceAndAllocateNic(final NicProfile requested, final Netwo
11421141
public Pair<NicProfile, Integer> allocateNic(final NicProfile requested, final Network network, final Boolean isDefaultNic, int deviceId, final VirtualMachineProfile vm)
11431142
throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException {
11441143

1145-
int virtualMachineMaxNicsValue = getVirtualMachineMaxNicsValue(vm.getVirtualMachine());
1144+
Integer virtualMachineMaxNicsValue = getVirtualMachineMaxNicsValue(vm.getVirtualMachine());
11461145
List<NicVO> nics = _nicDao.listByVmId(vm.getId());
11471146

1148-
if (nics.size() >= virtualMachineMaxNicsValue) {
1147+
if (virtualMachineMaxNicsValue != null && nics.size() >= virtualMachineMaxNicsValue) {
11491148
throw new CloudRuntimeException(String.format("Failed to allocate NIC on network [%s] because VM [%s] has reached its maximum NIC capacity [%s].", network.getUuid(), vm.getUuid(), virtualMachineMaxNicsValue));
11501149
}
11511150

@@ -1202,16 +1201,16 @@ private boolean isNicAllocatedForProviderPublicNetworkOnVR(Network network, NicP
12021201
}
12031202

12041203
@Override
1205-
public int getVirtualMachineMaxNicsValue(VirtualMachine virtualMachine) {
1204+
public Integer getVirtualMachineMaxNicsValue(VirtualMachine virtualMachine) {
12061205
Integer virtualMachineMaxNicsValue = getVirtualMachineMaxNicsValueFromCluster(virtualMachine);
12071206

12081207
if (virtualMachineMaxNicsValue != null) {
12091208
return virtualMachineMaxNicsValue;
12101209
}
12111210

12121211
if (virtualMachine.getHypervisorType() == null) {
1213-
logger.debug("Using the smallest setting global value between {}, {} and {} as the VM {} does not have a hypervisor type and is not deployed on either a host or a cluster.", VirtualMachineMaxNicsKvm, VirtualMachineMaxNicsVmware, VirtualMachineMaxNicsXenserver, virtualMachine.getUuid());
1214-
return NumberUtils.min(VirtualMachineMaxNicsKvm.value(), VirtualMachineMaxNicsVmware.value(), VirtualMachineMaxNicsXenserver.value());
1212+
logger.debug("Not considering the hypervisor maximum limits as we were unable to find a compatible hypervisor on the VM and VM cluster for virtual machine maximum NICs settings.");
1213+
return null;
12151214
}
12161215

12171216
return getVirtualMachineMaxNicsValueFromVmHypervisorType(virtualMachine);
@@ -1243,22 +1242,22 @@ protected Integer getVirtualMachineMaxNicsValueFromCluster(VirtualMachine virtua
12431242
* @param cluster Cluster to get the virtual machine max NICs value from.
12441243
* @return The maximum number of NICs that the virtual machine can have.
12451244
*/
1246-
protected int getVirtualMachineMaxNicsValueFromCluster(ClusterVO cluster) {
1247-
int virtualMachineMaxNicsValue = 0;
1248-
HypervisorType hypervisor = cluster.getHypervisorType();
1249-
1250-
if (HypervisorType.KVM.equals(hypervisor)) {
1251-
virtualMachineMaxNicsValue = VirtualMachineMaxNicsKvm.valueIn(cluster.getId());
1252-
logger.debug("The cluster {} where the VM is deployed uses the {} hypervisor. Therefore, the {} setting value [{}] will be used.", cluster.getName(), hypervisor, VirtualMachineMaxNicsKvm, virtualMachineMaxNicsValue);
1253-
} else if (HypervisorType.VMware.equals(hypervisor)) {
1254-
virtualMachineMaxNicsValue = VirtualMachineMaxNicsVmware.valueIn(cluster.getId());
1255-
logger.debug("The cluster {} where the VM is deployed uses the {} hypervisor. Therefore, the {} setting value [{}] will be used.", cluster.getName(), hypervisor, VirtualMachineMaxNicsVmware, virtualMachineMaxNicsValue);
1256-
} else {
1257-
virtualMachineMaxNicsValue = VirtualMachineMaxNicsXenserver.valueIn(cluster.getId());
1258-
logger.debug("The cluster {} where the VM is deployed uses the {} hypervisor. Therefore, the {} setting value [{}] will be used.", cluster.getName(), hypervisor, VirtualMachineMaxNicsXenserver, virtualMachineMaxNicsValue);
1245+
protected Integer getVirtualMachineMaxNicsValueFromCluster(ClusterVO cluster) {
1246+
HypervisorType clusterHypervisor = cluster.getHypervisorType();
1247+
1248+
switch (clusterHypervisor) {
1249+
case KVM:
1250+
logger.debug("The cluster {} where the VM is deployed uses the {} hypervisor. Therefore, the {} setting value [{}] will be used.", cluster.getName(), clusterHypervisor, VirtualMachineMaxNicsKvm, VirtualMachineMaxNicsKvm.valueIn(cluster.getId()));
1251+
return VirtualMachineMaxNicsKvm.valueIn(cluster.getId());
1252+
case VMware:
1253+
logger.debug("The cluster {} where the VM is deployed uses the {} hypervisor. Therefore, the {} setting value [{}] will be used.", cluster.getName(), clusterHypervisor, VirtualMachineMaxNicsKvm, VirtualMachineMaxNicsVmware.valueIn(cluster.getId()));
1254+
return VirtualMachineMaxNicsVmware.valueIn(cluster.getId());
1255+
case XenServer:
1256+
logger.debug("The cluster {} where the VM is deployed uses the {} hypervisor. Therefore, the {} setting value [{}] will be used.", cluster.getName(), clusterHypervisor, VirtualMachineMaxNicsXenserver, VirtualMachineMaxNicsXenserver.valueIn(cluster.getId()));
1257+
return VirtualMachineMaxNicsXenserver.valueIn(cluster.getId());
1258+
default:
1259+
return null;
12591260
}
1260-
1261-
return virtualMachineMaxNicsValue;
12621261
}
12631262

12641263
/**
@@ -1267,19 +1266,23 @@ protected int getVirtualMachineMaxNicsValueFromCluster(ClusterVO cluster) {
12671266
* @param virtualMachine Virtual machine to get the hypervisor type.
12681267
* @return The maximum number of NICs that the virtual machine can have.
12691268
*/
1270-
protected int getVirtualMachineMaxNicsValueFromVmHypervisorType(VirtualMachine virtualMachine) {
1269+
protected Integer getVirtualMachineMaxNicsValueFromVmHypervisorType(VirtualMachine virtualMachine) {
12711270
HypervisorType virtualMachineHypervisorType = virtualMachine.getHypervisorType();
12721271

1273-
if (HypervisorType.KVM.equals(virtualMachineHypervisorType)) {
1274-
logger.debug("Using the {} setting global value {} as the VM {} has the {} hypervisor type and is not deployed on either a host or a cluster.", VirtualMachineMaxNicsKvm, VirtualMachineMaxNicsKvm.value(), virtualMachine.getUuid(), virtualMachineHypervisorType);
1275-
return VirtualMachineMaxNicsKvm.value();
1276-
} else if (HypervisorType.VMware.equals(virtualMachineHypervisorType)) {
1277-
logger.debug("Using the {} setting global value {} as the VM {} has the {} hypervisor type and is not deployed on either a host or a cluster.", VirtualMachineMaxNicsVmware, VirtualMachineMaxNicsVmware.value(), virtualMachine.getUuid(), virtualMachineHypervisorType);
1278-
return VirtualMachineMaxNicsVmware.value();
1272+
switch (virtualMachineHypervisorType) {
1273+
case KVM:
1274+
logger.debug("Using the {} setting global value {} as the VM {} has the {} hypervisor type and is not deployed on either a host or a cluster.", VirtualMachineMaxNicsKvm, VirtualMachineMaxNicsKvm.value(), virtualMachine.getUuid(), virtualMachineHypervisorType);
1275+
return VirtualMachineMaxNicsKvm.value();
1276+
case VMware:
1277+
logger.debug("Using the {} setting global value {} as the VM {} has the {} hypervisor type and is not deployed on either a host or a cluster.", VirtualMachineMaxNicsVmware, VirtualMachineMaxNicsVmware.value(), virtualMachine.getUuid(), virtualMachineHypervisorType);
1278+
return VirtualMachineMaxNicsVmware.value();
1279+
case XenServer:
1280+
logger.debug("Using the {} setting global value {} as the VM {} has the {} hypervisor type and is not deployed on either a host or a cluster.", VirtualMachineMaxNicsXenserver, VirtualMachineMaxNicsXenserver.value(), virtualMachine.getUuid(), virtualMachineHypervisorType);
1281+
return VirtualMachineMaxNicsXenserver.value();
1282+
default:
1283+
logger.debug("Not considering the hypervisor maximum limits as we were unable to find a compatible hypervisor on the VM and VM cluster for virtual machine maximum NICs configurations.");
1284+
return null;
12791285
}
1280-
1281-
logger.debug("Using the {} setting global value {} as the VM {} has the {} hypervisor type and is not deployed on either a host or a cluster.", VirtualMachineMaxNicsXenserver, VirtualMachineMaxNicsXenserver.value(), virtualMachine.getUuid(), virtualMachineHypervisorType);
1282-
return VirtualMachineMaxNicsXenserver.value();
12831286
}
12841287

12851288
private void setMtuDetailsInVRNic(final Pair<NetworkVO, VpcVO> networks, Network network, NicVO vo) {

engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestratorTest.java

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,32 +1025,23 @@ public void getVirtualMachineMaxNicsValueTestVirtualMachineDeployedReturnsVirtua
10251025
VirtualMachine virtualMachineMock = Mockito.mock(VirtualMachine.class);
10261026
Mockito.doReturn(44).when(testOrchestrator).getVirtualMachineMaxNicsValueFromCluster(virtualMachineMock);
10271027

1028-
int virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValue(virtualMachineMock);
1028+
Integer virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValue(virtualMachineMock);
10291029

10301030
Mockito.verify(testOrchestrator, Mockito.times(1)).getVirtualMachineMaxNicsValueFromCluster((VirtualMachine) Mockito.any());
1031-
Assert.assertEquals(44, virtualMachineMaxNicsValue);
1031+
Assert.assertEquals((Integer) 44, virtualMachineMaxNicsValue);
10321032
}
10331033

10341034
@Test
1035-
public void getVirtualMachineMaxNicsValueTestVirtualMachineWithoutDeployAndTemplateReturnsSmallestGlobalValueBetweenVirtualMachineMaxNicsSettings() throws NoSuchFieldException, IllegalAccessException {
1035+
public void getVirtualMachineMaxNicsValueTestVirtualMachineIncompatibleHypervisorReturnsNull() {
10361036
VirtualMachineProfile virtualMachineProfileMock = Mockito.mock(VirtualMachineProfile.class);
10371037
VirtualMachine virtualMachineMock = Mockito.mock(VirtualMachine.class);
1038-
ConfigKey virtualMachineMaxNicsKvmMock = Mockito.mock(ConfigKey.class);
1039-
ConfigKey virtualMachineMaxNicsVmwareMock = Mockito.mock(ConfigKey.class);
1040-
ConfigKey virtualMachineMaxNicsXenserverMock = Mockito.mock(ConfigKey.class);
10411038
Mockito.doReturn(virtualMachineMock).when(virtualMachineProfileMock).getVirtualMachine();
10421039
Mockito.doReturn(null).when(virtualMachineMock).getHypervisorType();
10431040
Mockito.doReturn(null).when(testOrchestrator).getVirtualMachineMaxNicsValueFromCluster(virtualMachineMock);
1044-
Mockito.doReturn(23).when(virtualMachineMaxNicsKvmMock).value();
1045-
Mockito.doReturn(10).when(virtualMachineMaxNicsVmwareMock).value();
1046-
Mockito.doReturn(7).when(virtualMachineMaxNicsXenserverMock).value();
1047-
updateFinalStaticField(testOrchestrator.getClass().getField("VirtualMachineMaxNicsKvm"), virtualMachineMaxNicsKvmMock);
1048-
updateFinalStaticField(testOrchestrator.getClass().getField("VirtualMachineMaxNicsVmware"), virtualMachineMaxNicsVmwareMock);
1049-
updateFinalStaticField(testOrchestrator.getClass().getField("VirtualMachineMaxNicsXenserver"), virtualMachineMaxNicsXenserverMock);
10501041

1051-
int virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValue(virtualMachineMock);
1042+
Integer virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValue(virtualMachineMock);
10521043

1053-
Assert.assertEquals(7, virtualMachineMaxNicsValue);
1044+
Assert.assertNull(virtualMachineMaxNicsValue);
10541045
}
10551046

10561047
@Test
@@ -1062,10 +1053,10 @@ public void getVirtualMachineMaxNicsValueTestVirtualMachineWithoutDeployReturnsV
10621053
Mockito.doReturn(null).when(testOrchestrator).getVirtualMachineMaxNicsValueFromCluster(virtualMachineMock);
10631054
Mockito.doReturn(33).when(testOrchestrator).getVirtualMachineMaxNicsValueFromVmHypervisorType(virtualMachineMock);
10641055

1065-
int virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValue(virtualMachineMock);
1056+
Integer virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValue(virtualMachineMock);
10661057

10671058
Mockito.verify(testOrchestrator, Mockito.times(1)).getVirtualMachineMaxNicsValueFromVmHypervisorType(Mockito.any());
1068-
Assert.assertEquals(33, virtualMachineMaxNicsValue);
1059+
Assert.assertEquals((Integer) 33, virtualMachineMaxNicsValue);
10691060
}
10701061

10711062
@Test
@@ -1102,9 +1093,9 @@ public void getVirtualMachineMaxNicsValueFromClusterTestKvmClusterReturnsVirtual
11021093
Mockito.doReturn(33).when(virtualMachineMaxNicsKvmMock).valueIn(1L);
11031094
updateFinalStaticField(testOrchestrator.getClass().getField("VirtualMachineMaxNicsKvm"), virtualMachineMaxNicsKvmMock);
11041095

1105-
int virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValueFromCluster(clusterVoMock);
1096+
Integer virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValueFromCluster(clusterVoMock);
11061097

1107-
Assert.assertEquals(33, virtualMachineMaxNicsValue);
1098+
Assert.assertEquals((Integer) 33, virtualMachineMaxNicsValue);
11081099
}
11091100

11101101
@Test
@@ -1116,9 +1107,9 @@ public void getVirtualMachineMaxNicsValueFromClusterTestVmwareClusterReturnsVirt
11161107
Mockito.doReturn(22).when(virtualMachineMaxNicsVmwareMock).valueIn(1L);
11171108
updateFinalStaticField(testOrchestrator.getClass().getField("VirtualMachineMaxNicsVmware"), virtualMachineMaxNicsVmwareMock);
11181109

1119-
int virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValueFromCluster(clusterVoMock);
1110+
Integer virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValueFromCluster(clusterVoMock);
11201111

1121-
Assert.assertEquals(22, virtualMachineMaxNicsValue);
1112+
Assert.assertEquals((Integer) 22, virtualMachineMaxNicsValue);
11221113
}
11231114

11241115
@Test
@@ -1130,9 +1121,20 @@ public void getVirtualMachineMaxNicsValueFromClusterTestXenserverClusterReturnsV
11301121
Mockito.doReturn(11).when(virtualMachineMaxNicsXenserverMock).valueIn(1L);
11311122
updateFinalStaticField(testOrchestrator.getClass().getField("VirtualMachineMaxNicsXenserver"), virtualMachineMaxNicsXenserverMock);
11321123

1133-
int virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValueFromCluster(clusterVoMock);
1124+
Integer virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValueFromCluster(clusterVoMock);
11341125

1135-
Assert.assertEquals(11, virtualMachineMaxNicsValue);
1126+
Assert.assertEquals((Integer) 11, virtualMachineMaxNicsValue);
1127+
}
1128+
1129+
@Test
1130+
public void getVirtualMachineMaxNicsValueFromClusterTestIncompatibleHypervisorReturnsNull() {
1131+
ClusterVO clusterVoMock = Mockito.mock(ClusterVO.class);
1132+
Mockito.doReturn(1L).when(clusterVoMock).getId();
1133+
Mockito.doReturn(Hypervisor.HypervisorType.Hyperv).when(clusterVoMock).getHypervisorType();
1134+
1135+
Integer virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValueFromCluster(clusterVoMock);
1136+
1137+
Assert.assertNull(virtualMachineMaxNicsValue);
11361138
}
11371139

11381140
@Test
@@ -1143,9 +1145,9 @@ public void getVirtualMachineMaxNicsValueFromVmHypervisorTypeTestKvmHypervisorRe
11431145
Mockito.doReturn(23).when(virtualMachineMaxNicsKvmMock).value();
11441146
updateFinalStaticField(testOrchestrator.getClass().getField("VirtualMachineMaxNicsKvm"), virtualMachineMaxNicsKvmMock);
11451147

1146-
int virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValueFromVmHypervisorType(virtualMachineMock);
1148+
Integer virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValueFromVmHypervisorType(virtualMachineMock);
11471149

1148-
Assert.assertEquals(23, virtualMachineMaxNicsValue);
1150+
Assert.assertEquals((Integer) 23, virtualMachineMaxNicsValue);
11491151
}
11501152

11511153
@Test
@@ -1156,9 +1158,9 @@ public void getVirtualMachineMaxNicsValueFromVmHypervisorTypeTestVmwareHyperviso
11561158
Mockito.doReturn(10).when(virtualMachineMaxNicsVmwareMock).value();
11571159
updateFinalStaticField(testOrchestrator.getClass().getField("VirtualMachineMaxNicsVmware"), virtualMachineMaxNicsVmwareMock);
11581160

1159-
int virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValueFromVmHypervisorType(virtualMachineMock);
1161+
Integer virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValueFromVmHypervisorType(virtualMachineMock);
11601162

1161-
Assert.assertEquals(10, virtualMachineMaxNicsValue);
1163+
Assert.assertEquals((Integer) 10, virtualMachineMaxNicsValue);
11621164
}
11631165

11641166
@Test
@@ -1169,9 +1171,19 @@ public void getVirtualMachineMaxNicsValueFromVmHypervisorTypeTestXenserverHyperv
11691171
Mockito.doReturn(7).when(virtualMachineMaxNicsXenserverMock).value();
11701172
updateFinalStaticField(testOrchestrator.getClass().getField("VirtualMachineMaxNicsXenserver"), virtualMachineMaxNicsXenserverMock);
11711173

1172-
int virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValueFromVmHypervisorType(virtualMachineMock);
1174+
Integer virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValueFromVmHypervisorType(virtualMachineMock);
1175+
1176+
Assert.assertEquals((Integer) 7, virtualMachineMaxNicsValue);
1177+
}
1178+
1179+
@Test
1180+
public void getVirtualMachineMaxNicsValueFromVmHypervisorTypeTestIncompatibleHypervisorReturnsNull() {
1181+
VirtualMachine virtualMachineMock = Mockito.mock(VirtualMachine.class);
1182+
Mockito.doReturn(Hypervisor.HypervisorType.Hyperv).when(virtualMachineMock).getHypervisorType();
1183+
1184+
Integer virtualMachineMaxNicsValue = testOrchestrator.getVirtualMachineMaxNicsValueFromVmHypervisorType(virtualMachineMock);
11731185

1174-
Assert.assertEquals(7, virtualMachineMaxNicsValue);
1186+
Assert.assertNull(virtualMachineMaxNicsValue);
11751187
}
11761188

11771189
void updateFinalStaticField(Field field, Object newValue) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {

server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2238,7 +2238,13 @@ protected boolean existsVpcDomainRouterWithSufficientNicCapacity(long vpcId) {
22382238
int countRouterDefaultNetworks = domainRouterJoinDao.countDefaultNetworksById(vpcDomainRouter.getId());
22392239
long countVpcNetworks = _ntwkDao.countVpcNetworks(vpcId);
22402240

2241-
int totalNicsAvailable = networkOrchestrationService.getVirtualMachineMaxNicsValue(vpcDomainRouter) - countRouterDefaultNetworks;
2241+
Integer routerMaxNicsValue = networkOrchestrationService.getVirtualMachineMaxNicsValue(vpcDomainRouter);
2242+
2243+
if (routerMaxNicsValue == null) {
2244+
return true;
2245+
}
2246+
2247+
int totalNicsAvailable = routerMaxNicsValue - countRouterDefaultNetworks;
22422248

22432249
return totalNicsAvailable > countVpcNetworks;
22442250
}

0 commit comments

Comments
 (0)