Skip to content

Commit 1efe6e2

Browse files
committed
Merge remote-tracking branch 'origin/4.13' into 4.14
Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
2 parents ca1e02f + d6152b3 commit 1efe6e2

3 files changed

Lines changed: 131 additions & 15 deletions

File tree

api/src/main/java/com/cloud/network/Networks.java

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.net.URISyntaxException;
2121

2222
import com.cloud.utils.exception.CloudRuntimeException;
23+
import org.apache.commons.lang3.StringUtils;
2324

2425
/**
2526
* Network includes all of the enums used within networking.
@@ -253,20 +254,42 @@ public static URI fromString(String candidate) {
253254
Long.parseLong(candidate);
254255
return Vlan.toUri(candidate);
255256
} catch (NumberFormatException nfe) {
256-
if (com.cloud.dc.Vlan.UNTAGGED.equalsIgnoreCase(candidate)) {
257-
return Native.toUri(candidate);
258-
}
259-
try {
260-
URI uri = new URI(candidate);
261-
BroadcastDomainType tiep = getSchemeValue(uri);
262-
if (tiep.scheme != null && tiep.scheme.equals(uri.getScheme())) {
263-
return uri;
264-
} else {
265-
throw new CloudRuntimeException("string '" + candidate + "' has an unknown BroadcastDomainType.");
266-
}
267-
} catch (URISyntaxException e) {
268-
throw new CloudRuntimeException("string is not a broadcast URI: " + candidate);
257+
return getVlanUriWhenNumberFormatException(candidate);
258+
}
259+
}
260+
261+
/**
262+
* This method is called in case of NumberFormatException is thrown when parsing the String into long
263+
*/
264+
private static URI getVlanUriWhenNumberFormatException(String candidate) {
265+
if(StringUtils.isBlank(candidate)) {
266+
throw new CloudRuntimeException("Expected VLAN or VXLAN but got a null isolation method");
267+
}
268+
if (com.cloud.dc.Vlan.UNTAGGED.equalsIgnoreCase(candidate)) {
269+
return Native.toUri(candidate);
270+
}
271+
try {
272+
URI uri = new URI(candidate);
273+
BroadcastDomainType tiep = getSchemeValue(uri);
274+
if (tiep.scheme != null && tiep.scheme.equals(uri.getScheme())) {
275+
return uri;
276+
} else {
277+
throw new CloudRuntimeException("string '" + candidate + "' has an unknown BroadcastDomainType.");
269278
}
279+
} catch (URISyntaxException e) {
280+
throw new CloudRuntimeException("string is not a broadcast URI: " + candidate);
281+
}
282+
}
283+
284+
/**
285+
* Encodes a string into a BroadcastUri, according to the given BroadcastDomainType
286+
*/
287+
public static URI encodeStringIntoBroadcastUri(String candidate, BroadcastDomainType isolationMethod) {
288+
try{
289+
Long.parseLong(candidate);
290+
return isolationMethod.toUri(candidate);
291+
} catch (NumberFormatException nfe) {
292+
return getVlanUriWhenNumberFormatException(candidate);
270293
}
271294
}
272295
};

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

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2311,7 +2311,7 @@ private Network createGuestNetwork(final long networkOfferingId, final String na
23112311
}
23122312

23132313
if (vlanSpecified) {
2314-
URI uri = BroadcastDomainType.fromString(vlanId);
2314+
URI uri = encodeVlanIdIntoBroadcastUri(vlanId, pNtwk);
23152315
// Aux: generate secondary URI for secondary VLAN ID (if provided) for performing checks
23162316
URI secondaryUri = isNotBlank(isolatedPvlan) ? BroadcastDomainType.fromString(isolatedPvlan) : null;
23172317
//don't allow to specify vlan tag used by physical network for dynamic vlan allocation
@@ -2465,7 +2465,7 @@ public Network doInTransaction(final TransactionStatus status) {
24652465
//Logical router's UUID provided as VLAN_ID
24662466
userNetwork.setVlanIdAsUUID(vlanIdFinal); //Set transient field
24672467
} else {
2468-
uri = BroadcastDomainType.fromString(vlanIdFinal);
2468+
uri = encodeVlanIdIntoBroadcastUri(vlanIdFinal, pNtwk);
24692469
}
24702470
userNetwork.setBroadcastUri(uri);
24712471
if (!vlanIdFinal.equalsIgnoreCase(Vlan.UNTAGGED)) {
@@ -2523,6 +2523,25 @@ public Network doInTransaction(final TransactionStatus status) {
25232523
return network;
25242524
}
25252525

2526+
/**
2527+
* Encodes VLAN/VXLAN ID into a Broadcast URI according to the isolation method from the Physical Network.
2528+
* @return Broadcast URI, e.g. 'vlan://vlan_ID' or 'vxlan://vlxan_ID'
2529+
*/
2530+
protected URI encodeVlanIdIntoBroadcastUri(String vlanId, PhysicalNetwork pNtwk) {
2531+
if (pNtwk == null) {
2532+
throw new InvalidParameterValueException(String.format("Failed to encode VLAN/VXLAN %s into a Broadcast URI. Physical Network cannot be null.", vlanId));
2533+
}
2534+
2535+
if(StringUtils.isNotBlank(pNtwk.getIsolationMethods().get(0))) {
2536+
String isolationMethod = pNtwk.getIsolationMethods().get(0).toLowerCase();
2537+
String vxlan = BroadcastDomainType.Vxlan.toString().toLowerCase();
2538+
if(isolationMethod.equals(vxlan)) {
2539+
return BroadcastDomainType.encodeStringIntoBroadcastUri(vlanId, BroadcastDomainType.Vxlan);
2540+
}
2541+
}
2542+
return BroadcastDomainType.fromString(vlanId);
2543+
}
2544+
25262545
/**
25272546
* Checks bypass VLAN id/range overlap check during network creation for guest networks
25282547
* @param bypassVlanOverlapCheck bypass VLAN id/range overlap check

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

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,15 @@
2222
import static org.mockito.Mockito.verify;
2323
import static org.mockito.Mockito.when;
2424

25+
import java.net.URI;
2526
import java.util.ArrayList;
2627
import java.util.Arrays;
2728
import java.util.HashMap;
2829
import java.util.List;
2930
import java.util.Map;
3031

32+
import com.cloud.network.dao.PhysicalNetworkVO;
33+
import com.cloud.utils.exception.CloudRuntimeException;
3134
import org.apache.log4j.Logger;
3235
import org.junit.Assert;
3336
import org.junit.Before;
@@ -463,4 +466,75 @@ public void validateLockedRequestedIpTestFreeAndNotNullIp() {
463466
testOrchastrator.validateLockedRequestedIp(ipVoSpy, lockedIp);
464467
}
465468

469+
@Test
470+
public void encodeVlanIdIntoBroadcastUriTestVxlan() {
471+
encodeVlanIdIntoBroadcastUriPrepareAndTest("123", "VXLAN", "vxlan", "vxlan://123");
472+
}
473+
474+
@Test
475+
public void encodeVlanIdIntoBroadcastUriTestVlan() {
476+
encodeVlanIdIntoBroadcastUriPrepareAndTest("123", "VLAN", "vlan", "vlan://123");
477+
}
478+
479+
@Test
480+
public void encodeVlanIdIntoBroadcastUriTestEmpty() {
481+
encodeVlanIdIntoBroadcastUriPrepareAndTest("123", "", "vlan", "vlan://123");
482+
}
483+
484+
@Test
485+
public void encodeVlanIdIntoBroadcastUriTestNull() {
486+
encodeVlanIdIntoBroadcastUriPrepareAndTest("123", null, "vlan", "vlan://123");
487+
}
488+
489+
@Test(expected = CloudRuntimeException.class)
490+
public void encodeVlanIdIntoBroadcastUriTestEmptyVlanId() {
491+
encodeVlanIdIntoBroadcastUriPrepareAndTest("", "vxlan", "vlan", "vlan://123");
492+
}
493+
494+
@Test(expected = CloudRuntimeException.class)
495+
public void encodeVlanIdIntoBroadcastUriTestNullVlanId() {
496+
encodeVlanIdIntoBroadcastUriPrepareAndTest(null, "vlan", "vlan", "vlan://123");
497+
}
498+
499+
@Test(expected = CloudRuntimeException.class)
500+
public void encodeVlanIdIntoBroadcastUriTestBlankVlanId() {
501+
encodeVlanIdIntoBroadcastUriPrepareAndTest(" ", "vlan", "vlan", "vlan://123");
502+
}
503+
504+
@Test
505+
public void encodeVlanIdIntoBroadcastUriTestNullVlanIdWithSchema() {
506+
encodeVlanIdIntoBroadcastUriPrepareAndTest("vlan://123", "vlan", "vlan", "vlan://123");
507+
}
508+
509+
@Test
510+
public void encodeVlanIdIntoBroadcastUriTestNullVlanIdWithSchemaIsolationVxlan() {
511+
encodeVlanIdIntoBroadcastUriPrepareAndTest("vlan://123", "vxlan", "vlan", "vlan://123");
512+
}
513+
514+
@Test
515+
public void encodeVlanIdIntoBroadcastUriTestNullVxlanIdWithSchema() {
516+
encodeVlanIdIntoBroadcastUriPrepareAndTest("vxlan://123", "vxlan", "vxlan", "vxlan://123");
517+
}
518+
519+
@Test
520+
public void encodeVlanIdIntoBroadcastUriTestNullVxlanIdWithSchemaIsolationVlan() {
521+
encodeVlanIdIntoBroadcastUriPrepareAndTest("vxlan://123", "vlan", "vxlan", "vxlan://123");
522+
}
523+
524+
@Test(expected = InvalidParameterValueException.class)
525+
public void encodeVlanIdIntoBroadcastUriTestNullNetwork() {
526+
URI resultUri = testOrchastrator.encodeVlanIdIntoBroadcastUri("vxlan://123", null);
527+
}
528+
529+
private void encodeVlanIdIntoBroadcastUriPrepareAndTest(String vlanId, String isolationMethod, String expectedIsolation, String expectedUri) {
530+
PhysicalNetworkVO physicalNetwork = new PhysicalNetworkVO();
531+
List<String> isolationMethods = new ArrayList<>();
532+
isolationMethods.add(isolationMethod);
533+
physicalNetwork.setIsolationMethods(isolationMethods);
534+
535+
URI resultUri = testOrchastrator.encodeVlanIdIntoBroadcastUri(vlanId, physicalNetwork);
536+
537+
Assert.assertEquals(expectedIsolation, resultUri.getScheme());
538+
Assert.assertEquals(expectedUri, resultUri.toString());
539+
}
466540
}

0 commit comments

Comments
 (0)