mirror of https://github.com/halo-dev/halo
feat: add API to update system config by group
parent
9de18d82c3
commit
dd2080c3ae
|
@ -3,26 +3,34 @@ package run.halo.app.core.endpoint;
|
||||||
import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder;
|
import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder;
|
||||||
import static org.springdoc.core.fn.builders.content.Builder.contentBuilder;
|
import static org.springdoc.core.fn.builders.content.Builder.contentBuilder;
|
||||||
import static org.springdoc.core.fn.builders.parameter.Builder.parameterBuilder;
|
import static org.springdoc.core.fn.builders.parameter.Builder.parameterBuilder;
|
||||||
|
import static org.springdoc.core.fn.builders.requestbody.Builder.requestBodyBuilder;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||||
|
import java.time.Duration;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springdoc.webflux.core.fn.SpringdocRouteBuilder;
|
import org.springdoc.webflux.core.fn.SpringdocRouteBuilder;
|
||||||
|
import org.springframework.dao.OptimisticLockingFailureException;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
import reactor.util.retry.Retry;
|
||||||
import run.halo.app.core.extension.endpoint.CustomEndpoint;
|
import run.halo.app.core.extension.endpoint.CustomEndpoint;
|
||||||
import run.halo.app.extension.GroupVersion;
|
import run.halo.app.extension.GroupVersion;
|
||||||
|
import run.halo.app.extension.ReactiveExtensionClient;
|
||||||
import run.halo.app.infra.SystemConfigurableEnvironmentFetcher;
|
import run.halo.app.infra.SystemConfigurableEnvironmentFetcher;
|
||||||
|
import run.halo.app.infra.utils.JsonUtils;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class SystemConfigEndpoint implements CustomEndpoint {
|
public class SystemConfigEndpoint implements CustomEndpoint {
|
||||||
private final SystemConfigurableEnvironmentFetcher configurableEnvironmentFetcher;
|
private final SystemConfigurableEnvironmentFetcher configurableEnvironmentFetcher;
|
||||||
|
private final ReactiveExtensionClient client;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RouterFunction<ServerResponse> endpoint() {
|
public RouterFunction<ServerResponse> endpoint() {
|
||||||
|
@ -44,9 +52,42 @@ public class SystemConfigEndpoint implements CustomEndpoint {
|
||||||
.description("Group of the system config")
|
.description("Group of the system config")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
.PUT("/systemconfigs/{group}", this::updateConfigByGroup,
|
||||||
|
builder -> builder.operationId("updateSystemConfigByGroup")
|
||||||
|
.description("Update system config by group")
|
||||||
|
.tag(tag)
|
||||||
|
.parameter(parameterBuilder()
|
||||||
|
.in(ParameterIn.PATH)
|
||||||
|
.name("group")
|
||||||
|
.required(true)
|
||||||
|
.description("Group of the system config")
|
||||||
|
)
|
||||||
|
.requestBody(requestBodyBuilder()
|
||||||
|
.implementation(ObjectNode.class)
|
||||||
|
)
|
||||||
|
.response(responseBuilder()
|
||||||
|
.responseCode(String.valueOf(HttpStatus.NO_CONTENT))
|
||||||
|
.implementation(Void.class)
|
||||||
|
)
|
||||||
|
)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Mono<ServerResponse> updateConfigByGroup(ServerRequest request) {
|
||||||
|
final var group = request.pathVariable("group");
|
||||||
|
return request.bodyToMono(ObjectNode.class)
|
||||||
|
.flatMap(objectNode -> configurableEnvironmentFetcher.getConfigMap()
|
||||||
|
.flatMap(configMap -> {
|
||||||
|
var data = configMap.getData();
|
||||||
|
data.put(group, JsonUtils.objectToJson(objectNode));
|
||||||
|
return client.update(configMap);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.retryWhen(Retry.backoff(5, Duration.ofMillis(100))
|
||||||
|
.filter(OptimisticLockingFailureException.class::isInstance))
|
||||||
|
.then(ServerResponse.noContent().build());
|
||||||
|
}
|
||||||
|
|
||||||
private Mono<ServerResponse> getConfigByGroup(ServerRequest request) {
|
private Mono<ServerResponse> getConfigByGroup(ServerRequest request) {
|
||||||
final var group = request.pathVariable("group");
|
final var group = request.pathVariable("group");
|
||||||
return configurableEnvironmentFetcher.fetch(group, ObjectNode.class)
|
return configurableEnvironmentFetcher.fetch(group, ObjectNode.class)
|
||||||
|
|
|
@ -14,6 +14,10 @@ rules:
|
||||||
- apiGroups: [ "" ]
|
- apiGroups: [ "" ]
|
||||||
resources: [ "menus", "menuitems" ]
|
resources: [ "menus", "menuitems" ]
|
||||||
verbs: [ "*" ]
|
verbs: [ "*" ]
|
||||||
|
- apiGroups: [ "console.api.halo.run" ]
|
||||||
|
resources: [ "systemconfigs" ]
|
||||||
|
resourceNames: [ "menu" ]
|
||||||
|
verbs: [ "update" ]
|
||||||
---
|
---
|
||||||
apiVersion: v1alpha1
|
apiVersion: v1alpha1
|
||||||
kind: "Role"
|
kind: "Role"
|
||||||
|
|
Loading…
Reference in New Issue