This is an automated email from the ASF dual-hosted git repository.
roryqi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 8868eb2f36 [#12493] feat(idp): Add optional comment to idp_group_meta
(#12494)
8868eb2f36 is described below
commit 8868eb2f36697577ff90718e2797dd5a2a5cfdef
Author: MaSai <[email protected]>
AuthorDate: Wed Aug 19 10:13:59 2026 +0800
[#12493] feat(idp): Add optional comment to idp_group_meta (#12494)
### What changes were proposed in this pull request?
Add an optional description for built-in IdP groups.
- Persist `group_comment VARCHAR(1024) DEFAULT ''` on `idp_group_meta`
(utf8mb4, 1024 Unicode characters).
- Expose optional REST JSON field `comment` on group create (`POST
/api/idp/groups`) and get.
- Omit or `null` on create → store empty string.
- Existing rows get `''` via column default / 1.3.0 → 2.0.0 upgrade.
- Schema: 2.0.0 CREATE + 1.3.0 → 2.0.0 ALTER for MySQL, PostgreSQL, and
H2. Released 1.3.0 schema is unchanged.
- OpenAPI, `docs/security/local-users-and-groups.md`, and the local-auth
design doc table snippet updated.
Update-group REST (`PUT /api/idp/groups/{group}`) is out of scope;
create writes the comment and GET returns it.
### Why are the changes needed?
Local IdP groups currently store only `group_name`. Operators have no
place to record a short description (purpose, owner, etc.) when creating
a group.
Fix: #12493
### Does this PR introduce _any_ user-facing change?
- Optional `comment` on `POST /api/idp/groups` request body (max 1024
characters).
- `comment` returned on group GET responses (`null` JSON normalizes to
`""`).
- New `idp_group_meta.group_comment` column after upgrade to 2.0.0.
### How was this patch tested?
- Unit tests: `TestIdpUserGroupManager`, `TestAddGroupRequest`,
`TestIdpGroupDTO`, `TestIdpGroupPO`, `TestIdpGroupMetaStorage`,
`TestIdpOperations`.
- REST IT: `IdpRESTApiIT` create/get comment round-trip and
1025-character rejection.
---------
Co-authored-by: Cursor <[email protected]>
---
design-docs/gravitino-local-authentication.md | 1 +
docs/open-api/idp/idp.yaml | 14 +++++++-
docs/security/local-users-and-groups.md | 4 +--
.../apache/gravitino/idp/IdpUserGroupManager.java | 20 +++++++++--
.../idp/basic/IdpCredentialValidator.java | 13 +++++++
.../org/apache/gravitino/idp/dto/IdpGroupDTO.java | 15 +++++++-
.../idp/dto/requests/AddGroupRequest.java | 19 +++++++++-
.../org/apache/gravitino/idp/model/IdpGroup.java | 28 ++++++++++++---
.../provider/base/IdpGroupMetaBaseSQLProvider.java | 7 ++--
.../mapper/provider/h2/IdpGroupMetaH2Provider.java | 3 +-
.../postgresql/IdpGroupMetaPostgreSQLProvider.java | 3 +-
.../gravitino/idp/storage/po/IdpGroupPO.java | 1 +
.../idp/storage/po/IdpGroupWithUsersPO.java | 1 +
.../storage/relational/utils/IdpPOConverters.java | 3 +-
.../gravitino/idp/web/rest/IdpGroupOperations.java | 3 +-
.../gravitino/idp/TestIdpUserGroupManager.java | 11 ++++++
.../apache/gravitino/idp/dto/TestIdpGroupDTO.java | 13 +++++--
.../idp/dto/requests/TestAddGroupRequest.java | 15 ++++++++
.../idp/integration/test/IdpRESTApiIT.java | 25 +++++++++++++-
.../storage/mapper/TestIdpGroupMetaStorage.java | 25 ++++++++++++++
.../gravitino/idp/storage/po/TestIdpGroupPO.java | 5 +++
.../gravitino/idp/web/rest/TestIdpOperations.java | 40 ++++++++++++++++++----
scripts/h2/schema-2.0.0-h2.sql | 1 +
scripts/h2/upgrade-1.3.0-to-2.0.0-h2.sql | 2 ++
scripts/mysql/schema-2.0.0-mysql.sql | 1 +
scripts/mysql/upgrade-1.3.0-to-2.0.0-mysql.sql | 3 ++
scripts/postgresql/schema-2.0.0-postgresql.sql | 2 ++
.../upgrade-1.3.0-to-2.0.0-postgresql.sql | 3 ++
28 files changed, 254 insertions(+), 27 deletions(-)
diff --git a/design-docs/gravitino-local-authentication.md
b/design-docs/gravitino-local-authentication.md
index 77e64c6010..1728a9a42f 100644
--- a/design-docs/gravitino-local-authentication.md
+++ b/design-docs/gravitino-local-authentication.md
@@ -201,6 +201,7 @@ CREATE TABLE IF NOT EXISTS `idp_user_meta` (
CREATE TABLE IF NOT EXISTS `idp_group_meta` (
`group_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'group id',
`group_name` VARCHAR(128) NOT NULL COMMENT 'group name',
+ `group_comment` VARCHAR(1024) DEFAULT '' COMMENT 'group comment',
`current_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'group current
version',
`last_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'group last
version',
`deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'group deleted
at',
diff --git a/docs/open-api/idp/idp.yaml b/docs/open-api/idp/idp.yaml
index 2437519f9d..23ac9e7dcb 100644
--- a/docs/open-api/idp/idp.yaml
+++ b/docs/open-api/idp/idp.yaml
@@ -357,6 +357,10 @@ components:
type: string
maxLength: 128
description: The name of the local user store group
+ comment:
+ type: string
+ maxLength: 1024
+ description: Optional description of the local user store group
users:
type: array
items:
@@ -407,6 +411,10 @@ components:
minLength: 1
maxLength: 128
description: The group name to add.
+ comment:
+ type: string
+ maxLength: 1024
+ description: Optional description of the group.
GroupMembershipChangeRequest:
type: object
@@ -485,7 +493,8 @@ components:
AddGroupRequest:
value: {
- "group": "engineers"
+ "group": "engineers",
+ "comment": "Platform engineering"
}
GroupMembershipChangeRequest:
@@ -526,6 +535,7 @@ components:
"code": 0,
"group": {
"name": "engineers",
+ "comment": "Platform engineering",
"users": []
}
}
@@ -535,6 +545,7 @@ components:
"code": 0,
"group": {
"name": "engineers",
+ "comment": "Platform engineering",
"users": ["alice", "bob"]
}
}
@@ -544,6 +555,7 @@ components:
"code": 0,
"group": {
"name": "engineers",
+ "comment": "Platform engineering",
"users": ["alice", "bob"]
}
}
diff --git a/docs/security/local-users-and-groups.md
b/docs/security/local-users-and-groups.md
index 069ab8d31d..4d661358bb 100644
--- a/docs/security/local-users-and-groups.md
+++ b/docs/security/local-users-and-groups.md
@@ -103,11 +103,11 @@ curl -s -X POST -H "Accept:
application/vnd.gravitino.v1+json" \
| Operation | Method | Path
| Body |
|--------------------------|--------|---------------------------------------------|------------------------------------------------------------|
| Get a group | GET | `/api/idp/groups/{group}`
| None |
-| Add a group | POST | `/api/idp/groups`
| `{"group":"engineering"}` |
+| Add a group | POST | `/api/idp/groups`
| `{"group":"engineering","comment":"Platform engineering"}` |
| Remove a group | DELETE | `/api/idp/groups/{group}?force={true
false}`| None |
| Change group membership | PUT | `/api/idp/groups/{group}/users`
| `{"usersToAdd":["alice"],"usersToRemove":["carol"]}` |
-The add-group body uses the field name `group` rather than `name`. Removing a
group that still has members fails unless `force=true`. A membership change
requires at least one of `usersToAdd` or `usersToRemove`, and accepts both in a
single request.
+The add-group body uses the field name `group` rather than `name`. `comment`
is optional (max 1024 characters, utf8mb4) and stored as the group description.
Removing a group that still has members fails unless `force=true`. A membership
change requires at least one of `usersToAdd` or `usersToRemove`, and accepts
both in a single request.
```shell
curl -s -X PUT -H "Accept: application/vnd.gravitino.v1+json" \
diff --git
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/IdpUserGroupManager.java
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/IdpUserGroupManager.java
index 72e36d73f3..c4f89ad4ca 100644
---
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/IdpUserGroupManager.java
+++
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/IdpUserGroupManager.java
@@ -183,8 +183,21 @@ public class IdpUserGroupManager implements Closeable {
* @return The created built-in IdP group.
*/
public IdpGroup addGroup(String groupName) throws IOException {
- GROUP_SERVICE.insertIdpGroup(newGroupPO(groupName));
- return new IdpGroup(groupName, Collections.emptyList());
+ return addGroup(groupName, "");
+ }
+
+ /**
+ * Adds a built-in IdP group.
+ *
+ * @param groupName The group name.
+ * @param comment The optional group comment.
+ * @return The created built-in IdP group.
+ */
+ public IdpGroup addGroup(String groupName, String comment) throws
IOException {
+ IdpCredentialValidator.validateGroupComment(comment);
+ String normalizedComment = comment == null ? "" : comment;
+ GROUP_SERVICE.insertIdpGroup(newGroupPO(groupName, normalizedComment));
+ return new IdpGroup(groupName, Collections.emptyList(), normalizedComment);
}
/**
@@ -254,10 +267,11 @@ public class IdpUserGroupManager implements Closeable {
}
}
- private IdpGroupPO newGroupPO(String groupName) {
+ private IdpGroupPO newGroupPO(String groupName, String comment) {
return IdpGroupPO.builder()
.withGroupId(idGenerator.nextId())
.withGroupName(groupName)
+ .withGroupComment(comment == null ? "" : comment)
.withCurrentVersion(POConverters.INIT_VERSION)
.withLastVersion(POConverters.INIT_VERSION)
.withDeletedAt(POConverters.DEFAULT_DELETED_AT)
diff --git
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/basic/IdpCredentialValidator.java
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/basic/IdpCredentialValidator.java
index b27855c577..a565f0ab3b 100644
---
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/basic/IdpCredentialValidator.java
+++
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/basic/IdpCredentialValidator.java
@@ -32,6 +32,9 @@ public final class IdpCredentialValidator {
/** Matches {@code idp_user_meta.user_name} and {@code
idp_group_meta.group_name} column size. */
private static final int MAX_NAME_LENGTH = 128;
+ /** Matches {@code idp_group_meta.group_comment} column size (utf8mb4
VARCHAR(1024)). */
+ private static final int MAX_COMMENT_LENGTH = 1024;
+
private IdpCredentialValidator() {}
public static void validateUsername(String username) {
@@ -53,6 +56,16 @@ public final class IdpCredentialValidator {
MAX_NAME_LENGTH);
}
+ public static void validateGroupComment(String comment) {
+ if (comment == null) {
+ return;
+ }
+ Preconditions.checkArgument(
+ comment.codePointCount(0, comment.length()) <= MAX_COMMENT_LENGTH,
+ "Group comment must not exceed %s characters",
+ MAX_COMMENT_LENGTH);
+ }
+
public static void validatePassword(String password) {
Preconditions.checkArgument(
StringUtils.isNotBlank(password), "\"password\" field is required and
cannot be empty");
diff --git
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/dto/IdpGroupDTO.java
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/dto/IdpGroupDTO.java
index 2fc1120466..121e7b6c61 100644
---
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/dto/IdpGroupDTO.java
+++
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/dto/IdpGroupDTO.java
@@ -41,6 +41,10 @@ public class IdpGroupDTO {
@JsonProperty("name")
private String name;
+ @JsonProperty("comment")
+ @JsonSetter(nulls = Nulls.AS_EMPTY)
+ private String comment = "";
+
@JsonProperty("users")
@JsonSetter(nulls = Nulls.AS_EMPTY)
private List<String> users = Collections.emptyList();
@@ -49,10 +53,11 @@ public class IdpGroupDTO {
* Creates a new instance of IdpGroupDTO.
*
* @param name The name of the built-in IdP group DTO.
+ * @param comment The comment of the built-in IdP group DTO.
* @param users The users of the built-in IdP group DTO.
*/
@Builder(setterPrefix = "with")
- protected IdpGroupDTO(String name, List<String> users) {
+ protected IdpGroupDTO(String name, String comment, List<String> users) {
Preconditions.checkArgument(StringUtils.isNotBlank(name), "name cannot be
null or empty");
if (users != null) {
users.forEach(
@@ -61,6 +66,7 @@ public class IdpGroupDTO {
StringUtils.isNotBlank(user), "users cannot contain null or
empty user names"));
}
this.name = name;
+ this.comment = comment == null ? "" : comment;
this.users = users == null ? Collections.emptyList() : users;
}
@@ -71,6 +77,13 @@ public class IdpGroupDTO {
return name;
}
+ /**
+ * @return The comment of the built-in IdP group DTO, or an empty string if
none.
+ */
+ public String comment() {
+ return comment == null ? "" : comment;
+ }
+
/**
* The users of the built-in IdP group. A group can contain multiple users.
*
diff --git
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/dto/requests/AddGroupRequest.java
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/dto/requests/AddGroupRequest.java
index fb1b91aa93..407b01cb1a 100644
---
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/dto/requests/AddGroupRequest.java
+++
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/dto/requests/AddGroupRequest.java
@@ -19,6 +19,7 @@
package org.apache.gravitino.idp.dto.requests;
+import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.EqualsAndHashCode;
@@ -39,9 +40,13 @@ public class AddGroupRequest implements RESTRequest {
@JsonProperty("group")
private final String group;
+ @JsonProperty("comment")
+ @JsonInclude(JsonInclude.Include.NON_NULL)
+ private final String comment;
+
/** Default constructor for AddGroupRequest. (Used for Jackson
deserialization.) */
public AddGroupRequest() {
- this(null);
+ this(null, null);
}
/**
@@ -50,8 +55,19 @@ public class AddGroupRequest implements RESTRequest {
* @param group The group name of the built-in IdP group.
*/
public AddGroupRequest(String group) {
+ this(group, null);
+ }
+
+ /**
+ * Creates a new AddGroupRequest.
+ *
+ * @param group The group name of the built-in IdP group.
+ * @param comment The optional group comment.
+ */
+ public AddGroupRequest(String group, String comment) {
super();
this.group = group;
+ this.comment = comment;
}
/**
@@ -62,5 +78,6 @@ public class AddGroupRequest implements RESTRequest {
@Override
public void validate() throws IllegalArgumentException {
IdpCredentialValidator.validateGroupName(group);
+ IdpCredentialValidator.validateGroupComment(comment);
}
}
diff --git
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/model/IdpGroup.java
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/model/IdpGroup.java
index 10f4aee5df..9ac51eb3ac 100644
---
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/model/IdpGroup.java
+++
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/model/IdpGroup.java
@@ -26,6 +26,7 @@ import org.apache.gravitino.idp.dto.IdpGroupDTO;
public class IdpGroup {
private final String name;
+ private final String comment;
private final List<String> usernames;
/**
@@ -35,8 +36,20 @@ public class IdpGroup {
* @param usernames The usernames in the group.
*/
public IdpGroup(String name, List<String> usernames) {
+ this(name, usernames, "");
+ }
+
+ /**
+ * Creates a built-in IdP group.
+ *
+ * @param name The group name.
+ * @param usernames The usernames in the group.
+ * @param comment The group comment, or empty if none.
+ */
+ public IdpGroup(String name, List<String> usernames, String comment) {
this.name = name;
this.usernames = usernames;
+ this.comment = comment == null ? "" : comment;
}
/** Returns the group name. */
@@ -44,6 +57,11 @@ public class IdpGroup {
return name;
}
+ /** Returns the group comment, or an empty string if none. */
+ public String comment() {
+ return comment;
+ }
+
/** Returns the usernames in the group. */
public List<String> usernames() {
return usernames;
@@ -55,7 +73,7 @@ public class IdpGroup {
* @return the group DTO
*/
public IdpGroupDTO toDTO() {
- return IdpGroupDTO.builder().withName(name).withUsers(usernames).build();
+ return
IdpGroupDTO.builder().withName(name).withComment(comment).withUsers(usernames).build();
}
@Override
@@ -67,16 +85,18 @@ public class IdpGroup {
return false;
}
IdpGroup that = (IdpGroup) other;
- return Objects.equals(name, that.name) && Objects.equals(usernames,
that.usernames);
+ return Objects.equals(name, that.name)
+ && Objects.equals(comment, that.comment)
+ && Objects.equals(usernames, that.usernames);
}
@Override
public int hashCode() {
- return Objects.hash(name, usernames);
+ return Objects.hash(name, comment, usernames);
}
@Override
public String toString() {
- return "IdpGroup{name='" + name + "', usernames=" + usernames + '}';
+ return "IdpGroup{name='" + name + "', comment='" + comment + "',
usernames=" + usernames + '}';
}
}
diff --git
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/mapper/provider/base/IdpGroupMetaBaseSQLProvider.java
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/mapper/provider/base/IdpGroupMetaBaseSQLProvider.java
index ff071e4678..78e299a3c5 100644
---
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/mapper/provider/base/IdpGroupMetaBaseSQLProvider.java
+++
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/mapper/provider/base/IdpGroupMetaBaseSQLProvider.java
@@ -29,6 +29,7 @@ public class IdpGroupMetaBaseSQLProvider {
public String selectIdpGroup(@Param("groupName") String groupName) {
return "SELECT group_id as groupId, group_name as groupName,"
+ + " COALESCE(group_comment, '') as groupComment,"
+ " current_version as currentVersion,"
+ " last_version as lastVersion, deleted_at as deletedAt"
+ " FROM "
@@ -38,6 +39,7 @@ public class IdpGroupMetaBaseSQLProvider {
public String selectIdpGroupWithUsers(@Param("groupName") String groupName) {
return "SELECT g.group_name as name,"
+ + " COALESCE(g.group_comment, '') as comment,"
+ " COALESCE(JSON_ARRAYAGG(u.user_name), JSON_ARRAY()) as usernames"
+ " FROM "
+ IdpGroupMetaMapper.IDP_GROUP_TABLE_NAME
@@ -48,16 +50,17 @@ public class IdpGroupMetaBaseSQLProvider {
+ IdpUserMetaMapper.IDP_USER_TABLE_NAME
+ " u ON u.user_id = r.user_id AND u.deleted_at = 0"
+ " WHERE g.group_name = #{groupName} AND g.deleted_at = 0"
- + " GROUP BY g.group_id, g.group_name";
+ + " GROUP BY g.group_id, g.group_name, g.group_comment";
}
public String insertIdpGroup(@Param("groupMeta") IdpGroupPO groupPO) {
return "INSERT INTO "
+ IdpGroupMetaMapper.IDP_GROUP_TABLE_NAME
- + " (group_id, group_name, current_version, last_version, deleted_at)"
+ + " (group_id, group_name, group_comment, current_version,
last_version, deleted_at)"
+ " VALUES ("
+ " #{groupMeta.groupId},"
+ " #{groupMeta.groupName},"
+ + " COALESCE(#{groupMeta.groupComment}, ''),"
+ " #{groupMeta.currentVersion},"
+ " #{groupMeta.lastVersion},"
+ " #{groupMeta.deletedAt}"
diff --git
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/mapper/provider/h2/IdpGroupMetaH2Provider.java
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/mapper/provider/h2/IdpGroupMetaH2Provider.java
index e15542f518..cb84d4d98d 100644
---
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/mapper/provider/h2/IdpGroupMetaH2Provider.java
+++
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/mapper/provider/h2/IdpGroupMetaH2Provider.java
@@ -31,6 +31,7 @@ public class IdpGroupMetaH2Provider extends
IdpGroupMetaBaseSQLProvider {
@Override
public String selectIdpGroupWithUsers(@Param("groupName") String groupName) {
return "SELECT g.group_name as name,"
+ + " COALESCE(g.group_comment, '') as comment,"
+ " '['"
+ " || COALESCE(GROUP_CONCAT('\"' || u.user_name || '\"'), '')"
+ " || ']' as usernames"
@@ -43,7 +44,7 @@ public class IdpGroupMetaH2Provider extends
IdpGroupMetaBaseSQLProvider {
+ IdpUserMetaMapper.IDP_USER_TABLE_NAME
+ " u ON u.user_id = r.user_id AND u.deleted_at = 0"
+ " WHERE g.group_name = #{groupName} AND g.deleted_at = 0"
- + " GROUP BY g.group_id, g.group_name";
+ + " GROUP BY g.group_id, g.group_name, g.group_comment";
}
@Override
diff --git
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/mapper/provider/postgresql/IdpGroupMetaPostgreSQLProvider.java
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/mapper/provider/postgresql/IdpGroupMetaPostgreSQLProvider.java
index 28e0869367..b839bd1a6f 100644
---
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/mapper/provider/postgresql/IdpGroupMetaPostgreSQLProvider.java
+++
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/mapper/provider/postgresql/IdpGroupMetaPostgreSQLProvider.java
@@ -30,6 +30,7 @@ public class IdpGroupMetaPostgreSQLProvider extends
IdpGroupMetaBaseSQLProvider
@Override
public String selectIdpGroupWithUsers(@Param("groupName") String groupName) {
return "SELECT g.group_name as name,"
+ + " COALESCE(g.group_comment, '') as comment,"
+ " COALESCE(JSON_AGG(u.user_name), '[]'::json) as usernames"
+ " FROM "
+ IdpGroupMetaMapper.IDP_GROUP_TABLE_NAME
@@ -40,7 +41,7 @@ public class IdpGroupMetaPostgreSQLProvider extends
IdpGroupMetaBaseSQLProvider
+ IdpUserMetaMapper.IDP_USER_TABLE_NAME
+ " u ON u.user_id = r.user_id AND u.deleted_at = 0"
+ " WHERE g.group_name = #{groupName} AND g.deleted_at = 0"
- + " GROUP BY g.group_id, g.group_name";
+ + " GROUP BY g.group_id, g.group_name, g.group_comment";
}
@Override
diff --git
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/po/IdpGroupPO.java
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/po/IdpGroupPO.java
index 0aa518a1eb..6a53e2051c 100644
---
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/po/IdpGroupPO.java
+++
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/po/IdpGroupPO.java
@@ -35,6 +35,7 @@ import lombok.ToString;
public class IdpGroupPO {
private Long groupId;
private String groupName;
+ private String groupComment;
private Long currentVersion;
private Long lastVersion;
private Long deletedAt;
diff --git
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/po/IdpGroupWithUsersPO.java
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/po/IdpGroupWithUsersPO.java
index d971ae1773..99306d8071 100644
---
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/po/IdpGroupWithUsersPO.java
+++
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/po/IdpGroupWithUsersPO.java
@@ -38,5 +38,6 @@ import lombok.ToString;
@Builder(setterPrefix = "with")
public class IdpGroupWithUsersPO {
private String name;
+ private String comment;
private String usernames;
}
diff --git
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/relational/utils/IdpPOConverters.java
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/relational/utils/IdpPOConverters.java
index 41dbe3bfcc..66a43a5dcb 100644
---
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/relational/utils/IdpPOConverters.java
+++
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/storage/relational/utils/IdpPOConverters.java
@@ -56,7 +56,8 @@ public final class IdpPOConverters {
*/
public static IdpGroup fromIdpGroupWithUsersPO(IdpGroupWithUsersPO groupPO) {
Preconditions.checkNotNull(groupPO, "groupPO must not be null");
- return new IdpGroup(groupPO.getName(),
parseJsonStringList(groupPO.getUsernames()));
+ return new IdpGroup(
+ groupPO.getName(), parseJsonStringList(groupPO.getUsernames()),
groupPO.getComment());
}
@SuppressWarnings("unchecked")
diff --git
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/web/rest/IdpGroupOperations.java
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/web/rest/IdpGroupOperations.java
index f2ad5233d4..968fc83071 100644
---
a/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/web/rest/IdpGroupOperations.java
+++
b/plugins/idp-basic/src/main/java/org/apache/gravitino/idp/web/rest/IdpGroupOperations.java
@@ -82,7 +82,8 @@ public class IdpGroupOperations {
() -> {
request.validate();
return IdpRESTUtils.ok(
- new
IdpGroupResponse(userGroupManager.addGroup(request.getGroup()).toDTO()));
+ new IdpGroupResponse(
+ userGroupManager.addGroup(request.getGroup(),
request.getComment()).toDTO()));
},
"group",
IdpOperationType.ADD,
diff --git
a/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/TestIdpUserGroupManager.java
b/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/TestIdpUserGroupManager.java
index 419b688dcf..03547c43b3 100644
---
a/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/TestIdpUserGroupManager.java
+++
b/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/TestIdpUserGroupManager.java
@@ -137,8 +137,19 @@ public class TestIdpUserGroupManager {
public void testAddGroup() throws IOException {
IdpGroup group = manager.addGroup("testAddGroup");
Assertions.assertEquals("testAddGroup", group.name());
+ Assertions.assertEquals("", group.comment());
Assertions.assertTrue(group.usernames().isEmpty());
+ IdpGroup commented = manager.addGroup("testAddGroupComment", "on-call
rotation");
+ Assertions.assertEquals("on-call rotation", commented.comment());
+ Assertions.assertEquals("on-call rotation",
manager.getGroup("testAddGroupComment").comment());
+
+ Assertions.assertDoesNotThrow(
+ () -> manager.addGroup("testAddGroupMaxComment", "a".repeat(1024)));
+ Assertions.assertThrows(
+ IllegalArgumentException.class,
+ () -> manager.addGroup("testAddGroupTooLongComment",
"a".repeat(1025)));
+
Assertions.assertThrows(AlreadyExistsException.class, () ->
manager.addGroup("testAddGroup"));
}
diff --git
a/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/dto/TestIdpGroupDTO.java
b/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/dto/TestIdpGroupDTO.java
index d0b5bd75ac..1bdc6bbbc0 100644
---
a/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/dto/TestIdpGroupDTO.java
+++
b/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/dto/TestIdpGroupDTO.java
@@ -52,14 +52,23 @@ public class TestIdpGroupDTO {
Assertions.assertEquals(groupDTO1, deserialized1);
Assertions.assertEquals("test_group", deserialized1.name());
Assertions.assertTrue(deserialized1.users().isEmpty());
- Assertions.assertEquals("IdpGroupDTO(name=test_group, users=[])",
deserialized1.toString());
+ Assertions.assertEquals("", deserialized1.comment());
+ Assertions.assertEquals(
+ "IdpGroupDTO(name=test_group, comment=, users=[])",
deserialized1.toString());
IdpGroupDTO deserializedWithNullUsers =
JsonUtils.objectMapper()
.readValue("{\"name\":\"test_group\",\"users\":null}",
IdpGroupDTO.class);
Assertions.assertTrue(deserializedWithNullUsers.users().isEmpty());
+ Assertions.assertEquals("", deserializedWithNullUsers.comment());
Assertions.assertEquals(
- "IdpGroupDTO(name=test_group, users=[])",
deserializedWithNullUsers.toString());
+ "IdpGroupDTO(name=test_group, comment=, users=[])",
deserializedWithNullUsers.toString());
+
+ IdpGroupDTO deserializedNullComment =
+ JsonUtils.objectMapper()
+ .readValue("{\"name\":\"test_group\",\"comment\":null}",
IdpGroupDTO.class);
+ Assertions.assertEquals("", deserializedNullComment.comment());
+ Assertions.assertEquals(groupDTO1, deserializedNullComment);
Assertions.assertThrows(
IllegalArgumentException.class, () -> IdpGroupDTO.builder().withName("
").build());
diff --git
a/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/dto/requests/TestAddGroupRequest.java
b/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/dto/requests/TestAddGroupRequest.java
index 77f3c19d21..e93e3aaf48 100644
---
a/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/dto/requests/TestAddGroupRequest.java
+++
b/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/dto/requests/TestAddGroupRequest.java
@@ -36,6 +36,16 @@ public class TestAddGroupRequest {
Assertions.assertEquals(request, deserRequest);
Assertions.assertEquals("test_group", deserRequest.getGroup());
+ Assertions.assertNull(deserRequest.getComment());
+
+ AddGroupRequest requestWithComment = new AddGroupRequest("test_group",
"engineering team");
+ AddGroupRequest deserWithComment =
+ JsonUtils.objectMapper()
+ .readValue(
+
JsonUtils.objectMapper().writeValueAsString(requestWithComment),
+ AddGroupRequest.class);
+ Assertions.assertEquals(requestWithComment, deserWithComment);
+ Assertions.assertEquals("engineering team", deserWithComment.getComment());
// Test with null group
AddGroupRequest request1 = new AddGroupRequest();
@@ -56,5 +66,10 @@ public class TestAddGroupRequest {
IllegalArgumentException.class, () -> new AddGroupRequest("
").validate());
Assertions.assertThrows(
IllegalArgumentException.class, () -> new
AddGroupRequest("a".repeat(129)).validate());
+ Assertions.assertDoesNotThrow(
+ () -> new AddGroupRequest("test_group", "a".repeat(1024)).validate());
+ Assertions.assertThrows(
+ IllegalArgumentException.class,
+ () -> new AddGroupRequest("test_group", "a".repeat(1025)).validate());
}
}
diff --git
a/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/integration/test/IdpRESTApiIT.java
b/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/integration/test/IdpRESTApiIT.java
index ca18bfcf6c..78c13129ca 100644
---
a/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/integration/test/IdpRESTApiIT.java
+++
b/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/integration/test/IdpRESTApiIT.java
@@ -191,14 +191,24 @@ public class IdpRESTApiIT extends BaseIT {
IdpGroupResponse group = postGroup(GROUP1);
Assertions.assertEquals(GROUP1, group.getGroup().name());
+ Assertions.assertEquals("", group.getGroup().comment());
Assertions.assertTrue(group.getGroup().users().isEmpty());
+ IdpGroupResponse commented = postGroup("commented-group", "on-call
rotation");
+ Assertions.assertEquals("on-call rotation",
commented.getGroup().comment());
+ Assertions.assertEquals("on-call rotation",
getGroup("commented-group").getGroup().comment());
+ Assertions.assertTrue(deleteGroup("commented-group", false));
+
assertError(
409, post("/idp/groups", new AddGroupRequest(GROUP1)),
ErrorConstants.ALREADY_EXISTS_CODE);
assertError(
400,
post("/idp/groups", new AddGroupRequest("a".repeat(129))),
ErrorConstants.ILLEGAL_ARGUMENTS_CODE);
+ assertError(
+ 400,
+ post("/idp/groups", new AddGroupRequest("too-long-comment",
"a".repeat(1025))),
+ ErrorConstants.ILLEGAL_ARGUMENTS_CODE);
assertError(
404,
get("/idp/groups/" + MISSING_GROUP, ADMIN, ADMIN_PASSWORD),
@@ -304,7 +314,20 @@ public class IdpRESTApiIT extends BaseIT {
}
private static IdpGroupResponse postGroup(String groupName) throws Exception
{
- HttpResponse<String> response = post("/idp/groups", new
AddGroupRequest(groupName));
+ return postGroup(groupName, null);
+ }
+
+ private static IdpGroupResponse postGroup(String groupName, String comment)
throws Exception {
+ HttpResponse<String> response = post("/idp/groups", new
AddGroupRequest(groupName, comment));
+ Assertions.assertEquals(200, response.statusCode(), response.body());
+ IdpGroupResponse groupResponse =
+ JsonUtils.objectMapper().readValue(response.body(),
IdpGroupResponse.class);
+ groupResponse.validate();
+ return groupResponse;
+ }
+
+ private static IdpGroupResponse getGroup(String groupName) throws Exception {
+ HttpResponse<String> response = get("/idp/groups/" + groupName, ADMIN,
ADMIN_PASSWORD);
Assertions.assertEquals(200, response.statusCode(), response.body());
IdpGroupResponse groupResponse =
JsonUtils.objectMapper().readValue(response.body(),
IdpGroupResponse.class);
diff --git
a/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/storage/mapper/TestIdpGroupMetaStorage.java
b/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/storage/mapper/TestIdpGroupMetaStorage.java
index ffc00944ba..c4be1c4e9a 100644
---
a/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/storage/mapper/TestIdpGroupMetaStorage.java
+++
b/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/storage/mapper/TestIdpGroupMetaStorage.java
@@ -49,6 +49,7 @@ class TestIdpGroupMetaStorage extends
AbstractIdpMetaStorageTest {
IdpGroupPO.builder()
.withGroupId(1L)
.withGroupName("dev")
+ .withGroupComment("")
.withCurrentVersion(1L)
.withLastVersion(0L)
.withDeletedAt(0L)
@@ -59,6 +60,26 @@ class TestIdpGroupMetaStorage extends
AbstractIdpMetaStorageTest {
assertNull(idpGroupMetaMapper.selectIdpGroup("unknown"));
}
+ @ParameterizedTest
+ @MethodSource("storageProvider")
+ void testInsertIdpGroupPersistsComment(String type) throws IOException {
+ init(type);
+ IdpGroupPO group =
+ IdpGroupPO.builder()
+ .withGroupId(1L)
+ .withGroupName("dev")
+ .withGroupComment("on-call rotation")
+ .withCurrentVersion(1L)
+ .withLastVersion(0L)
+ .withDeletedAt(0L)
+ .build();
+ idpGroupMetaMapper.insertIdpGroup(group);
+
+ assertEquals(group, idpGroupMetaMapper.selectIdpGroup("dev"));
+ assertEquals(
+ "on-call rotation",
idpGroupMetaMapper.selectIdpGroupWithUsers("dev").getComment());
+ }
+
@ParameterizedTest
@MethodSource("storageProvider")
void testSelectIdpGroupWithUsers(String type) throws IOException {
@@ -67,6 +88,7 @@ class TestIdpGroupMetaStorage extends
AbstractIdpMetaStorageTest {
IdpGroupPO.builder()
.withGroupId(1L)
.withGroupName("dev")
+ .withGroupComment("")
.withCurrentVersion(1L)
.withLastVersion(0L)
.withDeletedAt(0L)
@@ -113,6 +135,7 @@ class TestIdpGroupMetaStorage extends
AbstractIdpMetaStorageTest {
var groupWithUsers = idpGroupMetaMapper.selectIdpGroupWithUsers("dev");
assertEquals("dev", groupWithUsers.getName());
+ assertEquals("", groupWithUsers.getComment());
assertTrue(groupWithUsers.getUsernames().contains("alice"));
assertTrue(groupWithUsers.getUsernames().contains("bob"));
assertNull(idpGroupMetaMapper.selectIdpGroupWithUsers("unknown"));
@@ -126,6 +149,7 @@ class TestIdpGroupMetaStorage extends
AbstractIdpMetaStorageTest {
IdpGroupPO.builder()
.withGroupId(1L)
.withGroupName("dev")
+ .withGroupComment("")
.withCurrentVersion(1L)
.withLastVersion(0L)
.withDeletedAt(0L)
@@ -152,6 +176,7 @@ class TestIdpGroupMetaStorage extends
AbstractIdpMetaStorageTest {
IdpGroupPO.builder()
.withGroupId(1L)
.withGroupName("dev")
+ .withGroupComment("")
.withCurrentVersion(1L)
.withLastVersion(0L)
.withDeletedAt(0L)
diff --git
a/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/storage/po/TestIdpGroupPO.java
b/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/storage/po/TestIdpGroupPO.java
index baaefb8e96..a10ba8db8d 100644
---
a/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/storage/po/TestIdpGroupPO.java
+++
b/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/storage/po/TestIdpGroupPO.java
@@ -29,6 +29,7 @@ public class TestIdpGroupPO {
IdpGroupPO.builder()
.withGroupId(1L)
.withGroupName("engineering")
+ .withGroupComment("platform engineering")
.withCurrentVersion(1L)
.withLastVersion(1L)
.withDeletedAt(0L)
@@ -36,6 +37,7 @@ public class TestIdpGroupPO {
Assertions.assertEquals(1L, groupPO.getGroupId());
Assertions.assertEquals("engineering", groupPO.getGroupName());
+ Assertions.assertEquals("platform engineering", groupPO.getGroupComment());
Assertions.assertEquals(1L, groupPO.getCurrentVersion());
Assertions.assertEquals(1L, groupPO.getLastVersion());
Assertions.assertEquals(0L, groupPO.getDeletedAt());
@@ -47,6 +49,7 @@ public class TestIdpGroupPO {
IdpGroupPO.builder()
.withGroupId(1L)
.withGroupName("engineering")
+ .withGroupComment("platform engineering")
.withCurrentVersion(1L)
.withLastVersion(1L)
.withDeletedAt(0L)
@@ -56,6 +59,7 @@ public class TestIdpGroupPO {
IdpGroupPO.builder()
.withGroupId(1L)
.withGroupName("engineering")
+ .withGroupComment("platform engineering")
.withCurrentVersion(1L)
.withLastVersion(1L)
.withDeletedAt(0L)
@@ -71,6 +75,7 @@ public class TestIdpGroupPO {
IdpGroupPO.builder()
.withGroupId(1L)
.withGroupName("engineering")
+ .withGroupComment("platform engineering")
.withCurrentVersion(1L)
.withLastVersion(1L)
.withDeletedAt(0L);
diff --git
a/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/web/rest/TestIdpOperations.java
b/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/web/rest/TestIdpOperations.java
index f8ae328fe1..e165202948 100644
---
a/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/web/rest/TestIdpOperations.java
+++
b/plugins/idp-basic/src/test/java/org/apache/gravitino/idp/web/rest/TestIdpOperations.java
@@ -18,6 +18,8 @@
*/
package org.apache.gravitino.idp.web.rest;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
@@ -40,6 +42,7 @@ import org.apache.gravitino.dto.responses.RemoveResponse;
import org.apache.gravitino.exceptions.AlreadyExistsException;
import org.apache.gravitino.exceptions.NotFoundException;
import org.apache.gravitino.idp.IdpUserGroupManager;
+import org.apache.gravitino.idp.dto.IdpGroupDTO;
import org.apache.gravitino.idp.dto.requests.AddGroupRequest;
import org.apache.gravitino.idp.dto.requests.AddUserRequest;
import org.apache.gravitino.idp.dto.requests.ChangePasswordRequest;
@@ -140,14 +143,31 @@ class TestIdpOperations extends JerseyTest {
@Test
void testAddAndGetGroup() throws Exception {
AddGroupRequest req = new AddGroupRequest("group1");
- doReturn(buildGroup("group1")).when(MANAGER).addGroup("group1");
+ doReturn(buildGroup("group1")).when(MANAGER).addGroup(eq("group1"),
nullable(String.class));
when(MANAGER.getGroup("group1")).thenReturn(buildGroup("group1"));
- assertStatus(Response.Status.OK, post("/idp/groups", req));
+ IdpGroupDTO created = post("/idp/groups",
req).readEntity(IdpGroupResponse.class).getGroup();
+ Assertions.assertEquals("group1", created.name());
+ Assertions.assertEquals("", created.comment());
Assertions.assertEquals(
- "group1",
get("/idp/groups/group1").readEntity(IdpGroupResponse.class).getGroup().name());
+ "",
get("/idp/groups/group1").readEntity(IdpGroupResponse.class).getGroup().comment());
- doThrow(new AlreadyExistsException("mock
error")).when(MANAGER).addGroup("group1");
+ AddGroupRequest withComment = new AddGroupRequest("group2", "platform
engineering");
+ doReturn(buildGroup("group2", "platform engineering"))
+ .when(MANAGER)
+ .addGroup(eq("group2"), eq("platform engineering"));
+ Assertions.assertEquals(
+ "platform engineering",
+ post("/idp/groups",
withComment).readEntity(IdpGroupResponse.class).getGroup().comment());
+
+ assertError(
+ Response.Status.BAD_REQUEST,
+ post("/idp/groups", new AddGroupRequest("group3", "a".repeat(1025))),
+ ErrorConstants.ILLEGAL_ARGUMENTS_CODE);
+
+ doThrow(new AlreadyExistsException("mock error"))
+ .when(MANAGER)
+ .addGroup(eq("group1"), nullable(String.class));
assertStatus(Response.Status.CONFLICT, post("/idp/groups", req));
}
@@ -220,10 +240,18 @@ class TestIdpOperations extends JerseyTest {
}
private IdpGroup buildGroup(String group) {
- return buildGroup(group, Collections.emptyList());
+ return buildGroup(group, Collections.emptyList(), "");
+ }
+
+ private IdpGroup buildGroup(String group, String comment) {
+ return buildGroup(group, Collections.emptyList(), comment);
}
private IdpGroup buildGroup(String group, List<String> users) {
- return new IdpGroup(group, users);
+ return buildGroup(group, users, "");
+ }
+
+ private IdpGroup buildGroup(String group, List<String> users, String
comment) {
+ return new IdpGroup(group, users, comment);
}
}
diff --git a/scripts/h2/schema-2.0.0-h2.sql b/scripts/h2/schema-2.0.0-h2.sql
index 4eb0d46fc9..834d234ff1 100644
--- a/scripts/h2/schema-2.0.0-h2.sql
+++ b/scripts/h2/schema-2.0.0-h2.sql
@@ -269,6 +269,7 @@ CREATE TABLE IF NOT EXISTS `idp_user_meta` (
CREATE TABLE IF NOT EXISTS `idp_group_meta` (
`group_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'idp group id',
`group_name` VARCHAR(128) NOT NULL COMMENT 'idp group name',
+ `group_comment` VARCHAR(1024) DEFAULT '' COMMENT 'idp group comment',
`current_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'idp group
current version',
`last_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'idp group last
version',
`deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'idp group
deleted at',
diff --git a/scripts/h2/upgrade-1.3.0-to-2.0.0-h2.sql
b/scripts/h2/upgrade-1.3.0-to-2.0.0-h2.sql
index f7a856845e..489a8ea057 100644
--- a/scripts/h2/upgrade-1.3.0-to-2.0.0-h2.sql
+++ b/scripts/h2/upgrade-1.3.0-to-2.0.0-h2.sql
@@ -34,5 +34,7 @@ ALTER TABLE `tag_relation_meta` DROP INDEX `uk_ti_mi_del`;
ALTER TABLE `tag_relation_meta` ADD COLUMN `tag_value` VARCHAR(256) NOT NULL
DEFAULT '' COMMENT 'tag assignment value, empty string means no value' AFTER
`metadata_object_type`;
+ALTER TABLE `idp_group_meta` ADD COLUMN `group_comment` VARCHAR(1024) DEFAULT
'' COMMENT 'idp group comment' AFTER `group_name`;
+
CREATE UNIQUE INDEX IF NOT EXISTS `uk_ti_mi_mo_tv_del` ON `tag_relation_meta`
(`tag_id`, `metadata_object_id`, `metadata_object_type`, `tag_value`,
`deleted_at`);
CREATE INDEX IF NOT EXISTS `idx_tid_value` ON `tag_relation_meta` (`tag_id`,
`tag_value`);
diff --git a/scripts/mysql/schema-2.0.0-mysql.sql
b/scripts/mysql/schema-2.0.0-mysql.sql
index 8b23ebca77..174af1dab9 100644
--- a/scripts/mysql/schema-2.0.0-mysql.sql
+++ b/scripts/mysql/schema-2.0.0-mysql.sql
@@ -260,6 +260,7 @@ CREATE TABLE IF NOT EXISTS `idp_user_meta` (
CREATE TABLE IF NOT EXISTS `idp_group_meta` (
`group_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'idp group id',
`group_name` VARCHAR(128) NOT NULL COMMENT 'idp group name',
+ `group_comment` VARCHAR(1024) DEFAULT '' COMMENT 'idp group comment',
`current_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'idp group
current version',
`last_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'idp group last
version',
`deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'idp group
deleted at',
diff --git a/scripts/mysql/upgrade-1.3.0-to-2.0.0-mysql.sql
b/scripts/mysql/upgrade-1.3.0-to-2.0.0-mysql.sql
index 077c21c0c4..2d0b8e1417 100644
--- a/scripts/mysql/upgrade-1.3.0-to-2.0.0-mysql.sql
+++ b/scripts/mysql/upgrade-1.3.0-to-2.0.0-mysql.sql
@@ -39,6 +39,9 @@ ALTER TABLE `tag_relation_meta`
ALTER TABLE `tag_relation_meta`
ADD COLUMN `tag_value` VARCHAR(256) NOT NULL DEFAULT '' COMMENT 'tag
assignment value, empty string means no value' AFTER `metadata_object_type`;
+ALTER TABLE `idp_group_meta`
+ ADD COLUMN `group_comment` VARCHAR(1024) DEFAULT '' COMMENT 'idp group
comment' AFTER `group_name`;
+
CREATE UNIQUE INDEX `uk_ti_mi_mo_tv_del` ON `tag_relation_meta` (`tag_id`,
`metadata_object_id`, `metadata_object_type`, `tag_value`, `deleted_at`);
CREATE INDEX `idx_tid_value` ON `tag_relation_meta` (`tag_id`, `tag_value`);
diff --git a/scripts/postgresql/schema-2.0.0-postgresql.sql
b/scripts/postgresql/schema-2.0.0-postgresql.sql
index 6f602d5fd4..28b19dd2ec 100644
--- a/scripts/postgresql/schema-2.0.0-postgresql.sql
+++ b/scripts/postgresql/schema-2.0.0-postgresql.sql
@@ -459,6 +459,7 @@ COMMENT ON COLUMN idp_user_meta.deleted_at IS 'idp user
deleted at';
CREATE TABLE IF NOT EXISTS idp_group_meta (
group_id BIGINT NOT NULL,
group_name VARCHAR(128) NOT NULL,
+ group_comment VARCHAR(1024) DEFAULT '',
current_version INT NOT NULL DEFAULT 1,
last_version INT NOT NULL DEFAULT 1,
deleted_at BIGINT NOT NULL DEFAULT 0,
@@ -469,6 +470,7 @@ COMMENT ON TABLE idp_group_meta IS 'local IdP group
metadata';
COMMENT ON COLUMN idp_group_meta.group_id IS 'idp group id';
COMMENT ON COLUMN idp_group_meta.group_name IS 'idp group name';
+COMMENT ON COLUMN idp_group_meta.group_comment IS 'idp group comment';
COMMENT ON COLUMN idp_group_meta.current_version IS 'idp group current
version';
COMMENT ON COLUMN idp_group_meta.last_version IS 'idp group last version';
COMMENT ON COLUMN idp_group_meta.deleted_at IS 'idp group deleted at';
diff --git a/scripts/postgresql/upgrade-1.3.0-to-2.0.0-postgresql.sql
b/scripts/postgresql/upgrade-1.3.0-to-2.0.0-postgresql.sql
index 73c04328a7..0244409955 100644
--- a/scripts/postgresql/upgrade-1.3.0-to-2.0.0-postgresql.sql
+++ b/scripts/postgresql/upgrade-1.3.0-to-2.0.0-postgresql.sql
@@ -38,6 +38,9 @@ COMMENT ON COLUMN tag_meta.allowed_values IS 'tag allowed
values as a JSON strin
ALTER TABLE tag_relation_meta ADD COLUMN IF NOT EXISTS tag_value VARCHAR(256)
NOT NULL DEFAULT '';
COMMENT ON COLUMN tag_relation_meta.tag_value IS 'tag assignment value, empty
string means no value';
+ALTER TABLE idp_group_meta ADD COLUMN IF NOT EXISTS group_comment
VARCHAR(1024) DEFAULT '';
+COMMENT ON COLUMN idp_group_meta.group_comment IS 'idp group comment';
+
ALTER TABLE tag_relation_meta DROP CONSTRAINT IF EXISTS
tag_relation_meta_tag_id_metadata_object_id_metadata_object_key;
CREATE UNIQUE INDEX IF NOT EXISTS uk_ti_mi_mo_tv_del ON tag_relation_meta
(tag_id, metadata_object_id, metadata_object_type, tag_value, deleted_at);