apache / apache/rocketmq-dashboard

[Studio][Bug] A topic remark cannot be cleared through POST /api/topics/update

Open
#4,272 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
1.4k
Forks
683
Avg merge
2d 14h
Merged PRs (30d)
58

Description

## 1. Symptom

`POST /api/topics/update` (`TopicController.updateTopic` -> `ApacheInstanceProvider.updateTopic` -> `RocketMQAdminClientImpl.updateTopic`) cannot remove a topic's stored remark.

A blank remark is accepted (HTTP 200) and the response echoes the blank value, but the `rmq_instance_topic` row keeps the previous remark, so the next topic list load shows the old text again. Editing a remark to a different non-blank value works; only clearing it is lost.

## 2. Root cause

`server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQAdminClientImpl.java:382-384`

```java
if (StringUtils.hasText(topic.getRemark())) {
existing.setRemark(topic.getRemark());
}
```

The cached row is only written when the submitted remark has text, so a blank submission is treated exactly like an omitted one. `TopicVO.remark` / `UpdateTopicDTO.remark` are plain nullable strings with no validation and no separate clear flag (unlike `clearApiKey` / `clearDingtalkSigningSecret` in general settings), so a blank remark is the only way a caller can express "this topic has no remark".

Clearing is a two-part problem: assigning `null` to the entity field would not persist either, because MyBatis-Plus `updateById` omits null entity fields (`FieldStrategy.NOT_NULL`). That mechanism is already documented and fixed for the ACL user/rule columns in #3342, and it has to be handled explicitly on this path as well.

## 3. Impact

- The remark column of a managed topic is write-once: it can be created and edited, never cleared. Operators have to recreate the topic or edit MySQL directly.
- The endpoint lies: the 200 response carries the cleared value while the database still holds the old one.
- The update path is the one the create dialog's edit mode is wired to (`POST /api/topics/update` is documented in `docs/api-spec.md` §5.4 and implemented for all three providers, and `web/src/pages/instance/topic.tsx` is being wired to it in #4249), so the UI cannot clear a remark either.

## 4. Reproduction

1. Create a topic with a remark, or update one to have a remark.
2. `POST /api/topics/update` with `{"name": "", "instanceId": "", "remark": ""}`.
3. Response: 200, `remark` is empty.
4. Reload the topic list (`GET /api/topics`) or `SELECT remark FROM rmq_instance_topic WHERE name = ''`: the previous remark is still there.

## 5. Expected behaviour

- An omitted remark (`null`) keeps the stored value, which is what the existing partial-update comment in `updateTopic` describes.
- A submitted blank remark clears it (the column must become NULL).
- The response reports the persisted remark instead of the submitted one.
- `CreateTopicDTO`/`UpdateTopicDTO` stay unchanged; no behavioural change for callers that submit a real remark.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQAdminClientImpl.java at updateTopic, then trace TopicController.updateTopic and the entity update path. Preserve omitted remarks, persist a submitted blank remark as NULL, and ensure the response reflects the stored value; review the ACL persistence fix described in #3342 for the null-update mechanism.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api, backend, database
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
82/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.