Skip to content

Commit 5636b1b

Browse files
committed
Possible error in the equals method for collection #6641
1 parent 392cdd5 commit 5636b1b

File tree

10 files changed

+72
-15
lines changed

10 files changed

+72
-15
lines changed

api/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ plugins {
2424

2525
dependencies {
2626
implementation(libs.commons.lang3)
27+
implementation(libs.commons.collections4)
2728
implementation(libs.guava)
2829
implementation(libs.slf4j.api)
2930

api/src/main/java/org/apache/gravitino/authorization/SecurableObjects.java

+14-1
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@
2222
import com.google.common.collect.ImmutableList;
2323
import com.google.common.collect.Lists;
2424
import com.google.common.collect.Sets;
25+
import java.util.Collection;
2526
import java.util.List;
2627
import java.util.Objects;
2728
import java.util.stream.Collectors;
29+
import org.apache.commons.collections4.CollectionUtils;
2830
import org.apache.gravitino.MetadataObject;
2931
import org.apache.gravitino.MetadataObjects;
3032
import org.apache.gravitino.MetadataObjects.MetadataObjectImpl;
@@ -168,7 +170,18 @@ public boolean equals(Object other) {
168170
}
169171

170172
SecurableObject otherSecurableObject = (SecurableObject) other;
171-
return super.equals(other) && Objects.equals(privileges, otherSecurableObject.privileges());
173+
return super.equals(other)
174+
&& isEqualCollection(privileges, otherSecurableObject.privileges());
175+
}
176+
177+
private boolean isEqualCollection(Collection<?> c1, Collection<?> c2) {
178+
if (c1 == c2) {
179+
return true;
180+
}
181+
if (c1 == null || c2 == null) {
182+
return false;
183+
}
184+
return CollectionUtils.isEqualCollection(c1, c2);
172185
}
173186
}
174187

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.gravitino.utils;
21+
22+
import java.util.Collection;
23+
24+
/** Utility class for working with collection. */
25+
public class CollectionUtils {
26+
private CollectionUtils() {}
27+
28+
/**
29+
* Returns true if the two collections are equal.
30+
*
31+
* @param c1 the first collection, may be null
32+
* @param c2 the second collection, may be null
33+
* @return true if the two collections are equal
34+
*/
35+
public static boolean isEqualCollection(Collection<?> c1, Collection<?> c2) {
36+
if (c1 == c2) {
37+
return true;
38+
}
39+
if (c1 == null || c2 == null) {
40+
return false;
41+
}
42+
return org.apache.commons.collections4.CollectionUtils.isEqualCollection(c1, c2);
43+
}
44+
}

core/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ dependencies {
3333
implementation(libs.commons.dbcp2)
3434
implementation(libs.commons.io)
3535
implementation(libs.commons.lang3)
36+
implementation(libs.commons.collections4)
3637
implementation(libs.guava)
3738
implementation(libs.h2db)
3839
implementation(libs.mybatis)

core/src/main/java/org/apache/gravitino/meta/GroupEntity.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.apache.gravitino.HasIdentifier;
3030
import org.apache.gravitino.Namespace;
3131
import org.apache.gravitino.authorization.Group;
32+
import org.apache.gravitino.utils.CollectionUtils;
3233

3334
public class GroupEntity implements Group, Entity, Auditable, HasIdentifier {
3435

@@ -161,8 +162,8 @@ public boolean equals(Object o) {
161162
&& Objects.equals(name, that.name)
162163
&& Objects.equals(namespace, that.namespace)
163164
&& Objects.equals(auditInfo, that.auditInfo)
164-
&& Objects.equals(roleNames, that.roleNames)
165-
&& Objects.equals(roleIds, that.roleIds);
165+
&& CollectionUtils.isEqualCollection(roleNames, that.roleNames)
166+
&& CollectionUtils.isEqualCollection(roleIds, that.roleIds);
166167
}
167168

168169
@Override

core/src/main/java/org/apache/gravitino/meta/ModelVersionEntity.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.apache.gravitino.HasIdentifier;
3232
import org.apache.gravitino.NameIdentifier;
3333
import org.apache.gravitino.Namespace;
34+
import org.apache.gravitino.utils.CollectionUtils;
3435

3536
@ToString
3637
public class ModelVersionEntity implements Entity, Auditable, HasIdentifier {
@@ -146,7 +147,7 @@ public boolean equals(Object o) {
146147
return Objects.equals(version, that.version)
147148
&& Objects.equals(modelIdent, that.modelIdent)
148149
&& Objects.equals(comment, that.comment)
149-
&& Objects.equals(aliases, that.aliases)
150+
&& CollectionUtils.isEqualCollection(aliases, that.aliases)
150151
&& Objects.equals(uri, that.uri)
151152
&& Objects.equals(properties, that.properties)
152153
&& Objects.equals(auditInfo, that.auditInfo);

core/src/main/java/org/apache/gravitino/meta/RoleEntity.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.apache.gravitino.Namespace;
3232
import org.apache.gravitino.authorization.Role;
3333
import org.apache.gravitino.authorization.SecurableObject;
34+
import org.apache.gravitino.utils.CollectionUtils;
3435

3536
public class RoleEntity implements Role, Entity, Auditable, HasIdentifier {
3637

@@ -142,7 +143,7 @@ public boolean equals(Object o) {
142143
&& Objects.equals(namespace, that.namespace)
143144
&& Objects.equals(auditInfo, that.auditInfo)
144145
&& Objects.equals(properties, that.properties)
145-
&& Objects.equals(securableObjects, that.securableObjects);
146+
&& CollectionUtils.isEqualCollection(securableObjects, that.securableObjects);
146147
}
147148

148149
@Override

core/src/main/java/org/apache/gravitino/meta/TableEntity.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.apache.gravitino.Field;
3030
import org.apache.gravitino.HasIdentifier;
3131
import org.apache.gravitino.Namespace;
32+
import org.apache.gravitino.utils.CollectionUtils;
3233

3334
/** A class representing a table entity in Apache Gravitino. */
3435
@ToString
@@ -135,7 +136,7 @@ public boolean equals(Object o) {
135136
&& Objects.equal(name, baseTable.name)
136137
&& Objects.equal(namespace, baseTable.namespace)
137138
&& Objects.equal(auditInfo, baseTable.auditInfo)
138-
&& Objects.equal(columns, baseTable.columns);
139+
&& CollectionUtils.isEqualCollection(columns, baseTable.columns);
139140
}
140141

141142
@Override

core/src/main/java/org/apache/gravitino/meta/UserEntity.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.apache.gravitino.HasIdentifier;
3131
import org.apache.gravitino.Namespace;
3232
import org.apache.gravitino.authorization.User;
33+
import org.apache.gravitino.utils.CollectionUtils;
3334

3435
/** A class representing a user metadata entity in Apache Gravitino. */
3536
@ToString
@@ -164,8 +165,8 @@ public boolean equals(Object o) {
164165
&& Objects.equals(name, that.name)
165166
&& Objects.equals(namespace, that.namespace)
166167
&& Objects.equals(auditInfo, that.auditInfo)
167-
&& Objects.equals(roleNames, that.roleNames)
168-
&& Objects.equals(roleIds, that.roleIds);
168+
&& CollectionUtils.isEqualCollection(roleNames, that.roleNames)
169+
&& CollectionUtils.isEqualCollection(roleIds, that.roleIds);
169170
}
170171

171172
@Override

core/src/main/java/org/apache/gravitino/storage/relational/service/RoleMetaService.java

-7
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import com.google.common.collect.Sets;
2525
import java.io.IOException;
2626
import java.util.Collections;
27-
import java.util.Comparator;
2827
import java.util.HashMap;
2928
import java.util.HashSet;
3029
import java.util.List;
@@ -412,12 +411,6 @@ private static List<SecurableObject> listSecurableObjects(RolePO po) {
412411
}
413412
}
414413
});
415-
416-
// To ensure that the order of the returned securable objects remains consistent,
417-
// the securable objects are sorted by fullName here,
418-
// since the order of securable objects after grouping by is different each time.
419-
securableObjects.sort(Comparator.comparing(MetadataObject::fullName));
420-
421414
return securableObjects;
422415
}
423416

0 commit comments

Comments
 (0)