Skip to content

Commit b572e15

Browse files
authored
Merge branch 'master' into fix/commons_lang3_upgrade_non_vulnerable_version
2 parents d371d2e + 0680aa7 commit b572e15

File tree

14 files changed

+149
-61
lines changed

14 files changed

+149
-61
lines changed

CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ and what APIs have changed, if applicable.
1414

1515
## [Unreleased]
1616

17+
## [29.74.1] - 2025-08-13
18+
- Add new fields to D2Uri.pdl for debugging. These mirror fields in the D2URI proto in XdsD2.proto.
19+
20+
## [29.74.0] - 2025-08-12
21+
- Bump gRPC version to fix IPv6AwarePickFirstLoadBalancer
22+
23+
## [29.73.0] - 2025-08-08
24+
- Empty version bump
25+
1726
## [29.72.1] - 2025-08-07
1827
- Introduce new IPv6 aware Pick First policy
1928

@@ -5864,7 +5873,10 @@ patch operations can re-use these classes for generating patch messages.
58645873

58655874
## [0.14.1]
58665875

5867-
[Unreleased]: https://github.com/linkedin/rest.li/compare/v29.72.1...master
5876+
[Unreleased]: https://github.com/linkedin/rest.li/compare/v29.74.1...master
5877+
[29.74.1]: https://github.com/linkedin/rest.li/compare/v29.74.0...v29.74.1
5878+
[29.74.0]: https://github.com/linkedin/rest.li/compare/v29.73.0...v29.74.0
5879+
[29.73.0]: https://github.com/linkedin/rest.li/compare/v29.72.1...v29.73.0
58685880
[29.72.1]: https://github.com/linkedin/rest.li/compare/v29.72.0...v29.72.1
58695881
[29.72.0]: https://github.com/linkedin/rest.li/compare/v29.71.0...v29.72.0
58705882
[29.71.0]: https://github.com/linkedin/rest.li/compare/v29.70.2...v29.71.0

build.gradle

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -115,21 +115,21 @@ project.ext.externalDependency = [
115115
'springBeans': 'org.springframework:spring-beans:3.2.18.RELEASE',
116116

117117
// for restli-guice-bridge ONLY, we should keep these dependencies isolated
118-
'guice': 'com.google.inject:guice:3.0',
119-
'guiceServlet': 'com.google.inject.extensions:guice-servlet:3.0',
118+
'guice' : 'com.google.inject:guice:3.0',
119+
'guiceServlet' : 'com.google.inject.extensions:guice-servlet:3.0',
120120

121-
'jsr305': 'com.google.code.findbugs:jsr305:3.0.0',
122-
"avroSpotBugsPlugin": "com.linkedin.avroutil1:spotbugs-plugin:0.2.56",
123-
"classgraph": "io.github.classgraph:classgraph:4.8.149",
121+
'jsr305' : 'com.google.code.findbugs:jsr305:3.0.0',
122+
"avroSpotBugsPlugin" : "com.linkedin.avroutil1:spotbugs-plugin:0.2.56",
123+
"classgraph" : "io.github.classgraph:classgraph:4.8.149",
124124

125125
// for integrating with xDS service discovery
126-
'grpcNettyShaded': 'io.grpc:grpc-netty-shaded:1.59.1',
127-
'grpcProtobuf': 'io.grpc:grpc-protobuf:1.59.1',
128-
'grpcStub': 'io.grpc:grpc-stub:1.59.1',
129-
'protoc': 'com.google.protobuf:protoc:3.24.0',
130-
'protobufJava': 'com.google.protobuf:protobuf-java:3.24.0',
131-
'protobufJavaUtil': 'com.google.protobuf:protobuf-java-util:3.24.0',
132-
'envoyApi': 'io.envoyproxy.controlplane:api:0.1.35',
126+
'grpcNettyShaded' : 'io.grpc:grpc-netty-shaded:1.68.3',
127+
'grpcProtobuf' : 'io.grpc:grpc-protobuf:1.68.3',
128+
'grpcStub' : 'io.grpc:grpc-stub:1.68.3',
129+
'protoc' : 'com.google.protobuf:protoc:3.25.5',
130+
'protobufJava' : 'com.google.protobuf:protobuf-java:3.25.5',
131+
'protobufJavaUtil' : 'com.google.protobuf:protobuf-java-util:3.25.5',
132+
'envoyApi' : 'io.envoyproxy.controlplane:api:0.1.35',
133133
];
134134

135135
if (!project.ext.isDefaultEnvironment)
@@ -234,7 +234,10 @@ subprojects {
234234
// so they don't conflict with "velocity-engine-core" module used
235235
// for versions >=2.0
236236
all*.exclude group: 'org.apache.velocity', module: 'velocity'
237-
237+
238+
//Excluding vulnerable package (commons-lang)(CVE-2025-48924)
239+
all*.exclude group: 'commons-lang', module: 'commons-lang'
240+
238241
configureEach {
239242
// Force commons-lang3 to a fixed safe version
240243
resolutionStrategy {
@@ -441,6 +444,16 @@ subprojects {
441444
}
442445
logger.lifecycle "Tests for subproject ${project.name} will be skipped."
443446
}
447+
448+
// The following prevent gradle from picking android-specific artifacts, which breaks compilation. This was introduced
449+
// by more recent versions of guava which produces android and JVM variants of their jars.
450+
dependencies.constraints {
451+
add("compile", "com.google.guava:guava") {
452+
attributes {
453+
attribute(Attribute.of("org.gradle.jvm.environment", String),"standard-jvm")
454+
}
455+
}
456+
}
444457
}
445458

446459
final skippedTests = [:].withDefault {[]}
@@ -481,4 +494,3 @@ project.gradle.buildFinished { BuildResult result ->
481494
logger.warn msgBuilder.toString()
482495
}
483496
}
484-

d2-schemas/src/main/pegasus/com/linkedin/d2/D2Uri.pdl

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,44 @@ record D2Uri {
1919
* partitionId key to weight
2020
*/
2121
partitionDescription: map[string, double]
22+
23+
/**
24+
* URI for this machine with the hostname replaced with an ipv4. Only set if an ipv4 is provided and isIpv4InSan is true.
25+
*/
26+
ipv4VariantURI: optional string
27+
28+
/**
29+
* URI for this machine with the hostname replaced with an ipv6. Only set if an ipv6 is provided and isIpv6InSan is true
30+
*/
31+
ipv6VariantURI: optional string
32+
33+
/**
34+
* The time this URI was last modified, in RFC 3339 date string format
35+
*/
36+
modifiedTime: optional string
37+
38+
/**
39+
* The hostname of the machine making this announcement
40+
*/
41+
hostname: optional string
42+
43+
/**
44+
* The ipv4 of the machine making this announcement
45+
*/
46+
ipv4Address: optional string
47+
48+
/**
49+
* The ipv6 of the machine making this announcement
50+
*/
51+
ipv6Address: optional string
52+
53+
/**
54+
* Whether the ipv4 provided is also in the app's TLS cert
55+
*/
56+
isIpv4InSan: optional boolean
57+
58+
/**
59+
* Whether the ipv6 provided is also in the app's TLS cert
60+
*/
61+
isIpv6InSan: optional boolean
2262
}

d2/src/main/java/com/linkedin/d2/balancer/clients/RetryClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656

5757
import java.util.concurrent.TimeUnit;
5858
import javax.annotation.concurrent.ThreadSafe;
59-
import org.apache.commons.lang.exception.ExceptionUtils;
59+
import org.apache.commons.lang3.exception.ExceptionUtils;
6060
import org.checkerframework.checker.lock.qual.GuardedBy;
6161
import org.slf4j.Logger;
6262
import org.slf4j.LoggerFactory;

d2/src/main/java/com/linkedin/d2/xds/IPv6AwarePickFirstLoadBalancer.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,13 @@
66
import io.grpc.LoadBalancerRegistry;
77
import io.grpc.NameResolver.ConfigOrError;
88
import io.grpc.Status;
9-
import io.grpc.internal.PickFirstLoadBalancerProvider;
109
import java.net.Inet6Address;
1110
import java.net.InetSocketAddress;
1211
import java.net.SocketAddress;
1312
import java.util.ArrayList;
1413
import java.util.Collections;
1514
import java.util.Iterator;
1615
import java.util.List;
17-
import java.util.ListIterator;
1816
import java.util.Map;
1917

2018
/**
@@ -48,16 +46,13 @@ public class IPv6AwarePickFirstLoadBalancer extends LoadBalancer
4846

4947
IPv6AwarePickFirstLoadBalancer(Helper helper)
5048
{
51-
this(new PickFirstLoadBalancerProvider().newLoadBalancer(helper));
52-
}
53-
54-
IPv6AwarePickFirstLoadBalancer(LoadBalancer delegate)
55-
{
56-
_delegate = delegate;
49+
_delegate = LoadBalancerRegistry.getDefaultRegistry()
50+
.getProvider("pick_first")
51+
.newLoadBalancer(helper);
5752
}
5853

5954
@Override
60-
public boolean acceptResolvedAddresses(ResolvedAddresses resolvedAddresses)
55+
public Status acceptResolvedAddresses(ResolvedAddresses resolvedAddresses)
6156
{
6257
return _delegate.acceptResolvedAddresses(resolvedAddresses.toBuilder()
6358
.setAddresses(ipAwareShuffle(resolvedAddresses.getAddresses()))
@@ -156,7 +151,6 @@ public int getPriority()
156151
@Override
157152
public String getPolicyName()
158153
{
159-
160154
return POLICY_NAME;
161155
}
162156

d2/src/test/java/com/linkedin/d2/xds/IPv6AwarePickFirstLoadBalancerTest.java

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import io.grpc.EquivalentAddressGroup;
44
import io.grpc.LoadBalancer;
5+
import io.grpc.LoadBalancerProvider;
56
import io.grpc.LoadBalancerRegistry;
67
import java.net.InetAddress;
78
import java.net.InetSocketAddress;
@@ -14,24 +15,15 @@
1415
import java.util.stream.Collectors;
1516
import java.util.stream.IntStream;
1617
import org.mockito.ArgumentCaptor;
17-
import org.mockito.Mockito;
18-
import org.testng.annotations.DataProvider;
1918
import org.testng.annotations.Test;
2019

2120
import static com.linkedin.d2.xds.IPv6AwarePickFirstLoadBalancer.*;
22-
import static org.mockito.Mockito.verify;
21+
import static org.mockito.Mockito.*;
2322
import static org.testng.Assert.*;
2423

2524
public class IPv6AwarePickFirstLoadBalancerTest
2625
{
27-
@Test
28-
public void testRegistration()
29-
{
30-
assertNotNull(LoadBalancerRegistry.getDefaultRegistry().getProvider(POLICY_NAME));
31-
}
32-
33-
@DataProvider
34-
public Object[] addresses()
26+
public List<List<EquivalentAddressGroup>> generateAddressGroups()
3527
{
3628
List<List<EquivalentAddressGroup>> addresses = new ArrayList<>();
3729
for (int i = 0; i < 10; i++)
@@ -49,26 +41,64 @@ public Object[] addresses()
4941
addresses.add(IntStream.range(0, 100)
5042
.mapToObj(j -> newGroup(j >= 50))
5143
.collect(Collectors.toList()));
52-
return addresses.toArray();
44+
return addresses;
5345
}
5446

55-
@Test(invocationCount = 10, dataProvider = "addresses")
56-
public void testShuffling(List<EquivalentAddressGroup> addresses)
47+
@Test
48+
public void testShuffling()
5749
{
58-
LoadBalancer mock = Mockito.mock(LoadBalancer.class);
59-
IPv6AwarePickFirstLoadBalancer lb = new IPv6AwarePickFirstLoadBalancer(mock);
60-
lb.acceptResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(addresses).build());
61-
50+
LoadBalancer mockedPickFirst = mock(LoadBalancer.class);
6251
ArgumentCaptor<ResolvedAddresses> addressesCaptor = ArgumentCaptor.forClass(ResolvedAddresses.class);
63-
verify(mock).acceptResolvedAddresses(addressesCaptor.capture());
6452

65-
List<EquivalentAddressGroup> shuffledAddresses = addressesCaptor.getValue().getAddresses();
66-
assertNotEquals(addresses, shuffledAddresses);
67-
assertEquals(new HashSet<>(addresses), new HashSet<>(shuffledAddresses));
53+
LoadBalancerRegistry.getDefaultRegistry().register(new LoadBalancerProvider()
54+
{
55+
@Override
56+
public boolean isAvailable()
57+
{
58+
return true;
59+
}
60+
61+
@Override
62+
public int getPriority()
63+
{
64+
// Set the highest priority, so it overrides the built-in "pick_first" policy and return the mock.
65+
return Integer.MAX_VALUE;
66+
}
6867

69-
for (int i = 0; i < addresses.size(); i++)
68+
@Override
69+
public String getPolicyName()
70+
{
71+
return "pick_first";
72+
}
73+
74+
@Override
75+
public LoadBalancer newLoadBalancer(Helper helper)
76+
{
77+
return mockedPickFirst;
78+
}
79+
});
80+
LoadBalancer lb = LoadBalancerRegistry.getDefaultRegistry()
81+
.getProvider(POLICY_NAME)
82+
.newLoadBalancer(mock(Helper.class));
83+
assertTrue(lb instanceof IPv6AwarePickFirstLoadBalancer);
84+
85+
for (List<EquivalentAddressGroup> addresses : generateAddressGroups())
7086
{
71-
assertEquals(hasIPv6Address(addresses.get(i)), hasIPv6Address(shuffledAddresses.get(i)));
87+
reset(mockedPickFirst);
88+
89+
lb.acceptResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(addresses).build());
90+
91+
verify(mockedPickFirst).acceptResolvedAddresses(addressesCaptor.capture());
92+
93+
94+
List<EquivalentAddressGroup> shuffledAddresses = addressesCaptor.getValue().getAddresses();
95+
assertNotEquals(addresses, shuffledAddresses);
96+
assertEquals(new HashSet<>(addresses), new HashSet<>(shuffledAddresses));
97+
98+
for (int i = 0; i < addresses.size(); i++)
99+
{
100+
assertEquals(hasIPv6Address(addresses.get(i)), hasIPv6Address(shuffledAddresses.get(i)));
101+
}
72102
}
73103
}
74104

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version=29.72.1
1+
version=29.74.1
22
group=com.linkedin.pegasus
33
org.gradle.configureondemand=true
44
org.gradle.parallel=true

restli-client/src/main/java/com/linkedin/restli/client/BatchingKey.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
import java.util.Map;
55

66
import com.linkedin.data.template.RecordTemplate;
7-
import org.apache.commons.lang.builder.EqualsBuilder;
8-
import org.apache.commons.lang.builder.HashCodeBuilder;
7+
import org.apache.commons.lang3.builder.EqualsBuilder;
8+
import org.apache.commons.lang3.builder.HashCodeBuilder;
99

1010

1111
/**

restli-client/src/main/java/com/linkedin/restli/client/Request.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
import java.util.Map;
4242
import java.util.Set;
4343
import java.util.regex.Pattern;
44-
import org.apache.commons.lang.StringUtils;
44+
import org.apache.commons.lang3.StringUtils;
4545

4646

4747
/**

restli-docgen/src/main/java/com/linkedin/restli/docgen/RestLiHTMLDocumentationRenderer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
import java.util.Collections;
4949
import java.util.function.Function;
5050
import java.util.stream.Collectors;
51-
import org.apache.commons.lang.exception.ExceptionUtils;
51+
import org.apache.commons.lang3.exception.ExceptionUtils;
5252
import org.slf4j.Logger;
5353
import org.slf4j.LoggerFactory;
5454

0 commit comments

Comments
 (0)