fix: default value cannot be read when the setting is not created because of asynchrony (#3236)

#### What type of PR is this?
/kind improvement
/area core
/milestone 2.2.x
/cherry-pick release-2.2
#### What this PR does / why we need it:
修复插件安装时有几率出现设置没有默认值导致无法保存的问题

see https://github.com/halo-dev/halo/issues/3224#issuecomment-1418825809 for more details

#### Which issue(s) this PR fixes:

Fixes #3224

#### Special notes for your reviewer:
how to test it?
1. 安装 https://github.com/halo-sigs/plugin-feed 插件并立即启用(或以开发模式)
2. 到此插件设置**始终**能查询到默认值并且能保存

/cc @halo-dev/sig-halo 
#### Does this PR introduce a user-facing change?

```release-note
修复插件安装时有几率出现设置没有默认值导致无法保存的问题
```
pull/3261/head
guqing 2023-02-08 15:16:13 +08:00 committed by GitHub
parent 6809dbb251
commit 7453b93b1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 31 additions and 11 deletions

View File

@ -9,6 +9,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
@ -353,7 +354,8 @@ public class PluginReconciler implements Reconciler<Request> {
private void settingDefaultConfig(Plugin plugin) {
Assert.notNull(plugin, "The plugin must not be null.");
if (StringUtils.isBlank(plugin.getSpec().getSettingName())) {
final String settingName = plugin.getSpec().getSettingName();
if (StringUtils.isBlank(settingName)) {
return;
}
@ -368,16 +370,34 @@ public class PluginReconciler implements Reconciler<Request> {
return;
}
client.fetch(Setting.class, plugin.getSpec().getSettingName())
.ifPresent(setting -> {
var data = SettingUtils.settingDefinedDefaultValueMap(setting);
// Create with or without default value
ConfigMap configMap = new ConfigMap();
configMap.setMetadata(new Metadata());
configMap.getMetadata().setName(configMapNameToUse);
configMap.setData(data);
client.create(configMap);
});
Optional<Setting> settingOption = client.fetch(Setting.class, settingName);
// Fix gh-3224
// Maybe Setting is being created and cannot be queried. so try again.
if (settingOption.isEmpty()) {
client.fetch(Plugin.class, plugin.getMetadata().getName())
.ifPresent(newPlugin -> {
final Plugin.PluginStatus oldStatus =
JsonUtils.deepCopy(newPlugin.statusNonNull());
Plugin.PluginStatus status = newPlugin.statusNonNull();
status.setPhase(PluginState.FAILED);
status.setReason("ResourceNotReady");
status.setMessage("Setting for " + settingName + " is not ready, retrying...");
status.setLastTransitionTime(Instant.now());
if (!oldStatus.equals(status)) {
client.update(newPlugin);
}
throw new IllegalStateException(status.getMessage());
});
return;
}
var data = SettingUtils.settingDefinedDefaultValueMap(settingOption.get());
// Create with or without default value
ConfigMap configMap = new ConfigMap();
configMap.setMetadata(new Metadata());
configMap.getMetadata().setName(configMapNameToUse);
configMap.setData(data);
client.create(configMap);
}
static String initialReverseProxyName(String pluginName) {