Skip to content

Commit

Permalink
Merge branch 'main' into feature/3016
Browse files Browse the repository at this point in the history
  • Loading branch information
ruibaby committed Aug 21, 2023
2 parents 6d6d358 + b437756 commit 8c5d2fa
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 95 deletions.
Expand Up @@ -22,6 +22,7 @@
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.function.UnaryOperator;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
Expand Down Expand Up @@ -139,34 +140,36 @@ boolean readinessDetection(String name) {
}
createInitialReverseProxyIfNotPresent(plugin);

// filled logo path
generateAccessibleLogoUrl(plugin);

// update phase
Plugin.PluginStatus status = plugin.statusNonNull();
PluginWrapper pluginWrapper = getPluginWrapper(name);
status.setPhase(pluginWrapper.getPluginState());
updateStatus(plugin.getMetadata().getName(), status);
updateStatus(name, status -> {
String logoUrl = generateAccessibleLogoUrl(plugin);
status.setLogo(logoUrl);

// Synchronize to plugin state in manager based on the phase of database
// to avoid the plugin state in manager is inconsistent with the database
// It is possible that the in-memory plugin has successfully started,
// but the status update of the database has failed.
// The status in the database will prevail
getPluginWrapper(name).setPluginState(status.getPhase());
return status;
});
return false;
})
.orElse(false);
}

void generateAccessibleLogoUrl(Plugin plugin) {
String generateAccessibleLogoUrl(Plugin plugin) {
String logo = plugin.getSpec().getLogo();
if (StringUtils.isBlank(logo)) {
return;
return null;
}
Plugin.PluginStatus status = plugin.statusNonNull();
if (PathUtils.isAbsoluteUri(logo)) {
status.setLogo(logo);
} else {
if (!PathUtils.isAbsoluteUri(logo)) {
String assetsPrefix =
PluginConst.assertsRoutePrefix(plugin.getMetadata().getName());
String versionedLogo =
applyVersioningToStaticResource(logo, plugin.getSpec().getVersion());
status.setLogo(PathUtils.combinePath(assetsPrefix, versionedLogo));
return PathUtils.combinePath(assetsPrefix, versionedLogo);
}
return logo;
}

Optional<Setting> lookupPluginSetting(String name, String settingName) {
Expand Down Expand Up @@ -231,18 +234,19 @@ boolean waitForSettingCreation(Plugin plugin) {
// Fix gh-3224
// Maybe Setting is being created and cannot be queried. so try again.
if (settingOption.isEmpty()) {
Plugin.PluginStatus status = plugin.statusNonNull();
status.setPhase(PluginState.FAILED);
var condition = Condition.builder()
.type("BackOff")
.reason("BackOff")
.message("Wait for setting [" + settingName + "] creation")
.status(ConditionStatus.FALSE)
.lastTransitionTime(Instant.now())
.build();
Plugin.PluginStatus.nullSafeConditions(status)
.addAndEvictFIFO(condition);
updateStatus(plugin.getMetadata().getName(), status);
updateStatus(plugin.getMetadata().getName(), status -> {
status.setPhase(PluginState.FAILED);
var condition = Condition.builder()
.type("BackOff")
.reason("BackOff")
.message("Wait for setting [" + settingName + "] creation")
.status(ConditionStatus.FALSE)
.lastTransitionTime(Instant.now())
.build();
Plugin.PluginStatus.nullSafeConditions(status)
.addAndEvictFIFO(condition);
return status;
});
// need requeue
return true;
}
Expand Down Expand Up @@ -316,9 +320,7 @@ void stateTransition(String name, Function<PluginState, Boolean> stateAction,
}

void persistenceFailureStatus(String pluginName, Throwable e) {
client.fetch(Plugin.class, pluginName).ifPresent(plugin -> {
Plugin.PluginStatus status = plugin.statusNonNull();

updateStatus(pluginName, status -> {
PluginWrapper pluginWrapper = haloPluginManager.getPlugin(pluginName);
if (pluginWrapper != null) {
pluginWrapper.setPluginState(PluginState.FAILED);
Expand All @@ -327,7 +329,6 @@ void persistenceFailureStatus(String pluginName, Throwable e) {

status.setPhase(PluginState.FAILED);

Plugin.PluginStatus oldStatus = JsonUtils.deepCopy(status);
Condition condition = Condition.builder()
.type(PluginState.FAILED.toString())
.reason("UnexpectedState")
Expand All @@ -337,9 +338,7 @@ void persistenceFailureStatus(String pluginName, Throwable e) {
.build();
Plugin.PluginStatus.nullSafeConditions(status)
.addAndEvictFIFO(condition);
if (!Objects.equals(oldStatus, status)) {
client.update(plugin);
}
return status;
});
}

Expand All @@ -352,33 +351,35 @@ private PluginWrapper getPluginWrapper(String name) {
}

if (pluginWrapper == null) {
Plugin.PluginStatus status = new Plugin.PluginStatus();
status.setPhase(PluginState.FAILED);

String errorMsg = "Plugin " + name + " not found in plugin manager.";
Condition condition = Condition.builder()
.type(PluginState.FAILED.toString())
.reason("PluginNotFound")
.message(errorMsg)
.status(ConditionStatus.FALSE)
.lastTransitionTime(Instant.now())
.build();
Plugin.PluginStatus.nullSafeConditions(status)
.addAndEvictFIFO(condition);
updateStatus(name, status);
updateStatus(name, status -> {
status.setPhase(PluginState.FAILED);

Condition condition = Condition.builder()
.type(PluginState.FAILED.toString())
.reason("PluginNotFound")
.message(errorMsg)
.status(ConditionStatus.FALSE)
.lastTransitionTime(Instant.now())
.build();
Plugin.PluginStatus.nullSafeConditions(status)
.addAndEvictFIFO(condition);
return status;
});
throw new DoNotRetryException(errorMsg);
}
return pluginWrapper;
}

void updateStatus(String name, Plugin.PluginStatus status) {
if (status == null) {
return;
}
void updateStatus(String name, UnaryOperator<Plugin.PluginStatus> operator) {
client.fetch(Plugin.class, name).ifPresent(plugin -> {
Plugin.PluginStatus oldStatus = JsonUtils.deepCopy(plugin.statusNonNull());
plugin.setStatus(status);
URI loadLocation = status.getLoadLocation();
Plugin.PluginStatus newStatus =
Optional.ofNullable(operator.apply(plugin.statusNonNull()))
.orElse(new Plugin.PluginStatus());
plugin.setStatus(newStatus);

URI loadLocation = newStatus.getLoadLocation();
if (loadLocation == null) {
String pluginPath = nullSafeAnnotations(plugin).get(PLUGIN_PATH);
if (StringUtils.isNotBlank(pluginPath)) {
Expand All @@ -387,9 +388,9 @@ void updateStatus(String name, Plugin.PluginStatus status) {
} else {
loadLocation = getPluginWrapper(name).getPluginPath().toUri();
}
status.setLoadLocation(loadLocation);
newStatus.setLoadLocation(loadLocation);
}
if (!Objects.equals(oldStatus, status)) {
if (!Objects.equals(oldStatus, newStatus)) {
client.update(plugin);
}
});
Expand All @@ -411,20 +412,19 @@ void doStart(String name) {
"The plugin is disabled for some reason and cannot be started.");
}

client.fetch(Plugin.class, name).ifPresent(plugin -> {
final Plugin.PluginStatus status = plugin.statusNonNull();
final Plugin.PluginStatus oldStatus = JsonUtils.deepCopy(status);

String pluginVersion = pluginWrapper.getDescriptor().getVersion();
updateStatus(name, status -> {
PluginState currentState = haloPluginManager.startPlugin(name);
if (!PluginState.STARTED.equals(currentState)) {
PluginStartingError staringErrorInfo = getStaringErrorInfo(name);
log.debug("Failed to start plugin: " + staringErrorInfo.getDevMessage());
throw new IllegalStateException(staringErrorInfo.getMessage());
log.debug("Failed to start plugin: " + staringErrorInfo.getDevMessage(),
pluginWrapper.getFailedException());
throw new IllegalStateException(staringErrorInfo.getMessage(),
pluginWrapper.getFailedException());
}

plugin.statusNonNull().setLastStartTime(Instant.now());
status.setLastStartTime(Instant.now());

final String pluginVersion = plugin.getSpec().getVersion();
String jsBundlePath =
BundleResourceUtils.getJsBundlePath(haloPluginManager, name);
jsBundlePath = applyVersioningToStaticResource(jsBundlePath, pluginVersion);
Expand All @@ -445,9 +445,7 @@ void doStart(String name) {
.build();
Plugin.PluginStatus.nullSafeConditions(status)
.addAndEvictFIFO(condition);
if (!Objects.equals(oldStatus, status)) {
client.update(plugin);
}
return status;
});
}

Expand All @@ -470,10 +468,7 @@ PluginStartingError getStaringErrorInfo(String name) {
}

void doStop(String name) {
client.fetch(Plugin.class, name).ifPresent(plugin -> {
final Plugin.PluginStatus status = plugin.statusNonNull();
final Plugin.PluginStatus oldStatus = JsonUtils.deepCopy(status);

updateStatus(name, status -> {
PluginState currentState = haloPluginManager.stopPlugin(name);
if (!PluginState.STOPPED.equals(currentState)) {
throw new IllegalStateException("Failed to stop plugin: " + name);
Expand All @@ -492,9 +487,7 @@ void doStop(String name) {
.build();
Plugin.PluginStatus.nullSafeConditions(status)
.addAndEvictFIFO(condition);
if (!Objects.equals(oldStatus, status)) {
client.update(plugin);
}
return status;
});
}

Expand Down Expand Up @@ -640,16 +633,24 @@ URI toUri(String pathString) {
return Paths.get(pathString).toUri();
}

private boolean shouldReconcileStartState(Plugin plugin) {
boolean shouldReconcileStartState(Plugin plugin) {
PluginWrapper pluginWrapper = getPluginWrapper(plugin.getMetadata().getName());
return BooleanUtils.isTrue(plugin.getSpec().getEnabled())
&& !PluginState.STARTED.equals(pluginWrapper.getPluginState());
if (BooleanUtils.isNotTrue(plugin.getSpec().getEnabled())) {
return false;
}
// phase is not started or plugin state is not started should start
return !PluginState.STARTED.equals(plugin.statusNonNull().getPhase())
|| !PluginState.STARTED.equals(pluginWrapper.getPluginState());
}

private boolean shouldReconcileStopState(Plugin plugin) {
boolean shouldReconcileStopState(Plugin plugin) {
PluginWrapper pluginWrapper = getPluginWrapper(plugin.getMetadata().getName());
return BooleanUtils.isFalse(plugin.getSpec().getEnabled())
&& PluginState.STARTED.equals(pluginWrapper.getPluginState());
if (BooleanUtils.isNotFalse(plugin.getSpec().getEnabled())) {
return false;
}
// phase is not stopped or plugin state is not stopped should stop
return !PluginState.STOPPED.equals(plugin.statusNonNull().getPhase())
|| !PluginState.STOPPED.equals(pluginWrapper.getPluginState());
}

private void addFinalizerIfNecessary(Plugin oldPlugin) {
Expand Down

0 comments on commit 8c5d2fa

Please sign in to comment.