-
Notifications
You must be signed in to change notification settings - Fork 86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[controller] Fix mismatch between hybrid version partition count and real-time partition count #1338
Draft
sushantmane
wants to merge
5
commits into
linkedin:main
Choose a base branch
from
sushantmane:li-hybrid-store-partition-count-issue
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
[controller] Fix mismatch between hybrid version partition count and real-time partition count #1338
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
2386418
fix: ensure real-time topic partition count matches hybrid version pa…
sushantmane 4b4113e
Do not create meta & ps3 RT in parent regions; Skips RT creation for …
sushantmane edc8621
Move check for RT topic creation for system stores
sushantmane 7bbe45b
Add isParent checks
sushantmane 516e78e
Fix flaky tests
sushantmane File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
178 changes: 178 additions & 0 deletions
178
...ce-common/src/main/java/com/linkedin/venice/controllerapi/RequestTopicForPushRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
package com.linkedin.venice.controllerapi; | ||
|
||
import com.linkedin.venice.meta.Version.PushType; | ||
import java.security.cert.X509Certificate; | ||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
|
||
|
||
public class RequestTopicForPushRequest { | ||
private final String clusterName; | ||
private final String storeName; | ||
private final PushType pushType; | ||
private final String pushJobId; | ||
|
||
private boolean sendStartOfPush = false; | ||
private boolean sorted = false; // an inefficient but safe default | ||
private boolean isWriteComputeEnabled = false; | ||
private long rewindTimeInSecondsOverride = -1L; | ||
private boolean deferVersionSwap = false; | ||
private String targetedRegions = null; | ||
private int repushSourceVersion = -1; | ||
private Set<String> partitioners = Collections.emptySet(); | ||
private String compressionDictionary = null; | ||
private X509Certificate certificateInRequest = null; | ||
private String sourceGridFabric = null; | ||
private String emergencySourceRegion = null; | ||
|
||
public RequestTopicForPushRequest(String clusterName, String storeName, PushType pushType, String pushJobId) { | ||
if (clusterName == null || clusterName.isEmpty()) { | ||
throw new IllegalArgumentException("clusterName is required"); | ||
} | ||
if (storeName == null || storeName.isEmpty()) { | ||
throw new IllegalArgumentException("storeName is required"); | ||
} | ||
if (pushType == null) { | ||
throw new IllegalArgumentException("pushType is required"); | ||
} | ||
|
||
if (pushJobId == null || pushJobId.isEmpty()) { | ||
throw new IllegalArgumentException("pushJobId is required"); | ||
} | ||
|
||
this.clusterName = clusterName; | ||
this.storeName = storeName; | ||
this.pushType = pushType; | ||
this.pushJobId = pushJobId; | ||
} | ||
|
||
public static PushType extractPushType(String pushTypeString) { | ||
try { | ||
return PushType.valueOf(pushTypeString); | ||
} catch (IllegalArgumentException e) { | ||
throw new IllegalArgumentException( | ||
pushTypeString + " is an invalid push type. Valid push types are: " + Arrays.toString(PushType.values())); | ||
} | ||
} | ||
|
||
public String getClusterName() { | ||
return clusterName; | ||
} | ||
|
||
public String getStoreName() { | ||
return storeName; | ||
} | ||
|
||
public PushType getPushType() { | ||
return pushType; | ||
} | ||
|
||
public String getPushJobId() { | ||
return pushJobId; | ||
} | ||
|
||
public boolean isSendStartOfPush() { | ||
return sendStartOfPush; | ||
} | ||
|
||
public boolean isSorted() { | ||
return sorted; | ||
} | ||
|
||
public boolean isWriteComputeEnabled() { | ||
return isWriteComputeEnabled; | ||
} | ||
|
||
public String getSourceGridFabric() { | ||
return sourceGridFabric; | ||
} | ||
|
||
public long getRewindTimeInSecondsOverride() { | ||
return rewindTimeInSecondsOverride; | ||
} | ||
|
||
public boolean isDeferVersionSwap() { | ||
return deferVersionSwap; | ||
} | ||
|
||
public String getTargetedRegions() { | ||
return targetedRegions; | ||
} | ||
|
||
public int getRepushSourceVersion() { | ||
return repushSourceVersion; | ||
} | ||
|
||
public Set<String> getPartitioners() { | ||
return partitioners; | ||
} | ||
|
||
public String getCompressionDictionary() { | ||
return compressionDictionary; | ||
} | ||
|
||
public X509Certificate getCertificateInRequest() { | ||
return certificateInRequest; | ||
} | ||
|
||
public String getEmergencySourceRegion() { | ||
return emergencySourceRegion; | ||
} | ||
|
||
public void setSendStartOfPush(boolean sendStartOfPush) { | ||
this.sendStartOfPush = sendStartOfPush; | ||
} | ||
|
||
public void setSorted(boolean sorted) { | ||
this.sorted = sorted; | ||
} | ||
|
||
public void setWriteComputeEnabled(boolean writeComputeEnabled) { | ||
isWriteComputeEnabled = writeComputeEnabled; | ||
} | ||
|
||
public void setSourceGridFabric(String sourceGridFabric) { | ||
this.sourceGridFabric = sourceGridFabric; | ||
} | ||
|
||
public void setRewindTimeInSecondsOverride(long rewindTimeInSecondsOverride) { | ||
this.rewindTimeInSecondsOverride = rewindTimeInSecondsOverride; | ||
} | ||
|
||
public void setDeferVersionSwap(boolean deferVersionSwap) { | ||
this.deferVersionSwap = deferVersionSwap; | ||
} | ||
|
||
public void setTargetedRegions(String targetedRegions) { | ||
this.targetedRegions = targetedRegions; | ||
} | ||
|
||
public void setRepushSourceVersion(int repushSourceVersion) { | ||
this.repushSourceVersion = repushSourceVersion; | ||
} | ||
|
||
public void setPartitioners(String commaSeparatedPartitioners) { | ||
if (commaSeparatedPartitioners == null || commaSeparatedPartitioners.isEmpty()) { | ||
return; | ||
} | ||
setPartitioners(new HashSet<>(Arrays.asList(commaSeparatedPartitioners.split(",")))); | ||
} | ||
|
||
public void setPartitioners(Set<String> partitioners) { | ||
this.partitioners = partitioners; | ||
} | ||
|
||
public void setCompressionDictionary(String compressionDictionary) { | ||
this.compressionDictionary = compressionDictionary; | ||
} | ||
|
||
public void setCertificateInRequest(X509Certificate certificateInRequest) { | ||
this.certificateInRequest = certificateInRequest; | ||
} | ||
|
||
public void setEmergencySourceRegion(String emergencySourceRegion) { | ||
this.emergencySourceRegion = emergencySourceRegion; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
114 changes: 114 additions & 0 deletions
114
...ommon/src/test/java/com/linkedin/venice/controllerapi/RequestTopicForPushRequestTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package com.linkedin.venice.controllerapi; | ||
|
||
import static com.linkedin.venice.meta.Version.PushType.BATCH; | ||
import static com.linkedin.venice.meta.Version.PushType.STREAM; | ||
import static org.testng.Assert.assertEquals; | ||
import static org.testng.Assert.assertTrue; | ||
|
||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.HashSet; | ||
import org.testng.Assert; | ||
import org.testng.annotations.BeforeMethod; | ||
import org.testng.annotations.Test; | ||
|
||
|
||
public class RequestTopicForPushRequestTest { | ||
private RequestTopicForPushRequest request; | ||
|
||
@BeforeMethod | ||
public void setUp() { | ||
request = new RequestTopicForPushRequest("clusterA", "storeA", BATCH, "job123"); | ||
} | ||
|
||
@Test | ||
public void testRequestTopicForPushRequestConstructorArgs() { | ||
assertEquals(request.getClusterName(), "clusterA"); | ||
assertEquals(request.getStoreName(), "storeA"); | ||
assertEquals(request.getPushType(), BATCH); | ||
assertEquals(request.getPushJobId(), "job123"); | ||
|
||
// Invalid clusterName | ||
IllegalArgumentException ex1 = Assert.expectThrows( | ||
IllegalArgumentException.class, | ||
() -> new RequestTopicForPushRequest("", "storeA", BATCH, "job123")); | ||
assertEquals(ex1.getMessage(), "clusterName is required"); | ||
|
||
// Invalid storeName | ||
IllegalArgumentException ex2 = Assert.expectThrows( | ||
IllegalArgumentException.class, | ||
() -> new RequestTopicForPushRequest("clusterA", "", BATCH, "job123")); | ||
assertEquals(ex2.getMessage(), "storeName is required"); | ||
|
||
// Null pushType | ||
IllegalArgumentException ex3 = Assert.expectThrows( | ||
IllegalArgumentException.class, | ||
() -> new RequestTopicForPushRequest("clusterA", "storeA", null, "job123")); | ||
assertEquals(ex3.getMessage(), "pushType is required"); | ||
|
||
// Invalid pushJobId | ||
IllegalArgumentException ex4 = Assert.expectThrows( | ||
IllegalArgumentException.class, | ||
() -> new RequestTopicForPushRequest("clusterA", "storeA", BATCH, "")); | ||
assertEquals(ex4.getMessage(), "pushJobId is required"); | ||
} | ||
|
||
@Test | ||
public void testExtractPushTypeValidAndInvalidValues() { | ||
// Valid cases | ||
assertEquals(RequestTopicForPushRequest.extractPushType("BATCH"), BATCH); | ||
assertEquals(RequestTopicForPushRequest.extractPushType("STREAM"), STREAM); | ||
|
||
// Invalid case | ||
IllegalArgumentException ex = Assert | ||
.expectThrows(IllegalArgumentException.class, () -> RequestTopicForPushRequest.extractPushType("INVALID")); | ||
assertTrue(ex.getMessage().contains("INVALID is an invalid push type")); | ||
} | ||
|
||
@Test | ||
public void testRequestTopicForPushRequestSettersAndGetters() { | ||
request.setSendStartOfPush(true); | ||
request.setSorted(true); | ||
request.setWriteComputeEnabled(true); | ||
request.setSourceGridFabric("fabricA"); | ||
request.setRewindTimeInSecondsOverride(3600); | ||
request.setDeferVersionSwap(true); | ||
request.setTargetedRegions("regionA,regionB"); | ||
request.setRepushSourceVersion(42); | ||
request.setPartitioners("partitioner1,partitioner2"); | ||
request.setCompressionDictionary("compressionDict"); | ||
request.setEmergencySourceRegion("regionX"); | ||
|
||
assertTrue(request.isSendStartOfPush()); | ||
assertTrue(request.isSorted()); | ||
assertTrue(request.isWriteComputeEnabled()); | ||
assertEquals(request.getSourceGridFabric(), "fabricA"); | ||
assertEquals(request.getRewindTimeInSecondsOverride(), 3600); | ||
assertTrue(request.isDeferVersionSwap()); | ||
assertEquals(request.getTargetedRegions(), "regionA,regionB"); | ||
assertEquals(request.getRepushSourceVersion(), 42); | ||
assertEquals(request.getPartitioners(), new HashSet<>(Arrays.asList("partitioner1", "partitioner2"))); | ||
assertEquals(request.getCompressionDictionary(), "compressionDict"); | ||
assertEquals(request.getEmergencySourceRegion(), "regionX"); | ||
} | ||
|
||
@Test | ||
public void testSetPartitionersValidAndEmptyCases() { | ||
// Valid partitioners | ||
request.setPartitioners("partitioner1"); | ||
assertEquals(request.getPartitioners(), new HashSet<>(Collections.singletonList("partitioner1"))); | ||
request.setPartitioners("partitioner1,partitioner2"); | ||
assertEquals(request.getPartitioners(), new HashSet<>(Arrays.asList("partitioner1", "partitioner2"))); | ||
|
||
// Empty set | ||
request.setPartitioners(Collections.emptySet()); | ||
assertEquals(request.getPartitioners(), Collections.emptySet()); | ||
|
||
// Null and empty string | ||
request.setPartitioners((String) null); | ||
assertEquals(request.getPartitioners(), Collections.emptySet()); | ||
|
||
request.setPartitioners(""); | ||
assertEquals(request.getPartitioners(), Collections.emptySet()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect there is a bug here in this function. I need to think through