Skip to content

Commit

Permalink
faet: Add file prefix search function in s3link
Browse files Browse the repository at this point in the history
  • Loading branch information
longjuan committed May 25, 2024
1 parent 2a26171 commit d9877ee
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export function getApisS3OsHaloRunV1Alpha1ObjectsByPolicyName(params: GetApisS3O
continuationObject: params.continuationObject,
pageSize: params.pageSize,
unlinked: params.unlinked,
filePrefix: params.filePrefix,
};
return request.get<DeepRequired<S3ListResult>>(`/apis/s3os.halo.run/v1alpha1/objects/${params.policyName}`, {
params: paramsInput,
Expand All @@ -22,4 +23,5 @@ interface GetApisS3OsHaloRunV1Alpha1ObjectsByPolicyNameParams {
continuationObject?: any;
pageSize: any;
unlinked?: any;
filePrefix?: any;
}
4 changes: 3 additions & 1 deletion console/src/utils/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ request.interceptors.response.use(
return Promise.reject(error);
}
const { status } = errorResponse;
if (status !== 200) {
if (status === 400) {
Toast.error(errorResponse.data.detail);
} else if (status !== 200) {
Toast.error("status: " + status);
}
return Promise.reject(error);
Expand Down
18 changes: 17 additions & 1 deletion console/src/views/S3Link.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
VTag,
} from "@halo-dev/components";
import CarbonFolderDetailsReference from "~icons/carbon/folder-details-reference";
import IconErrorWarning from "~icons/ri/error-warning-line";
import {computed, onMounted, ref, watch} from "vue";
import {
getApisS3OsHaloRunV1Alpha1ObjectsByPolicyName,
Expand All @@ -31,6 +32,10 @@ const policyOptions = ref<{ label: string; value: string; attrs: any }[]>([{
value: "",
attrs: {disabled: true}
}]);
// update when fetch first page
const filePrefix = ref<string>("");
// update when user input
const filePrefixBind = ref<string>("");
const s3Objects = ref<S3ListResult>({
objects: [],
hasMore: false,
Expand Down Expand Up @@ -139,6 +144,8 @@ const clearTokenAndObject = () => {
s3Objects.value.nextContinuationObject = "";
};
// filePrefix will not be updated from user input
// if you want to update filePrefix, please call `handleFirstPage`
const fetchObjects = async () => {
if (!policyName.value) {
return;
Expand All @@ -152,6 +159,7 @@ const fetchObjects = async () => {
continuationToken: s3Objects.value.currentToken,
continuationObject: s3Objects.value.currentContinuationObject,
unlinked: selectedLinkedStatusItem.value,
filePrefix: filePrefix.value
});
if (objectsData.status == 200) {
s3Objects.value = objectsData.data;
Expand Down Expand Up @@ -222,6 +230,7 @@ const handleFirstPage = () => {
isFetching.value = true;
page.value = 1;
clearTokenAndObject();
filePrefix.value = filePrefixBind.value;
fetchObjects();
};
Expand Down Expand Up @@ -266,8 +275,15 @@ const handleModalClose = () => {
name="policyName"
type="select"
:options="policyOptions"
@change="fetchObjects()"
@change="handleFirstPage"
></FormKit>
<icon-error-warning v-if="!policyName" class="text-red-500"/>
<SearchInput
v-model="filePrefixBind"
v-if="policyName"
placeholder="请输入文件名前缀搜索"
@update:modelValue="handleFirstPage"
></SearchInput>
</div>
<VSpace v-else>
<VButton type="primary" @click="handleLink">
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/run/halo/s3os/S3LinkController.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ public Mono<S3ListResult> listObjects(@PathVariable(value = "policyName") String
@RequestParam(name = "continuationToken", required = false) String continuationToken,
@RequestParam(name = "continuationObject", required = false) String continuationObject,
@RequestParam(name = "pageSize") Integer pageSize,
@RequestParam(name = "unlinked", required = false, defaultValue = "false")
Boolean unlinked) {
@RequestParam(name = "unlinked", required = false, defaultValue = "false") Boolean unlinked,
@RequestParam(name = "filePrefix", required = false) String filePrefix) {
if (unlinked) {
return s3LinkService.listObjectsUnlinked(policyName, continuationToken,
continuationObject, pageSize);
continuationObject, pageSize, filePrefix);
} else {
return s3LinkService.listObjects(policyName, continuationToken, pageSize);
return s3LinkService.listObjects(policyName, continuationToken, pageSize, filePrefix);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/run/halo/s3os/S3LinkService.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ public interface S3LinkService {
Flux<Policy> listS3Policies();

Mono<S3ListResult> listObjects(String policyName, String continuationToken,
Integer pageSize);
Integer pageSize, String filePrefix);

Mono<LinkResult> addAttachmentRecords(String policyName, Set<String> objectKeys);

Mono<S3ListResult> listObjectsUnlinked(String policyName, String continuationToken,
String continuationObject, Integer pageSize);
String continuationObject, Integer pageSize, String filePrefix);
}
27 changes: 22 additions & 5 deletions src/main/java/run/halo/s3os/S3LinkServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public Flux<Policy> listS3Policies() {

@Override
public Mono<S3ListResult> listObjects(String policyName, String continuationToken,
Integer pageSize) {
Integer pageSize, String filePrefix) {
return client.fetch(Policy.class, policyName)
.flatMap((policy) -> {
var configMapName = policy.getSpec().getConfigMapName();
Expand All @@ -68,11 +68,11 @@ public Mono<S3ListResult> listObjects(String policyName, String continuationToke
var properties = handler.getProperties(configMap);
var finalLocation = FilePathUtils.getFilePathByPlaceholder(properties.getLocation());
return Mono.using(() -> handler.buildS3Client(properties),
// 执行 listObjects
(s3Client) -> Mono.fromCallable(
() -> s3Client.listObjectsV2(ListObjectsV2Request.builder()
.bucket(properties.getBucket())
.prefix(StringUtils.isNotEmpty(finalLocation)
? finalLocation + "/" : null)
.prefix(buildPrefix(finalLocation, filePrefix))
.delimiter("/")
.maxKeys(pageSize)
.continuationToken(StringUtils.isNotEmpty(continuationToken)
Expand All @@ -81,10 +81,12 @@ public Mono<S3ListResult> listObjects(String policyName, String continuationToke
S3Client::close)
.flatMap(listObjectsV2Response -> {
List<S3Object> contents = listObjectsV2Response.contents();
// 过滤掉目录并转换为ObjectVo
var objectVos = contents
.stream().map(S3ListResult.ObjectVo::fromS3Object)
.filter(objectVo -> !objectVo.getKey().endsWith("/"))
.collect(Collectors.toMap(S3ListResult.ObjectVo::getKey, o -> o));
// 获取已经关联的附件并标记
ListOptions listOptions = new ListOptions();
listOptions.setFieldSelector(
FieldSelector.of(QueryFactory.equal("spec.policyName", policyName)));
Expand Down Expand Up @@ -163,7 +165,7 @@ private Flux<LinkResult.LinkResultItem> getLinkResultItems(Set<String> objectKey

@Override
public Mono<S3ListResult> listObjectsUnlinked(String policyName, String continuationToken,
String continuationObject, Integer pageSize) {
String continuationObject, Integer pageSize, String filePrefix) {
// TODO 优化成查一次数据库
return Mono.defer(() -> {
List<S3ListResult.ObjectVo> s3Objects = new ArrayList<>();
Expand All @@ -172,7 +174,8 @@ public Mono<S3ListResult> listObjectsUnlinked(String policyName, String continua

return Flux.defer(() -> Flux.just(
new TokenState(null, currToken.get() == null ? "" : currToken.get())))
.flatMap(tokenState -> listObjects(policyName, tokenState.nextToken, pageSize))
.flatMap(tokenState -> listObjects(policyName, tokenState.nextToken,
pageSize, filePrefix))
.flatMap(s3ListResult -> {
var filteredObjects = s3ListResult.getObjects();
if (!continuationObjectMatched.get()) {
Expand Down Expand Up @@ -267,4 +270,18 @@ private <T> Mono<T> authenticationConsumer(Function<Authentication, Mono<T>> fun
.flatMap(func);
}

public String buildPrefix(String finalLocation, String filePrefix) {
if (StringUtils.isBlank(finalLocation) && StringUtils.isBlank(filePrefix)) {
return null;
}
StringBuilder sb = new StringBuilder();
if (StringUtils.isNotBlank(finalLocation)) {
sb.append(finalLocation).append("/");
}
if (StringUtils.isNotBlank(filePrefix)) {
sb.append(filePrefix);
}
return sb.toString();
}

}

0 comments on commit d9877ee

Please sign in to comment.