feat: add an API to invalidate theme template cache (#5906)

#### What type of PR is this?
/kind feature
/area core
/area theme
/milestone 2.16.x

#### What this PR does / why we need it:
为主题管理增加在线清理缓存功能

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

#### Does this PR introduce a user-facing change?
```release-note
为主题管理增加在线清理缓存功能
```
pull/5928/head
guqing 2024-05-16 10:36:36 +08:00 committed by GitHub
parent e5bc699fb2
commit f24b08c7db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 172 additions and 1 deletions

View File

@ -4231,6 +4231,30 @@
]
}
},
"/apis/api.console.halo.run/v1alpha1/themes/{name}/invalidate-cache": {
"put": {
"description": "Invalidate theme template cache.",
"operationId": "InvalidateCache",
"parameters": [
{
"in": "path",
"name": "name",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "No Content"
}
},
"tags": [
"api.console.halo.run/v1alpha1/Theme"
]
}
},
"/apis/api.console.halo.run/v1alpha1/themes/{name}/reload": {
"put": {
"description": "Reload theme setting.",

View File

@ -6,6 +6,7 @@ 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.requestbody.Builder.requestBodyBuilder;
import static org.springdoc.core.fn.builders.schema.Builder.schemaBuilder;
import static org.springframework.http.HttpStatus.NO_CONTENT;
import static org.springframework.web.reactive.function.server.RequestPredicates.contentType;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
@ -188,6 +189,20 @@ public class ThemeEndpoint implements CustomEndpoint {
.response(responseBuilder()
.implementation(Theme.class))
)
.PUT("/themes/{name}/invalidate-cache", this::invalidateCache,
builder -> builder.operationId("InvalidateCache")
.description("Invalidate theme template cache.")
.tag(tag)
.parameter(parameterBuilder()
.name("name")
.in(ParameterIn.PATH)
.required(true)
.implementation(String.class)
)
.response(responseBuilder()
.responseCode(String.valueOf(NO_CONTENT.value()))
)
)
.GET("themes", this::listThemes,
builder -> {
builder.operationId("ListThemes")
@ -234,6 +249,13 @@ public class ThemeEndpoint implements CustomEndpoint {
.build();
}
private Mono<ServerResponse> invalidateCache(ServerRequest request) {
final var name = request.pathVariable("name");
return client.get(Theme.class, name)
.flatMap(theme -> templateEngineManager.clearCache(name))
.then(ServerResponse.noContent().build());
}
private Mono<ServerResponse> upgradeFromUri(ServerRequest request) {
final var name = request.pathVariable("name");
var content = request.bodyToMono(UpgradeFromUriRequest.class)

View File

@ -16,7 +16,7 @@ rules:
verbs: [ "*" ]
- apiGroups: [ "api.console.halo.run" ]
resources: [ "themes", "themes/reload", "themes/resetconfig", "themes/config", "themes/activation",
"themes/install-from-uri", "themes/upgrade-from-uri" ]
"themes/install-from-uri", "themes/upgrade-from-uri", "themes/invalidate-cache" ]
verbs: [ "*" ]
- nonResourceURLs: [ "/apis/api.console.halo.run/themes/install" ]
verbs: [ "create" ]

View File

@ -32,6 +32,27 @@ const themesModal = inject<Ref<boolean>>("themesModal");
const { isActivated, getFailedMessage, handleResetSettingConfig } =
useThemeLifeCycle(selectedTheme);
async function handleClearCache() {
Dialog.warning({
title: t("core.theme.operations.clear_templates_cache.title"),
description: t("core.theme.operations.clear_templates_cache.description"),
confirmText: t("core.common.buttons.confirm"),
cancelText: t("core.common.buttons.cancel"),
async onConfirm() {
if (!selectedTheme.value) {
console.error("No selected or activated theme");
return;
}
await apiClient.theme.invalidateCache({
name: selectedTheme.value?.metadata.name,
});
Toast.success(t("core.common.toast.operation_success"));
},
});
}
const handleReloadTheme = async () => {
Dialog.warning({
title: t("core.theme.operations.reload.title"),
@ -109,6 +130,9 @@ const handleReloadTheme = async () => {
<VDropdownItem type="danger" @click="handleReloadTheme">
{{ $t("core.theme.operations.reload.button") }}
</VDropdownItem>
<VDropdownItem type="danger" @click="handleClearCache">
{{ $t("core.theme.operations.clear_templates_cache.button") }}
</VDropdownItem>
<VDropdownItem type="danger" @click="handleResetSettingConfig">
{{ $t("core.common.buttons.reset") }}
</VDropdownItem>

View File

@ -279,6 +279,47 @@ export const ApiConsoleHaloRunV1alpha1ThemeApiAxiosParamCreator = function (conf
options: localVarRequestOptions,
};
},
/**
* Invalidate theme template cache.
* @param {string} name
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
invalidateCache: async (name: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'name' is not null or undefined
assertParamExists('invalidateCache', 'name', name)
const localVarPath = `/apis/api.console.halo.run/v1alpha1/themes/{name}/invalidate-cache`
.replace(`{${"name"}}`, encodeURIComponent(String(name)));
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
// authentication BasicAuth required
// http basic authentication required
setBasicAuthToObject(localVarRequestOptions, configuration)
// authentication BearerAuth required
// http bearer authentication required
await setBearerAuthToObject(localVarHeaderParameter, configuration)
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
* List themes.
* @param {number} [page] Page number. Default is 0.
@ -649,6 +690,18 @@ export const ApiConsoleHaloRunV1alpha1ThemeApiFp = function(configuration?: Conf
const localVarOperationServerBasePath = operationServerMap['ApiConsoleHaloRunV1alpha1ThemeApi.installThemeFromUri']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
/**
* Invalidate theme template cache.
* @param {string} name
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async invalidateCache(name: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.invalidateCache(name, options);
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['ApiConsoleHaloRunV1alpha1ThemeApi.invalidateCache']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
/**
* List themes.
* @param {number} [page] Page number. Default is 0.
@ -790,6 +843,15 @@ export const ApiConsoleHaloRunV1alpha1ThemeApiFactory = function (configuration?
installThemeFromUri(requestParameters: ApiConsoleHaloRunV1alpha1ThemeApiInstallThemeFromUriRequest, options?: RawAxiosRequestConfig): AxiosPromise<Theme> {
return localVarFp.installThemeFromUri(requestParameters.installFromUriRequest, options).then((request) => request(axios, basePath));
},
/**
* Invalidate theme template cache.
* @param {ApiConsoleHaloRunV1alpha1ThemeApiInvalidateCacheRequest} requestParameters Request parameters.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
invalidateCache(requestParameters: ApiConsoleHaloRunV1alpha1ThemeApiInvalidateCacheRequest, options?: RawAxiosRequestConfig): AxiosPromise<void> {
return localVarFp.invalidateCache(requestParameters.name, options).then((request) => request(axios, basePath));
},
/**
* List themes.
* @param {ApiConsoleHaloRunV1alpha1ThemeApiListThemesRequest} requestParameters Request parameters.
@ -903,6 +965,20 @@ export interface ApiConsoleHaloRunV1alpha1ThemeApiInstallThemeFromUriRequest {
readonly installFromUriRequest: InstallFromUriRequest
}
/**
* Request parameters for invalidateCache operation in ApiConsoleHaloRunV1alpha1ThemeApi.
* @export
* @interface ApiConsoleHaloRunV1alpha1ThemeApiInvalidateCacheRequest
*/
export interface ApiConsoleHaloRunV1alpha1ThemeApiInvalidateCacheRequest {
/**
*
* @type {string}
* @memberof ApiConsoleHaloRunV1alpha1ThemeApiInvalidateCache
*/
readonly name: string
}
/**
* Request parameters for listThemes operation in ApiConsoleHaloRunV1alpha1ThemeApi.
* @export
@ -1107,6 +1183,17 @@ export class ApiConsoleHaloRunV1alpha1ThemeApi extends BaseAPI {
return ApiConsoleHaloRunV1alpha1ThemeApiFp(this.configuration).installThemeFromUri(requestParameters.installFromUriRequest, options).then((request) => request(this.axios, this.basePath));
}
/**
* Invalidate theme template cache.
* @param {ApiConsoleHaloRunV1alpha1ThemeApiInvalidateCacheRequest} requestParameters Request parameters.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof ApiConsoleHaloRunV1alpha1ThemeApi
*/
public invalidateCache(requestParameters: ApiConsoleHaloRunV1alpha1ThemeApiInvalidateCacheRequest, options?: RawAxiosRequestConfig) {
return ApiConsoleHaloRunV1alpha1ThemeApiFp(this.configuration).invalidateCache(requestParameters.name, options).then((request) => request(this.axios, this.basePath));
}
/**
* List themes.
* @param {ApiConsoleHaloRunV1alpha1ThemeApiListThemesRequest} requestParameters Request parameters.

View File

@ -708,6 +708,12 @@ core:
existed_during_installation:
title: The theme already exists.
description: The currently installed theme already exists, do you want to upgrade?
clear_templates_cache:
button: Clear templates cache
title: Clear templates cache
description: >-
This feature allows you to refresh the cache to view the latest web
results after modifying template files at runtime.
list_modal:
tabs:
installed: Installed

View File

@ -680,6 +680,10 @@ core:
existed_during_installation:
title: 主题已存在
description: 当前安装的主题已存在,是否升级?
clear_templates_cache:
button: 清理模板缓存
title: 清除模板缓存
description: 此功能适用于在运行时修改模板文件后,刷新缓存以查看最新网页结果。
list_modal:
tabs:
installed: 已安装

View File

@ -660,6 +660,10 @@ core:
existed_during_installation:
title: 主題已存在
description: 當前安裝的主題已存在,是否升級?
clear_templates_cache:
button: 清除模板快取
title: 清除模板快取
description: 此功能適用於在運行時修改模板檔案後,刷新快取以查看最新網頁結果。
list_modal:
tabs:
installed: 已安裝